19 Commits

Author SHA1 Message Date
Colin Woodbury
f7871899d9 1.2.0 2020-08-24 14:19:46 -07:00
Colin Woodbury
06c5ab9b69 Add --version flag 2020-08-24 14:17:55 -07:00
Colin Woodbury
8903c72da6 1.1.2 2020-08-11 14:24:24 -07:00
Colin Woodbury
109d9a66a7 Mention --musl in the README 2020-08-11 14:20:52 -07:00
Colin Woodbury
8e223c5a2d Warn if the MUSL target is missing when using --musl 2020-08-11 14:14:26 -07:00
Colin Woodbury
b1383ff6ff Strip the release binary before tarring it 2020-08-11 13:49:18 -07:00
Colin Woodbury
c8892b4189 1.1.1 2020-08-11 13:28:35 -07:00
Colin Woodbury
ab018dce5f Capture all free arguments 2020-08-11 13:27:40 -07:00
Colin Woodbury
e92757c05f 1.1.0 2020-08-10 16:37:01 -07:00
Colin Woodbury
86adc54767 New --musl flag to link statically 2020-08-10 16:35:20 -07:00
Colin Woodbury
1a9d6d4a5d 1.0.3 2020-07-18 08:07:12 -07:00
Colin Woodbury
4d49e5de70 Dependabot config 2020-07-09 18:46:41 -07:00
Colin Woodbury
a7069f4516 AUR readme badge 2020-06-22 12:08:38 -07:00
Colin Woodbury
386817305a 1.0.2 2020-06-22 12:00:32 -07:00
Colin Woodbury
700cd6ca81 Drop auto_from for anyhow 2020-06-22 11:57:09 -07:00
Colin Woodbury
523c30c138 Update README 2020-06-17 19:03:36 -07:00
Colin Woodbury
d04ece223f CHANGELOG 2020-06-17 18:50:15 -07:00
Colin Woodbury
d2753668c1 Auto-detect the git host instead 2020-06-17 18:48:36 -07:00
Colin Woodbury
2e89c3f8cb Provide --gitlab to override source link 2020-06-17 18:40:16 -07:00
5 changed files with 188 additions and 45 deletions

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@@ -1,5 +1,49 @@
# `cargo-aur` Changelog
## 1.2.0 (2020-08-24)
#### Added
- A `--version` flag to display the current version of `cargo-aur`.
## 1.1.2 (2020-08-11)
#### Added
- When using `--musl`, the user is warned if they don't have the
`x86_64-unknown-linux-musl` target installed.
#### Changed
- Run `strip` on the release binary before `tar`ring it.
## 1.1.1 (2020-08-11)
#### Fixed
- A breaking bug in `1.1.0` which prevented it from working at all.
## 1.1.0 (2020-08-10)
#### Added
- The `--musl` flag to compile the release binary with the MUSL target. In most
cases, this will result in a fully statically linked binary.
## 1.0.3 (2020-07-18)
#### Changed
- Better release profile which produces smaller binaries.
## 1.0.2 (2020-06-22)
#### Changed
- `cargo aur` will now auto-detect the git host (Github or Gitlab) and generated
a `source` link based on that.
- Fewer dependencies.
## 1.0.1 (2020-06-17)
#### Changed

View File

@@ -1,6 +1,6 @@
[package]
name = "cargo-aur"
version = "1.0.1"
version = "1.2.0"
authors = ["Colin Woodbury <colin@fosskers.ca>"]
edition = "2018"
description = "Prepare Rust projects to be released on the Arch Linux User Repository."
@@ -12,9 +12,13 @@ keywords = ["cargo", "subcommand", "archlinux", "aur"]
categories = ["command-line-utilities"]
[dependencies]
auto_from = "0.3"
anyhow = "1.0"
gumdrop = "0.8"
hmac-sha256 = "0.1"
itertools = "0.9"
serde = "1.0"
serde_derive = "1.0"
toml = "0.5"
[profile.release]
lto = true

