func generate()

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
    }
  }