diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a98995411..328e05e23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,7 @@ jobs: - name: Install tools run: | + # smoelius: Prettier is still needed for scripts/update_example_READMEs.sh. npm install -g prettier rm -f "$HOME"/.cargo/bin/cargo-fmt rm -f "$HOME"/.cargo/bin/rustfmt @@ -61,9 +62,6 @@ jobs: cargo install cargo-rdme || true cargo install cargo-sort || true - - name: Prettier - run: ./scripts/check_prettier.sh - - name: Cargo sort run: find . -name Cargo.toml -print0 | xargs -0 -n 1 dirname | xargs -n 1 cargo sort --check --grouped @@ -130,6 +128,7 @@ jobs: # smoelius: This list will grow: https://github.com/trailofbits/dylint/issues/636 - name: Install tools run: | + npm install -g prettier cargo install cargo-hack || true cargo install cargo-msrv || true cargo install cargo-supply-chain || true diff --git a/cargo-dylint/tests/dylint.rs b/cargo-dylint/tests/dylint.rs index 51f7e6102..41b5e71e7 100644 --- a/cargo-dylint/tests/dylint.rs +++ b/cargo-dylint/tests/dylint.rs @@ -11,8 +11,10 @@ use std::{ env::{set_current_dir, set_var}, ffi::OsStr, fs::{read_to_string, write}, + io::{stderr, Write}, path::Path, str::FromStr, + sync::Mutex, }; use tempfile::tempdir; @@ -294,6 +296,32 @@ fn msrv() { } } +#[cfg(not(windows))] +#[test] +fn prettier_all_but_examples_and_template() { + Command::new("prettier") + .args([ + "--check", + "--ignore-path", + "cargo-dylint/tests/prettier_ignore.txt", + "**/*.md", + "**/*.yml", + ]) + .assert() + .success(); +} + +#[cfg(not(windows))] +#[test] +fn prettier_examples_and_template() { + preserves_cleanliness("prettier", true, || { + Command::new("prettier") + .args(["--write", "examples/**/*.md", "internal/template/**/*.md"]) + .assert() + .success(); + }); +} + // smoelius: `supply_chain` is the only test that uses `supply_chain.json`. So there is no race. #[cfg_attr(dylint_lib = "general", allow(non_thread_safe_call_in_test))] #[cfg_attr(dylint_lib = "overscoped_allow", allow(overscoped_allow))] @@ -351,3 +379,51 @@ fn walkdir(include_examples: bool) -> impl Iterator = Mutex::new(()); + +fn preserves_cleanliness(test_name: &str, ignore_blank_lines: bool, f: impl FnOnce()) { + let _lock = MUTEX.lock().unwrap(); + + if cfg!(not(feature = "strict")) && dirty(false).is_some() { + #[allow(clippy::explicit_write)] + writeln!( + stderr(), + "Skipping `{test_name}` test as repository is dirty" + ) + .unwrap(); + return; + } + + f(); + + if let Some(stdout) = dirty(ignore_blank_lines) { + panic!("{}", stdout); + } + + // smoelius: If the repository is not dirty with `ignore_blank_lines` set to true, but would be + // dirty otherwise, then restore the repository's contents. + if ignore_blank_lines && dirty(false).is_some() { + Command::new("git") + .args(["checkout", "."]) + .assert() + .success(); + } +} + +fn dirty(ignore_blank_lines: bool) -> Option { + let mut command = Command::new("git"); + command.arg("diff"); + if ignore_blank_lines { + command.arg("--ignore-blank-lines"); + } + let output = command.output().unwrap(); + + // smoelius: `--ignore-blank-lines` does not work with `--exit-code`. So instead check whether + // stdout is empty. + if output.stdout.is_empty() { + None + } else { + Some(String::from_utf8(output.stdout).unwrap()) + } +} diff --git a/cargo-dylint/tests/prettier_ignore.txt b/cargo-dylint/tests/prettier_ignore.txt new file mode 100644 index 000000000..d34e15f30 --- /dev/null +++ b/cargo-dylint/tests/prettier_ignore.txt @@ -0,0 +1,2 @@ +examples +template diff --git a/scripts/check_prettier.sh b/scripts/check_prettier.sh deleted file mode 100755 index 258d4c608..000000000 --- a/scripts/check_prettier.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! /bin/bash - -# set -x -set -euo pipefail - -if [[ $# -ne 0 ]]; then - echo "$0: expect no arguments" >&2 - exit 1 -fi - -SCRIPTS="$(dirname "$(realpath "$0")")" -WORKSPACE="$(realpath "$SCRIPTS"/..)" - -cd "$WORKSPACE" - -prettier --check --ignore-path <(echo examples; echo template) '**/*.md' '**/*.yml' - -if ! git diff --exit-code; then - echo "$0: aborting as repository is dirty" >&2 - exit 1 -fi - -prettier --write 'examples/**/*.md' 'internal/template/**/*.md' && - git diff --ignore-blank-lines | (! grep .) && - git checkout examples internal/template - -scripts/unquote_yaml_strings.sh && git diff --exit-code diff --git a/scripts/unquote_yaml_strings.sh b/scripts/unquote_yaml_strings.sh deleted file mode 100755 index 3991f44fa..000000000 --- a/scripts/unquote_yaml_strings.sh +++ /dev/null @@ -1,16 +0,0 @@ -#! /bin/bash - -# set -x -set -euo pipefail - -if [[ $# -ne 0 ]]; then - echo "$0: expect no arguments" >&2 - exit 1 -fi - -SCRIPTS="$(dirname "$(realpath "$0")")" -WORKSPACE="$(realpath "$SCRIPTS"/..)" - -cd "$WORKSPACE" - -find . -name '*.yml' -exec sed -i 's/^\([^#]*:[[:space:]]*\)"\(.*[^0-9:].*\)"\([[:space:]]*\)$/\1\2\3/' {} \;