blob: 895831080f7932e0036dc1f4f4226126ca1fdee6 [file] [log] [blame]
// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import Cocoa
import TulsiGenerator
private func main() {
// Parse the commandline parameters to see if the app should operate in headless mode or not.
let commandlineParser = TulsiCommandlineParser()
let consoleLogger = EventLogger(verboseLevel: commandlineParser.arguments.verboseLevel)
consoleLogger.startLogging()
if !commandlineParser.commandlineSentinalFound {
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
exit(0)
}
let version = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "unknown"
LogMessage.postSyslog("Tulsi CLI: version \(version)")
let queue = DispatchQueue(label: "com.google.Tulsi.xcodeProjectGenerator", attributes: [])
queue.async {
do {
switch commandlineParser.mode {
case .invalid:
print("Missing mode parameter. Please see the help message.")
exit(2)
case .tulsiProjectCreator:
let generator = HeadlessTulsiProjectCreator(arguments: commandlineParser.arguments)
try generator.generate()
case .xcodeProjectGenerator:
let generator = HeadlessXcodeProjectGenerator(arguments: commandlineParser.arguments)
try generator.generate()
}
} catch HeadlessModeError.invalidConfigPath(let reason) {
print("Invalid \(TulsiCommandlineParser.ParamGeneratorConfigLong) param: \(reason)")
exit(11)
} catch HeadlessModeError.invalidConfigFileContents(let reason) {
print("Failed to read the given generator config: \(reason)")
exit(12)
} catch HeadlessModeError.explicitOutputOptionRequired {
print("The \(TulsiCommandlineParser.ParamOutputFolderLong) option is required for the selected config")
exit(13)
} catch HeadlessModeError.invalidBazelPath {
print("The path to the bazel binary is invalid")
exit(14)
} catch HeadlessModeError.generationFailed() {
print("Xcode project generation failed")
exit(15)
} catch HeadlessModeError.invalidWorkspaceRootOverride {
print("The parameter given as the workspace root path is not a valid directory")
exit(16)
} catch HeadlessModeError.invalidProjectFileContents(let reason) {
print("Failed to read the given project: \(reason)")
exit(20)
} catch HeadlessModeError.missingBazelPath {
print("The path to the bazel binary must be specified")
exit(21)
} catch HeadlessModeError.missingWORKSPACEFile(let path) {
print("The workspace root at '\(path)' does not contain a Bazel WORKSPACE file.")
exit(21)
} catch HeadlessModeError.missingBuildTargets {
print("At least one build target must be specified with the \(TulsiCommandlineParser.ParamBuildTargetLong) parameter.")
exit(22)
} catch HeadlessModeError.invalidProjectBundleName {
print("The parameter given to \(TulsiCommandlineParser.ParamCreateTulsiProj) is invalid. " +
"It must be the name of the .tulsiproj bundle to be created, without any other " +
"path elements.")
exit(23)
} catch HeadlessModeError.bazelTargetProcessingFailed {
print("Failed to identify any valid build targets.")
exit(24)
} catch let e as NSError {
print("An unexpected exception occurred: \(e.localizedDescription)")
exit(126)
} catch {
print("An unexpected exception occurred")
exit(127)
}
// Ideally this would go just after generator.generate() inside the do block, but doing so trips
// up the coverage tool as exit is @noreturn. It is important that all catch blocks exit with
// non-zero codes so that they do not reach this.
exit(0)
}
dispatchMain()
}
// MARK: - Application entrypoint
main()