From 2e415b79d78b59c93d4624b62257e83f328bf154 Mon Sep 17 00:00:00 2001 From: Tiago Castro Date: Wed, 17 Jul 2024 12:14:52 +0100 Subject: [PATCH] ci: add rust and nix linter action Should hopefully prevent further mishaps. Signed-off-by: Tiago Castro --- .github/workflows/pr-rust-lint.yaml | 32 +++++++ nix/overlay.nix | 12 +-- nix/pkgs/libspdk/default.nix | 31 ++++--- nix/shell/default.nix | 9 +- nix/shell/rust.nix | 18 ++-- nix/shell/spdk.nix | 8 +- scripts/rust-linter-env.sh | 134 ++++++++++++++++++++++++++++ scripts/rust-linter.sh | 4 + scripts/rust-style.sh | 6 ++ 9 files changed, 216 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/pr-rust-lint.yaml create mode 100644 scripts/rust-linter-env.sh create mode 100755 scripts/rust-linter.sh create mode 100755 scripts/rust-style.sh diff --git a/.github/workflows/pr-rust-lint.yaml b/.github/workflows/pr-rust-lint.yaml new file mode 100644 index 0000000..3993fea --- /dev/null +++ b/.github/workflows/pr-rust-lint.yaml @@ -0,0 +1,32 @@ +name: Code Linter +on: + merge_group: + pull_request: + types: ['opened', 'edited', 'reopened', 'synchronize'] +jobs: + rust-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - uses: cachix/install-nix-action@v26 + with: + nix_path: nixpkgs=channel:nixos-22.11 + - name: nix-shell + run: nix-shell --pure --run exit + - name: cargo-clippy + run: nix-shell --pure --run ./scripts/rust-linter.sh + - name: cargo-fmt + run: nix-shell --pure --run "FMT_OPTS=--check ./scripts/rust-style.sh" + nix-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - uses: cachix/install-nix-action@v26 + with: + nix_path: nixpkgs=channel:nixos-22.11 + - name: nix-shell + run: nix-shell --pure -p nixpkgs-fmt --run "nixpkgs-fmt --check ." diff --git a/nix/overlay.nix b/nix/overlay.nix index 0cc1cf3..3d2473a 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -1,9 +1,9 @@ {}: final: prev: rec { - fio = prev.callPackage ./pkgs/fio { }; - libnvme = prev.callPackage ./pkgs/libnvme { }; - nvme-cli = prev.callPackage ./pkgs/nvme-cli { }; - libspdk = prev.callPackage ./pkgs/libspdk { with-fio = false; build-type = "release"; }; - libspdk-fio = prev.callPackage ./pkgs/libspdk { with-fio = true; build-type = "release"; multi-outputs = true; }; - libspdk-dev = prev.callPackage ./pkgs/libspdk { with-fio = true; build-type = "debug"; }; + fio = prev.callPackage ./pkgs/fio { }; + libnvme = prev.callPackage ./pkgs/libnvme { }; + nvme-cli = prev.callPackage ./pkgs/nvme-cli { }; + libspdk = prev.callPackage ./pkgs/libspdk { with-fio = false; build-type = "release"; }; + libspdk-fio = prev.callPackage ./pkgs/libspdk { with-fio = true; build-type = "release"; multi-outputs = true; }; + libspdk-dev = prev.callPackage ./pkgs/libspdk { with-fio = true; build-type = "debug"; }; } diff --git a/nix/pkgs/libspdk/default.nix b/nix/pkgs/libspdk/default.nix index f036030..24322a5 100644 --- a/nix/pkgs/libspdk/default.nix +++ b/nix/pkgs/libspdk/default.nix @@ -55,23 +55,26 @@ let fioOutput = if multi-outputs then "fio" else "out"; # Additional build inputs for debug build. - extraBuildInputs = if build-type == "debug" then [cunit lcov] else []; + extraBuildInputs = if build-type == "debug" then [ cunit lcov ] else [ ]; # Build script path. buildScript = "../build_scripts/build_spdk.sh"; # Common arguments for the build script. - commonArgs = let - fioArg = if with-fio then - "--with-fio ${fio.dev}/include" - else - "--without-fio"; - - crossPrefix = if targetPlatform.config != buildPlatform.config then - "--crossPrefix=${targetPlatform.config}" - else - ""; - in + commonArgs = + let + fioArg = + if with-fio then + "--with-fio ${fio.dev}/include" + else + "--without-fio"; + + crossPrefix = + if targetPlatform.config != buildPlatform.config then + "--crossPrefix=${targetPlatform.config}" + else + ""; + in "-v --no-log --with-spdk . -b ${build-type} -t ${targetPlatform.config} ${fioArg} ${crossPrefix}"; # Arguments for the install phase. @@ -84,7 +87,7 @@ let pname = "libspdk${nameSuffix}"; version = "24.01-535a9e2"; - src = [ + src = [ (fetchFromGitHub { name = pname; owner = "openebs"; @@ -167,4 +170,4 @@ let ''; }; in - llvmPackages.stdenv.mkDerivation drvAttrs +llvmPackages.stdenv.mkDerivation drvAttrs diff --git a/nix/shell/default.nix b/nix/shell/default.nix index c60bda3..14cd544 100644 --- a/nix/shell/default.nix +++ b/nix/shell/default.nix @@ -8,16 +8,15 @@ let rustCfg = import ./rust.nix { inherit pkgs; inherit sources; inherit rust; }; spdkCfg = import ./spdk.nix { inherit pkgs; inherit spdk; inherit spdk-path; }; - ciCfg = import ./ci.nix { inherit pkgs; }; -in rec { + ciCfg = import ./ci.nix { inherit pkgs; }; +in +rec { # fortify does not work with -O0 which is used by spdk when --enable-debug hardeningDisable = [ "fortify" ]; buildInputs = with pkgs; [ commitlint - libnvme libunwind - nvme-cli ] ++ rustCfg.buildInputs ++ spdkCfg.buildInputs @@ -39,4 +38,4 @@ in rec { } // rustCfg.shellEnv // spdkCfg.shellEnv -// cfg.shellEnv + // cfg.shellEnv diff --git a/nix/shell/rust.nix b/nix/shell/rust.nix index babbf07..01f300f 100644 --- a/nix/shell/rust.nix +++ b/nix/shell/rust.nix @@ -75,15 +75,15 @@ let shellEnv = shellEnv // { # ASAN-related Cargo settings. - ASAN_ENABLE = "1"; - ASAN_OPTIONS = "detect_leaks=0"; - ASAN_BUILD_ENV = "shell"; - RUSTFLAGS = "-Zsanitizer=address"; - CARGO_BUILD_RUSTFLAGS = "-Zbuild-std"; - CARGO_BUILD_TARGET = "x86_64-unknown-linux-gnu"; + ASAN_ENABLE = "1"; + ASAN_OPTIONS = "detect_leaks=0"; + ASAN_BUILD_ENV = "shell"; + RUSTFLAGS = "-Zsanitizer=address"; + CARGO_BUILD_RUSTFLAGS = "-Zbuild-std"; + CARGO_BUILD_TARGET = "x86_64-unknown-linux-gnu"; CARGO_PROFILE_DEV_PANIC = "unwind"; - RUST_BACKTRACE = "full"; - RUST_TARGET_DEBUG = "target/x86_64-unknown-linux-gnu/debug"; + RUST_BACKTRACE = "full"; + RUST_TARGET_DEBUG = "target/x86_64-unknown-linux-gnu/debug"; }; shellHook = '' @@ -127,4 +127,4 @@ let }; }; in - configurations.${rust} +configurations.${rust} diff --git a/nix/shell/spdk.nix b/nix/shell/spdk.nix index 676b330..089de22 100644 --- a/nix/shell/spdk.nix +++ b/nix/shell/spdk.nix @@ -71,18 +71,18 @@ let shellEnv = { CFLAGS = "-msse4"; - SPDK_RS_BUILD_USE_LOGS = "yes"; # Tells spdk-rs build.rs script to rerun when build_logs dir is updated. + SPDK_RS_BUILD_USE_LOGS = "yes"; # Tells spdk-rs build.rs script to rerun when build_logs dir is updated. }; shellHook = fioDetectHook - + (if spdk-path == null then "" else '' + + (if spdk-path == null then "" else '' export SPDK_ROOT_DIR=$(realpath ${spdk-path} 2>/dev/null); if [[ -n "$SPDK_ROOT_DIR" ]]; then export FIO_SPDK="$SPDK_ROOT_DIR/build/fio/spdk_nvme"; fi '') - + '' + + '' echo echo "You have requested Nix shell without SPDK." echo "Use 'build_scripts/build_spdk.sh' to configure and compile SPDK." @@ -96,4 +96,4 @@ let }; }; in - configurations.${spdkCfg} +configurations.${spdkCfg} diff --git a/scripts/rust-linter-env.sh b/scripts/rust-linter-env.sh new file mode 100644 index 0000000..39ce7db --- /dev/null +++ b/scripts/rust-linter-env.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash + +MSG_PREFIX="rust linter env" +VERBOSE=0 + +err_exit() { + echo "$MSG_PREFIX error: $1" + exit 1 +} + +info() { + if [[ $VERBOSE == "1" ]]; then + echo "$MSG_PREFIX info: $1" + fi +} + +make_regex() { + local res=$1 + local res=$(echo "$res" | sed "s/\\./\\\\./g") + local res=$(echo "$res" | sed "s/(/\\\\(/g") + local res=$(echo "$res" | sed "s/)/\\\\)/g") + local res=$(echo "$res" | sed "s/\\*/.*/g") + echo "$res" +} + +echo "configuring Rust linter environment..." + +# Parse arguments +while [ "$#" -gt 0 ]; do + case $1 in + -v|--verbose) + VERBOSE=1 + shift + ;; + *) + err_exit "unknown option: $1" + ;; + esac +done + +if [[ $(uname) != "Linux" ]]; then + err_exit "must be run on Linux with Mayastor prerequisities installed" +fi + +# Rust nightly toolchain "2021-11-30" installs cargo version "2021-11-24" and +# rustfmt and clippy "2021-11-29". +# When upgrading Rust toolchain version, check 'cargo --version', +# 'cargo fmt --version', 'cargo clippy --version' and put them here. +RUST_TOOLCHAIN_VER="2023-08-25" +WANTED_CARGO_VER="cargo 1.74.0-nightly (* 2023-08-22)" +WANTED_RUSTFMT_VER="rustfmt 1.6.0-nightly (* 2023-08-24)" +WANTED_CLIPPY_VER="clippy 0.1.73 (* 2023-08-24)" +CARGO="cargo" +CARGO_MODE="system" + +CARGO_VER_RE=$(make_regex "$WANTED_CARGO_VER") +RUSTFMT_VER_RE=$(make_regex "$WANTED_RUSTFMT_VER") +CLIPPY_VER_RE=$(make_regex "$WANTED_CLIPPY_VER") + +# If RUST_NIGHTLY_PATH is defined, use it. +if [ -n "$RUST_NIGHTLY_PATH" ]; then + info "RUST_NIGHTLY_PATH is set: $RUST_NIGHTLY_PATH" + CARGO="$RUST_NIGHTLY_PATH/bin/cargo" + CARGO_MODE="explicit nightly" + + # cargo searches PATH for its subcommands (e.g. cargo fmt), so export + # PATH with RUST_NIGHTLY_PATH put before all other PATHs. + PATH=$RUST_NIGHTLY_PATH/bin:$PATH +fi + +# Try cargo from PATH. +info "using $CARGO_MODE cargo command: '$CARGO'" +CARGO_VER=$($CARGO --version 2>/dev/null) + +if [[ $? != 0 ]]; then + err_exit "'cargo' not found" +fi + +info "found 'cargo' version: $CARGO_VER" + +if ! [[ "$CARGO_VER" =~ $CARGO_VER_RE ]]; then + info "required $WANTED_CARGO_VER, trying rustup +nightly..." + + # Try +nightly option of cargo installed via rustup. + # Give up, if it fails. + CARGO="cargo +nightly-$RUST_TOOLCHAIN_VER" + CARGO_MODE="rustup nightly" + CARGO_VER=$($CARGO --version 2>/dev/null) + if [[ $? != 0 ]]; then + err_exit "'$CARGO' not found" + fi + + info "using $CARGO_MODE: $CARGO" + + if ! [[ "$CARGO_VER" =~ $CARGO_VER_RE ]]; then + err_exit "required $WANTED_CARGO_VER" + fi +fi + +# +# Check fmt version. +# +RUSTFMT_VER=$($CARGO fmt --version 2>/dev/null) +if [[ $? != 0 ]]; then + err_exit "'cargo fmt' not found" +fi + +info "found 'cargo fmt' version: $RUSTFMT_VER" + +if ! [[ "$RUSTFMT_VER" =~ $RUSTFMT_VER_RE ]]; then + err_exit "required $WANTED_RUSTFMT_VER" +fi + +# +# Check clippy version. +# +CLIPPY_VER=$($CARGO clippy --version 2>/dev/null) + +if [[ $? != 0 ]]; then + err_exit "'cargo clippy' not found" +fi + +info "found 'cargo clippy' version: $CLIPPY_VER" + +if ! [[ "$CLIPPY_VER" =~ $CLIPPY_VER_RE ]]; then + err_exit "required $WANTED_CLIPPY_VER" +fi + +echo " using cargo : $CARGO_MODE" +echo " cargo command : $CARGO" +echo " cargo version : $CARGO_VER" +echo " cargo fmt version : $RUSTFMT_VER" +echo " cargo clippy version : $CLIPPY_VER" +echo "configuration of Rust linter environment done" diff --git a/scripts/rust-linter.sh b/scripts/rust-linter.sh new file mode 100755 index 0000000..11e0be8 --- /dev/null +++ b/scripts/rust-linter.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +source ${BASH_SOURCE%/*}/rust-linter-env.sh +$CARGO clippy -p spdk-rs --all-targets -- -D warnings \ No newline at end of file diff --git a/scripts/rust-style.sh b/scripts/rust-style.sh new file mode 100755 index 0000000..312c483 --- /dev/null +++ b/scripts/rust-style.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +FMT_OPTS=${FMT_OPTS:-""} + +source ${BASH_SOURCE%/*}/rust-linter-env.sh +$CARGO fmt --all -- $FMT_OPTS