Skip to content

Commit

Permalink
Merge pull request #426 from cgwalters/xtask
Browse files Browse the repository at this point in the history
Copy xtask packaging bits from bootc
  • Loading branch information
jmarrero committed Feb 1, 2023
2 parents db96220 + 46a39e4 commit d582a30
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
xtask = "run --manifest-path ./xtask/Cargo.toml --"
7 changes: 7 additions & 0 deletions .copr/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
srpm:
dnf -y install cargo git openssl-devel
# similar to https://github.com/actions/checkout/issues/760, but for COPR
git config --global --add safe.directory '*'
cargo install cargo-vendor-filterer
cargo xtask package-srpm
mv target/*.src.rpm $$outdir
64 changes: 64 additions & 0 deletions contrib/packaging/bootupd.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
%bcond_without check
%global __cargo_skip_build 0

%global crate bootupd

Name: bootupd
Version: 0.2.9
Release: 1%{?dist}
Summary: Bootloader updater

License: ASL 2.0
URL: https://crates.io/crates/bootupd
Source0: https://github.com/coreos/bootupd/releases/download/v%{version}/bootupd-%{version}.tar.zstd
Source1: https://github.com/coreos/bootupd/releases/download/v%{version}/bootupd-%{version}-vendor.tar.zstd

# For now, see upstream
ExclusiveArch: x86_64 aarch64
BuildRequires: make
BuildRequires: cargo
# For autosetup -Sgit
BuildRequires: git
BuildRequires: openssl-devel
BuildRequires: systemd-devel

%description
%{summary}

%files
%license LICENSE
%doc README.md
%{_bindir}/bootupctl
%{_libexecdir}/bootupd
%{_unitdir}/*

%prep
%autosetup -n %{crate}-%{version} -p1 -Sgit
tar -xv -f %{SOURCE1}
mkdir -p .cargo
cat >.cargo/config << EOF
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"
EOF

%build
cargo build --release

%install
%make_install INSTALL="install -p -c"

%post -n %{crate}
%systemd_post bootupd.service bootupd.socket

%preun -n %{crate}
%systemd_preun bootupd.service bootupd.socket

%postun -n %{crate}
%systemd_postun bootupd.service bootupd.socket

%changelog
* Tue Oct 18 2022 Colin Walters <walters@verbum.org> - 0.2.8-3
- Dummy changelog
59 changes: 0 additions & 59 deletions packaging/rust-bootupd.spec

This file was deleted.

5 changes: 5 additions & 0 deletions xtask/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/target
fastbuild*.qcow2
_kola_temp
.cosa
Cargo.lock
13 changes: 13 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.68"
camino = "1.0"
fn-error-context = "0.2.0"
tempfile = "3.3"
xshell = { version = "0.2" }
187 changes: 187 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::process::{Command, Stdio};

use anyhow::{Context, Result};
use camino::{Utf8Path, Utf8PathBuf};
use fn_error_context::context;
use xshell::{cmd, Shell};

const NAME: &str = "bootupd";
const VENDORPATH: &str = "vendor.tar.zstd";

fn main() {
if let Err(e) = try_main() {
eprintln!("error: {e:#}");
std::process::exit(1);
}
}

fn try_main() -> Result<()> {
let task = std::env::args().nth(1);
let sh = xshell::Shell::new()?;
if let Some(cmd) = task.as_deref() {
let f = match cmd {
"vendor" => vendor,
"package" => package,
"package-srpm" => package_srpm,
_ => print_help,
};
f(&sh)?;
} else {
print_help(&sh)?;
}
Ok(())
}

fn get_target_dir() -> Result<Utf8PathBuf> {
let target = Utf8Path::new("target");
std::fs::create_dir_all(&target)?;
Ok(target.to_owned())
}

fn vendor(sh: &Shell) -> Result<()> {
let _targetdir = get_target_dir()?;
let target = VENDORPATH;
cmd!(
sh,
"cargo vendor-filterer --prefix=vendor --format=tar.zstd {target}"
)
.run()?;
Ok(())
}

fn gitrev_to_version(v: &str) -> String {
let v = v.trim().trim_start_matches('v');
v.replace('-', ".")
}

#[context("Finding gitrev")]
fn gitrev(sh: &Shell) -> Result<String> {
if let Ok(rev) = cmd!(sh, "git describe --tags").ignore_stderr().read() {
Ok(gitrev_to_version(&rev))
} else {
let mut desc = cmd!(sh, "git describe --tags --always").read()?;
desc.insert_str(0, "0.");
Ok(desc)
}
}

struct Package {
version: String,
srcpath: Utf8PathBuf,
}

#[context("Packaging")]
fn impl_package(sh: &Shell) -> Result<Package> {
let v = gitrev(sh)?;
println!("Using version {v}");
let namev = format!("{NAME}-{v}");
let target = get_target_dir()?;
let p = target.join(format!("{namev}.tar.zstd"));
let o = File::create(&p).context("Creating output file")?;
let prefix = format!("{namev}/");
let st = Command::new("git")
.args([
"archive",
"--format=tar",
"--prefix",
prefix.as_str(),
"HEAD",
])
.stdout(Stdio::from(o))
.status()
.context("Executing git archive")?;
if !st.success() {
anyhow::bail!("Failed to run {st:?}");
}
Ok(Package {
version: v,
srcpath: p,
})
}

fn package(sh: &Shell) -> Result<()> {
let p = impl_package(sh)?.srcpath;
println!("Generated: {p}");
Ok(())
}

fn impl_srpm(sh: &Shell) -> Result<Utf8PathBuf> {
let pkg = impl_package(sh)?;
vendor(sh)?;
let td = tempfile::tempdir_in("target").context("Allocating tmpdir")?;
let td = td.into_path();
let td: &Utf8Path = td.as_path().try_into().unwrap();
let srcpath = td.join(pkg.srcpath.file_name().unwrap());
std::fs::rename(pkg.srcpath, srcpath)?;
let v = pkg.version;
let vendorpath = td.join(format!("{NAME}-{v}-vendor.tar.zstd"));
std::fs::rename(VENDORPATH, vendorpath)?;
{
let specin = File::open(format!("contrib/packaging/{NAME}.spec"))
.map(BufReader::new)
.context("Opening spec")?;
let mut o = File::create(td.join(format!("{NAME}.spec"))).map(BufWriter::new)?;
for line in specin.lines() {
let line = line?;
if line.starts_with("Version:") {
writeln!(o, "# Replaced by cargo xtask package-srpm")?;
writeln!(o, "Version: {v}")?;
} else {
writeln!(o, "{}", line)?;
}
}
}
let d = sh.push_dir(td);
let mut cmd = cmd!(sh, "rpmbuild");
for k in [
"_sourcedir",
"_specdir",
"_builddir",
"_srcrpmdir",
"_rpmdir",
] {
cmd = cmd.arg("--define");
cmd = cmd.arg(format!("{k} {td}"));
}
let spec = format!("{NAME}.spec");
cmd.arg("--define")
.arg(format!("_buildrootdir {td}/.build"))
.args(["-bs", spec.as_str()])
.run()?;
drop(d);
let mut srpm = None;
for e in std::fs::read_dir(td)? {
let e = e?;
let n = e.file_name();
let n = if let Some(n) = n.to_str() {
n
} else {
continue;
};
if n.ends_with(".src.rpm") {
srpm = Some(td.join(n));
break;
}
}
let srpm = srpm.ok_or_else(|| anyhow::anyhow!("Failed to find generated .src.rpm"))?;
let dest = Utf8Path::new("target").join(srpm.file_name().unwrap());
std::fs::rename(&srpm, &dest)?;
Ok(dest)
}

fn package_srpm(sh: &Shell) -> Result<()> {
let srpm = impl_srpm(sh)?;
println!("Generated: {srpm}");
Ok(())
}

fn print_help(_sh: &Shell) -> Result<()> {
eprintln!(
"Tasks:
- vendor
"
);
Ok(())
}

0 comments on commit d582a30

Please sign in to comment.