mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
@@ -4,6 +4,7 @@
|
||||
|
||||
#### Added
|
||||
- Add Carthage static framework dependencies support. [#688](https://github.com/yonaskolb/XcodeGen/pull/688) @giginet
|
||||
- Added `xcodegen dump` command [#710](https://github.com/yonaskolb/XcodeGen/pull/710) @yonaskolb
|
||||
- Added `--no-env` option to disable environment variables expansion [#704](https://github.com/yonaskolb/XcodeGen/pull/704) @rcari
|
||||
|
||||
#### Fixed
|
||||
|
||||
@@ -130,7 +130,7 @@ Options:
|
||||
- **--use-cache**: Used to prevent unnecessarily generating the project. If this is set, then a cache file will be written to when a project is generated. If `xcodegen` is later run but the spec and all the files it contains are the same, the project won't be generated.
|
||||
- **--cache-path**: A custom path to use for your cache file. This defaults to `~/.xcodegen/cache/{PROJECT_SPEC_PATH_HASH}`
|
||||
|
||||
Use `xcodegen help` to see more detailed usage information.
|
||||
There are other commands as well. Use `xcodegen help` to see more detailed usage information.
|
||||
|
||||
## Editing
|
||||
```shell
|
||||
|
||||
@@ -144,7 +144,7 @@ extension Dictionary where Key == String, Value: Any {
|
||||
return merged
|
||||
}
|
||||
|
||||
func expand(variables: [String:String]) -> JSONDictionary {
|
||||
func expand(variables: [String: String]) -> JSONDictionary {
|
||||
var expanded: JSONDictionary = self
|
||||
|
||||
if !variables.isEmpty {
|
||||
@@ -189,8 +189,7 @@ extension Dictionary where Key == String, Value: Any {
|
||||
index = result.endIndex
|
||||
} else if substring[index] == "$"
|
||||
&& substring[substring.index(index, offsetBy: 1)] == "{"
|
||||
&& substring[substring.index(index, offsetBy: 2)] != "}"
|
||||
{
|
||||
&& substring[substring.index(index, offsetBy: 2)] != "}" {
|
||||
// This is the start of a variable expansion...
|
||||
let variableStart = index
|
||||
if let variableEnd = substring.firstIndex(of: "}") {
|
||||
|
||||
@@ -7,7 +7,7 @@ import Yams
|
||||
public class SpecLoader {
|
||||
|
||||
var project: Project!
|
||||
private var projectDictionary: [String: Any]?
|
||||
public private(set) var projectDictionary: [String: Any]?
|
||||
let version: Version
|
||||
|
||||
public init(version: Version) {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import Foundation
|
||||
import SwiftCLI
|
||||
import PathKit
|
||||
import ProjectSpec
|
||||
import Yams
|
||||
|
||||
class DumpCommand: ProjectCommand {
|
||||
|
||||
private let dumpType = Key<DumpType>(
|
||||
"--type",
|
||||
"-t",
|
||||
description: """
|
||||
The type of dump to output. Either \(DumpType.allCases.map { "\"\($0.rawValue)\"" }.joined(separator: ", ")). Defaults to \(DumpType.defaultValue.rawValue). The "parsed" types parse the project into swift and then back again.
|
||||
"""
|
||||
)
|
||||
|
||||
private let file = Key<Path>(
|
||||
"--file",
|
||||
"-f",
|
||||
description: "The path of a file to write to. If not supplied will output to stdout"
|
||||
)
|
||||
|
||||
init(version: Version) {
|
||||
super.init(version: version,
|
||||
name: "dump",
|
||||
shortDescription: "Dumps the resolved project spec to stdout or a file"
|
||||
)
|
||||
}
|
||||
|
||||
override func execute(specLoader: SpecLoader, projectSpecPath: Path, project: Project) throws {
|
||||
let type = dumpType.value ?? .defaultValue
|
||||
|
||||
let output: String
|
||||
switch type {
|
||||
case .swiftDump:
|
||||
var string = ""
|
||||
dump(project, to: &string)
|
||||
output = string
|
||||
case .json:
|
||||
let data = try JSONSerialization.data(withJSONObject: specLoader.projectDictionary!, options: .prettyPrinted)
|
||||
output = String(data: data, encoding: .utf8)!
|
||||
case .yaml:
|
||||
output = try Yams.dump(object: specLoader.projectDictionary!)
|
||||
case .parsedJSON:
|
||||
let data = try JSONSerialization.data(withJSONObject: project.toJSONDictionary(), options: .prettyPrinted)
|
||||
output = String(data: data, encoding: .utf8)!
|
||||
case .parsedYaml:
|
||||
output = try Yams.dump(object: project.toJSONDictionary())
|
||||
case .summary:
|
||||
output = project.debugDescription
|
||||
}
|
||||
|
||||
if let file = file.value {
|
||||
try file.parent().mkpath()
|
||||
try file.write(output)
|
||||
} else {
|
||||
stdout.print(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum DumpType: String, ConvertibleFromString, CaseIterable {
|
||||
case swiftDump = "swift-dump"
|
||||
case json
|
||||
case yaml
|
||||
case parsedJSON = "parsed-json"
|
||||
case parsedYaml = "parsed-yaml"
|
||||
case summary
|
||||
|
||||
static var defaultValue: DumpType { .yaml }
|
||||
}
|
||||
+10
-40
@@ -5,10 +5,7 @@ import SwiftCLI
|
||||
import XcodeGenKit
|
||||
import XcodeProj
|
||||
|
||||
class GenerateCommand: Command {
|
||||
|
||||
let name: String = "generate"
|
||||
let shortDescription: String = "Generate an Xcode project from a spec"
|
||||
class GenerateCommand: ProjectCommand {
|
||||
|
||||
let quiet = Flag(
|
||||
"-q",
|
||||
@@ -17,13 +14,6 @@ class GenerateCommand: Command {
|
||||
defaultValue: false
|
||||
)
|
||||
|
||||
let disableEnvExpansion = Flag(
|
||||
"-n",
|
||||
"--no-env",
|
||||
description: "Disable environment variables expansions",
|
||||
defaultValue: false
|
||||
)
|
||||
|
||||
let useCache = Flag(
|
||||
"-c",
|
||||
"--use-cache",
|
||||
@@ -36,43 +26,23 @@ class GenerateCommand: Command {
|
||||
description: "Where the cache file will be loaded from and save to. Defaults to ~/.xcodegen/cache/{SPEC_PATH_HASH}"
|
||||
)
|
||||
|
||||
let spec = Key<Path>(
|
||||
"-s",
|
||||
"--spec",
|
||||
description: "The path to the project spec file. Defaults to project.yml"
|
||||
let projectDirectory = Key<Path>(
|
||||
"-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"
|
||||
)
|
||||
|
||||
let projectDirectory = Key<Path>("-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")
|
||||
|
||||
let version: Version
|
||||
|
||||
init(version: Version) {
|
||||
self.version = version
|
||||
super.init(version: version,
|
||||
name: "generate",
|
||||
shortDescription: "Generate an Xcode project from a spec"
|
||||
)
|
||||
}
|
||||
|
||||
func execute() throws {
|
||||
|
||||
let projectSpecPath = (spec.value ?? "project.yml").absolute()
|
||||
override func execute(specLoader: SpecLoader, projectSpecPath: Path, project: Project) throws {
|
||||
|
||||
let projectDirectory = self.projectDirectory.value?.absolute() ?? projectSpecPath.parent()
|
||||
|
||||
if !projectSpecPath.exists {
|
||||
throw GenerationError.missingProjectSpec(projectSpecPath)
|
||||
}
|
||||
|
||||
let specLoader = SpecLoader(version: version)
|
||||
let project: Project
|
||||
|
||||
let variables: [String: String] = disableEnvExpansion.value ? [:] : ProcessInfo.processInfo.environment
|
||||
|
||||
// load project spec
|
||||
do {
|
||||
project = try specLoader.loadProject(path: projectSpecPath, variables: variables)
|
||||
info("Loaded project:\n \(project.debugDescription.replacingOccurrences(of: "\n", with: "\n "))")
|
||||
} catch {
|
||||
throw GenerationError.projectSpecParsingError(error)
|
||||
}
|
||||
|
||||
// validate project dictionary
|
||||
do {
|
||||
try specLoader.validateProjectDictionaryWarnings()
|
||||
@@ -0,0 +1,56 @@
|
||||
import Foundation
|
||||
import SwiftCLI
|
||||
import ProjectSpec
|
||||
import XcodeGenKit
|
||||
import PathKit
|
||||
import Core
|
||||
|
||||
class ProjectCommand: Command {
|
||||
|
||||
let version: Version
|
||||
let name: String
|
||||
let shortDescription: String
|
||||
|
||||
let spec = Key<Path>(
|
||||
"-s",
|
||||
"--spec",
|
||||
description: "The path to the project spec file. Defaults to project.yml"
|
||||
)
|
||||
|
||||
let disableEnvExpansion = Flag(
|
||||
"-n",
|
||||
"--no-env",
|
||||
description: "Disable environment variable expansions",
|
||||
defaultValue: false
|
||||
)
|
||||
|
||||
init(version: Version, name: String, shortDescription: String) {
|
||||
self.version = version
|
||||
self.name = name
|
||||
self.shortDescription = shortDescription
|
||||
}
|
||||
|
||||
func execute() throws {
|
||||
|
||||
let projectSpecPath = (spec.value ?? "project.yml").absolute()
|
||||
|
||||
if !projectSpecPath.exists {
|
||||
throw GenerationError.missingProjectSpec(projectSpecPath)
|
||||
}
|
||||
|
||||
let specLoader = SpecLoader(version: version)
|
||||
let project: Project
|
||||
|
||||
let variables: [String: String] = disableEnvExpansion.value ? [:] : ProcessInfo.processInfo.environment
|
||||
|
||||
do {
|
||||
project = try specLoader.loadProject(path: projectSpecPath, variables: variables)
|
||||
} catch {
|
||||
throw GenerationError.projectSpecParsingError(error)
|
||||
}
|
||||
|
||||
try execute(specLoader: specLoader, projectSpecPath: projectSpecPath, project: project)
|
||||
}
|
||||
|
||||
func execute(specLoader: SpecLoader, projectSpecPath: Path, project: Project) throws {}
|
||||
}
|
||||
@@ -12,7 +12,10 @@ public class XcodeGenCLI {
|
||||
name: "xcodegen",
|
||||
version: version.string,
|
||||
description: "Generates Xcode projects",
|
||||
commands: [generateCommand]
|
||||
commands: [
|
||||
generateCommand,
|
||||
DumpCommand(version: version),
|
||||
]
|
||||
)
|
||||
cli.parser.routeBehavior = .searchWithFallback(generateCommand)
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ public class PBXProjGenerator {
|
||||
let dependecyLinkage = dependencyTarget.defaultLinkage
|
||||
let link = dependency.link ??
|
||||
((dependecyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
(dependecyLinkage == .static && target.type.isExecutable))
|
||||
(dependecyLinkage == .static && target.type.isExecutable))
|
||||
|
||||
if link {
|
||||
let dependencyFile = targetFileReferences[dependencyTarget.name]!
|
||||
|
||||
Reference in New Issue
Block a user