@@ -252,24 +252,44 @@ public class Workspace {
252252 pinsFile: AbsolutePath ,
253253 manifestLoader: ManifestLoaderProtocol ,
254254 repositoryManager: RepositoryManager ? = nil ,
255- currentToolsVersion: ToolsVersion = ToolsVersion . currentToolsVersion ,
256- toolsVersionLoader: ToolsVersionLoaderProtocol = ToolsVersionLoader ( ) ,
255+ currentToolsVersion: ToolsVersion ? = nil ,
256+ toolsVersionLoader: ToolsVersionLoaderProtocol ? = nil ,
257257 delegate: WorkspaceDelegate ? = nil ,
258- config: Workspace . Configuration = Workspace . Configuration ( ) ,
259- fileSystem: FileSystem = localFileSystem ,
260- repositoryProvider: RepositoryProvider = GitRepositoryProvider ( ) ,
258+ config: Workspace . Configuration ? = nil ,
259+ fileSystem: FileSystem ? = nil ,
260+ repositoryProvider: RepositoryProvider ? = nil ,
261261 identityResolver: IdentityResolver ? = nil ,
262- httpClient: HTTPClient = HTTPClient ( ) ,
262+ httpClient: HTTPClient ? = nil ,
263263 netrcFilePath: AbsolutePath ? = nil ,
264- archiver: Archiver = ZipArchiver ( ) ,
265- checksumAlgorithm: HashAlgorithm = SHA256 ( ) ,
266- additionalFileRules: [ FileRuleDescription ] = [ ] ,
267- isResolverPrefetchingEnabled: Bool = false ,
268- enablePubgrubResolver: Bool = false ,
269- skipUpdate: Bool = false ,
270- enableResolverTrace: Bool = false ,
264+ archiver: Archiver ? = nil ,
265+ checksumAlgorithm: HashAlgorithm ? = nil ,
266+ additionalFileRules: [ FileRuleDescription ] ? = nil ,
267+ isResolverPrefetchingEnabled: Bool ? = nil ,
268+ enablePubgrubResolver: Bool ? = nil ,
269+ skipUpdate: Bool ? = nil ,
270+ enableResolverTrace: Bool ? = nil ,
271271 cachePath: AbsolutePath ? = nil
272272 ) {
273+ // defaults
274+ let currentToolsVersion = currentToolsVersion ?? ToolsVersion . currentToolsVersion
275+ let toolsVersionLoader = toolsVersionLoader ?? ToolsVersionLoader ( )
276+ let config = config ?? Workspace . Configuration ( )
277+ let fileSystem = fileSystem ?? localFileSystem
278+ let repositoryProvider = repositoryProvider ?? GitRepositoryProvider ( )
279+ let httpClient = httpClient ?? HTTPClient ( )
280+ let archiver = archiver ?? ZipArchiver ( )
281+ var checksumAlgorithm = checksumAlgorithm ?? SHA256 ( )
282+ #if canImport(CryptoKit)
283+ if checksumAlgorithm is SHA256 , #available( macOS 10 . 15 , * ) {
284+ checksumAlgorithm = CryptoKitSHA256 ( )
285+ }
286+ #endif
287+ let additionalFileRules = additionalFileRules ?? [ ]
288+ let isResolverPrefetchingEnabled = isResolverPrefetchingEnabled ?? false
289+ let skipUpdate = skipUpdate ?? false
290+ let enableResolverTrace = enableResolverTrace ?? false
291+
292+ // initialize
273293 self . delegate = delegate
274294 self . dataPath = dataPath
275295 self . config = config
@@ -281,12 +301,6 @@ public class Workspace {
281301 self . netrcFilePath = netrcFilePath
282302 self . archiver = archiver
283303
284- var checksumAlgorithm = checksumAlgorithm
285- #if canImport(CryptoKit)
286- if checksumAlgorithm is SHA256 , #available( macOS 10 . 15 , * ) {
287- checksumAlgorithm = CryptoKitSHA256 ( )
288- }
289- #endif
290304 self . checksumAlgorithm = checksumAlgorithm
291305 self . isResolverPrefetchingEnabled = isResolverPrefetchingEnabled
292306 self . skipUpdate = skipUpdate
@@ -329,21 +343,77 @@ public class Workspace {
329343 ///
330344 /// The root package path is used to compute the build directory and other
331345 /// default paths.
332- public static func create(
346+ ///
347+ /// - Parameters:
348+ /// - forRootPackage: The path for the root package.
349+ /// - toolchain: A custom toolchain.
350+ /// - repositoryManager: A custom repository manager.
351+ /// - delegate: Delegate for workspace events
352+ public convenience init (
353+ forRootPackage packagePath: AbsolutePath ,
354+ toolchain: UserToolchain ? = nil ,
355+ repositoryManager: RepositoryManager ? = nil ,
356+ delegate: WorkspaceDelegate ? = nil
357+ ) throws {
358+ let toolchain = try toolchain ?? UserToolchain ( destination: . hostDestination( ) )
359+ let manifestLoader = ManifestLoader ( toolchain: toolchain. configuration)
360+
361+ try self . init (
362+ forRootPackage: packagePath,
363+ manifestLoader: manifestLoader,
364+ repositoryManager: repositoryManager,
365+ delegate: delegate
366+ )
367+ }
368+
369+ /// A convenience method for creating a workspace for the given root
370+ /// package path.
371+ ///
372+ /// The root package path is used to compute the build directory and other
373+ /// default paths.
374+ ///
375+ /// - Parameters:
376+ /// - forRootPackage: The path for the root package.
377+ /// - manifestLoader: A custom manifest loader.
378+ /// - repositoryManager: A custom repository manager.
379+ /// - delegate: Delegate for workspace events
380+ public convenience init (
333381 forRootPackage packagePath: AbsolutePath ,
334382 manifestLoader: ManifestLoaderProtocol ,
335383 repositoryManager: RepositoryManager ? = nil ,
336- delegate: WorkspaceDelegate ? = nil ,
337- identityResolver : IdentityResolver ? = nil
338- ) -> Workspace {
339- return Workspace (
384+ delegate: WorkspaceDelegate ? = nil
385+ ) throws {
386+
387+ self . init (
340388 dataPath: packagePath. appending ( component: " .build " ) ,
341389 editablesPath: packagePath. appending ( component: " Packages " ) ,
342390 pinsFile: packagePath. appending ( component: " Package.resolved " ) ,
343391 manifestLoader: manifestLoader,
344392 repositoryManager: repositoryManager,
345- delegate: delegate,
346- identityResolver: identityResolver
393+ delegate: delegate
394+ )
395+ }
396+
397+ /// A convenience method for creating a workspace for the given root
398+ /// package path.
399+ ///
400+ /// The root package path is used to compute the build directory and other
401+ /// default paths.
402+ // FIXME: this one is kind of messy to backwards support, hopefully we can remove quickly
403+ // deprecated 8/2021
404+ @available ( * , deprecated, message: " use constructor instead " )
405+ public static func create(
406+ forRootPackage packagePath: AbsolutePath ,
407+ manifestLoader: ManifestLoaderProtocol ,
408+ repositoryManager: RepositoryManager ? = nil ,
409+ delegate: WorkspaceDelegate ? = nil ,
410+ identityResolver: IdentityResolver ? = nil
411+ ) -> Workspace {
412+ return try ! . init( forRootPackage: packagePath,
413+ manifestLoader: manifestLoader,
414+ repositoryManager: repositoryManager,
415+ delegate: delegate//,
416+ //identityResolver: identityResolver
347417 )
348418 }
349419}
@@ -628,14 +698,16 @@ extension Workspace {
628698 /// - diagnostics: Optional. The diagnostics engine.
629699 /// - on: The dispatch queue to perform asynchronous operations on.
630700 /// - completion: The completion handler .
701+ // deprecated 8/2021
702+ @available ( * , deprecated, message: " use workspace instance API instead " )
631703 public static func loadRootGraph(
632704 at packagePath: AbsolutePath ,
633705 swiftCompiler: AbsolutePath ,
634706 swiftCompilerFlags: [ String ] ,
635707 identityResolver: IdentityResolver ? = nil ,
636708 diagnostics: DiagnosticsEngine
637709 ) throws -> PackageGraph {
638- let toolchain = try ToolchainConfiguration ( swiftCompiler: swiftCompiler, swiftCompilerFlags: swiftCompilerFlags)
710+ let toolchain = ToolchainConfiguration ( swiftCompiler: swiftCompiler, swiftCompilerFlags: swiftCompilerFlags)
639711 let loader = ManifestLoader ( toolchain: toolchain)
640712 let workspace = Workspace . create ( forRootPackage: packagePath, manifestLoader: loader, identityResolver: identityResolver)
641713 return try workspace. loadPackageGraph ( rootPath: packagePath, diagnostics: diagnostics)
@@ -752,6 +824,48 @@ extension Workspace {
752824 }
753825 }
754826
827+ /// Loads and returns manifest at the given path.
828+ public func loadRootManifest(
829+ at path: AbsolutePath ,
830+ diagnostics: DiagnosticsEngine ,
831+ completion: @escaping ( Result < Manifest , Error > ) -> Void
832+ ) {
833+ self . loadRootManifests ( packages: [ path] , diagnostics: diagnostics) { result in
834+ completion ( result. tryMap {
835+ // normally, we call loadRootManifests which attempts to load any manifest it can and report errors via diagnostics
836+ // in this case, we want to load a specific manifest, so if the diagnostics contains an error we want to throw
837+ guard !diagnostics. hasErrors else {
838+ throw Diagnostics . fatalError
839+ }
840+ guard let manifest = $0 [ path] else {
841+ throw InternalError ( " Unknown manifest for ' \( path) ' " )
842+ }
843+ return manifest
844+ } )
845+ }
846+ }
847+
848+ public func loadRootPackage(
849+ at path: AbsolutePath ,
850+ diagnostics: DiagnosticsEngine ,
851+ completion: @escaping ( Result < Package , Error > ) -> Void
852+ ) {
853+ self . loadRootManifest ( at: path, diagnostics: diagnostics) { result in
854+ let result = result. tryMap { manifest -> Package in
855+ let identity = self . identityResolver. resolveIdentity ( for: manifest. packageLocation)
856+ let builder = PackageBuilder (
857+ identity: identity,
858+ manifest: manifest,
859+ productFilter: . everything,
860+ path: path,
861+ xcTestMinimumDeploymentTargets: MinimumDeploymentTarget . default. xcTestMinimumDeploymentTargets,
862+ diagnostics: diagnostics)
863+ return try builder. construct ( )
864+ }
865+ completion ( result)
866+ }
867+ }
868+
755869 /// Generates the checksum
756870 public func checksum(
757871 forBinaryArtifactAt path: AbsolutePath ,
0 commit comments