Update MonorepoConfig.from to use [packages.Name] section format, update tests
This commit is contained in:
parent
880c1574d5
commit
73d4b442b5
3 changed files with 66 additions and 21 deletions
|
|
@ -474,19 +474,29 @@ public struct IncludeEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MonorepoConfig {
|
extension MonorepoConfig {
|
||||||
/// Parses a monorepo TOML config file.
|
/// Parses a monorepo TOML config file using `[packages.Name]` section headers
|
||||||
|
/// (the TOML reader supports `[section]` headers but not `[[array-of-tables]]`).
|
||||||
|
///
|
||||||
|
/// Example config:
|
||||||
|
/// ```toml
|
||||||
|
/// output_dir = "."
|
||||||
|
///
|
||||||
|
/// [packages.GLib]
|
||||||
|
/// gir = "/usr/share/gir-1.0/GLib-2.0.gir"
|
||||||
|
///
|
||||||
|
/// [packages.GObject]
|
||||||
|
/// gir = "/usr/share/gir-1.0/GObject-2.0.gir"
|
||||||
|
/// concurrency = "mainActor"
|
||||||
|
/// ```
|
||||||
public static func from(toml: [String: Any], defaultOutputDir: String) throws -> MonorepoConfig {
|
public static func from(toml: [String: Any], defaultOutputDir: String) throws -> MonorepoConfig {
|
||||||
let outputDir = toml["output_dir"] as? String ?? defaultOutputDir
|
let outputDir = toml["output_dir"] as? String ?? defaultOutputDir
|
||||||
guard let pkgArray = toml["packages"] as? [[String: Any]] else {
|
guard let packagesDict = toml["packages"] as? [String: [String: Any]] else {
|
||||||
throw TOMLReaderError.parseError(line: 0, message: "monorepo config missing [[packages]] array")
|
throw TOMLReaderError.parseError(line: 0, message: "monorepo config missing [packages.*] sections")
|
||||||
}
|
}
|
||||||
var packages: [PackageEntry] = []
|
var packages: [PackageEntry] = []
|
||||||
for (index, pkgDict) in pkgArray.enumerated() {
|
for (name, pkgDict) in packagesDict.sorted(by: { $0.key < $1.key }) {
|
||||||
guard let name = pkgDict["name"] as? String else {
|
|
||||||
throw TOMLReaderError.parseError(line: 0, message: "packages[\(index)] missing 'name'")
|
|
||||||
}
|
|
||||||
guard let girPath = pkgDict["gir"] as? String else {
|
guard let girPath = pkgDict["gir"] as? String else {
|
||||||
throw TOMLReaderError.parseError(line: 0, message: "packages[\(index)].\(name) missing 'gir'")
|
throw TOMLReaderError.parseError(line: 0, message: "packages.\(name) missing 'gir'")
|
||||||
}
|
}
|
||||||
let concurrency = (pkgDict["concurrency"] as? String).flatMap(ConcurrencyModel.init(rawValue:))
|
let concurrency = (pkgDict["concurrency"] as? String).flatMap(ConcurrencyModel.init(rawValue:))
|
||||||
let objects = try parseMonorepoObjectConfigs(from: pkgDict)
|
let objects = try parseMonorepoObjectConfigs(from: pkgDict)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,16 @@ struct MonorepoConfigTests {
|
||||||
@Test func parsesValidMonorepoConfig() throws {
|
@Test func parsesValidMonorepoConfig() throws {
|
||||||
let toml = """
|
let toml = """
|
||||||
output_dir = "."
|
output_dir = "."
|
||||||
packages = [{ name = "Gtk", gir = "/usr/share/gir-1.0/Gtk-4.0.gir" },{ name = "Gdk", gir = "/usr/share/gir-1.0/Gdk-4.0.gir", concurrency = "mainActor" },{ name = "GObject", gir = "/usr/share/gir-1.0/GObject-2.0.gir" }]
|
|
||||||
|
[packages.Gtk]
|
||||||
|
gir = "/usr/share/gir-1.0/Gtk-4.0.gir"
|
||||||
|
|
||||||
|
[packages.Gdk]
|
||||||
|
gir = "/usr/share/gir-1.0/Gdk-4.0.gir"
|
||||||
|
concurrency = "mainActor"
|
||||||
|
|
||||||
|
[packages.GObject]
|
||||||
|
gir = "/usr/share/gir-1.0/GObject-2.0.gir"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let dict = try TOMLReader.parse(toml)
|
let dict = try TOMLReader.parse(toml)
|
||||||
|
|
@ -16,23 +25,22 @@ struct MonorepoConfigTests {
|
||||||
|
|
||||||
#expect(config.outputDir == ".")
|
#expect(config.outputDir == ".")
|
||||||
#expect(config.packages.count == 3)
|
#expect(config.packages.count == 3)
|
||||||
#expect(config.packages[0].name == "Gtk")
|
#expect(config.packages[0].name == "GObject")
|
||||||
#expect(config.packages[0].girPath == "/usr/share/gir-1.0/Gtk-4.0.gir")
|
#expect(config.packages[0].girPath == "/usr/share/gir-1.0/GObject-2.0.gir")
|
||||||
#expect(config.packages[0].concurrency == nil)
|
#expect(config.packages[0].concurrency == nil)
|
||||||
#expect(config.packages[1].name == "Gdk")
|
#expect(config.packages[1].name == "Gdk")
|
||||||
#expect(config.packages[1].concurrency == .mainActor)
|
#expect(config.packages[1].concurrency == .mainActor)
|
||||||
#expect(config.packages[2].name == "GObject")
|
#expect(config.packages[2].name == "Gtk")
|
||||||
#expect(config.packages[2].concurrency == nil)
|
#expect(config.packages[2].concurrency == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func parsesPackagesWithObjectOverrides() throws {
|
@Test func parsesPackagesWithObjectOverrides() throws {
|
||||||
let dict: [String: Any] = [
|
let dict: [String: Any] = [
|
||||||
"output_dir": "Sources",
|
"output_dir": "Sources",
|
||||||
"packages": [
|
"packages": [
|
||||||
[
|
"Gtk": [
|
||||||
"name": "Gtk",
|
"gir": "/usr/share/gir-1.0/Gtk-4.0.gir",
|
||||||
"gir": "/usr/share/gir-1.0/Gtk-4.0.gir",
|
"object": [
|
||||||
"object": [
|
|
||||||
"Gtk.Widget": ["status": "generate", "concurrency": "mainActor"],
|
"Gtk.Widget": ["status": "generate", "concurrency": "mainActor"],
|
||||||
"Gtk.Legacy": ["status": "ignore"],
|
"Gtk.Legacy": ["status": "ignore"],
|
||||||
],
|
],
|
||||||
|
|
@ -60,15 +68,17 @@ struct MonorepoConfigTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test func rejectsMissingName() {
|
@Test func rejectsMissingGir() throws {
|
||||||
let dict: [String: Any] = [
|
let dict: [String: Any] = [
|
||||||
"packages": [
|
"packages": [
|
||||||
["gir": "/usr/share/gir-1.0/Gtk-4.0.gir"],
|
"Broken": [
|
||||||
|
"concurrency": "mainActor",
|
||||||
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
do {
|
do {
|
||||||
_ = try MonorepoConfig.from(toml: dict, defaultOutputDir: ".")
|
_ = try MonorepoConfig.from(toml: dict, defaultOutputDir: ".")
|
||||||
Issue.record("Expected error for missing name")
|
Issue.record("Expected error for missing gir")
|
||||||
} catch {
|
} catch {
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +87,7 @@ struct MonorepoConfigTests {
|
||||||
@Test func usesDefaultOutputDirWhenNotSpecified() throws {
|
@Test func usesDefaultOutputDirWhenNotSpecified() throws {
|
||||||
let dict: [String: Any] = [
|
let dict: [String: Any] = [
|
||||||
"packages": [
|
"packages": [
|
||||||
["name": "Gtk", "gir": "/usr/share/gir-1.0/Gtk-4.0.gir"],
|
"Gtk": ["gir": "/usr/share/gir-1.0/Gtk-4.0.gir"],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -85,4 +95,19 @@ struct MonorepoConfigTests {
|
||||||
|
|
||||||
#expect(config.outputDir == "/custom/output")
|
#expect(config.outputDir == "/custom/output")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test func preservesSortedOrder() throws {
|
||||||
|
let dict: [String: Any] = [
|
||||||
|
"packages": [
|
||||||
|
"Zeta": ["gir": "/z"],
|
||||||
|
"Alpha": ["gir": "/a"],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
let config = try MonorepoConfig.from(toml: dict, defaultOutputDir: ".")
|
||||||
|
|
||||||
|
#expect(config.packages.count == 2)
|
||||||
|
#expect(config.packages[0].name == "Alpha")
|
||||||
|
#expect(config.packages[1].name == "Zeta")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
monorepo-config.toml
Normal file
10
monorepo-config.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
output_dir = "/tmp/monorepo-gen"
|
||||||
|
|
||||||
|
[packages.GLib]
|
||||||
|
gir = "/usr/share/gir-1.0/GLib-2.0.gir"
|
||||||
|
|
||||||
|
[packages.GObject]
|
||||||
|
gir = "/usr/share/gir-1.0/GObject-2.0.gir"
|
||||||
|
|
||||||
|
[packages.Gio]
|
||||||
|
gir = "/usr/share/gir-1.0/Gio-2.0.gir"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue