Skip to content

Commit

Permalink
Add support for child configs (#1338)
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmya authored Oct 24, 2024
1 parent c7000ef commit 402a79b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 7 deletions.
6 changes: 3 additions & 3 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"location" : "https://github.com/swiftlang/swift-syntax.git",
"state" : {
"revision" : "08a2f0a9a30e0f705f79c9cfaca1f68b71bdc775",
"version" : "510.0.0"
"revision" : "2bc86522d115234d1f588efe2bcb4ce4be8f8b82",
"version" : "510.0.3"
}
},
{
Expand Down
17 changes: 14 additions & 3 deletions Sourcery/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public struct Package {
})
semaphore.wait()

guard let manifest = try manifestResult?.get() else{
guard let manifest = try manifestResult?.get() else {
throw Configuration.Error.invalidSources(message: "Unable to load manifest")
}
self.root = path
Expand Down Expand Up @@ -227,6 +227,8 @@ public enum Source {
} else if let packages = (dict["package"] as? [[String: Any]]) ?? (dict["package"] as? [String: Any]).map({ [$0] }) {
guard !packages.isEmpty else { throw Configuration.Error.invalidSources(message: "No packages provided.") }
self = try .packages(packages.map({ try Package(dict: $0, relativePath: relativePath) }))
} else if dict["child"] != nil {
throw Configuration.Error.internalError(message: "'child' should have been parsed already.")
} else {
throw Configuration.Error.invalidSources(message: "'sources', 'project' or 'package' key are missing.")
}
Expand Down Expand Up @@ -315,6 +317,7 @@ public struct Configuration {
case invalidOutput(message: String)
case invalidCacheBasePath(message: String)
case invalidPaths(message: String)
case internalError(message: String)

public var description: String {
switch self {
Expand All @@ -332,6 +335,8 @@ public struct Configuration {
return "Invalid cacheBasePath. \(message)"
case .invalidPaths(let message):
return "\(message)"
case .internalError(let message):
return "\(message)"
}
}
}
Expand Down Expand Up @@ -431,8 +436,14 @@ public enum Configurations {
}

if let configurations = dict["configurations"] as? [[String: Any]] {
return try configurations.map { dict in
try Configuration(dict: dict, relativePath: relativePath)
return try configurations.flatMap { dict in
if let child = dict["child"] as? String {
let childPath = Path(child, relativeTo: relativePath)
let childRelativePath = Path(components: childPath.components.dropLast())
return try Configurations.make(path: childPath, relativePath: childRelativePath, env: env)
} else {
return try [Configuration(dict: dict, relativePath: relativePath)]
}
}
} else {
return try [Configuration(dict: dict, relativePath: relativePath)]
Expand Down
30 changes: 29 additions & 1 deletion SourceryTests/ConfigurationSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class ConfigurationSpec: QuickSpec {
describe("Configuration") {
let serverUrlArg = "serverUrl"
let serverUrl: String = "www.example.com"
let env = ["SOURCE_PATH": "Sources",
let sourcePath = "Sources"
let env = ["SOURCE_PATH": sourcePath,
serverUrlArg: serverUrl]

context("given valid config file with env placeholders") {
Expand Down Expand Up @@ -86,6 +87,33 @@ class ConfigurationSpec: QuickSpec {
}
}

context("given config file with child configurations") {
it("resolves each child configuration") {
do {
let configs = try Configurations.make(
path: Stubs.configs + "parent.yml",
relativePath: Stubs.configs,
env: env
)

expect(configs.count).to(equal(1))

guard case let Source.sources(paths) = configs[0].source,
let path = paths.include.first else {
fail("Config has no Source Paths")
return
}

let configServerUrl = configs[0].args[serverUrlArg] as? String

expect(configServerUrl).to(equal(serverUrl))
expect(path).to(equal(Stubs.configs + sourcePath))
} catch {
expect("\(error)").to(equal("Invalid config file format. Expected dictionary."))
}
}
}

context("given invalid config file") {

func configError(_ config: [String: Any]) -> String {
Expand Down
2 changes: 2 additions & 0 deletions SourceryTests/Stub/Configs/parent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
configurations:
- child: valid.yml
10 changes: 10 additions & 0 deletions guides/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ configurations:

This will be equivalent to running Sourcery separately for each of the configurations. In watch mode Sourcery will observe changes in the paths from all the configurations.

#### Child configurations

You can specify a child configurations by using the `child` key:
```yaml
configurations:
- child: ./.child_config.yml
- child: Subdirectory/.another_child_config.yml
```
Sources will be resolved relative to the child config paths.

#### Sources

You can provide sources using paths to directories or specific files.
Expand Down

0 comments on commit 402a79b

Please sign in to comment.