File: AddTarget.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (133 lines) | stat: -rw-r--r-- 4,587 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import ArgumentParser
import Basics
import CoreCommands
import PackageModel
import PackageModelSyntax
import SwiftParser
import SwiftSyntax
import TSCBasic
import TSCUtility
import Workspace

extension AddTarget.TestHarness: ExpressibleByArgument { }

extension SwiftPackageCommand {
    struct AddTarget: SwiftCommand {
        /// The type of target that can be specified on the command line.
        enum TargetType: String, Codable, ExpressibleByArgument {
            case library
            case executable
            case test
            case macro
        }

        package static let configuration = CommandConfiguration(
            abstract: "Add a new target to the manifest")

        @OptionGroup(visibility: .hidden)
        var globalOptions: GlobalOptions

        @Argument(help: "The name of the new target")
        var name: String

        @Option(help: "The type of target to add, which can be one of 'library', 'executable', 'test', or 'macro'")
        var type: TargetType = .library

        @Option(
            parsing: .upToNextOption,
            help: "A list of target dependency names"
        )
        var dependencies: [String] = []

        @Option(help: "The URL for a remote binary target")
        var url: String?

        @Option(help: "The path to a local binary target")
        var path: String?

        @Option(help: "The checksum for a remote binary target")
        var checksum: String?

        @Option(help: "The testing library to use when generating test targets, which can be one of 'xctest', 'swift-testing', or 'none'")
        var testingLibrary: PackageModelSyntax.AddTarget.TestHarness = .default

        func run(_ swiftCommandState: SwiftCommandState) throws {
            let workspace = try swiftCommandState.getActiveWorkspace()

            guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else {
                throw StringError("unknown package")
            }

            // Load the manifest file
            let fileSystem = workspace.fileSystem
            let manifestPath = packagePath.appending("Package.swift")
            let manifestContents: ByteString
            do {
                manifestContents = try fileSystem.readFileContents(manifestPath)
            } catch {
                throw StringError("cannot find package manifest in \(manifestPath)")
            }

            // Parse the manifest.
            let manifestSyntax = manifestContents.withData { data in
                data.withUnsafeBytes { buffer in
                    buffer.withMemoryRebound(to: UInt8.self) { buffer in
                        Parser.parse(source: buffer)
                    }
                }
            }

            // Map the target type.
            let type: TargetDescription.TargetKind = switch self.type {
                case .library: .regular
                case .executable: .executable
                case .test: .test
                case .macro: .macro
            }

            // Map dependencies
            let dependencies: [TargetDescription.Dependency] =
                self.dependencies.map {
                    .byName(name: $0, condition: nil)
                }

            let target = try TargetDescription(
                name: name,
                dependencies: dependencies,
                path: path,
                url: url,
                type: type,
                checksum: checksum
            )

            let editResult = try PackageModelSyntax.AddTarget.addTarget(
                target,
                to: manifestSyntax,
                configuration: .init(testHarness: testingLibrary),
                installedSwiftPMConfiguration: swiftCommandState
                  .getHostToolchain()
                  .installedSwiftPMConfiguration
            )

            try editResult.applyEdits(
                to: fileSystem,
                manifest: manifestSyntax,
                manifestPath: manifestPath,
                verbose: !globalOptions.logging.quiet
            )
        }
    }
}