Unable to add a valid .package(path:)
dependency to Package.Swift
via swift package add-dependency
command
#7738
Labels
.package(path:)
dependency to Package.Swift
via swift package add-dependency
command
#7738
Is it reproducible with SwiftPM command-line tools:
swift build
,swift test
,swift package
etc?swift build
,swift test
,swift package
etc.Description
Unable to add a valid
.package(path:)
dependency toPackage.Swift
viaswift package add-dependency
command.If the user passes a valid path (
AbsolutePath
)The
add-dependency
command forces the user to add one of these optionsWhen attempting to add a
.package(path:)
dependency to aPackage.swift
using the swift packageadd-dependency
command, the command requires one of the following options:--exact
--branch
--revision
--from
--up-to-next-minor-from
This is fine while trying to add a
.package(url:from:)
or.package(url:_:)
but not for.package(path:)
because no additional arguments are required.If the user passes a valid
AbsolutePath
it will add aPackageDependency.SourceControl.Requirement
to the.package(path:)
making it an invalidPackage.Dependency
declarationOriginal Swift-Evolution Proposal:
While investigating this bug I read through SE-0301 "Package Editing Commands" which includes the following information on this command:
swift package add-dependency <dependency> [--exact <version>] [--revision <revision>] [--branch <branch>] [--from <version>] [--up-to-next-minor-from <version>]
The following options can be used to specify a package dependency requirement:
If no requirement is specified, the command will default to a
.upToNextMajor
requirement on the latest version of the package.Expected behavior
Expected to be able to pass in a path without having to add extra options in the CLI
The swift code generated should be
Actual behavior
Forces user to selectiona additional options, then adds those options to the end of
.package(path:)
this breaks the
Package.swift
fileSteps to reproduce
clone the Xcode Project
Enter First Package Directory
cd swift-package-manager-add-dependency-sample-project/swift-package-manager-add-dependency-sample-project/LocalPackages/ParentPackage/
Now we want to add
ChildPackage
as a local package dependency toParentPackage
using the.package(path:)
swift package add-dependency /ChildPackage > error: must specify one of --exact, --branch, --revision, --from, or --up-to-next-minor-from
So we pass in one of the options and see what happens
swift package add-dependency /ChildPackage --exact 1.0.0 > Updating package manifest at Package.swift... done.
Open
Package.swift
Find that
.package(path:exact:)
is not a valid symbolSwift Package Manager version/commit hash
bf0272c
Swift & OS version (output of
swift --version ; uname -a
)Possible Solutions:
I spent some time working on fixing this issue and came up with two options.
Option 1:
Make the user decide what type of dependency they are creating: URL of a remote package, the path to a local package, or the name of a package in one of the user's package collections (implemented in the future for collections).
swift package add-dependency [--url <url>] [--path <path>] [--exact <version>] [--revision <revision>] [--branch <branch>] [--from <version>] [--up-to-next-minor-from <version>]
This allows for the user to be explicit with what type of dependency they want to add. This would make the command give better errors explaining why the user's intention is not possible:
--url
nor--path
is passed into the command--url
and--path
are passed into the command--url
is passed with an invalid URL--path
is passed with an invalidAbsolutePath
Option 2:
Keep the command interface the same but only require additional options if the
<dependency>
is not a validAbsolutePath
swift package add-dependency <dependency> [--exact <version>] [--revision <revision>] [--branch <branch>] [--from <version>] [--up-to-next-minor-from <version>]
This would allow for the command interface to remain as it currently is and requires fewer options to be passed into the command.
Recommendation:
There are pros and cons to both solutions, but I find the verbosity of Option 1 to be superior even if the command interface needs to change slightly. By forcing the user to decide what type of dependency they want to add to the
Package.swift
, the command is able to parse the values more safely and throw dependency-specific errors such as invalid path or invalid URL.If we went with Option 2, the user needs to understand that a path must be a
AbsolutePath
which always starts with a/
character. It could be extremely confusing if the user wants to pass in a relative path instead of an absolute path and they keep getting a.package(url:_:)
with the relative path.Thanks for reading and hope this helps!
The text was updated successfully, but these errors were encountered: