-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Allow relative path with swift package add-dependency
command
#7871
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
Conversation
swift package add-dependency
swift package add-dependency
command
c9073bd
to
3925579
Compare
@bnbarham Just wanted to bump this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @hi2gage! Definitely valuable to support relative paths here.
Due to access level and not wanting to make certain enums public, I opted to use MappablePackageDependency instead of Package.Dependency to represent the values coming from the CLI command.
Which enums would those be? Ideally MappablePackageDependency
would not be public, it really shouldn't be visible to commands.
@bnbarham No problem! I thought I would need to make // intentionally private to hide enum detail
private static func package(
name: String? = nil,
url: String,
requirement: Package.Dependency.SourceControlRequirement
) -> Package.Dependency {
return .init(name: name, location: url, requirement: requirement, traits: nil)
} but looking back over this again I realized this was written prior to the It would really simplify this PR to not use |
Aren't they already 🤔? I assume the issue was that there's no way to create a
If they need to be (depending on the above) - they just can't be public as this is the package manifest API. |
3925579
to
fbca3e6
Compare
fa8e2a3
to
153aa99
Compare
Hey @bnbarham I just pushed up the changes to use
Yes they are public 🤦I meant to say:
Technically I could call the existing initializers, but it requires some funky switching. The changes I just pushed uses the existing initializers. So let me know what you think about that. This being said if I made those initializers let packageDependency: PackageDescription.Package.Dependency
switch (firstRequirement, to) {
case (let .exact(version), nil):
packageDependency = .package(url: self.dependency, exact: version)
case (let .range(range), let to?):
packageDependency = .package(url: self.dependency, (range.lowerBound ..< to))
case (let .range(range), nil):
packageDependency = .package(url: self.dependency, range)
case (let .revision(revision), nil):
packageDependency = .package(url: self.dependency, revision: revision)
case (let .branch(branch), nil):
packageDependency = .package(url: self.dependency, branch: branch)
case (.branch, _?), (.revision, _?), (.exact, _?):
throw StringError("--to can only be specified with --from or --up-to-next-minor-from")
case (_, _):
throw StringError("unknown requirement")
} -> let packageDependency2: PackageDescription.Package.Dependency = .package(
url: self.dependency,
requirement: requirement,
traits: []
)
Agreed, they can't be public, making them package would be helpful but we can get around it if you want to keep those initializers locked down. |
I'd be fine making them |
153aa99
to
6aae1fd
Compare
Great! I just pushed up changes making those |
@bnbarham Just wanted to bump this, let me know if there is anything I can to help move this PR along. |
@swift-ci please test |
@swift-ci please test windows |
@hi2gage that did the trick. Running the tests now. I'm a little worried about adding the PackageDescription dependency since it was really only intended for the package manifest processing, but it actually makes sense how you're using it. This is actually pretty timely. We've been working at improving support for monorepos where relative packages are common. This will help setting them up. |
094ffe0
to
9615510
Compare
@swift-ci please test |
@swift-ci please test windows |
@dschaefer2 Just pushed up what I believe is the fix. |
@swift-ci please test windows |
Don't worry about the branching. We'll work to get this into 6.1. Our CI has been under the weather the last few days. |
Actually, they're going to set up an auto merge of main to releases/6.1 so it'll just go there automatically. I think they just wanted to branch the compiler now, which makes sense. It needs time to settle down. |
@swift-ci please test |
Sounds good! Any further action needed from me on this PR to get those windows tests passing? |
@swift-ci please test windows |
I am a little worried about adding the dependency from SwiftPM to PackageDescription. It seems a lot of effort was expended in the past to avoid that, including duplicating most of the types, which I agree is pretty annoying. I assume that was to keep it only for the package manifest library. @bnbarham any thoughts there? Any toolchain build issue we may run into? |
Hmm, the Windows build is failing with the missing dependency. It builds with CMake as well. Sorry for the delayed responses. Too many things on the go at once :(. |
No worries at all. Holidays are a busy time for me. The more I think about this the more I think that making this as DRY as possible might more pain than it's worth. Looking at PackageDescription+Syntax.swift really all we need is a model that resents a dependency that is added. Now it would have been convenient to use I propose we add a lightweight struct inside Thoughts on making this a little less DRY? Example (Just copied the main properties that are required for this use case):public struct Dependency {
/// The type of dependency.
@available(_PackageDescription, introduced: 5.6)
public enum Kind {
/// A dependency located at the given path.
/// - Parameters:
/// - name: The name of the dependency.
/// - path: The path to the dependency.
case fileSystem(name: String?, path: String)
/// A dependency based on a source control requirement.
/// - Parameters:
/// - name: The name of the dependency.
/// - location: The Git URL of the dependency.
/// - requirement: The version-based requirement for a package.
case sourceControl(name: String?, location: String, requirement: SourceControlRequirement)
/// A dependency based on a registry requirement.
/// - Parameters:
/// - id: The package identifier of the dependency.
/// - requirement: The version based requirement for a package.
case registry(id: String, requirement: RegistryRequirement)
}
/// A description of the package dependency.
@available(_PackageDescription, introduced: 5.6)
public let kind: Kind
}
// MARK: - SourceControlRequirement
extension Dependency {
@available(_PackageDescription, introduced: 5.6)
public enum SourceControlRequirement {
/// An exact version based requirement.
case exact(Version)
/// A requirement based on a range of versions.
case range(Range<Version>)
/// A commit based requirement.
case revision(String)
/// A branch based requirement.
case branch(String)
}
}
// MARK: - RegistryRequirement
extension Dependency {
@available(_PackageDescription, introduced: 999)
public enum RegistryRequirement {
/// A requirement based on an exact version.
case exact(Version)
/// A requirement based on a range of versions.
case range(Range<Version>)
}
}
// MARK: - Version
public struct Version: Sendable {
/// The major version according to the semantic versioning standard.
public let major: Int
/// The minor version according to the semantic versioning standard.
public let minor: Int
/// The patch version according to the semantic versioning standard.
public let patch: Int
/// The pre-release identifier according to the semantic versioning standard, such as `-beta.1`.
public let prereleaseIdentifiers: [String]
/// The build metadata of this version according to the semantic versioning standard, such as a commit hash.
public let buildMetadataIdentifiers: [String]
the |
Agreed. Does the PackageModel module contain types you could use? |
77615b9
to
63210b8
Compare
Actually yes looking through the Pushed up a new commit with that change. Tests are passing locally and no dependencies were added. So hopefully that passes the smell test. |
@@ -18,7 +18,7 @@ import SwiftSyntax | |||
import SwiftSyntaxBuilder | |||
|
|||
/// Add a package dependency to a manifest's source code. | |||
public struct AddPackageDependency { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swiftformat made this change
@@ -18,7 +18,7 @@ import SwiftSyntaxBuilder | |||
import struct TSCUtility.Version | |||
|
|||
/// Add a target to a manifest's source code. | |||
public struct AddTarget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swiftformat made this change
So much cleaner. Thank you! |
@swift-ci please test windows |
Hey @dschaefer2 just wanted to bump this. Anything else needed from me? |
Sorry about that. Things got pretty busy. Let me kick off the tests again. |
@swift-ci please test |
Finally back to this. Looks good. Thank you! |
…tlang#7871) Enable passing relative path into `swift package add-dependency` ### Motivation: Currently only `AbsolutePath`s are supported with `--type path` flag ```bash swift package add-dependency /packagePath --type path ``` There is a need to support `RelativePath` because it's not uncommon to have a package structure inside of an xcodeproj as shown below. ```bash LocalPackages ├── ChildPackage │ ├── .gitignore │ ├── .swiftpm │ ├── Package.swift │ ├── Sources │ └── Tests └── ParentPackage ├── .build ├── .gitignore ├── .swiftpm ├── Package.swift ├── Sources └── Tests ``` If we want to open `ParentPackage` by itself, it will not be able to resolve that package. This pr allows for the user to add a package with a `RelativePath` path via the `swift package add-dependency --type path` command. Access level for - `.package(name:url:requirement:traits:)` - `.package(name:url:requirement:)` - `.package(id:requirement:traits:)` were upgraded from `private` to `package` allowing access to these functions from the `PackageCommands` module. ### Modifications: - Enable passing relative path into `swift package add-dependency` - Add unit test coverage ### Result: Both of the following commands are valid ```bash swift package add-dependency ../relative --type path ``` ```bash swift package add-dependency /absolute --type path ```
Enable passing relative path into
swift package add-dependency
Motivation:
Currently only
AbsolutePath
s are supported with--type path
flagThere is a need to support
RelativePath
because it's not uncommon to have a package structure inside of an xcodeproj as shown below.If we want to open
ParentPackage
by itself, it will not be able to resolve that package.This pr allows for the user to add a package with a
RelativePath
path via theswift package add-dependency --type path
command.Access level for
.package(name:url:requirement:traits:)
.package(name:url:requirement:)
.package(id:requirement:traits:)
were upgraded from
private
topackage
allowing access to these functions from thePackageCommands
module.Modifications:
swift package add-dependency
Result:
Both of the following commands are valid