mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-06 04:00:02 +00:00
Split {format} and allow use of {binary-ext} in pkg-url (#95)
This from feedback in #19: > wrt. bin-dir and bin-path, this appears to be a typo / should all be called bin-dir This is only a readme fix afaict, I changed all occurences of `bin-path` in there to `bin-dir`. > wrt. format, those are actually two (unfortunately named) different concepts, the first refers to the archive format (eg. .tgz), the second to the binary format (which needs a .exe appended for windows). This introduces two new substitutions: - `binary-ext` is the old "`format` in `bin-dir`" - `archive-format` is the old "`format` in `pkg-url`" Contents are unchanged: `binary-ext` includes the dot, `archive-format` doesn't. That makes it easy to upgrade and also personally I slightly prefer it that way. The old contextual `format` is still available, "soft deprecated": it will be accepted silently so everything will work, but all documentation will use the new syntax. In the future we could move to a "hard deprecated" model where installing a package that uses `format` will warn the user / tell them to report that to the maintainer. I don't think we'll ever really be able to remove it but that should be good enough. A cool new feature is that `binary-ext` is now usable in `pkg-url`, which will be useful for raw binary downloads: ```toml pkg_url = "{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }{ binary-ext }" ``` I've also added a bunch of tests to GhCrateMeta around the templating for `pkg-url`.
This commit is contained in:
parent
370ae05620
commit
6dcb1dd1b4
5 changed files with 215 additions and 34 deletions
|
@ -16,18 +16,11 @@ pub struct GhCrateMeta {
|
|||
#[async_trait::async_trait]
|
||||
impl super::Fetcher for GhCrateMeta {
|
||||
async fn new(data: &Data) -> Result<Box<Self>, anyhow::Error> {
|
||||
// Generate context for URL interpolation
|
||||
let ctx = Context {
|
||||
name: &data.name,
|
||||
repo: data.repo.as_ref().map(|s| &s[..]),
|
||||
target: &data.target,
|
||||
version: &data.version,
|
||||
format: data.meta.pkg_fmt.to_string(),
|
||||
};
|
||||
let ctx = Context::from_data(data);
|
||||
debug!("Using context: {:?}", ctx);
|
||||
|
||||
Ok(Box::new(Self {
|
||||
url: Url::parse(&ctx.render(&data.meta.pkg_url)?)?,
|
||||
url: ctx.render_url(&data.meta.pkg_url)?,
|
||||
pkg_fmt: data.meta.pkg_fmt,
|
||||
}))
|
||||
}
|
||||
|
@ -68,7 +61,184 @@ struct Context<'c> {
|
|||
pub repo: Option<&'c str>,
|
||||
pub target: &'c str,
|
||||
pub version: &'c str,
|
||||
|
||||
/// Soft-deprecated alias for archive-format
|
||||
pub format: String,
|
||||
|
||||
/// Archive format e.g. tar.gz, zip
|
||||
#[serde(rename = "archive-format")]
|
||||
pub archive_format: String,
|
||||
|
||||
/// Filename extension on the binary, i.e. .exe on Windows, nothing otherwise
|
||||
#[serde(rename = "binary-ext")]
|
||||
pub binary_ext: &'c str,
|
||||
}
|
||||
|
||||
impl<'c> Template for Context<'c> {}
|
||||
|
||||
impl<'c> Context<'c> {
|
||||
pub(self) fn from_data(data: &'c Data) -> Self {
|
||||
let pkg_fmt = data.meta.pkg_fmt.to_string();
|
||||
Self {
|
||||
name: &data.name,
|
||||
repo: data.repo.as_ref().map(|s| &s[..]),
|
||||
target: &data.target,
|
||||
version: &data.version,
|
||||
format: pkg_fmt.clone(),
|
||||
archive_format: pkg_fmt,
|
||||
binary_ext: if data.target.contains("windows") {
|
||||
".exe"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(self) fn render_url(&self, template: &str) -> Result<Url, anyhow::Error> {
|
||||
Ok(Url::parse(&self.render(template)?)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{super::Data, Context};
|
||||
use crate::{PkgFmt, PkgMeta};
|
||||
use url::Url;
|
||||
|
||||
fn url(s: &str) -> Url {
|
||||
Url::parse(s).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defaults() {
|
||||
let meta = PkgMeta::default();
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
version: "1.2.3".to_string(),
|
||||
repo: Some("https://github.com/ryankurte/cargo-binstall".to_string()),
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://github.com/ryankurte/cargo-binstall/releases/download/v1.2.3/cargo-binstall-x86_64-unknown-linux-gnu-v1.2.3.tgz")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn no_repo() {
|
||||
let meta = PkgMeta::default();
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
version: "1.2.3".to_string(),
|
||||
repo: None,
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_repo_but_full_url() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = format!("https://example.com{}", meta.pkg_url);
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
version: "1.2.3".to_string(),
|
||||
repo: None,
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://example.com/releases/download/v1.2.3/cargo-binstall-x86_64-unknown-linux-gnu-v1.2.3.tgz")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_url() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ archive-format }".to_string();
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
version: "0.14.1-alpha.5".to_string(),
|
||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://github.com/rust-iot/rust-radio-sx128x/releases/download/v0.14.1-alpha.5/sx128x-util-x86_64-unknown-linux-gnu-v0.14.1-alpha.5.tgz")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deprecated_format() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ format }".to_string();
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
version: "0.14.1-alpha.5".to_string(),
|
||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://github.com/rust-iot/rust-radio-sx128x/releases/download/v0.14.1-alpha.5/sx128x-util-x86_64-unknown-linux-gnu-v0.14.1-alpha.5.tgz")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_ext() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url =
|
||||
"{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }.tar.xz"
|
||||
.to_string();
|
||||
meta.pkg_fmt = PkgFmt::Txz;
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_string(),
|
||||
target: "aarch64-apple-darwin".to_string(),
|
||||
version: "9.0.0".to_string(),
|
||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://github.com/watchexec/cargo-watch/releases/download/v9.0.0/cargo-watch-v9.0.0-aarch64-apple-darwin.tar.xz")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_archive() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }{ binary-ext }".to_string();
|
||||
meta.pkg_fmt = PkgFmt::Bin;
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_string(),
|
||||
target: "aarch64-pc-windows-msvc".to_string(),
|
||||
version: "9.0.0".to_string(),
|
||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
meta,
|
||||
};
|
||||
|
||||
let ctx = Context::from_data(&data);
|
||||
assert_eq!(
|
||||
ctx.render_url(&data.meta.pkg_url).unwrap(),
|
||||
url("https://github.com/watchexec/cargo-watch/releases/download/v9.0.0/cargo-watch-v9.0.0-aarch64-pc-windows-msvc.exe")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue