Skip to content

Commit 17f1803

Browse files
committed
added version parsing
1 parent e0bf803 commit 17f1803

1 file changed

Lines changed: 87 additions & 33 deletions

File tree

src/commands/plug.rs

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2828
impl 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!("\nWrote plugged component: `{path}`", path = path.display());
202256
}
203257
None => {
204258
std::io::stdout()

0 commit comments

Comments
 (0)