289 lines
11 KiB
Makefile
289 lines
11 KiB
Makefile
# ~~~ Constants ~~~
|
|
LibName := "yary"
|
|
LibMsrv := "1.53"
|
|
|
|
# ~~~ Environment overrides ~~~
|
|
Color := env_var_or_default("YARY_COLOR", env_var_or_default("CARGO_TERM_COLOR", "1"))
|
|
Dryrun := env_var_or_default("YARY_DRYRUN", None)
|
|
Features := env_var_or_default("YARY_FEATURES", None)
|
|
Profile := env_var_or_default("YARY_PROFILE", None)
|
|
RustFlags := env_var_or_default("YARY_RUSTFLAGS", env_var_or_default("RUSTFLAGS", None))
|
|
DocFlags := env_var_or_default("YARY_RUSTDOCFLAGS", env_var_or_default("RUSTDOCFLAGS", None))
|
|
|
|
# Default to listing recipes
|
|
_default:
|
|
@just --list --list-prefix ' > '
|
|
|
|
# Display the recipe's steps
|
|
show recipe:
|
|
@just --show {{recipe}}
|
|
|
|
# Open library documentation in your browser
|
|
docs: (_build-docs "open")
|
|
|
|
# Check the library for syntax errors
|
|
check:
|
|
@$Say "Checking library for syntax errors..."
|
|
@$Cargo check
|
|
|
|
# Print entire changelog
|
|
changelog range=None: (_changelog range)
|
|
|
|
# Print patch notes for unreleased changes
|
|
patchnotes range=None: (_changelog if range != None { range } else { LibVersion + ".." } "all")
|
|
|
|
# Build the library
|
|
build: (_build Profile Features)
|
|
|
|
# Build library documentation
|
|
build-docs: _build-docs
|
|
|
|
# Display dependency tree of the library
|
|
deps edges="normal": _need_tree
|
|
@$Cargo tree --edges {{edges}}
|
|
|
|
# Display reverse dependency tree of the given crate
|
|
rdeps crate=LibName edges="normal": _need_tree
|
|
@$Cargo tree --invert --package {{crate}} --edges {{edges}}
|
|
|
|
# Check for unused dependencies
|
|
udeps: _need_udeps
|
|
@$Say "Checking for unused dependencies..."
|
|
@$Cargo +nightly udeps
|
|
|
|
# Run unit tests
|
|
test selector=None: (_test "lib" Profile Features selector)
|
|
|
|
# Run documentation tests
|
|
test-docs: (_test "doc" Profile Features)
|
|
|
|
# Run example tests
|
|
test-examples: (_test "examples" Profile Features)
|
|
|
|
# Run entire test suite
|
|
test-all: test test-docs test-examples lint-docs
|
|
|
|
# Clean the local build artifacts
|
|
clean:
|
|
@$Say "Cleaning build artifacts..."
|
|
@$Cargo clean
|
|
|
|
# Clean the documentation artifacts
|
|
clean-docs:
|
|
@$Say "Cleaning documentation artifacts..."
|
|
@$Cargo clean --doc
|
|
|
|
# Clean the cargo binaries used by this repo (modifies ~/.cargo/bin)
|
|
clean-bins: && _clean_deps
|
|
@$Say "Cleaning Cargo binaries..."
|
|
|
|
# Clean Cargo's cache (modifies ~/.cargo)
|
|
clean-cache: _need_cache
|
|
@$Say "Cleaning Cargo cache..."
|
|
@$Cargo cache --auto-clean
|
|
|
|
# Remove all local artifacts
|
|
clean-all: clean clean-docs
|
|
|
|
# Format library code
|
|
fmt: (_format)
|
|
|
|
# Initialize this library checkout, installing the required rustc version & components
|
|
fresh-system: (_fresh-system LibMsrv) install-bins check
|
|
|
|
# Install the cargo binaries used by this repo
|
|
install-bins update=None: (_build_deps update)
|
|
|
|
# Prune git local branches which previously had a tracking branch
|
|
git-branch-prune:
|
|
@$Say "Pruning [gone] branches..."
|
|
@$Git fetch --prune --all --quiet && \
|
|
git for-each-ref --format '%(refname) %(upstream:track)' refs/heads \
|
|
| awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}' \
|
|
| xargs -n1 ${NODRYRUN:+$Git branch -D}
|
|
|
|
# Run comprehensive check suite
|
|
git-pre-push: lint build lint-docs udeps audit test-all
|
|
alias pp := git-pre-push
|
|
|
|
# Lint library code
|
|
lint: (_format "check") _clippy
|
|
|
|
# Lint library documentation
|
|
lint-docs: (_build-docs "no-open" "check")
|
|
|
|
# Audit dependencies, checking for any known vulnerabilities or CVEs
|
|
audit: _need_audit
|
|
@$Say "Auditing dependencies..."
|
|
@$Say "[{{C_RED}}SKIP{{C_RESET}}] Tool is seg-faulting. See {{C_YELLOW}}https://github.com/rustsec/rustsec/issues/466{{C_RESET}}"
|
|
@#$Cargo audit
|
|
|
|
# Update the library's version to the specified
|
|
bump-version to: (_bump-cargo-version "Cargo.toml" trim_start_match(to, "v")) check (_bump-git-version "v" + trim_start_match(to, "v"))
|
|
@$Say "Run the following command when ready"
|
|
@echo "{{C_RED}}==> {{C_GREEN}}git push --atomic origin master v{{trim_start_match(to, "v")}}{{C_RESET}}"
|
|
|
|
# ~~~ Private recipes ~~~
|
|
|
|
# Run cargo test with the given suite, profile, features and selector (if any)
|
|
_test $suite=None $profile=Profile $features=Features selector=None:
|
|
@$Say "Running tests" \
|
|
"${suite:+{{C_GREEN}}suite:{{C_YELLOW}}$suite{{C_RESET}}}" \
|
|
"${features:+{{C_GREEN}}features:{{C_YELLOW}}$features{{C_RESET}}}" \
|
|
{{ if selector != None { C_GREEN + "selector:" + C_YELLOW + selector + C_RESET } else { None } }} \
|
|
| xargs
|
|
@$Cargo test \
|
|
${suite:+--$suite} \
|
|
${features:+--features $features} \
|
|
{{ if profile =~ '(?i)^release$' { "--release" } else { None } }} \
|
|
{{selector}}
|
|
|
|
# Run rustfmt with nightly so it understands our .rustfmt.toml rules
|
|
_format $check=None:
|
|
@$Say "Formating library..."
|
|
@$Cargo +nightly fmt ${check:+--check}
|
|
|
|
# Run clippy with the correct args
|
|
_clippy:
|
|
@$Say "Linting library..."
|
|
@$Cargo clippy -- -D clippy::all -W clippy::style
|
|
|
|
# Build the library
|
|
_build $profile=Profile $features=Features:
|
|
@$Say "Building library..."
|
|
@$Cargo build \
|
|
{{ if profile =~ '(?i)^release$' { "--release" } else { None } }} \
|
|
${features:+--features $features}
|
|
|
|
# Build our documentation
|
|
_build-docs open="no" check="no" features=Features:
|
|
#!/bin/sh
|
|
set -eu
|
|
|
|
{{ if check =~ '(?i)^check|true|yes|1$' { 'export RUSTDOCFLAGS="$RUSTDOCFLAGS -Dwarnings"' } else { None } }}
|
|
|
|
$Say "Building library docs..."
|
|
$Cargo +nightly doc \
|
|
--document-private-items \
|
|
{{ if features != None { "--features " + features } else { "--all-features" } }} \
|
|
{{ if open =~ '(?i)^open|true|yes|1$' { "--open" } else { None } }}
|
|
|
|
@_changelog range=None $strip=None $output=None +extra=None: _need_cliff
|
|
$Cliff {{extra}} ${strip:+--strip $strip} ${output:+--output $output} {{range}}
|
|
|
|
# Tiny perl script to bump the Cargo version field
|
|
@_bump-cargo-version file $version temp=`mktemp`:
|
|
$Say "Bumping {{file}} version to $version"
|
|
$Perl -spe \
|
|
{{ if Dryrun != None { '"' } else { '' } }} \
|
|
'if (/^version/) { s/("[\w.]+")/"$version"/ }' \
|
|
-- -version=$version < {{file}} > {{temp}} \
|
|
&& mv -f {{temp}} {{file}} \
|
|
{{ if Dryrun != None { '"' } else { '' } }}
|
|
|
|
# Add commit + tag to Git for the provided version
|
|
@_bump-git-version version temp=`mktemp`: (_changelog LibVersion + ".." "all" temp "--tag" version "--body" '"$(cat .git-cliff/tag.tera)"') (_changelog None None "CHANGELOG.md" "--tag" version)
|
|
$Say "Adding git tag {{version}} to HEAD"
|
|
if ! git branch --show-current | grep -qF 'master'; then \
|
|
$Say 'Refusing to set git tag, branch is not master' && false; \
|
|
fi
|
|
$Git add Cargo.toml Cargo.lock CHANGELOG.md
|
|
$Git commit -m 'chore: release {{version}}'
|
|
$Git tag -a {{version}} -F {{temp}}
|
|
|
|
# Install rustc version that we use in this repo + all the components we're expecting
|
|
@_fresh-system msrv=RustVersion:
|
|
$Say "Installing Rust version {{msrv}}..."
|
|
$Rustup install {{msrv}}
|
|
$Rustup install nightly
|
|
$Say "Setting override for {{justfile_directory()}}"
|
|
$Rustup override set {{msrv}}
|
|
$Say "Installing rustc components..."
|
|
$Rustup component add rustfmt clippy rust-src
|
|
$Rustup component add --toolchain nightly rustfmt clippy rust-docs
|
|
|
|
# ~~~ Cargo binary management ~~~
|
|
|
|
_build_deps update=None: (_need_cache update) (_need_udeps update) (_need_audit update) (_need_tree update) (_need_cliff update)
|
|
_clean_deps: _clean_cache _clean_udeps _clean_audit _clean_tree _clean_cliff
|
|
|
|
# Cargo udeps
|
|
_need_udeps update=None: (_need "udeps" update None "nightly")
|
|
_clean_udeps: (_clean_need "udeps" "nightly")
|
|
|
|
# Cargo cache
|
|
_need_cache update=None: (_need "cache" update "no-default-features,ci-autoclean" "nightly")
|
|
_clean_cache: (_clean_need "cache")
|
|
|
|
# Cargo audit
|
|
_need_audit update=None: (_need "audit" update None "nightly")
|
|
_clean_audit: (_clean_need "audit")
|
|
|
|
# Cargo tree
|
|
_need_tree update=None: (_need "tree" update None "nightly")
|
|
_clean_tree: (_clean_need "tree")
|
|
|
|
# Git-cliff
|
|
_need_cliff update=None: (_need "git-cliff" update None "nightly" None)
|
|
_clean_cliff: (_clean_need "git-cliff")
|
|
|
|
# Specify a dependency on a cargo binary
|
|
@_need crate $update=None features=None $nightly=None prefix="cargo-":
|
|
needed={{ if prefix != None { prefix + crate } else { crate } }}; \
|
|
{{ if update == None { "command -v $needed 2>/dev/null 1>/dev/null" } else { "false" } }} \
|
|
|| $Cargo ${nightly:++nightly} install \
|
|
${update:+--force} \
|
|
{{ if features =~ "no-default-features" { "--no-default-features" } else { None } }} \
|
|
{{ if features != None { "--features " + replace(features, "no-default-features,", None)} else { None } }} \
|
|
$needed
|
|
|
|
# Clean a cargo binary
|
|
@_clean_need crate $nightly=None:
|
|
needed=cargo-{{crate}}; \
|
|
command -v $needed 2>/dev/null 1>/dev/null \
|
|
&& $Cargo ${nightly:++nightly} uninstall $needed \
|
|
|| true
|
|
|
|
# ~~~ Global shell variables ~~~
|
|
export Say := "echo " + C_RED + "==> " + C_RESET + BuildId
|
|
export Cargo := if Dryrun == None { "cargo" } else { DryrunPrefix + "cargo" }
|
|
export Rustup := if Dryrun == None { "rustup" } else { DryrunPrefix + "cargo" }
|
|
export Git := if Dryrun == None { "git" } else { DryrunPrefix + "git" }
|
|
export Sed := if Dryrun == None { "sed" } else { DryrunPrefix + "sed" }
|
|
export Perl := if Dryrun == None { "perl" } else { DryrunPrefix + "perl" }
|
|
export Cliff := if Dryrun == None { "git-cliff" } else { DryrunPrefix + "git-cliff" }
|
|
export DRYRUN := if Dryrun == None { None } else { "1" }
|
|
export NODRYRUN := if Dryrun == None { "1" } else { None }
|
|
export RUSTFLAGS := RustFlags
|
|
export RUSTDOCFLAGS := DocFlags
|
|
|
|
# Nicer name for empty strings
|
|
None := ""
|
|
|
|
# ~~~ Contextual information ~~~
|
|
GitCommitish := if `git tag --points-at HEAD` != None {
|
|
`git tag --points-at HEAD`
|
|
} else if `git branch --show-current` != None {
|
|
`git branch --show-current`
|
|
} else {
|
|
`git rev-parse --short HEAD`
|
|
}
|
|
RustVersion := `rustc --version | cut -d' ' -f2`
|
|
LibVersion := `git describe --abbrev=0 2>/dev/null || echo -n "0.0.0"`
|
|
|
|
DryrunPrefix := "echo " + "[" + C_GREEN + "DRYRUN" + C_RESET + "] "
|
|
BuildId := "[" + C_YELLOW + RustVersion + C_RESET + "/" + C_GREEN + LibName + C_RESET + "@" + C_CYAN + GitCommitish + C_RESET + "]"
|
|
|
|
# ~~~ Color Codes ~~~
|
|
C_ENABLED := if Color =~ '(?i)^auto|always|yes|1$' { "1" } else { None }
|
|
|
|
C_RESET := if C_ENABLED == "1" { `echo -e "\033[0m"` } else { None }
|
|
C_BLACK := if C_ENABLED == "1" { `echo -e "\033[0;30m"` } else { None }
|
|
C_RED := if C_ENABLED == "1" { `echo -e "\033[0;31m"` } else { None }
|
|
C_GREEN := if C_ENABLED == "1" { `echo -e "\033[0;32m"` } else { None }
|
|
C_YELLOW := if C_ENABLED == "1" { `echo -e "\033[0;33m"` } else { None }
|
|
C_BLUE := if C_ENABLED == "1" { `echo -e "\033[0;34m"` } else { None }
|
|
C_MAGENTA := if C_ENABLED == "1" { `echo -e "\033[0;35m"` } else { None }
|
|
C_CYAN := if C_ENABLED == "1" { `echo -e "\033[0;36m"` } else { None }
|
|
C_WHITE := if C_ENABLED == "1" { `echo -e "\033[0;37m"` } else { None }
|