mirror of
https://github.com/fosskers/cargo-aur.git
synced 2026-03-09 07:13:12 -05:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7871899d9 | ||
|
|
06c5ab9b69 | ||
|
|
8903c72da6 | ||
|
|
109d9a66a7 | ||
|
|
8e223c5a2d | ||
|
|
b1383ff6ff | ||
|
|
c8892b4189 | ||
|
|
ab018dce5f | ||
|
|
e92757c05f | ||
|
|
86adc54767 | ||
|
|
1a9d6d4a5d | ||
|
|
4d49e5de70 | ||
|
|
a7069f4516 | ||
|
|
386817305a | ||
|
|
700cd6ca81 | ||
|
|
523c30c138 | ||
|
|
d04ece223f | ||
|
|
d2753668c1 | ||
|
|
2e89c3f8cb |
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
44
CHANGELOG.md
44
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
19
README.md
19
README.md
@@ -2,6 +2,7 @@
|
||||
|
||||
[](https://github.com/fosskers/cargo-aur/actions)
|
||||
[](https://crates.io/crates/cargo-aur)
|
||||

|
||||
|
||||
`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
|
||||
```
|
||||
|
||||
156
src/main.rs
156
src/main.rs
@@ -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"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user