Skip to content

Commit

Permalink
feat: add dual arm/intel support, other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jondot committed May 6, 2024
1 parent 1a7899d commit 8edd1fd
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 49 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

# master

* supporting `rustwrap --latest` for figuring out the next version by itself
* **BREAKING** homebrew now supports arm and intel, so template variables must carry an arch postfix:
* `__URL__[arm64]` or `__URL__[x86]`
* `__SHA__[arm64]` or `__SHA__[x86]`
* fixing archive logic
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ brew:
class Recon < Formula
desc "recon"
homepage "http://www.example.com"
url "__URL__"
version "__VERSION__"
url "__URL__"
sha256 "__SHA__"
def install
Expand Down
13 changes: 9 additions & 4 deletions rustwrap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@ targets:
arch: arm64
url_template: https://github.com/rusty-ferris-club/rustwrap/releases/download/v__VERSION__/rustwrap-aarch64-macos.tar.xz
brew:
name: rustwrap
name: rustwrap
publish: true
tap: rusty-ferris-club/homebrew-tap
recipe_fname: rustwrap.rb
recipe_template: |
class Rustwrap < Formula
desc "A tool that helps wrap binary releases for easy distribution"
homepage "http://github.com/rusty-ferris-club/rustwrap"
url "__URL__"
version "__VERSION__"
sha256 "__SHA__"
if Hardware::CPU.intel?
url "__URL__[x64]"
sha256 "__SHA__[x64]"
elsif Hardware::CPU.arm?
url "__URL__[arm64]"
sha256 "__SHA__[arm64]"
end
def install
bin.install "rustwrap"
end
end
6 changes: 1 addition & 5 deletions rustwrap/src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,7 @@ impl<'a> TargetsDownloader<'a> {
.iter()
.map(|t| {
// if we have an archive and it exists on disk return it, otherwise download it
if t.archive.is_some()
&& t.archive
.as_ref()
.map(|a| Path::new(&self.out_dir.join(a)).exists())
.unwrap_or_default()
if t.archive.is_some() && t.archive.as_ref().is_some_and(|a| Path::new(&a).exists())
{
Ok(t.clone())
} else {
Expand Down
64 changes: 38 additions & 26 deletions rustwrap/src/providers/brew.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const VAR_URL: &str = "__URL__";
const VAR_SHA: &str = "__SHA__";
const VAR_VERSION: &str = "__VERSION__";

#[derive(Deserialize)]
#[derive(Deserialize, Default)]
pub struct BrewOpts {
pub name: String,
pub tap: String,
Expand All @@ -45,11 +45,14 @@ impl BrewOpts {
Ok(())
}

fn recipe(&self, version: &str, url: &str, sha: &str) -> String {
self.recipe_template
.replace(VAR_VERSION, version)
.replace(VAR_URL, url)
.replace(VAR_SHA, sha)
fn recipe(&self, version: &str, target_details: Vec<(Architecture, String, String)>) -> String {
let mut out = self.recipe_template.replace(VAR_VERSION, version);
for (arch, url, sha) in target_details {
out = out
.replace(&format!("{VAR_URL}[{arch}]"), &url)
.replace(&format!("{VAR_SHA}[{arch}]"), &sha);
}
out
}

fn recipe_file(&self) -> String {
Expand Down Expand Up @@ -108,28 +111,37 @@ pub fn publish(

opts.validate()?;

let target = targets
let mac_targets = targets
.iter()
.find(|t| t.arch == Architecture::X64 && t.platform == Platform::Darwin)
.ok_or_else(|| anyhow::anyhow!("no Intel macOS compatible target found"))?;

//
// prep: file name, template, hash, and render the url incl. version
// then, render the recipe file (ruby source)
//
let fname = target
.archive
.as_ref()
.ok_or_else(|| anyhow::anyhow!("archive '{:?}' was not found", target))?;

let mut file = fs::File::open(fname)?;

let mut hasher = sha2::Sha256::new();
io::copy(&mut file, &mut hasher)?;
let hash = hasher.finalize();
let sha = format!("{hash:x}");
.filter(|t| {
(t.arch == Architecture::X64 || t.arch == Architecture::ARM64)
&& t.platform == Platform::Darwin
})
.collect::<Vec<_>>();

let recipe = opts.recipe(version, &target.url(version), &sha);
if mac_targets.is_empty() {
anyhow::bail!("no targets available");
}
let mut target_details = Vec::new();
for target in mac_targets {
//
// prep: file name, template, hash, and render the url incl. version
// then, render the recipe file (ruby source)
//
let fname = target
.archive
.as_ref()
.ok_or_else(|| anyhow::anyhow!("archive '{:?}' was not found", target))?;

let mut file = fs::File::open(fname)?;

let mut hasher = sha2::Sha256::new();
io::copy(&mut file, &mut hasher)?;
let hash = hasher.finalize();
let sha = format!("{hash:x}");
target_details.push((target.arch.clone(), target.url(version), sha));
}
let recipe = opts.recipe(version, target_details);
tracing::info!(recipe, "rendered recipe");

//
Expand Down
25 changes: 12 additions & 13 deletions rustwrap/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,22 @@ pub fn run(version: Option<String>, config_file: &Path, out_path: &Path) -> Resu

if let Some(brew) = config.brew.as_ref() {
let prefix = format!("{} {}", crate::console::COFFEE, style("brew").green());
let latest_v = brew::latest(brew)?;
if latest_v < target_v {
if brew.publish {
let latest_v = brew::latest(brew)?;
if latest_v < target_v {
bail!("current latest version is newer, aborting publish")
}
session.console.say(&format!(
"{prefix} current: {latest_v}, publishing: {target_v}..."
));
brew::publish(
&mut session,
out_path,
&target_v.to_string(),
&versioned_targets,
brew,
)?;
} else {
session
.console
.say(&format!("{prefix} discovered version ({latest_v}) higher/equal to target version ({target_v}), skipping."));
}
brew::publish(
&mut session,
out_path,
&target_v.to_string(),
&versioned_targets,
brew,
)?;
}
Ok(())
}

0 comments on commit 8edd1fd

Please sign in to comment.