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

[SE-0301] Introduce swift package add-target support to add targets to a package #7474

Closed
wants to merge 22 commits into from

Conversation

DougGregor
Copy link
Member

@DougGregor DougGregor commented Apr 20, 2024

Add a new package command to add a target with the given name, type, and
dependencies to the package. This includes adding the target to the
package manifest as well as creating stub source files for the target to
guide the user. For example, this command:

swift package add-target SocialGraphClientTests --dependencies SocialGraphClient --type test

adds the following to the targets in the package manifest:

.testTarget(name: "SocialGraphClientTests", dependencies: ["SocialGraphClient"]),

as well as creating the file Tests/SocialGraphClientTests/SocialGraphClientTests.swift,
which looks like this:

import SocialGraphClient
import XCTest

class SocialGraphClientTests: XCTestCase {
    func testSocialGraphClientTests() {
        XCTAssertEqual(42, 17 + 25)
    }
}

There is, undoubtedly, some tuning to do to clean this up. Here's the
command-line interface, which mostly aligns with SE-0301:

OVERVIEW: Add a new target to the manifest

USAGE: swift package add-target <name> [--type <type>] [--dependencies <dependencies> ...] [--url <url>] [--path <path>] [--checksum <checksum>]

ARGUMENTS:
  <name>                  The name of the new target

OPTIONS:
  --type <type>           The type of target to add, which can be one of
                          (default: library)
  --dependencies <dependencies>
                          A list of target dependency names
  --url <url>             The URL for a remote binary target
  --path <path>           The path to a local binary target
  --checksum <checksum>   The checksum for a remote binary target
  --version               Show the version.
  -h, -help, --help       Show help information.

…ifest file

Package manifest files are Swift source code, so editing them means working
with the source code directly. Introduce a new library based on swift-syntax
that allows us to perform targeted manipulations of the manifest file
programmatically, making suggested edits to the file without having to
understand everything in it.

Introduce one editing operation that adds a particular package dependency
to the manifest file. For example, it takes the programmatic representation
of a package dependency in the model
(`PackageModel.PackageDependency`) and the syntax for a manifest file,
then it will produce a set of edits that extend (or add) the
dependencies in the `Package` instance to the manifest file, e.g.,

    .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1"),

We make an attempt to match the surrounding trivia so that we don't make
an ugly mess of the resulting manifest. I have tests for a number of
cases to make sure they look nice, but I expect we'll have to refine
the heuristics over time.
…nifest

Introduce a new `package add` command that adds a package dependency to
your manifest file, given command-line arguments containing the URL and
the version requiements (branch, from-version, etc.). This utilizes the new
infrastructure for swift-syntax based package editing, putting a
command-line interface over it.

Here's the help output:

    OVERVIEW: Add a dependency to the package manifest

    USAGE: swift package add [--branch <branch>] [--from-version <from-version>] [--exact-version <exact-version>] [--revision <revision>] <url>

    ARGUMENTS:
      <url>                   The URL or directory of the package to add

    OPTIONS:
      --branch <branch>       The branch to depend on
      --from-version <from-version>
                              The minimum version requirement
      --exact-version <exact-version>
                              The exact version requirement
      --revision <revision>   A specific revision requirement
      --version               Show the version.
      -h, -help, --help       Show help information.
The manifest format has changed a bit since then, and conditionalizing
out processing here for older manifests is not worth the effort. Thanks
@owenv!
Modern SwiftPM implementations warn about the

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

syntax that's being rendered into the package manifest, because this syntax
was replaced in SwiftPM 5.5 with something that uses argument labels:

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

Since generating code with warnings is bad, and we've already stated
that we won't edit packages for tools version < 5.5, switch to this new
style.

This does mean that we drop the (internal) dependency on
ManifestSourceGeneration, which is producing the older format, because
I don't have a strong sense of whether we can modernize that code.
Instead, we have a new path that generates swift-syntax nodes directly
for the types we generate.
Blame Owen for the evil genius of this hack, me for trying to put it in
The formatting is a mess, but the functionality is sound.
… to a package

Add a new package command to add a target with the given name, type, and
dependencies to the package. This includes adding the target to the
package manifest as well as creating stub source files for the target to
guide the user. For example, this command:

    swift package add-target SocialGraphClientTests --dependencies SocialGraphClient --type test

adds the following to the targets in the package manifest:

    .testTarget(name: "SocialGraphClientTests", dependencies: ["SocialGraphClient"]),

as well as creating the file `Tests/SocialGraphClientTests/SocialGraphClientTests.swift`,
which looks like this:

    import SocialGraphClient
    import XCTest

    class SocialGraphClientTests: XCTestCase {
        func testSocialGraphClientTests() {
            XCTAssertEqual(42, 17 + 25)
        }
    }

There is, undoubtedly, some tuning to do to clean this up. Here's the
command-line interface, which mostly aligns with SE-0301:

    OVERVIEW: Add a new target to the manifest

    USAGE: swift package add-target <name> [--type <type>]
[--dependencies <dependencies> ...] [--url <url>] [--path <path>]
[--checksum <checksum>]

    ARGUMENTS:
      <name>                  The name of the new target

    OPTIONS:
      --type <type>           The type of target to add, which can be
one of
                              (default: library)
      --dependencies <dependencies>
                              A list of target dependency names
      --url <url>             The URL for a remote binary target
      --path <path>           The path to a local binary target
      --checksum <checksum>   The checksum for a remote binary target
      --version               Show the version.
      -h, -help, --help       Show help information.
@DougGregor
Copy link
Member Author

This builds on #7467. Only the last two commits are meant to be in this PR.

@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test Windows

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test Windows

Rather than trying to thread through trivia everywhere, apply BasicFormat
to arguments.
@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

1 similar comment
@DougGregor
Copy link
Member Author

@swift-ci please test Windows

For macro targets, we need to add two new files: one with a macro definition,
and another with the list of provided macros for the macro plugin. Reshuffle
some code to make that easier.
@DougGregor
Copy link
Member Author

@swift-ci please test

@DougGregor
Copy link
Member Author

@swift-ci please test Windows

Comment on lines +42 to +60
set(SWIFT_SYNTAX_MODULES
SwiftBasicFormat
SwiftParser
SwiftParserDiagnostics
SwiftDiagnostics
SwiftSyntax
SwiftOperators
SwiftSyntaxBuilder
SwiftSyntaxMacros
SwiftSyntaxMacroExpansion
SwiftCompilerPluginMessageHandling
# Support for LSP
SwiftIDEUtils
SwiftRefactor
)
export(TARGETS ${SWIFT_SYNTAX_MODULES}
NAMESPACE SwiftSyntax::
FILE ${CMAKE_BINARY_DIR}/cmake/modules/SwiftSyntaxConfig.cmake
EXPORT_LINK_INTERFACE_LIBRARIES)
Copy link
Contributor

Choose a reason for hiding this comment

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

Left over from a copy?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, actually! I tried removing it, and got a failure because we need a public dependency of PackageModelSyntax on these libraries, and CMake wants these targets exported to declare the public dependency.

@DougGregor
Copy link
Member Author

This is stale; all of it got merged elsewhere

@DougGregor DougGregor closed this Apr 28, 2024
@DougGregor DougGregor deleted the package-add-target branch April 28, 2024 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants