mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
43e40a9efc
* wip * Added scheme management metadata properties to TargetScheme * wip * Added Scheme.Management for metadata * use sharedDefault * move generateSchemeManagement to SchemeGenerator * revert * update changelog * update docs * update test case * remove * remove unused file * revert * changed on fixtures project * Updated ProjectSpec docs index * User Scheme.Management also for TargetSchemes, use XCUserData * Changelog * Switch XcodeProj back tuist/XcodeProj - 8.9.0 * Reindent TOC Docs/ProjectSpec.md * Revert swift tools version --------- Co-authored-by: Tieme van Veen <tiemevanveen@hotmail.com>
160 lines
5.0 KiB
Swift
160 lines
5.0 KiB
Swift
import Foundation
|
|
import PathKit
|
|
import ProjectSpec
|
|
import SwiftCLI
|
|
import XcodeGenKit
|
|
import XcodeProj
|
|
import Version
|
|
|
|
class GenerateCommand: ProjectCommand {
|
|
|
|
@Flag("-q", "--quiet", description: "Suppress all informational and success output")
|
|
var quiet: Bool
|
|
|
|
@Flag("-c", "--use-cache", description: "Use a cache for the xcodegen spec. This will prevent unnecessarily generating the project if nothing has changed")
|
|
var useCache: Bool
|
|
|
|
@Key("--cache-path", description: "Where the cache file will be loaded from and save to. Defaults to ~/.xcodegen/cache/{SPEC_PATH_HASH}")
|
|
var cacheFilePath: Path?
|
|
|
|
@Key("-p", "--project", description: "The path to the directory where the project should be generated. Defaults to the directory the spec is in. The filename is defined in the project spec")
|
|
var projectDirectory: Path?
|
|
|
|
@Flag("--only-plists", description: "Generate only plist files")
|
|
var onlyPlists: Bool
|
|
|
|
init(version: Version) {
|
|
super.init(version: version,
|
|
name: "generate",
|
|
shortDescription: "Generate an Xcode project from a spec")
|
|
}
|
|
|
|
override func execute(specLoader: SpecLoader, projectSpecPath: Path, project: Project) throws {
|
|
|
|
let projectDirectory = self.projectDirectory?.absolute() ?? projectSpecPath.parent()
|
|
|
|
// validate project dictionary
|
|
do {
|
|
try specLoader.validateProjectDictionaryWarnings()
|
|
} catch {
|
|
warning("\(error)")
|
|
}
|
|
|
|
let projectPath = projectDirectory + "\(project.name).xcodeproj"
|
|
|
|
let cacheFilePath = self.cacheFilePath ??
|
|
Path("~/.xcodegen/cache/\(projectSpecPath.absolute().string.md5)").absolute()
|
|
var cacheFile: CacheFile?
|
|
|
|
// read cache
|
|
if useCache || self.cacheFilePath != nil {
|
|
do {
|
|
cacheFile = try specLoader.generateCacheFile()
|
|
} catch {
|
|
throw GenerationError.projectSpecParsingError(error)
|
|
}
|
|
}
|
|
|
|
let projectExists = XcodeProj.pbxprojPath(projectPath).exists
|
|
|
|
// check cache
|
|
if let cacheFile = cacheFile,
|
|
projectExists,
|
|
cacheFilePath.exists {
|
|
do {
|
|
let existingCacheFile: String = try cacheFilePath.read()
|
|
if cacheFile.string == existingCacheFile {
|
|
info("Project \(project.name) has not changed since cache was written")
|
|
return
|
|
}
|
|
} catch {
|
|
info("Couldn't load cache at \(cacheFile)")
|
|
}
|
|
}
|
|
|
|
// validate project
|
|
do {
|
|
try project.validateMinimumXcodeGenVersion(version)
|
|
try project.validate()
|
|
} catch let error as SpecValidationError {
|
|
throw GenerationError.validationError(error)
|
|
}
|
|
|
|
// run pre gen command
|
|
if let command = project.options.preGenCommand {
|
|
try Task.run(bash: command, directory: projectDirectory.absolute().string)
|
|
}
|
|
|
|
// generate plists
|
|
info("⚙️ Generating plists...")
|
|
let fileWriter = FileWriter(project: project)
|
|
do {
|
|
try fileWriter.writePlists()
|
|
if onlyPlists {
|
|
return
|
|
}
|
|
} catch {
|
|
throw GenerationError.writingError(error)
|
|
}
|
|
|
|
// generate project
|
|
info("⚙️ Generating project...")
|
|
let xcodeProject: XcodeProj
|
|
do {
|
|
let projectGenerator = ProjectGenerator(project: project)
|
|
|
|
guard let userName = ProcessInfo.processInfo.environment["LOGNAME"] else {
|
|
throw GenerationError.missingUsername
|
|
}
|
|
|
|
xcodeProject = try projectGenerator.generateXcodeProject(in: projectDirectory, userName: userName)
|
|
|
|
} catch {
|
|
throw GenerationError.generationError(error)
|
|
}
|
|
|
|
// write project
|
|
info("⚙️ Writing project...")
|
|
do {
|
|
try fileWriter.writeXcodeProject(xcodeProject, to: projectPath)
|
|
|
|
success("Created project at \(projectPath)")
|
|
} catch {
|
|
throw GenerationError.writingError(error)
|
|
}
|
|
|
|
// write cache
|
|
if let cacheFile = cacheFile {
|
|
do {
|
|
try cacheFilePath.parent().mkpath()
|
|
try cacheFilePath.write(cacheFile.string)
|
|
} catch {
|
|
info("Failed to write cache: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
|
|
// run post gen command
|
|
if let command = project.options.postGenCommand {
|
|
try Task.run(bash: command, directory: projectDirectory.absolute().string)
|
|
}
|
|
}
|
|
|
|
func info(_ string: String) {
|
|
if !quiet {
|
|
stdout.print(string)
|
|
}
|
|
}
|
|
|
|
func warning(_ string: String) {
|
|
if !quiet {
|
|
stdout.print(string.yellow)
|
|
}
|
|
}
|
|
|
|
func success(_ string: String) {
|
|
if !quiet {
|
|
stdout.print(string.green)
|
|
}
|
|
}
|
|
}
|