@@ -2368,22 +2368,25 @@ extension Workspace {
2368
2368
2369
2369
switch requirement {
2370
2370
case . version( let version) :
2371
- // FIXME: We need to get the revision here, and we don't have a
2372
- // way to get it back out of the resolver which is very
2373
- // annoying. Maybe we should make an SPI on the provider for
2374
- // this?
2375
- // FIXME: this should not block
2376
- // FIXME: this should be updated to support registry
2377
- guard let container = ( try temp_await {
2378
- self . getContainer ( for: package , skipUpdate: true , on: . sharedConcurrent, completion: $0)
2379
- } ) as? SourceControlPackageContainer else {
2380
- throw InternalError ( " invalid container for \( package ) expected a RepositoryPackageContainer " )
2381
- }
2382
- guard let tag = container. getTag ( for: version) else {
2383
- throw InternalError ( " unable to get tag for \( package ) \( version) ; available versions \( try container. versionsDescending ( ) ) " )
2371
+ if let _ = package . identity. scopeAndName {
2372
+ checkoutState = . version( version, revision: . init( identifier: " \( version) " ) )
2373
+ } else {
2374
+ // FIXME: We need to get the revision here, and we don't have a
2375
+ // way to get it back out of the resolver which is very
2376
+ // annoying. Maybe we should make an SPI on the provider for
2377
+ // this?
2378
+ // FIXME: this should not block
2379
+ guard let container = ( try temp_await {
2380
+ self . getContainer ( for: package , skipUpdate: true , on: . sharedConcurrent, completion: $0)
2381
+ } ) as? SourceControlPackageContainer else {
2382
+ throw InternalError ( " invalid container for \( package ) expected a SourceControlPackageContainer " )
2383
+ }
2384
+ guard let tag = container. getTag ( for: version) else {
2385
+ throw InternalError ( " unable to get tag for \( package ) \( version) ; available versions \( try container. versionsDescending ( ) ) " )
2386
+ }
2387
+ let revision = try container. getRevision ( forTag: tag)
2388
+ checkoutState = . version( version, revision: revision)
2384
2389
}
2385
- let revision = try container. getRevision ( forTag: tag)
2386
- checkoutState = . version( version, revision: revision)
2387
2390
2388
2391
case . revision( let revision, . none) :
2389
2392
checkoutState = . revision( revision)
@@ -2828,8 +2831,33 @@ extension Workspace: PackageContainerProvider {
2828
2831
completion ( . failure( error) )
2829
2832
}
2830
2833
}
2831
- case . registry:
2832
- fatalError ( " registry dependencies are supported at this point " )
2834
+ case . registry( let identity) :
2835
+ do {
2836
+ guard let registryManager = registryManager else {
2837
+ throw InternalError ( " registry manager not configured " )
2838
+ }
2839
+
2840
+ guard let _ = identity. scopeAndName else {
2841
+ throw InternalError ( " cannot get registry container for package \( identity) " )
2842
+ }
2843
+
2844
+ let container = RegistryPackageContainer (
2845
+ package : package ,
2846
+ identityResolver: identityResolver,
2847
+ manager: registryManager,
2848
+ manifestLoader: manifestLoader,
2849
+ toolsVersionLoader: toolsVersionLoader,
2850
+ currentToolsVersion: currentToolsVersion
2851
+ )
2852
+
2853
+ queue. async {
2854
+ completion ( . success( container) )
2855
+ }
2856
+ } catch {
2857
+ queue. async {
2858
+ completion ( . failure( error) )
2859
+ }
2860
+ }
2833
2861
}
2834
2862
}
2835
2863
@@ -2846,7 +2874,11 @@ extension Workspace: PackageContainerProvider {
2846
2874
case . localSourceControl, . remoteSourceControl:
2847
2875
return try self . checkoutRepository ( package : package , at: checkoutState)
2848
2876
case . registry:
2849
- fatalError ( " registry dependencies are supported at this point " )
2877
+ guard case . version( let version, _) = checkoutState else {
2878
+ fatalError ( " cannot download source archive for package \( package ) with checkout state \( checkoutState) " )
2879
+ }
2880
+
2881
+ return try self . downloadSourceArchive ( for: package , at: version)
2850
2882
}
2851
2883
}
2852
2884
@@ -2863,24 +2895,16 @@ extension Workspace: PackageContainerProvider {
2863
2895
// a local package.
2864
2896
//
2865
2897
// Note that we don't actually remove a local package from disk.
2866
- switch dependency. state {
2867
- case . local:
2898
+ if case . local = dependency. state {
2868
2899
self . state. dependencies. remove ( package . identity)
2869
2900
try self . state. save ( )
2870
2901
return
2871
- case . checkout, . edited:
2872
- break
2873
- case . downloaded:
2874
- break
2875
2902
}
2876
2903
2877
- // Inform the delegate.
2878
- delegate? . removing ( repository: dependency. packageRef. location)
2879
-
2880
2904
// Compute the dependency which we need to remove.
2881
2905
let dependencyToRemove : ManagedDependency
2882
2906
2883
- if case . edited( let _basedOn , let unmanagedPath) = dependency. state, let basedOn = _basedOn {
2907
+ if case . edited( let basedOn ? , let unmanagedPath) = dependency. state {
2884
2908
// Remove the underlying dependency for edited packages.
2885
2909
dependencyToRemove = basedOn
2886
2910
let updatedDependency = Workspace . ManagedDependency. edited (
@@ -2895,13 +2919,17 @@ extension Workspace: PackageContainerProvider {
2895
2919
self . state. dependencies. remove ( dependencyToRemove. packageRef. identity)
2896
2920
}
2897
2921
2922
+ delegate? . removing ( repository: dependency. packageRef. location)
2923
+
2898
2924
switch package . kind {
2899
- case . root, . fileSystem:
2900
- fatalError ( " local dependencies are supported " )
2925
+ case . root( let path) :
2926
+ throw InternalError ( " root dependency \( dependencyToRemove) cannot be removed at \( path) " )
2927
+ case . fileSystem( let path) :
2928
+ throw InternalError ( " local dependency \( dependencyToRemove) cannot be removed at \( path) " )
2901
2929
case . localSourceControl, . remoteSourceControl:
2902
2930
try self . removeRepository ( dependency: dependencyToRemove)
2903
2931
case . registry:
2904
- fatalError ( " registry dependencies are supported at this point " )
2932
+ try self . removeSourceArchive ( for : dependencyToRemove )
2905
2933
}
2906
2934
2907
2935
// Save the state.
@@ -3026,6 +3054,52 @@ extension Workspace {
3026
3054
}
3027
3055
}
3028
3056
3057
+ // MARK: - Source archive management
3058
+
3059
+ extension Workspace {
3060
+ func downloadSourceArchive(
3061
+ for package : PackageReference ,
3062
+ at version: Version
3063
+ ) throws -> AbsolutePath {
3064
+ guard let registryManager = registryManager else {
3065
+ throw InternalError ( " registry manager not initialized " )
3066
+ }
3067
+
3068
+ let path = self . location. sourceArchivesSubdirectory ( for: package , at: version)
3069
+
3070
+ if !localFileSystem. exists ( path) {
3071
+ _ = try temp_await {
3072
+ registryManager. downloadSourceArchive ( for: version,
3073
+ of: package ,
3074
+ into: localFileSystem,
3075
+ at: path,
3076
+ on: . sharedConcurrent,
3077
+ completion: $0)
3078
+ }
3079
+ }
3080
+
3081
+ self . state. dependencies. add ( . downloaded( packageRef: package , version: version) )
3082
+ try self . state. save ( )
3083
+
3084
+ return path
3085
+ }
3086
+
3087
+ func removeSourceArchive(
3088
+ for dependency: ManagedDependency
3089
+ ) throws {
3090
+ guard case . downloaded( let version) = dependency. state else {
3091
+ throw InternalError ( " cannot remove source archive for \( dependency) with state \( dependency. state) " )
3092
+ }
3093
+
3094
+ let path = self . location. sourceArchivesSubdirectory ( for: dependency. packageRef, at: version)
3095
+
3096
+ try localFileSystem. removeFileTree ( path)
3097
+
3098
+ self . state. dependencies. remove ( dependency. packageRef. identity)
3099
+
3100
+ try self . state. save ( )
3101
+ }
3102
+ }
3029
3103
3030
3104
// MARK: - Utility extensions
3031
3105
0 commit comments