Motivation
Function builders allow us to have declarative interface. Declarative interface also gives you simpler and less source code. SwiftUI is a good example. It allows you to have declarative syntax to build view hierarchy very easily.
Currently, SwiftPM package description provides static func to build the description, but we might have alternative way using function builder here.
Function Builders
Below is an example of current package description. It provides convenient static func, so I think it's good enough interface.
let package = Package(
name: "MyLibrary",
platforms: [
.macOS(.v10_14),
],
products: [
.library(name: "MyLibrary", targets: ["MyLibrary"]),
],
dependencies: [
.package(url: "https://url/of/another/package/named/Utility", from: "1.0.0"),
],
targets: [
.target(name: "MyLibrary", dependencies: ["Utility"]),
.testTarget(name: "MyLibraryTests", dependencies: ["MyLibrary"]),
]
)
Below is an example of new approach using function builder. It can be more declarative than current one.
let package = Package(name: "Paper") {
ProductList {
Product(name: "tool", type: .static) {
TargetList {
Target(name: "tool")
}
}
}
DependencyList {
Dependency(
url: "http://example.com.com/ExamplePackage/ExamplePackage",
from: "1.2.3"
)
Dependency(url: "dev", exact: "1.2.3")
}
TargetList {
Target(name: "tool") {
TargetDependencyList {
TargetDependency(name: "Paper")
TargetDependency(name: "ExamplePackage")
}
}
Target(name: "Paper") {
TargetDependencyList {
TargetDependency(name: "Basic")
Target(name: "Utility")
Product(name: "AnotherExamplePackage")
}
}
}
}
However, I think this approach has some downsides. So I would like to hear your opinions.
Pros
- Declarative description
Cons
- Can't have type constraints for all of description contents unless we defined function builder for specific types
- Compiler error is not friendly when we have wrong content at unexpected place
The only concern I have for function builder is that it might not work with package description well because it has type constraints in the tree structure. For example, it's not allowed to have Target on top level. We need to think if it should get compiler error or be ignored for encoded data.
Data mapping
As long as each description content conforms to Encodable, it can be mapped with current data types.
Here is my rough implementation of the functionality. With this, we don't need to modify current data types.