Skip to content

Add AbsolutePath and SourceControlURL parsing to swift package add-dependency #7769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

hi2gage
Copy link
Contributor

@hi2gage hi2gage commented Jul 11, 2024

Fix issue #7738
Allow user to add .package(path:) dependencies usingswift package add-dependency`

Motivation:

I wanted to be able to add .package(path:) using the command line and was unable to do so with the given parsing.

This PR updates the parsing logic to check if the dependency argument is a valid SourceControlURL or AbsolutePath.

Modifications:

  • Introduces a failable initializer to SourceControlURL allowing https://domain or git@domain URLs
  • Changes AddDependency to only require additional options if the dependency is the SourceControlURL format
  • Runs SwiftFormat in the files that were edited

Result:

User can run the following commands

AbsolutePath

swift package add-dependency /ChildPackage
> Updating package manifest at Package.swift... done.

resulting in

.package(path: "/ChildPackage")

SourceControlURL

swift-package add-dependency https://github.com/swiftlang/swift-syntax.git --branch main
> Updating package manifest at Package.swift... done.

resulting in

.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "main")

RelativePath

swift-package add-dependency ../ChildPackage
> error: relative paths not supported

Switched back to dependency Argument
Copy link
Contributor

@bnbarham bnbarham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @hi2gage! This LGTM generally, only have a small suggestion.

manifestContents = try fileSystem.readFileContents(manifestPath)
} catch {
throw StringError("cannot find package manifest in \(manifestPath)")
if let url = SourceControlURL(absoluteString: dependency) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have a CanonicalPackageURL that @francescomikulis is changing a little in #7741. What if instead of the new SourceControlURL here, we use CanonicalPackageURL and then check if the scheme is either file or nil?

@neonichu
Copy link
Contributor

I would very much caution against trying to parse URLs here and just let the user explicitly choose between URL- and path-based dependencies via arguments.

@hi2gage
Copy link
Contributor Author

hi2gage commented Jul 12, 2024

I would very much caution against trying to parse URLs here and just let the user explicitly choose between URL- and path-based dependencies via arguments.

@neonichu I brought that up as option 1 in the original issue #7738. I agree letting the user explicitly decide is better. There were concerns changing the command interface would not be following the accepted proposal (SE-0301 "Package Editing Commands")

More than willing to go through the proposal process if needed

/// e.g. https://github.com/apple/swift
/// e.g. git@github.com:apple/swift
public init?(absoluteString url: String) {
guard let regex = try? NSRegularExpression(pattern: "^(?:https://|git@)", options: .caseInsensitive) else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this use Swift regex literals instead?

@neonichu
Copy link
Contributor

More than willing to go through the proposal process if needed

That seems preferable since otherwise we're cutting off legitimate uses through the CLI, e.g.

.package(url: "/abcd", from: "1.0.0")

is a valid dependency.

@bnbarham
Copy link
Contributor

Given:

That seems preferable since otherwise we're cutting off legitimate uses through the CLI, e.g.

And that the proposal states (not currently implemented):

If no requirement is specified, the command will default to a .upToNextMajor requirement on the latest version of the package

My vote would be for another argument that specifies adding it as a path dependency instead (this seems pretty inline with all the other version arguments, you could reasonably think of "path" as specifying the version, ie. "use local as is").

@hi2gage
Copy link
Contributor Author

hi2gage commented Jul 23, 2024

Finally getting back around to this PR. Sorry for the delay.

My vote would be for another argument that specifies adding it as a path dependency instead (this seems pretty inline with all the other version arguments, you could reasonably think of "path" as specifying the version, ie. "use local as is").

@bnbarham, Are you suggesting a boolean --path flag argument?
or a --type argument that accepts url, path, id similar to swift package add-target?

@bnbarham
Copy link
Contributor

@bnbarham, Are you suggesting a boolean --path flag argument?
or a --type argument that accepts url, path, id similar to swift package add-target

I was suggesting a boolean and treating it in the same "group" as specifying a version. I forgot about the id case though, so maybe type does make more sense given that.

@hi2gage
Copy link
Contributor Author

hi2gage commented Jul 23, 2024

@bnbarham, Are you suggesting a boolean --path flag argument?
or a --type argument that accepts url, path, id similar to swift package add-target

I was suggesting a boolean and treating it in the same "group" as specifying a version. I forgot about the id case though, so maybe type does make more sense given that.

ha yeah I guess we've almost come full circle.
My personal vote would be instead of an additional type argument we should just have multiple arguments as shown below:
swift package add-dependency [--url <url>] [--path <path>] [--id <id>] [--exact <version>] [--revision <revision>] [--branch <branch>] [--from <version>] [--up-to-next-minor-from <version>]

Another benefit is that the command pattern follows the same pattern that the user would interact with using one of the
static func package(...) -> Package.Dependency inside of the Package.swift file.

This structure would allow the following commands:

swift package add-dependency path /ChildPackage
> Updating package manifest at Package.swift... done.
swift package add-dependency url /ChildPackage --from 1.0.0
> Updating package manifest at Package.swift... done.
swift package add-dependency url https://github.com/swiftlang/swift-syntax.git --branch main
> Updating package manifest at Package.swift... done.
swift package add-dependency id scope.name --from: 1.2.3
> Updating package manifest at Package.swift... done.

More than happy to discuss this offline to get alignment here

@bnbarham
Copy link
Contributor

My personal vote would be instead of an additional type argument we should just have multiple arguments as shown below:

IMO the downside here is that it makes the 99% case more difficult (ie. URL).

More than happy to discuss this offline to get alignment here

Given all the different opinions, I definitely think this is worth bringing up on the forums for discussion.

@hi2gage
Copy link
Contributor Author

hi2gage commented Jul 24, 2024

IMO the downside here is that it makes the 99% case more difficult (ie. URL).

Yeah that's true. Plus a quick search through GitHub shows that the registry (id) adoption really isn't that high for public repos either.

I would be ok with this for the id

swift package add-dependency scope.name --from: 1.2.3 --type id
> Updating package manifest at Package.swift... done.

and

for path dependencies

swift package add-dependency /abcd --type path
> Updating package manifest at Package.swift... done.

I'll give this a go this evening. Given all of this dialog does it make sense to close this PR and create new one for this work?

@bnbarham
Copy link
Contributor

Given all of this dialog does it make sense to close this PR and create new one for this work?

Either is okay. If you do make another PR, I'd reference this one.

@hi2gage
Copy link
Contributor Author

hi2gage commented Jul 24, 2024

Implemented changes in #7815

@hi2gage hi2gage closed this Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants