@@ -22,20 +22,28 @@ pub enum PackageRef {
2222 LocalPath ( PathBuf ) ,
2323 /// The registry package name.
2424 #[ cfg( feature = "registry" ) ]
25- RegistryPackage ( PackageName ) , // TODO handle package versions
25+ RegistryPackage ( ( PackageName , Option < semver :: Version > ) ) ,
2626}
2727
2828impl FromStr for PackageRef {
2929 type Err = Error ;
3030
3131 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
3232 #[ cfg( feature = "registry" ) ]
33- return if let Ok ( package_name) = PackageName :: new ( s) {
34- // only `namespace:package-name` without file extensions is valid
35- Ok ( Self :: RegistryPackage ( package_name) )
36- } else {
37- Ok ( Self :: LocalPath ( PathBuf :: from ( s) ) )
38- } ;
33+ return Ok ( s
34+ . split_once ( '@' )
35+ . map ( |( name, version) | {
36+ match ( PackageName :: new ( name) , semver:: Version :: parse ( version) ) {
37+ ( Ok ( name) , Ok ( ver) ) => Ok ( Some ( Self :: RegistryPackage ( ( name, Some ( ver) ) ) ) ) ,
38+ ( Ok ( _) , Err ( e) ) => bail ! ( "invalid version for package `{s}`: {e}" ) ,
39+ ( Err ( _) , _) => Ok ( None ) ,
40+ }
41+ } )
42+ . unwrap_or ( Ok ( None ) ) ?
43+ . unwrap_or_else ( || match PackageName :: new ( s) {
44+ Ok ( name) => Self :: RegistryPackage ( ( name, None ) ) ,
45+ _ => Self :: LocalPath ( PathBuf :: from ( s) ) ,
46+ } ) ) ;
3947
4048 #[ cfg( not( feature = "registry" ) ) ]
4149 Ok ( Self :: LocalPath ( PathBuf :: from ( s) ) )
@@ -47,7 +55,9 @@ impl std::fmt::Display for PackageRef {
4755 match self {
4856 Self :: LocalPath ( path) => write ! ( f, "{}" , path. display( ) ) ,
4957 #[ cfg( feature = "registry" ) ]
50- Self :: RegistryPackage ( name) => write ! ( f, "{}" , name) ,
58+ Self :: RegistryPackage ( ( name, Some ( ver) ) ) => write ! ( f, "{}@{}" , name, ver) ,
59+ #[ cfg( feature = "registry" ) ]
60+ Self :: RegistryPackage ( ( name, None ) ) => write ! ( f, "{}" , name) ,
5161 }
5262 }
5363}
@@ -93,20 +103,39 @@ impl PlugCommand {
93103
94104 let socket_path = match & self . socket {
95105 #[ cfg( feature = "registry" ) ]
96- PackageRef :: RegistryPackage ( name) => {
97- client
98- . as_ref ( )
99- . ok_or_else ( || {
100- anyhow:: anyhow!(
101- "Warg registry is not configured. Package `{name}` was not found."
102- )
103- } ) ?
104- . download ( name, & semver:: VersionReq :: STAR )
105- . await ?
106- . ok_or_else ( || anyhow:: anyhow!( "package `{name}` was not found" ) ) ?
107- . path
106+ PackageRef :: RegistryPackage ( ( name, version) ) => {
107+ let client = client. as_ref ( ) . ok_or_else ( || {
108+ anyhow:: anyhow!(
109+ "Warg registry is not configured. Package `{name}` was not found."
110+ )
111+ } ) ?;
112+
113+ if let Some ( ver) = version {
114+ let download = client. download_exact ( name, ver) . await ?;
115+ println ! (
116+ "Plugging `{name}` version `{ver}` using registry `{registry}`" ,
117+ registry = client. url( )
118+ ) ;
119+ download. path
120+ } else {
121+ let download = client
122+ . download ( name, & semver:: VersionReq :: STAR )
123+ . await ?
124+ . ok_or_else ( || anyhow:: anyhow!( "package `{name}` was not found" ) ) ?;
125+
126+ println ! (
127+ "Plugging `{name}` version `{ver}` using registry `{registry}`" ,
128+ ver = & download. version,
129+ registry = client. url( )
130+ ) ;
131+ download. path
132+ }
133+ }
134+ PackageRef :: LocalPath ( path) => {
135+ println ! ( "Plugging `{path}`" , path = path. display( ) ) ;
136+
137+ path. clone ( )
108138 }
109- PackageRef :: LocalPath ( path) => path. clone ( ) ,
110139 } ;
111140 let socket = std:: fs:: read ( socket_path) . with_context ( || {
112141 format ! (
@@ -124,7 +153,7 @@ impl PlugCommand {
124153 for plug in self . plugs . iter ( ) {
125154 let name = match plug {
126155 #[ cfg( feature = "registry" ) ]
127- PackageRef :: RegistryPackage ( name) => std:: borrow:: Cow :: Borrowed ( name. as_ref ( ) ) ,
156+ PackageRef :: RegistryPackage ( ( name, _ ) ) => std:: borrow:: Cow :: Borrowed ( name. as_ref ( ) ) ,
128157 PackageRef :: LocalPath ( path) => path
129158 . file_stem ( )
130159 . map ( |fs| fs. to_string_lossy ( ) )
@@ -140,17 +169,41 @@ impl PlugCommand {
140169 for ( i, plug_ref) in plug_refs. iter ( ) . enumerate ( ) {
141170 let ( mut name, path) = match plug_ref {
142171 #[ cfg( feature = "registry" ) ]
143- PackageRef :: RegistryPackage ( name) => (
144- name. as_ref ( ) . to_string ( ) ,
145- client
146- . as_ref ( )
147- . ok_or_else ( || anyhow:: anyhow!( "Warg registry is not configured. Package `{name}` was not found." ) ) ?
148- . download ( name, & semver:: VersionReq :: STAR )
149- . await ?
150- . ok_or_else ( || anyhow:: anyhow!( "package `{name}` was not found" ) ) ?
151- . path ,
152- ) ,
153- PackageRef :: LocalPath ( path) => ( format ! ( "plug:{name}" ) , path. clone ( ) ) ,
172+ PackageRef :: RegistryPackage ( ( name, version) ) => {
173+ let client = client. as_ref ( ) . ok_or_else ( || {
174+ anyhow:: anyhow!(
175+ "Warg registry is not configured. Package `{name}` was not found."
176+ )
177+ } ) ?;
178+
179+ let path = if let Some ( ver) = version {
180+ let download = client. download_exact ( name, ver) . await ?;
181+ println ! (
182+ " with `{name}` version `{ver}` using registry `{registry}`" ,
183+ registry = client. url( )
184+ ) ;
185+ download. path
186+ } else {
187+ let download = client
188+ . download ( name, & semver:: VersionReq :: STAR )
189+ . await ?
190+ . ok_or_else ( || anyhow:: anyhow!( "package `{name}` was not found" ) ) ?;
191+
192+ println ! (
193+ " with `{name}` version `{ver}` using registry `{registry}`" ,
194+ ver = & download. version,
195+ registry = client. url( )
196+ ) ;
197+ download. path
198+ } ;
199+
200+ let name = name. as_ref ( ) . to_string ( ) ;
201+ ( name, path)
202+ }
203+ PackageRef :: LocalPath ( path) => {
204+ println ! ( " with `{path}`" , path = path. display( ) ) ;
205+ ( format ! ( "plug:{name}" ) , path. clone ( ) )
206+ }
154207 } ;
155208 // If there's more than one plug with the same name, append an index to the name.
156209 if plug_refs. len ( ) > 1 {
@@ -199,6 +252,7 @@ impl PlugCommand {
199252 "failed to write output file `{path}`" ,
200253 path = path. display( )
201254 ) ) ?;
255+ println ! ( "\n Wrote plugged component: `{path}`" , path = path. display( ) ) ;
202256 }
203257 None => {
204258 std:: io:: stdout ( )
0 commit comments