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 @package
.
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
,
package-product
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.
package-product →
product
:
package-product-name
There’re three kinds of package description, matching Package.Dependency.Kind
definitions in PackageDescription
.
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.
file-system-package-description →
path
:
package-pathpackage-path → string-literal
Source-control package description contains the Git URL of the dependent package and package requirement.
source-control-package-description →
url
:
package-url,
source-control-package-requirementpackage-url → string-literal
Registry package description contains the identifier of the dependent package and package requirement.
registry-package-description →
id
:
package-identifier,
registry-package-requirementpackage-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 ..<
or ...
operator.
package-version-range → semantic-version-string range-operator semantic-version-string
semantic-version-string → string-literal
range-operator →
..<
|...
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
:
package-requirement-parameterlabeled-registry-package-requirement → registry-package-requirement-label
:
package-requirement-parametersource-control-package-requirement-label →
branch
|exact
|from
|revision
registry-package-requirement-label →
exact
|from
package-requirement-parameter → string-literal