@@ -35,7 +35,7 @@ pub struct Package {
3535
3636impl Package {
3737 pub fn new ( name : String , version : VersionSpec ) -> Fallible < Self > {
38- let staging = setup_staging_directory ( PackageManager :: Npm ) ?;
38+ let staging = setup_staging_directory ( PackageManager :: Npm , false /* needs_scope */ ) ?;
3939
4040 Ok ( Package {
4141 name,
@@ -126,13 +126,28 @@ impl Display for Package {
126126pub struct DirectInstall {
127127 staging : TempDir ,
128128 manager : PackageManager ,
129+ name : Option < String > ,
129130}
130131
131132impl DirectInstall {
132133 pub fn new ( manager : PackageManager ) -> Fallible < Self > {
133- let staging = setup_staging_directory ( manager) ?;
134+ let staging = setup_staging_directory ( manager, false /* needs_scope */ ) ?;
134135
135- Ok ( DirectInstall { staging, manager } )
136+ Ok ( DirectInstall {
137+ staging,
138+ manager,
139+ name : None ,
140+ } )
141+ }
142+
143+ pub fn with_name ( manager : PackageManager , name : String ) -> Fallible < Self > {
144+ let staging = setup_staging_directory ( manager, name. contains ( '/' ) ) ?;
145+
146+ Ok ( DirectInstall {
147+ staging,
148+ manager,
149+ name : Some ( name) ,
150+ } )
136151 }
137152
138153 pub fn setup_command ( & self , command : & mut Command ) {
@@ -141,16 +156,20 @@ impl DirectInstall {
141156 }
142157
143158 pub fn complete_install ( self , image : & Image ) -> Fallible < ( ) > {
144- let name = self
145- . manager
146- . get_installed_package ( self . staging . path ( ) . to_owned ( ) )
159+ let DirectInstall {
160+ staging,
161+ name,
162+ manager,
163+ } = self ;
164+
165+ let name = name
166+ . or_else ( || manager. get_installed_package ( staging. path ( ) . to_owned ( ) ) )
147167 . ok_or ( ErrorKind :: InstalledPackageNameError ) ?;
148- let manifest =
149- configure:: parse_manifest ( & name, self . staging . path ( ) . to_owned ( ) , self . manager ) ?;
168+ let manifest = configure:: parse_manifest ( & name, staging. path ( ) . to_owned ( ) , manager) ?;
150169
151- persist_install ( & name, & manifest. version , self . staging . path ( ) ) ?;
152- link_package_to_shared_dir ( & name, self . manager ) ?;
153- configure:: write_config_and_shims ( & name, & manifest, image, self . manager )
170+ persist_install ( & name, & manifest. version , staging. path ( ) ) ?;
171+ link_package_to_shared_dir ( & name, manager) ?;
172+ configure:: write_config_and_shims ( & name, & manifest, image, manager)
154173 }
155174}
156175
@@ -211,17 +230,22 @@ impl InPlaceUpgrade {
211230
212231/// Create the temporary staging directory we will use to install and ensure expected
213232/// subdirectories exist within it
214- fn setup_staging_directory ( manager : PackageManager ) -> Fallible < TempDir > {
233+ fn setup_staging_directory ( manager : PackageManager , needs_scope : bool ) -> Fallible < TempDir > {
215234 // Workaround to ensure relative symlinks continue to work.
216235 // The final installed location of packages is:
217236 // $VOLTA_HOME/tools/image/packages/{name}/
218237 // To ensure that the temp directory has the same amount of nesting, we use:
219238 // $VOLTA_HOME/tmp/image/packages/{tempdir}/
220239 // This way any relative symlinks will have the same amount of nesting and will remain valid
221240 // even when the directory is persisted.
241+ // We also need to handle the case when the linked package has a scope, which requires another
242+ // level of nesting
222243 let mut staging_root = volta_home ( ) ?. tmp_dir ( ) . to_owned ( ) ;
223244 staging_root. push ( "image" ) ;
224245 staging_root. push ( "packages" ) ;
246+ if needs_scope {
247+ staging_root. push ( "scope" ) ;
248+ }
225249 create_dir_all ( & staging_root) . with_context ( || ErrorKind :: ContainingDirError {
226250 path : staging_root. clone ( ) ,
227251 } ) ?;
0 commit comments