in src/Tulsi/HeadlessXcodeProjectGenerator.swift [24:119]
func generate() throws {
TulsiProjectDocument.showAlertsOnErrors = false
let explicitBazelURL: URL?
if let bazelPath = arguments.bazel {
if !FileManager.default.isExecutableFile(atPath: bazelPath) {
throw HeadlessModeError.invalidBazelPath
}
explicitBazelURL = URL(fileURLWithPath: bazelPath)
TulsiProjectDocument.suppressRuleEntryUpdateOnLoad = true
} else {
explicitBazelURL = nil
}
defer {
TulsiProjectDocument.showAlertsOnErrors = true
TulsiProjectDocument.suppressRuleEntryUpdateOnLoad = false
}
guard let configPath = arguments.generatorConfig else {
fatalError("HeadlessXcodeProjectGenerator invoked without a valid generatorConfig")
}
let (projectURL, configURL, defaultOutputFolderURL) = try resolveConfigPath(configPath)
let documentController = NSDocumentController.shared
let doc: NSDocument
do {
doc = try documentController.makeDocument(withContentsOf: projectURL,
ofType: "com.google.tulsi.project")
} catch TulsiProjectDocument.DocumentError.invalidWorkspace(let info) {
throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to invalid workspace: \(info)")
} catch let e as NSError {
throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to unexpected exception: \(e)")
} catch {
throw HeadlessModeError.invalidProjectFileContents("Failed to load project due to unexpected exception.")
}
guard let projectDocument = doc as? TulsiProjectDocument else {
throw HeadlessModeError.invalidProjectFileContents("\(doc) is not of the expected type.")
}
let outputFolderURL: URL
if let option = arguments.outputFolder {
outputFolderURL = URL(fileURLWithPath: option, isDirectory: true)
} else if let defaultOutputFolderURL = defaultOutputFolderURL {
outputFolderURL = defaultOutputFolderURL
} else {
throw HeadlessModeError.explicitOutputOptionRequired
}
var config = try loadConfig(configURL, bazelURL: explicitBazelURL)
config = config.configByAppendingPathFilters(arguments.additionalPathFilters)
if let project = projectDocument.project {
config = config.configByResolvingInheritedSettingsFromProject(project)
}
let workspaceRootURL: URL
let projectWorkspaceRootURL = projectDocument.workspaceRootURL
if let workspaceRootOverride = arguments.workspaceRootOverride {
workspaceRootURL = URL(fileURLWithPath: workspaceRootOverride, isDirectory: true)
if !isExistingDirectory(workspaceRootURL) {
throw HeadlessModeError.invalidWorkspaceRootOverride
}
if projectWorkspaceRootURL != nil {
print("Overriding project workspace root (\(projectWorkspaceRootURL!.path)) with " +
"command-line parameter (\(workspaceRootOverride))")
}
} else {
guard let projectWorkspaceRootURL = projectWorkspaceRootURL else {
throw HeadlessModeError.invalidProjectFileContents("Invalid workspaceRoot")
}
workspaceRootURL = projectWorkspaceRootURL as URL
}
print("Generating project into '\(outputFolderURL.path)' using:\n" +
"\tconfig at '\(configURL.path)'\n" +
"\tBazel workspace at '\(workspaceRootURL.path)'\n" +
"\tBazel at '\(config.bazelURL.path)'.\n" +
"This may take a while.")
let result = TulsiGeneratorConfigDocument.generateXcodeProjectInFolder(outputFolderURL,
withGeneratorConfig: config,
workspaceRootURL: workspaceRootURL,
messageLog: nil)
switch result {
case .success(let url):
print("Generated project at \(url.path)")
if arguments.openXcodeOnSuccess {
print("Opening generated project in Xcode")
NSWorkspace.shared.open(url)
}
case .failure:
throw HeadlessModeError.generationFailed
}
}