Hello folks at the Swift community!
A year and a while ago, I started the work of supporting
@package(...) import syntax for importing SwiftPM dependencies in Swift scripts as a GSoC project. During the project, I managed to work out a proof-of-concept of this feature with Swift Driver integration. The PoC implementation consists of a small standalone tool that depends on
SwiftSyntax, since adding
SwiftSyntax dependency to SwiftPM was a big trouble at that time.
With the great work from the Swift Syntax team, we now have a pure-Swift implementation of Swift parser that’s going to be part of the Swift toolchain. This makes depending on
SwiftSyntax a lot easier, and I believe it’s time to move on with this feature!
In the former pitch and implementation, the
@package attribute takes arbitrary parameters that will be passed to SwiftPM as-is. Now that
PackageDescription API is mostly stabilized since the introduction of package registry in SwiftPM 5.6, and
SwiftSyntax makes semantic parsing really easy, I'd like to propose the following syntax for
A draft parser implementation (using
@_package) is available at apple/swift-syntax#1233. Formal grammar is formatted after the new DocC-based TSPL.
Package attribute arguments consist of two parts: package description which is required, and package product which is optional.
package-attribute-arguments → package-description | package-description
A package product specifies the product name to import the module from. If there’s no explicit package product, we assume the product to be named after the imported module.
There’re three kinds of package description, matching
Package.Dependency.Kind definitions in
package-description → file-system-package-description
package-description → source-control-package-description
package-description → registry-package-description
File-system package description contains the relative or absolute path of the dependent package.
package-path → string-literal
Source-control package description contains the Git URL of the dependent package and package requirement.
package-url → string-literal
Registry package description contains the identifier of the dependent package and package requirement.
package-identifier → string-literal
A package requirement is either a labeled parameter or a version range expression.
source-control-package-requirement → labeled-source-control-package-requirement
source-control-package-requirement → package-version-range
registry-package-requirement → labeled-registry-package-requirement
registry-package-requirement → package-version-range
Package version range contains two semantic version string literals, joined with
package-version-range → semantic-version-string range-operator semantic-version-string
semantic-version-string → string-literal
Labeled package requirement tries to replicate the
Package.Dependency static APIs for source-control and registry package dependencies.
labeled-source-control-package-requirement → source-control-package-requirement-label
labeled-registry-package-requirement → registry-package-requirement-label
package-requirement-parameter → string-literal