From c5b40cc9821fa7ff457a2deca8c2431d44c29d9d Mon Sep 17 00:00:00 2001 From: Stephan Boyer Date: Sun, 20 Jun 2021 18:32:13 -0700 Subject: [PATCH] Add support for Windows and non-GNU Linux --- .github/ISSUE_TEMPLATE/bug_report.md | 4 +- .github/workflows/ci.yml | 162 ++++++++++++++++++++- .gitignore | 2 - .ignore | 4 - CHANGELOG.md | 5 + CONTRIBUTING.md | 42 ++++++ Cargo.lock | 4 +- Cargo.toml | 2 +- MAINTAINERS.md | 32 +++++ README.md | 12 +- install.sh | 42 +++--- release.sh | 46 ------ toast.yml | 204 +++++++++++++++++++-------- 13 files changed, 412 insertions(+), 149 deletions(-) delete mode 100644 .ignore create mode 100644 MAINTAINERS.md delete mode 100755 release.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 83c87aa..f1ba68a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -13,9 +13,9 @@ A clear description of what the bug is. **Instructions to reproduce the bug** A clear explanation of how to reproduce the bug. -**System information:** - - OS: [e.g. macOS Mojave 10.14.5] +**Environment information:** - Tagref version: [e.g. 0.0.0] + - OS: [e.g. macOS Big Sur 11.4 (20F71)] **Additional context** Add any other context about the problem here. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 552171e..ba93104 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,172 @@ name: Continuous integration on: [push, pull_request] +defaults: + run: + shell: bash jobs: - ci: + ci-linux: name: Build and test on Linux runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: azure/docker-login@v1 + - if: ${{ github.event_name == 'push' }} + uses: azure/docker-login@v1 with: username: stephanmisc password: ${{ secrets.DOCKER_PASSWORD }} - if: github.event_name == 'push' - uses: stepchowfun/toast/.github/actions/toast@main with: - tasks: build check test lint run + tasks: build test lint release run repo: stephanmisc/toast write_remote_cache: ${{ github.event_name == 'push' }} + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # The artifact name will contain the target triple, so the file name doesn't need to. + mv artifacts/tagref-x86_64-unknown-linux-gnu artifacts/tagref + - uses: actions/upload-artifact@v2 + with: + name: x86_64-unknown-linux-gnu + path: artifacts/tagref + if-no-files-found: error + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # The artifact name will contain the target triple, so the file name doesn't need to. + mv artifacts/tagref-x86_64-unknown-linux-musl artifacts/tagref + - uses: actions/upload-artifact@v2 + with: + name: x86_64-unknown-linux-musl + path: artifacts/tagref + if-no-files-found: error + ci-macos: + name: Build and test on macOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + rustup toolchain install 1.53.0 # [ref:rust_1_53_0] + rustup default 1.53.0 # [ref:rust_1_53_0] + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # Build and test. + cargo build --locked --release --target x86_64-apple-darwin + NO_COLOR=true cargo test --locked # [ref:colorless_tests] + - uses: actions/upload-artifact@v2 + with: + name: x86_64-apple-darwin + path: target/x86_64-apple-darwin/release/tagref + if-no-files-found: error + ci-windows: + name: Build and test on Windows + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + rustup toolchain install 1.53.0 # [ref:rust_1_53_0] + rustup default 1.53.0 # [ref:rust_1_53_0] + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # Build and test. + cargo build --locked --release --target x86_64-pc-windows-msvc + NO_COLOR=true cargo test --locked # [ref:colorless_tests] + - uses: actions/upload-artifact@v2 + with: + name: x86_64-pc-windows-msvc + path: target/x86_64-pc-windows-msvc/release/tagref.exe + if-no-files-found: error + install-macos: + name: Run the installer script on macOS to validate it + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # Run the installer script. + PREFIX=/tmp ./install.sh + + # Run the installed binary. + /tmp/tagref + install-ubuntu: + name: Run the installer script on Ubuntu to validate it + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # Run the installer script. + PREFIX=/tmp ./install.sh + + # Run the installed binary. + /tmp/tagref + create-release: + name: Create a release on GitHub if applicable + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + runs-on: ubuntu-latest + needs: [ci-linux, ci-macos, ci-windows, install-macos, install-ubuntu] + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + with: + path: artifacts/ + - env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Make Bash not silently ignore errors. + set -euo pipefail + + # Fetch the program version. + VERSION="$(cargo pkgid | cut -d# -f2 | cut -d: -f2)" + + # If the release already exists, exit early. + if hub release show "v$VERSION" &> /dev/null; then + echo "Release v$VERSION already exists." + exit + fi + + # Give the artifacts unique names. + mv \ + artifacts/x86_64-unknown-linux-gnu/tagref \ + artifacts/tagref-x86_64-unknown-linux-gnu + mv \ + artifacts/x86_64-unknown-linux-musl/tagref \ + artifacts/tagref-x86_64-unknown-linux-musl + mv \ + artifacts/x86_64-apple-darwin/tagref \ + artifacts/tagref-x86_64-apple-darwin + mv \ + artifacts/x86_64-pc-windows-msvc/tagref.exe \ + artifacts/tagref-x86_64-pc-windows-msvc.exe + + # Create the release. + hub release create \ + --commitish '${{ github.sha }}' \ + --message "v$VERSION" \ + --attach 'artifacts/tagref-x86_64-unknown-linux-gnu' \ + --attach 'artifacts/tagref-x86_64-unknown-linux-musl' \ + --attach 'artifacts/tagref-x86_64-apple-darwin' \ + --attach 'artifacts/tagref-x86_64-pc-windows-msvc.exe' \ + "v$VERSION" + echo "Created release v$VERSION." + - uses: stepchowfun/toast/.github/actions/toast@main + with: + tasks: publish + repo: stephanmisc/toast + env: + CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} diff --git a/.gitignore b/.gitignore index cfe356f..6367a60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ -# Keep this file in sync with `.ignore`. /artifacts/ -/release/ /target/ diff --git a/.ignore b/.ignore deleted file mode 100644 index 942e247..0000000 --- a/.ignore +++ /dev/null @@ -1,4 +0,0 @@ -# Keep this file in sync with `.gitignore`. -/artifacts/ -/release/ -/target/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 526ef6f..9227081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.5.0] - 2021-06-20 + +### Added +- Tagref now supports two new platforms: (1) Windows, and (2) Linux without glibc. + ## [1.4.1] - 2020-12-08 ### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b0d380..9a7292f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,3 +3,45 @@ Thank you for your interest in contributing! You can contribute by filing [issues](https://github.com/stepchowfun/tagref/issues) and submitting [pull requests](https://github.com/stepchowfun/tagref/pulls). Please observe our [code of conduct](https://github.com/stepchowfun/tagref/blob/main/CODE_OF_CONDUCT.md). If you submit a pull request, please ensure your change passes the [GitHub Actions](https://github.com/stepchowfun/tagref/actions) CI checks. This will be apparent from the required status check(s) in the pull request. + +## Rust style guide + +We are fortunate to have good tooling around enforcing a consistent style throughout the codebase. If you have [Toast](https://github.com/stepchowfun/toast), you can run the various lint checks by running `toast lint`. Otherwise, you can rely on our CI to do it for you. Here, we make note of a few conventions which are not yet enforced automatically. Please adhere to these conventions when possible, and provide appropriate justification for deviations from this guide. If you notice any style violations which appear unintentional, we invite you to bring them to our attention. + +### Comments + +**Rule:** Comments should be written in American English. + +**Rule:** Comments should always be capitalized unless they start with a code-like expression (see below). + +**Rule:** Comments which are sentences should be punctuated appropriately. For example: + +```rust +// The following logic implements beta reduction. +``` + +**Rule:** Comments which are not sentences should not have a trailing period. For example: + +```rust +// Already normalized +``` + +**Rule:** Code-like expressions, such as variable names, should be surrounded by backticks. For example: + +```rust +// `source_range` is a half-open interval, closed on the left and open on the right. +``` + +### Trailing commas + +The linter enforces that items in multi-line sequences (e.g., function arguments and macro arguments) have trailing commas. + +**Rule:** Macros should be written to accept trailing commas as follows: + +```rust +macro_rules! my_macro { + ($foo:expr, $bar:expr, $baz:expr $(,)?) => {{ + ... + }}; +} +``` diff --git a/Cargo.lock b/Cargo.lock index 1aef852..3b305c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.15" @@ -207,7 +209,7 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "tagref" -version = "1.4.1" +version = "1.5.0" dependencies = [ "atty", "clap", diff --git a/Cargo.toml b/Cargo.toml index 4e1ee2e..3851e9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tagref" -version = "1.4.1" +version = "1.5.0" authors = ["Stephan Boyer "] edition = "2018" description = "Tagref helps you refer to other locations in your codebase." diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..4d30e1d --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,32 @@ +# Maintainers + +This document describes some instructions for maintainers. Other contributors and users need not be concerned with this material. + +### GitHub instructions + +When setting up the repository on GitHub, configure the following settings: + +- Under `Secrets`, add the following repository secrets with appropriate values: + - `CRATES_IO_TOKEN` + - `DOCKER_PASSWORD` +- Under `Branches`, add a branch protection rule for the `main` branch. + - Enable `Require status checks to pass before merging`. + - Enable `Require branches to be up to date before merging`. + - Add the following status checks: + - `Build and test on Linux` + - `Build and test on Windows` + - `Build and test on macOS` + - `Create a release on GitHub if applicable` + - `Run the installer script on Ubuntu to validate it` + - `Run the installer script on macOS to validate it` + - Enable `Include administrators`. +- Under `Options`, enable `Automatically delete head branches`. + +The GitHub workflow will fail initially because the jobs which test the installer script will not find any release to download. You'll need to bootstrap a release by temporarily removing those jobs or changing them to no-ops. Be aware that the `create-release` job is configured to only run on the `main` branch, so you may also need to temporarily change that depending on which branch you're working on. + +### Release instructions + +Releasing a new version is a two-step process: + +1. Bump the version in `Cargo.toml`, run `cargo build` to update `Cargo.lock`, and update `CHANGELOG.md` with information about the new version. Ship those changes as a single commit. +2. Once the GitHub workflow has finished on the `main` branch, update the version in `install.sh` to point to the new release. diff --git a/README.md b/README.md index 2e49146..cbad452 100644 --- a/README.md +++ b/README.md @@ -89,11 +89,11 @@ SUBCOMMANDS: Lists the unreferenced tags ``` -## Installation +## Installation instructions -### Easy installation +### Easy installation on macOS or Linux -If you are running macOS or a GNU-based Linux on an x86-64 CPU, you can install Tagref with this command: +If you are running macOS or Linux on an x86-64 CPU, you can install Tagref with this command: ```sh curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs | sh @@ -101,7 +101,7 @@ curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs The same command can be used again to update Tagref to the latest version. -**NOTE:** Piping `curl` to `sh` is dangerous since the server might be compromised. If you're concerned about this, you can download and inspect the installation script or choose one of the other installation methods. +**NOTE:** Piping `curl` to `sh` is considered dangerous by some since the server might be compromised. If you're concerned about this, you can download and inspect the installation script or choose one of the other installation methods. #### Customizing the installation @@ -116,9 +116,9 @@ For example, the following will install Tagref into the working directory: curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs | PREFIX=. sh ``` -### Manual installation +### Manual installation for macOS, Linux, or Windows -The [releases page](https://github.com/stepchowfun/tagref/releases) has precompiled binaries for macOS or Linux systems running on an x86-64 CPU. You can download one of them and place it in a directory listed in your [`PATH`](https://en.wikipedia.org/wiki/PATH_\(variable\)). +The [releases page](https://github.com/stepchowfun/tagref/releases) has precompiled binaries for macOS, Linux, and Windows systems running on an x86-64 CPU. You can download one of them and place it in a directory listed in your [`PATH`](https://en.wikipedia.org/wiki/PATH_\(variable\)). ### Installation with Cargo diff --git a/install.sh b/install.sh index 3e5ddee..9893e81 100755 --- a/install.sh +++ b/install.sh @@ -1,14 +1,14 @@ #!/usr/bin/env sh +# This installer script supports Linux and macOS machines running on x86-64 only. + # Usage examples: # ./install.sh # VERSION=x.y.z ./install.sh # PREFIX=/usr/local/bin ./install.sh -# We wrap everything in parentheses for two reasons: -# 1. To prevent the shell from executing only a prefix of the script if the download is interrupted -# 2. To ensure that any working directory changes with `cd` are local to this script and don't -# affect the calling user's shell +# We wrap everything in parentheses to prevent the shell from executing only a prefix of the script +# if the download is interrupted. ( # Where the binary will be installed DESTINATION="${PREFIX:-/usr/local/bin}/tagref" @@ -19,11 +19,14 @@ # Determine which binary to download. FILENAME='' if uname -a | grep -qi 'x86_64.*GNU/Linux'; then - echo 'x86_64 GNU/Linux detected.' + echo 'x86-64 GNU Linux detected.' FILENAME=tagref-x86_64-unknown-linux-gnu + elif uname -a | grep -qi 'x86_64 Linux'; then + echo 'x86-64 non-GNU Linux detected.' + FILENAME=tagref-x86_64-unknown-linux-musl fi if uname -a | grep -qi 'Darwin.*x86_64'; then - echo 'macOS detected.' + echo 'x86-64 macOS detected.' FILENAME=tagref-x86_64-apple-darwin fi @@ -33,40 +36,37 @@ # This is a helper function to clean up and fail. fail() { echo "$1" >&2 - cd "$TEMPDIR/.." || exit 1 rm -rf "$TEMPDIR" exit 1 } - # Enter the temporary directory. - cd "$TEMPDIR" || fail "Unable to access the temporary directory $TEMPDIR." - # Fail if there is no pre-built binary for this platform. if [ -z "$FILENAME" ]; then fail 'Unfortunately, there is no pre-built binary for this platform.' fi + # Compute the full file path. + SOURCE="$TEMPDIR/$FILENAME" + # Download the binary. - if ! curl "https://github.com/stepchowfun/tagref/releases/download/$RELEASE/$FILENAME" \ - -o "$FILENAME" -LSf; then - fail 'There was an error downloading the binary.' - fi + curl \ + "https://github.com/stepchowfun/tagref/releases/download/$RELEASE/$FILENAME" \ + -o "$SOURCE" -LSf || fail 'There was an error downloading the binary.' # Make it executable. - if ! chmod a+rx "$FILENAME"; then - fail 'There was an error setting the permissions for the binary.' - fi + chmod a+rx "$SOURCE" || fail 'There was an error setting the permissions for the binary.' # Install it at the requested destination. # shellcheck disable=SC2024 - mv -f "$FILENAME" "$DESTINATION" 2> /dev/null || - sudo mv -f "$FILENAME" "$DESTINATION" < /dev/tty || + mv -f "$SOURCE" "$DESTINATION" 2> /dev/null || + sudo mv -f "$SOURCE" "$DESTINATION" < /dev/tty || fail "Unable to install the binary at $DESTINATION." # Remove the temporary directory. - cd .. rm -rf "$TEMPDIR" # Let the user know it worked. - echo "$("$DESTINATION" --version) is now installed." + echo "$( + "$DESTINATION" --version || fail 'There was an error executing the binary.' + ) is now installed." ) diff --git a/release.sh b/release.sh deleted file mode 100755 index 826c375..0000000 --- a/release.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# This script generates release artifacts in a directory called `release`. It should be run from a -# macOS machine with an x86-64 processor. Usage: -# ./release.sh - -# The release process involves three steps: -# 1. Bump the version in `Cargo.toml`, run `cargo build` to update `Cargo.lock`, and update -# `CHANGELOG.md` with information about the new version. Ship those changes as a single pull -# request. -# 2. Run this script on an x86-64 machine and upload the files in the `release` directory to GitHub -# as release artifacts. -# 3. Update the version in `install.sh` to point to the new release. - -# We wrap everything in parentheses to ensure that any working directory changes with `cd` are local -# to this script and don't affect the calling user's shell. -( - # x86-64 macOS build - rm -rf target/release - cargo build --release - - # x86-64 GNU/Linux build - rm -rf artifacts - toast release - - # Prepare the `release` directory. - rm -rf release - mkdir release - - # Copy the artifacts into the `release` directory. - cp target/release/tagref release/tagref-x86_64-apple-darwin - cp artifacts/tagref-x86_64-unknown-linux-gnu release/tagref-x86_64-unknown-linux-gnu - - # Compute checksums of the artifacts. - cd release - shasum --algorithm 256 --binary tagref-x86_64-apple-darwin > tagref-x86_64-apple-darwin.sha256 - shasum --algorithm 256 --binary tagref-x86_64-unknown-linux-gnu > tagref-x86_64-unknown-linux-gnu.sha256 - - # Verify the checksums. - shasum --algorithm 256 --check --status tagref-x86_64-apple-darwin.sha256 - shasum --algorithm 256 --check --status tagref-x86_64-unknown-linux-gnu.sha256 - - # Publish to crates.io. - cargo publish -) diff --git a/toast.yml b/toast.yml index 16c11ae..934bedb 100644 --- a/toast.yml +++ b/toast.yml @@ -1,10 +1,18 @@ image: ubuntu:20.04 -default: check +default: build tasks: install_packages: description: Install system packages. command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Install the following packages: + # + # - build-essential - Used for linking the binary + # - curl - Used for installing Tagref + # - ripgrep - Used for line length checking + # - shellcheck - Used for linting shell scripts apt-get update apt-get install --yes build-essential curl ripgrep shellcheck @@ -13,13 +21,19 @@ tasks: dependencies: - install_packages command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Install Tagref using the official installer script. curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs | sh create_user: description: Create a user who doesn't have root privileges. command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Create a user named `user` with a home directory. adduser --disabled-password --gecos '' user install_rust: @@ -29,16 +43,24 @@ tasks: - create_user user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail - curl https://sh.rustup.rs -sSf | - sh -s -- -y --default-toolchain 1.52.1 + + # Install stable Rust. [tag:rust_1_53_0] + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \ + -y \ + --default-toolchain 1.53.0 \ + --profile minimal \ + --component clippy + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - rustup component add clippy - rustup component add rustfmt - rm -rf "$(dirname "$(rustup which rustc)")/../share" + + # Install nightly Rust for the `trailing_comma` Rustfmt option. + rustup toolchain install nightly-2021-06-09 --profile minimal --component rustfmt install_tools: - description: Install the tools needed to build and lint the program. + description: Install the tools needed to build and validate the program. dependencies: - install_rust - install_tagref @@ -52,18 +74,29 @@ tasks: - Cargo.toml user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env + + # Create a "hello world" project with the dependencies we want to fetch. mv Cargo.lock Cargo.lock.og mv Cargo.toml Cargo.toml.og cargo init --vcs none mv Cargo.lock.og Cargo.lock mv Cargo.toml.og Cargo.toml - cargo build + + # Ask Cargo to build the project in order to fetch the dependencies. + cargo build --locked + cargo build --locked --release + cargo clippy + + # Delete the build artifacts. cargo clean --package tagref - cargo build --release cargo clean --release --package tagref - cargo clippy + + # Delete the "hello world" code. rm -rf src build: @@ -74,9 +107,14 @@ tasks: - src user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - cargo build + + # Build the project with Cargo. + cargo build --frozen test: description: Run the test suite. @@ -84,43 +122,55 @@ tasks: - build user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - cargo test + + # Run the tests with Cargo. The `NO_COLOR` variable is used to disable colored output for + # tests that make assertions regarding the output. [tag:colorless_tests] + NO_COLOR=true cargo test --frozen lint: description: Run the linters. dependencies: - build input_paths: - - .ignore # Used by `tagref` - - install.sh # Linted by ShellCheck - - release.sh # Linted by ShellCheck + - .github # Linted by `tagref` + - .gitignore # Used by `tagref` + - install.sh # Linted by `ShellCheck` + - toast.yml # Linted by `tagref` user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - # The command below is sometimes needed to force Clippy to actually run. It shouldn't be - # needed once https://github.com/rust-lang/rust-clippy/issues/4612 lands. At the time of this - # writing, it seems that will land in Rust 1.52.0 on 2021-05-06. - cargo clean --package tagref + # Lint the code with Clippy. + cargo clippy \ + --all-features \ + --all-targets -- \ + --deny clippy::all \ + --deny clippy::pedantic \ + --deny warnings - # Lint Rust files. - cargo clippy --all-targets --all-features -- \ - --deny warnings --deny clippy::all --deny clippy::pedantic + # Check references with Tagref. + tagref + + # Lint shell files with ShellCheck. + find . -type f -name '*.sh' | xargs shellcheck - # Check code formatting. - if ! cargo fmt --all -- --check; then + # Check code formatting with Rustfmt. We temporarily convert macro invocations into function + # calls so that Rustfmt's `trailing_comma` feature applies to macro arguments. [ref:format] + rg '!\(' --type rust --files-with-matches | xargs sed -i 's/!(/_(/g' + if ! cargo +nightly-2021-06-09 fmt --all -- --check; then echo 'ERROR: Please correct the formatting errors above.' 1>&2 exit 1 fi - - # Check references. - tagref - - # Lint shell files. - shellcheck install.sh release.sh + rg '_\(' --type rust --files-with-matches | xargs sed -i 's/_(/!(/g' # Enforce that lines span no more than 100 columns. if rg --line-number --type rust '.{101}'; then @@ -128,71 +178,101 @@ tasks: exit 1 fi - # Enforce trailing commas in multi-line sequences. - if rg --line-number --multiline --type rust '[^,]\n(\s*)\)'; then - echo "There are multi-line sequences without trailing commas." >&2 - exit 1 - fi - - # Forbid trailing commas in single-line sequences. - if rg --line-number --type rust '[^(],\s*\)'; then - echo "There are single-line sequences with trailing commas." >&2 - exit 1 - fi - run: description: Run the program. dependencies: - build - input_paths: - - .ignore # Used by `tagref` user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - cargo run - check: - description: Type-check the program. + # Run the program with Cargo. + cargo run --frozen + + format: + description: Format the source code. dependencies: - fetch_crates input_paths: - src + output_paths: + - src user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - find src -type f -name '*.rs' -exec touch {} + - cargo check --all --all-targets --all-features - format: - description: Format the source code. + # Format the code with Rustfmt. We temporarily convert macro invocations into function calls + # so that Rustfmt's `trailing_comma` feature applies to macro arguments. [tag:format] + rg '!\(' --type rust --files-with-matches | xargs sed -i 's/!(/_(/g' + cargo +nightly-2021-06-09 fmt --all + rg '_\(' --type rust --files-with-matches | xargs sed -i 's/_(/!(/g' + + release: + description: Build and output the release binaries for Linux. dependencies: - fetch_crates input_paths: - src output_paths: - - src + - artifacts user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - cargo fmt --all - release: - description: >- - Build the program in release mode and export the binary to the `artifacts` directory. + # Add the targets. It's likely that this script is currently running in one of them. + rustup target add x86_64-unknown-linux-gnu + rustup target add x86_64-unknown-linux-musl + + # Build the project for both Linux targets with Cargo. + cargo build --locked --release --target x86_64-unknown-linux-gnu + cargo build --locked --release --target x86_64-unknown-linux-musl + + # Move the binaries to a more conveniennt location for exporting. + mkdir artifacts + cp \ + target/x86_64-unknown-linux-gnu/release/tagref \ + artifacts/tagref-x86_64-unknown-linux-gnu + cp \ + target/x86_64-unknown-linux-musl/release/tagref \ + artifacts/tagref-x86_64-unknown-linux-musl + + publish: + description: Publish the crate to crates.io. dependencies: - fetch_crates + environment: + CRATES_IO_TOKEN: null input_paths: + - README.md - src - output_paths: - - artifacts user: user command: | + # Make Bash not silently ignore errors. set -euo pipefail + + # Add Rust tools to `$PATH`. . $HOME/.cargo/env - cargo build --release - mkdir artifacts - sha256sum --binary target/release/tagref - cp target/release/tagref artifacts/tagref-x86_64-unknown-linux-gnu + + # Fetch the program version. + VERSION="$(cargo pkgid | cut -d# -f2 | cut -d: -f2)" + + # If the package + if cargo search tagref | grep "tagref = \"$VERSION\""; then + echo "Version $VERSION of crate already exists." + exit + fi + + # Publish to crates.io. + cargo publish --locked --token "$CRATES_IO_TOKEN"