@@ -26,8 +26,12 @@ public final class PackageEditor {
26
26
let context : PackageEditorContext
27
27
28
28
/// Create a package editor instance.
29
- public convenience init ( buildDir: AbsolutePath , toolchain: UserToolchain ) throws {
30
- self . init ( context: try PackageEditorContext ( buildDir: buildDir, toolchain: toolchain) )
29
+ public convenience init ( manifestPath: AbsolutePath ,
30
+ buildDir: AbsolutePath ,
31
+ toolchain: UserToolchain ) throws {
32
+ self . init ( context: try PackageEditorContext ( manifestPath: manifestPath,
33
+ buildDir: buildDir,
34
+ toolchain: toolchain) )
31
35
}
32
36
33
37
/// Create a package editor instance.
@@ -41,41 +45,41 @@ public final class PackageEditor {
41
45
}
42
46
43
47
/// Add a package dependency.
44
- public func addPackageDependency( options : Options . AddPackageDependency ) throws {
45
- var options = options
46
-
48
+ public func addPackageDependency( url : String , requirement : PackageDependencyRequirement ? ) throws {
49
+ var requirement = requirement
50
+ let manifestPath = context . manifestPath
47
51
// Validate that the package doesn't already contain this dependency.
48
52
// FIXME: We need to handle version-specific manifests.
49
- let loadedManifest = try context. loadManifest ( at: options . manifestPath. parentDirectory)
53
+ let loadedManifest = try context. loadManifest ( at: context . manifestPath. parentDirectory)
50
54
let containsDependency = loadedManifest. dependencies. contains {
51
55
return PackageIdentity ( options. url) == PackageIdentity ( $0. url)
52
56
}
53
57
guard !containsDependency else {
54
- throw StringError ( " Already has dependency \( options . url) " )
58
+ throw StringError ( " Already has dependency \( url) " )
55
59
}
56
60
57
61
// If the input URL is a path, force the requirement to be a local package.
58
- if TSCUtility . URL. scheme ( options . url) == nil {
59
- assert ( options . requirement == nil || options . requirement == . localPackage)
60
- options . requirement = . localPackage
62
+ if TSCUtility . URL. scheme ( url) == nil {
63
+ assert ( requirement == nil || requirement == . localPackage)
64
+ requirement = . localPackage
61
65
}
62
66
63
67
// Load the dependency manifest depending on the inputs.
64
68
let dependencyManifest : Manifest
65
- let requirement : PackageDependencyRequirement
66
- if options. requirement == . localPackage {
69
+ if requirement == . localPackage {
67
70
// For local packages, load the manifest and get the first library product name.
68
- let path = AbsolutePath ( options . url, relativeTo: fs. currentWorkingDirectory!)
71
+ let path = AbsolutePath ( url, relativeTo: fs. currentWorkingDirectory!)
69
72
dependencyManifest = try context. loadManifest ( at: path)
70
73
requirement = . localPackage
71
74
} else {
72
75
// Otherwise, first lookup the dependency.
73
76
let spec = RepositorySpecifier ( url: options. url)
74
77
let handle = try tsc_await { context. repositoryManager. lookup ( repository: spec, completion: $0) }
78
+
75
79
let repo = try handle. open ( )
76
80
77
81
// Compute the requirement.
78
- if let inputRequirement = options . requirement {
82
+ if let inputRequirement = requirement {
79
83
requirement = inputRequirement
80
84
} else {
81
85
// Use the latest version or the master branch.
@@ -85,15 +89,15 @@ public final class PackageEditor {
85
89
}
86
90
87
91
// Load the manifest.
88
- let revision = try repo. resolveRevision ( identifier: requirement. ref!)
92
+ let revision = try repo. resolveRevision ( identifier: requirement! . ref!)
89
93
let repoFS = try repo. openFileView ( revision: revision)
90
94
dependencyManifest = try context. loadManifest ( at: . root, fs: repoFS)
91
95
}
92
96
93
97
// Add the package dependency.
94
- let manifestContents = try fs. readFileContents ( options . manifestPath) . cString
98
+ let manifestContents = try fs. readFileContents ( manifestPath) . cString
95
99
let editor = try ManifestRewriter ( manifestContents)
96
- try editor. addPackageDependency ( url: options . url, requirement: requirement)
100
+ try editor. addPackageDependency ( url: url, requirement: requirement! )
97
101
98
102
// Add the product in the first regular target, if possible.
99
103
let productName = dependencyManifest. products. filter { $0. type. isLibrary } . map { $0. name } . first
@@ -105,40 +109,39 @@ public final class PackageEditor {
105
109
}
106
110
107
111
// FIXME: We should verify our edits by loading the edited manifest before writing it to disk.
108
- try fs. writeFileContents ( options . manifestPath, bytes: ByteString ( encodingAsUTF8: editor. editedManifest) )
112
+ try fs. writeFileContents ( manifestPath, bytes: ByteString ( encodingAsUTF8: editor. editedManifest) )
109
113
}
110
114
111
115
/// Add a new target.
112
- public func addTarget( options: Options . AddTarget ) throws {
113
- let manifest = options. manifestPath
114
- let targetName = options. targetName
116
+ public func addTarget( name targetName: String , type targetType: TargetType ? ) throws {
117
+ let manifestPath = context. manifestPath
115
118
let testTargetName = targetName + " Tests "
116
119
117
120
// Validate that the package doesn't already contain this dependency.
118
121
// FIXME: We need to handle version-specific manifests.
119
- let loadedManifest = try context. loadManifest ( at: options . manifestPath. parentDirectory)
122
+ let loadedManifest = try context. loadManifest ( at: manifestPath. parentDirectory)
120
123
if loadedManifest. targets. contains ( where: { $0. name == targetName } ) {
121
124
throw StringError ( " Already has a target named \( targetName) " )
122
125
}
123
126
124
- let manifestContents = try fs. readFileContents ( options . manifestPath) . cString
127
+ let manifestContents = try fs. readFileContents ( manifestPath) . cString
125
128
let editor = try ManifestRewriter ( manifestContents)
126
129
try editor. addTarget ( targetName: targetName)
127
130
try editor. addTarget ( targetName: testTargetName, type: . test)
128
131
try editor. addTargetDependency ( target: testTargetName, dependency: targetName)
129
132
130
133
// FIXME: We should verify our edits by loading the edited manifest before writing it to disk.
131
- try fs. writeFileContents ( manifest , bytes: ByteString ( encodingAsUTF8: editor. editedManifest) )
134
+ try fs. writeFileContents ( manifestPath , bytes: ByteString ( encodingAsUTF8: editor. editedManifest) )
132
135
133
136
// Write template files.
134
- let targetPath = manifest . parentDirectory. appending ( components: " Sources " , targetName)
137
+ let targetPath = manifestPath . parentDirectory. appending ( components: " Sources " , targetName)
135
138
if !localFileSystem. exists ( targetPath) {
136
139
let file = targetPath. appending ( components: targetName + " .swift " )
137
140
try fs. createDirectory ( targetPath)
138
141
try fs. writeFileContents ( file, bytes: " " )
139
142
}
140
143
141
- let testTargetPath = manifest . parentDirectory. appending ( components: " Tests " , testTargetName)
144
+ let testTargetPath = manifestPath . parentDirectory. appending ( components: " Tests " , testTargetName)
142
145
if !fs. exists ( testTargetPath) {
143
146
let file = testTargetPath. appending ( components: testTargetName + " .swift " )
144
147
try fs. createDirectory ( testTargetPath)
@@ -204,40 +207,6 @@ public enum PackageDependencyRequirement: Equatable {
204
207
}
205
208
}
206
209
207
- public enum Options {
208
- public struct AddPackageDependency {
209
- public var manifestPath : AbsolutePath
210
- public var url : String
211
- public var requirement : PackageDependencyRequirement ?
212
-
213
- public init (
214
- manifestPath: AbsolutePath ,
215
- url: String ,
216
- requirement: PackageDependencyRequirement ? = nil
217
- ) {
218
- self . manifestPath = manifestPath
219
- self . url = url
220
- self . requirement = requirement
221
- }
222
- }
223
-
224
- public struct AddTarget {
225
- public var manifestPath : AbsolutePath
226
- public var targetName : String
227
- public var targetType : TargetType
228
-
229
- public init (
230
- manifestPath: AbsolutePath ,
231
- targetName: String ,
232
- targetType: TargetType = . regular
233
- ) {
234
- self . manifestPath = manifestPath
235
- self . targetName = targetName
236
- self . targetType = targetType
237
- }
238
- }
239
- }
240
-
241
210
extension ProductType {
242
211
var isLibrary : Bool {
243
212
switch self {
@@ -251,6 +220,8 @@ extension ProductType {
251
220
252
221
/// The global context for package editor.
253
222
public final class PackageEditorContext {
223
+ /// Path to the package manifest.
224
+ let manifestPath : AbsolutePath
254
225
255
226
/// Path to the build directory of the package.
256
227
let buildDir : AbsolutePath
@@ -264,7 +235,11 @@ public final class PackageEditorContext {
264
235
/// The file system in use.
265
236
let fs : FileSystem
266
237
267
- public init ( buildDir: AbsolutePath , toolchain: UserToolchain , fs: FileSystem = localFileSystem) throws {
238
+ public init ( manifestPath: AbsolutePath ,
239
+ buildDir: AbsolutePath ,
240
+ toolchain: UserToolchain ,
241
+ fs: FileSystem = localFileSystem) throws {
242
+ self . manifestPath = manifestPath
268
243
self . buildDir = buildDir
269
244
self . fs = fs
270
245
0 commit comments