The gyb.py plugin for SwiftPM project.
GYB is a lightweight templating system that allows you to use Python code for variable substitution and flow control:
- The sequence
%{ code }
evaluates a block of Python code - The sequence
% code: ... % end
manages control flow - The sequence
${ code }
substitutes the result of an expression
A good example of GYB can be found in Codable.swift.gyb. At the top of the file, the base Codable types are assigned to an instance variable:
%{
codable_types = ['Bool', 'String', 'Double', 'Float',
'Int', 'Int8', 'Int16', 'Int32', 'Int64',
'UInt', 'UInt8', 'UInt16', 'UInt32', 'UInt64']
}%
Later on, in the implementation of SingleValueEncodingContainer
, these types are iterated over to generate the methods declarations for the protocol’s requirements:
% for type in codable_types:
mutating func encode(_ value: ${type}) throws
% end
Evaluating the GYB template results in the following declarations:
mutating func encode(_ value: Bool) throws
mutating func encode(_ value: String) throws
mutating func encode(_ value: Double) throws
mutating func encode(_ value: Float) throws
mutating func encode(_ value: Int) throws
mutating func encode(_ value: Int8) throws
mutating func encode(_ value: Int16) throws
mutating func encode(_ value: Int32) throws
mutating func encode(_ value: Int64) throws
mutating func encode(_ value: UInt) throws
mutating func encode(_ value: UInt8) throws
mutating func encode(_ value: UInt16) throws
mutating func encode(_ value: UInt32) throws
mutating func encode(_ value: UInt64) throws
This pattern is used throughout the file to generate similarly formulaic declarations for methods like encode(_:forKey:)
, decode(_:forKey:)
, and decodeIfPresent(_:forKey:)
. In total, GYB reduces the amount of boilerplate code by a few thousand LOC:
$ wc -l Codable.swift.gyb
2183 Codable.swift.gyb
$ wc -l Codable.swift
5790 Codable.swift
To use the swift-gyb
plugin in a SwiftPM project,
add it to the dependencies for your package and your .swift.gyb
files contained target:
let package = Package(
// name, platforms, products, etc.
dependencies: [
// other dependencies
.package(url: "https://github.com/swift-library/swift-gyb", from: "0.0.1"),
],
targets: [
.executableTarget(
name: "<command-line-tool>",
dependencies: [
// other dependencies
],
plugins: [
.plugin(name: "GybPlugin", package: "swift-gyb"),
]
),
// other targets
]
)
The most recent versions of swift-gyb support Swift 5.8 and newer. The minimum Swift version supported by swift-gyb releases are detailed below:
swift-gyb | Minimum Swift Version |
---|---|
0.0.1 |
5.8 |