Skip to content
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

Swift package manifest refactoring actions #2904

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

DougGregor
Copy link
Member

Port the package manifest editing refactoring actions over to SwiftRefactor. These refactoring operations come from the swift-package-manager repository, and are being moved here for several reasons:

  1. They are shared by SwiftPM and SourceKit-LSP already, and are likely to also get used in the compiler, so swift-syntax is a good place for them to be to avoid code duplication.
  2. The SwiftRefactor module is where we are collecting various refactoring.
  3. Putting them here completely separates them from the semantic package model, so it's clear that we are just dealing with syntactic transforms.

This ports all of the package manifest refactoring actions over from swift-package-manager (add package dependency, add target, add product, add target dependency) and introduces a new one that will be used by swift-package-manager in the future, "add plugin usage". The code itself is little changed from the SwiftPM version, although the ManifestEditRefactoringProvider protocol that unifies them all is new.

Note that we end up bringing over syntactic versions of various SwiftPM types like TargetDescription and SourceControlURL, but in a string-backed, simplified form that is purely syntactic. These are needed to community with the refactoring actions, and can easily be constructed by clients.

Start porting the package manifest editing operations from the Swift
Package Manager package over here, so that all of the syntactic
refactorings are together in one common place. These refactorings are
needed by a number of tools, including SwiftPM, SourceKit-LSP, and
(soon) the Swift compiler itself, which can all depend on
swift-syntax.

The implementation here stubs out the various types used to describe
package syntax, using simple string-backed types in place of some of
the semantic types that are part of SwiftPM itself, such as
SemanticVersion or SourceControlURL. I've also introduced the notion
of a ManifestEditRefactoringProvider to generalize over all of the
package manifest editing operations.

This commit ports over the "Add Package Dependency" command and its
tests.
@DougGregor
Copy link
Member Author

@swift-ci please test

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test Windows

…Refactor

This manifest editing action introduces a new dependency to an existing target
…for a target

This allows one to add a plugin usage to a given target, given the target
name and description of how the plugin should be used.
@DougGregor DougGregor force-pushed the package-manifest-refactor branch from f371a2c to 4061163 Compare December 1, 2024 16:57
@DougGregor
Copy link
Member Author

@swift-ci please test

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test Windows

@DougGregor
Copy link
Member Author

@swift-ci please test

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test Linux

@DougGregor
Copy link
Member Author

@swift-ci please test macOS

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Thanks for moving the code, Doug.

/// Syntactic wrapper type that describes an absolute path for refactoring
/// purposes but does not interpret its contents.
public struct AbsolutePath: CustomStringConvertible, Equatable, Hashable, Sendable {
public private(set) var description: String
Copy link
Member

Choose a reason for hiding this comment

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

Doesn’t look like you ever modify it so could be

Suggested change
public private(set) var description: String
public let description: String

Same for the other wrapper types.

Copy link
Member

Choose a reason for hiding this comment

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

Since you’re adding new public declarations, could you add a release notes entry?


let separateParen: String = arguments.count > 1 ? "\n" : ""
let argumentsSyntax = LabeledExprListSyntax(arguments)
return ".\(raw: functionName)(\(argumentsSyntax)\(raw: separateParen))"
Copy link
Member

Choose a reason for hiding this comment

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

Maybe I’m missing something but this reads to me as if we put all the arguments on the same line as the function name and then the closing parenthesis on a new line. Am I missing something?

// or productFilter yet.
switch location {
case .local:
fatalError()
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way we can avoid the fatalError because this would take down SourceKit-LSP when hit, which we really want to avoid. Maybe return an optional or error and fail the refactoring? Or implement this case.


/// Produce trivia from the last newline to the end, dropping anything
/// prior to that.
func onlyLastLine() -> Trivia {
Copy link
Member

Choose a reason for hiding this comment

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

I think a computed property would fit better here.

/// The set of argument labels that can occur after the "dependencies"
/// argument in the various target initializers.
///
/// TODO: Could we generate this from the the PackageDescription module, so
Copy link
Member

Choose a reason for hiding this comment

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

If this is no longer defined in SwiftPM, I don’t think we’ll be able to generate it from the PackageDescription module, so I’m not sure if this comment is still applicable anymore.

Same in the other refactorings.

Comment on lines +65 to +69
public init(
testHarness: TestHarness = .default,
swiftSyntaxVersion: SemanticVersion = SemanticVersion("600.0.0-latest"),
swiftTestingVersion: SemanticVersion = SemanticVersion("0.8.0")
) {
Copy link
Member

Choose a reason for hiding this comment

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

I’m quite worried about this because we will forget to update these (they are already out-of-date).

target.dependencies.append(contentsOf: macroTargetDependencies)

default:
break;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
break;
break

}
}

default: break;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
default: break;
default: break

)
}

func XCTAssertThrows<T: Swift.Error, Ignore>(
Copy link
Member

Choose a reason for hiding this comment

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

Why doesn’t XCTAssertThrowsError from XCTest work here? If it doesn’t work, I would name this assertThrows because we don’t want to define local functions with the XCT prefix. Also, I would make this fileprivate to avoid it leaking into other tests.


/// Syntactic wrapper type that describes an absolute path for refactoring
/// purposes but does not interpret its contents.
public struct AbsolutePath: CustomStringConvertible, Equatable, Hashable, Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer not introducing so many fairly generic public types here (AbsolutePath, PackageIdentity, RelativePath, SemanticVersion, SourceControlURL). How much do you prefer this over just strings for these cases? Another alternative would be to namespace them in an enum, but I believe @ahoppen is generally not a fan of that.

Also, could we make Target -> PackageTarget?

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.

3 participants