View File

@@ -2,6 +2,7 @@
[![Build](https://github.com/fosskers/cargo-aur/workflows/Build/badge.svg)](https://github.com/fosskers/cargo-aur/actions)
[![](https://img.shields.io/crates/v/cargo-aur.svg)](https://crates.io/crates/cargo-aur)
![AUR version](https://img.shields.io/aur/version/cargo-aur-bin)
`cargo-aur` is a new subcommand for `cargo` that produces a release tarball and
PKGBUILD file for a Rust project, so that it can be released on the Arch Linux
@@ -14,7 +15,7 @@ a PKGBUILD will be generated with all the necessary sections filled out.
## Installation
Guess what? `cargo-aur` itself is on the AUR! Install it with an AUR-compatible
package manager:
package manager like [`aura`](https://github.com/fosskers/aura):
```
sudo aura -A cargo-aur-bin
@@ -52,11 +53,23 @@ AUR standard.
At this point, it is up to you to:
1. Create an official `Release` on Github, attaching the original binary tarball
that `cargo aur` produced.
1. Create an official `Release` on Github/Gitlab, attaching the original binary
tarball that `cargo aur` produced.
2. Copy the PKGBUILD to a git repo that tracks releases of your package.
3. Run `makepkg --printsrcinfo > .SRCINFO`.
4. Commit both files and push to the AUR.
Some of these steps may be automated in `cargo aur` at a later date if there is
sufficient demand.
### Static Binaries
Run with `--musl` to produce a release binary that is statically linked via
[MUSL](https://musl.libc.org/).
```
> cargo aur --musl
> cd target/x86_64-unknown-linux-musl/release/
> ldd <your-binary>
not a dynamic executable
```

View File

@@ -1,9 +1,47 @@
use auto_from::From;
use anyhow::anyhow;
use gumdrop::{Options, ParsingStyle};
use hmac_sha256::Hash;
use itertools::Itertools;
use serde_derive::Deserialize;
use std::fs;
use std::process::{self, Command};
use std::{fmt, fs, io};
use std::str;
#[derive(Options)]
struct Args {
/// Display this help message.
help: bool,
/// Display the current version of this software.
version: bool,
/// Unused.
#[options(free)]
args: Vec<String>,
/// Use the MUSL build target to produce a static binary.
musl: bool,
}
enum GitHost {
Github,
Gitlab,
}
impl GitHost {
fn source(&self, package: &Package) -> String {
match self {
GitHost::Github => format!(
"{}/releases/download/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
GitHost::Gitlab => format!(
"{}/-/archive/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
}
}
}
#[derive(Deserialize, Debug)]
struct Config {
@@ -26,36 +64,40 @@ impl Package {
fn tarball(&self) -> String {
format!("{}-{}-x86_64.tar.gz", self.name, self.version)
}
}
#[derive(From)]
enum Error {
Io(io::Error),
Parsing(toml::de::Error),
Utf8(std::string::FromUtf8Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Io(e) => write!(f, "{}", e),
Error::Parsing(e) => write!(f, "{}", e),
Error::Utf8(e) => write!(f, "{}", e),
fn git_host(&self) -> Option<GitHost> {
if self.repository.starts_with("https://github") {
Some(GitHost::Github)
} else if self.repository.starts_with("https://gitlab") {
Some(GitHost::Gitlab)
} else {
None
}
}
}
fn main() {
if let Err(e) = work() {
let args = Args::parse_args_or_exit(ParsingStyle::AllOptions);
if args.version {
let version = env!("CARGO_PKG_VERSION");
println!("{}", version);
} else if let Err(e) = work(args) {
eprintln!("{}", e);
process::exit(1)
}
}
fn work() -> Result<(), Error> {
fn work(args: Args) -> anyhow::Result<()> {
// We can't proceed if the user has specified `--musl` but doesn't have the
// target installed.
if args.musl {
musl_check()?
}
let config = cargo_config()?;
release_build()?;
tarball(&config.package)?;
release_build(args.musl)?;
tarball(args.musl, &config.package)?;
let sha256 = sha256sum(&config.package)?;
let pkgbuild = pkgbuild(&config.package, &sha256);
fs::write("PKGBUILD", pkgbuild)?;
@@ -63,14 +105,14 @@ fn work() -> Result<(), Error> {
Ok(())
}
fn cargo_config() -> Result<Config, Error> {
fn cargo_config() -> anyhow::Result<Config> {
let content = fs::read_to_string("Cargo.toml")?;
let proj = toml::from_str(&content)?;
Ok(proj) // TODO Would like to do this in one line with the above.
}
/// Produce a legal PKGBUILD.
fn pkgbuild(package: &Package, md5: &str) -> String {
fn pkgbuild(package: &Package, sha256: &str) -> String {
format!(
r#"{}
pkgname={}-bin
@@ -78,12 +120,12 @@ pkgver={}
pkgrel=1
pkgdesc="{}"
url="{}"
license=('{}')
arch=('x86_64')
provides=('{}')
options=('strip')
source=("{}/releases/download/v$pkgver/{}-$pkgver-x86_64.tar.gz")
sha256sums=('{}')
license=("{}")
arch=("x86_64")
provides=("{}")
options=("strip")
source=("{}")
sha256sums=("{}")
package() {{
install -Dm755 {} -t "$pkgdir/usr/bin/"
@@ -100,25 +142,35 @@ package() {{
package.homepage,
package.license,
package.name,
package.repository,
package.name,
md5,
package
.git_host()
.unwrap_or(GitHost::Github)
.source(package),
sha256,
package.name,
)
}
/// Run `cargo build --release`.
fn release_build() -> Result<(), Error> {
Command::new("cargo")
.arg("build")
.arg("--release")
.status()?;
/// Run `cargo build --release`, potentially building statically.
fn release_build(musl: bool) -> anyhow::Result<()> {
let mut args = vec!["build", "--release"];
if musl {
args.push("--target=x86_64-unknown-linux-musl");
}
Command::new("cargo").args(args).status()?;
Ok(())
}
fn tarball(package: &Package) -> Result<(), Error> {
let binary = format!("target/release/{}", package.name);
fn tarball(musl: bool, package: &Package) -> anyhow::Result<()> {
let binary = if musl {
format!("target/x86_64-unknown-linux-musl/release/{}", package.name)
} else {
format!("target/release/{}", package.name)
};
strip(&binary)?;
fs::copy(binary, &package.name)?;
Command::new("tar")
.arg("czf")
@@ -130,9 +182,33 @@ fn tarball(package: &Package) -> Result<(), Error> {
Ok(())
}
fn sha256sum(package: &Package) -> Result<String, Error> {
/// Strip the release binary, so that we aren't compressing more bytes than we
/// need to.
fn strip(path: &str) -> anyhow::Result<()> {
Command::new("strip").arg(path).status()?;
Ok(())
}
fn sha256sum(package: &Package) -> anyhow::Result<String> {
let bytes = fs::read(package.tarball())?;
let digest = Hash::hash(&bytes);
let hex = digest.iter().map(|u| format!("{:02x}", u)).collect();
Ok(hex)
}
/// Does the user have the `x86_64-unknown-linux-musl` target installed?
fn musl_check() -> anyhow::Result<()> {
let args = vec!["target", "list", "--installed"];
let output = Command::new("rustup").args(args).output()?.stdout;
let installed = str::from_utf8(&output)?
.lines()
.any(|tc| tc == "x86_64-unknown-linux-musl");
if installed {
Ok(())
} else {
Err(anyhow!(
"Missing target! Try: rustup target add x86_64-unknown-linux-musl"
))
}
}