diff --git a/.github/workflows/GnuComment.yml b/.github/workflows/GnuComment.yml index 509a9b8665c..ab218274d6b 100644 --- a/.github/workflows/GnuComment.yml +++ b/.github/workflows/GnuComment.yml @@ -59,4 +59,4 @@ jobs: issue_number: issue_number, body: 'GNU testsuite comparison:\n```\n' + content + '```' }); - } + } diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 11b733e0b49..57cf850a4e3 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -3,4 +3,3 @@ MD013: false # Disable 'Fenced code blocks should have a language specified' # Doesn't provide much in src/ to enforce it MD040: false - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 91847f96bd1..845b03f1a80 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: check-added-large-files - id: check-executables-have-shebangs - id: check-json - exclude: '.vscode/cSpell\.json' # cSpell.json uses comments + exclude: '\.vscode/(cSpell|extensions)\.json' # cSpell.json and extensions.json use comments - id: check-shebang-scripts-are-executable exclude: '.+\.rs' # would be triggered by #![some_attribute] - id: check-symlinks diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 7ee2695db0a..291cbaf580f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,8 @@ -// spell-checker:ignore (misc) matklad foxundermoon +// spell-checker:ignore (misc) foxundermoon // see for the documentation about the extensions.json format // * // "foxundermoon.shell-format" ~ shell script formatting ; note: ENABLE "Use EditorConfig" -// "matklad.rust-analyzer" ~ `rust` language support +// "rust-lang.rust-analyzer" ~ `rust` language support // "streetsidesoftware.code-spell-checker" ~ `cspell` spell-checker support { "recommendations": [ diff --git a/README.md b/README.md index 450dae31722..7c89d446864 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ cargo build --release --features windows cargo build --release --features unix ``` -To build SELinux-specific features, including `chcon` and `runcon`, ensure that `libselinux` +To build SELinux-specific features, including `chcon` and `runcon`, ensure that `libselinux` and `libclang` are installed on your system. Then, run the following command: ``` cargo build --release --features unix,feat_selinux diff --git a/README.package.md b/README.package.md index ebf7724f638..c69c1f67e66 100644 --- a/README.package.md +++ b/README.package.md @@ -28,4 +28,3 @@ uutils coreutils is a cross-platform reimplementation of the GNU coreutils in [Rust](http://www.rust-lang.org). This package does not have its specific `README.md`. - diff --git a/docs/.gitignore b/docs/.gitignore index be017dfbe7c..0ba78e8a963 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,4 +2,4 @@ book src/utils src/SUMMARY.md src/platform_table.md -tldr.zip \ No newline at end of file +tldr.zip diff --git a/docs/compiles_table.py b/docs/compiles_table.py old mode 100644 new mode 100755 diff --git a/docs/src/test_coverage.css b/docs/src/test_coverage.css index 37a658695bc..3b746dcde5a 100644 --- a/docs/src/test_coverage.css +++ b/docs/src/test_coverage.css @@ -43,4 +43,4 @@ } .counts { margin-right: 10px; -} \ No newline at end of file +} diff --git a/src/uu/dirname/locales/fr-FR.ftl b/src/uu/dirname/locales/fr-FR.ftl index 0cc0c1b4f47..b11ab567ede 100644 --- a/src/uu/dirname/locales/fr-FR.ftl +++ b/src/uu/dirname/locales/fr-FR.ftl @@ -4,4 +4,3 @@ dirname-after-help = Afficher chaque NOM avec son dernier composant non-slash et supprimés ; si NOM ne contient pas de '/', afficher '.' (signifiant le répertoire courant). dirname-missing-operand = opérande manquant dirname-zero-help = séparer la sortie avec NUL plutôt qu'avec un saut de ligne - diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md index 507906d497e..154115ab2c5 100644 --- a/src/uu/rm/BENCHMARKING.md +++ b/src/uu/rm/BENCHMARKING.md @@ -58,4 +58,3 @@ With Cargo Flamegraph you can easily make a flamegraph of `rm`: ```shell cargo flamegraph --cmd coreutils -- rm [additional parameters] ``` - diff --git a/src/uu/sleep/locales/fr-FR.ftl b/src/uu/sleep/locales/fr-FR.ftl index 7930b78feae..61393d1e9ad 100644 --- a/src/uu/sleep/locales/fr-FR.ftl +++ b/src/uu/sleep/locales/fr-FR.ftl @@ -12,4 +12,3 @@ sleep-error-missing-operand = opérande manquant # Messages d'aide sleep-help-number = faire une pause de NOMBRE secondes - diff --git a/src/uu/tr/BENCHMARKING.md b/src/uu/tr/BENCHMARKING.md index 2bdd16f75c9..0b6e723d74e 100644 --- a/src/uu/tr/BENCHMARKING.md +++ b/src/uu/tr/BENCHMARKING.md @@ -63,4 +63,3 @@ hyperfine 'tr -d aeiou < mixed_input > /dev/null' './target/release/tr -d aeiou - Uses lookup tables instead of hash maps for O(1) operations - 32KB I/O buffers for improved throughput - Should be competitive with GNU `tr` for most operations - diff --git a/src/uu/tsort/BENCHMARKING.md b/src/uu/tsort/BENCHMARKING.md index 52b9dfc57ef..8470212f9a4 100644 --- a/src/uu/tsort/BENCHMARKING.md +++ b/src/uu/tsort/BENCHMARKING.md @@ -1,12 +1,12 @@ # Benchmarking `tsort` -Much of what makes `tsort` fast is the efficiency of its algorithm and implementation for topological sorting. -Our implementation of `tsort` also outputs a cycle whenever such ordering does not exist, just like GNU `tsort`. +Much of what makes `tsort` fast is the efficiency of its algorithm and implementation for topological sorting. +Our implementation of `tsort` also outputs a cycle whenever such ordering does not exist, just like GNU `tsort`. ## Strategies -To test `tsort`'s performance for its nominal use case, we need to test it with a DAG. One of the worst cases is when all nodes are just representing a succession of independent steps. -We should also test cycle detection for good measure. +To test `tsort`'s performance for its nominal use case, we need to test it with a DAG. One of the worst cases is when all nodes are just representing a succession of independent steps. +We should also test cycle detection for good measure. ### Random acyclic graph (DAG) @@ -25,16 +25,16 @@ for i in range(100*N): ### Random graph with cycles -The following will output a graph with multiples edges, it also allows some degree of tuning to test different cases. +The following will output a graph with multiples edges, it also allows some degree of tuning to test different cases. ```python import random # Parameters for the graph -num_nodes = 100 -num_edges = 150 -cycle_percentage = 0.10 -max_cycle_size = 6 +num_nodes = 100 +num_edges = 150 +cycle_percentage = 0.10 +max_cycle_size = 6 num_cycles = int(num_edges * cycle_percentage) @@ -52,7 +52,7 @@ for _ in range(num_cycles): ``` ## Running Benchmarks -The above scripts will output the generated graphs to the standard output. They can therefore be used directly as tests. In order to run a Benchmark, the output should be redirected to a file. +The above scripts will output the generated graphs to the standard output. They can therefore be used directly as tests. In order to run a Benchmark, the output should be redirected to a file. Use [`hyperfine`](https://github.com/sharkdp/hyperfine) to compare the performance of different `tsort` versions. For example, you can compare the performance of GNU `tsort` and another implementation with the following command: ```sh diff --git a/tests/fixtures/.gitattributes b/tests/fixtures/.gitattributes index 2156bf6bdf3..42e422926f6 100644 --- a/tests/fixtures/.gitattributes +++ b/tests/fixtures/.gitattributes @@ -1 +1 @@ -* -text diff +* -text diff diff --git a/tests/fixtures/nohup/is_a_tty.sh b/tests/fixtures/nohup/is_a_tty.sh old mode 100644 new mode 100755 diff --git a/tests/fixtures/util/is_a_tty.sh b/tests/fixtures/util/is_a_tty.sh old mode 100644 new mode 100755 diff --git a/util/analyze-gnu-results.py b/util/analyze-gnu-results.py old mode 100644 new mode 100755 diff --git a/util/android-scripts/collect-info.sh b/util/android-scripts/collect-info.sh old mode 100644 new mode 100755 diff --git a/util/android-scripts/run-tests.sh b/util/android-scripts/run-tests.sh old mode 100644 new mode 100755 diff --git a/util/compare_test_results.py b/util/compare_test_results.py old mode 100644 new mode 100755 diff --git a/util/deps.nu b/util/deps.nu index 368048fff45..4a0ea354a36 100644 --- a/util/deps.nu +++ b/util/deps.nu @@ -88,7 +88,7 @@ export def all_dep_info [] { let features = [unix, feat_selinux] let lock = open Cargo.lock | from toml | get package - + $lock # Add number of versions | join ($lock | group-by name | transpose | update column1 { length } | rename name num_versions) name diff --git a/util/dwr.sh b/util/dwr.sh old mode 100644 new mode 100755 diff --git a/util/gnu-patches/tests_cksum_base64.patch b/util/gnu-patches/tests_cksum_base64.patch index ea6bf92e164..c5cbcab34a9 100644 --- a/util/gnu-patches/tests_cksum_base64.patch +++ b/util/gnu-patches/tests_cksum_base64.patch @@ -4,7 +4,7 @@ Index: gnu/tests/cksum/cksum-base64.pl +++ gnu/tests/cksum/cksum-base64.pl @@ -92,8 +92,8 @@ my $prog = 'cksum'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); - + # Ensure hash names from cksum --help match those in @pairs above. -my $help_algs = join ' ', map { m{^ ([[:alpha:]]\S+)} } - grep { m{^ ([[:alpha:]]\S+)} } split ('\n', `cksum --help`); @@ -12,4 +12,3 @@ Index: gnu/tests/cksum/cksum-base64.pl + grep { m{^\s*-\s*([[:alpha:]]\S+):} } split ('\n', `cksum --help`); my $test_algs = join ' ', map {$_->[0]} @pairs; $help_algs eq $test_algs or die "$help_algs not equal to\n$test_algs"; - diff --git a/util/gnu-patches/tests_cut_error_msg.patch b/util/gnu-patches/tests_cut_error_msg.patch index 1b1673fef72..63e3c381310 100644 --- a/util/gnu-patches/tests_cut_error_msg.patch +++ b/util/gnu-patches/tests_cut_error_msg.patch @@ -3,7 +3,7 @@ Index: gnu/tests/cut/cut.pl --- gnu.orig/tests/cut/cut.pl +++ gnu/tests/cut/cut.pl @@ -29,13 +29,15 @@ my $mb_locale = $ENV{LOCALE_FR_UTF8}; - + my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; -my $from_field1 = "$prog: fields are numbered from 1\n$try"; @@ -22,21 +22,21 @@ Index: gnu/tests/cut/cut.pl +my $inval_pos = "$prog: range '--' was invalid: failed to parse range\n"; +my $no_endpoint = "$prog: range '-' was invalid: invalid range with no endpoint\n"; +my $nofield = "$prog: invalid input: The '--delimiter' ('-d') option only usable if printing a sequence of fields\n"; - + my @Tests = ( @@ -44,16 +46,16 @@ my @Tests = - + # This failed (as it should) even before coreutils-6.9.90, # but cut from 6.9.90 produces a more useful diagnostic. - ['zero-1', '-b0', {ERR=>$from_pos1}, {EXIT => 1} ], + ['zero-1', '-b0', {ERR=>$from_field_0}, {EXIT => 1} ], - + # Up to coreutils-6.9, specifying a range of 0-2 was not an error. # It was treated just like "-2". - ['zero-2', '-f0-2', {ERR=>$from_field1}, {EXIT => 1} ], + ['zero-2', '-f0-2', {ERR=>$from_field_0_2}, {EXIT => 1} ], - + # Up to coreutils-8.20, specifying a range of 0- was not an error. - ['zero-3b', '-b0-', {ERR=>$from_pos1}, {EXIT => 1} ], - ['zero-3c', '-c0-', {ERR=>$from_pos1}, {EXIT => 1} ], @@ -44,7 +44,7 @@ Index: gnu/tests/cut/cut.pl + ['zero-3b', '-b0-', {ERR=>$from_field_0_dash}, {EXIT => 1} ], + ['zero-3c', '-c0-', {ERR=>$from_field_0_dash}, {EXIT => 1} ], + ['zero-3f', '-f0-', {ERR=>$from_field_0_dash}, {EXIT => 1} ], - + ['1', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}], ['2', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}], @@ -96,11 +98,10 @@ my @Tests = @@ -62,7 +62,7 @@ Index: gnu/tests/cut/cut.pl # Empty field list ['empty-fl', qw(-f ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, @@ -199,7 +200,7 @@ my @Tests = - + # None of the following invalid ranges provoked an error up to coreutils-6.9. ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, - {ERR=>"$prog: invalid decreasing range\n$try"}], diff --git a/util/gnu-patches/tests_du_move_dir_while_traversing.patch b/util/gnu-patches/tests_du_move_dir_while_traversing.patch index 12b7e5c36df..c6c594d6886 100644 --- a/util/gnu-patches/tests_du_move_dir_while_traversing.patch +++ b/util/gnu-patches/tests_du_move_dir_while_traversing.patch @@ -5,12 +5,12 @@ Index: gnu/tests/du/move-dir-while-traversing.sh @@ -91,9 +91,7 @@ retry_delay_ nonempty .1 5 || fail=1 # Before coreutils-8.10, du would abort. returns_ 1 du -a $t d2 2> err || fail=1 - + -# check for the new diagnostic -printf "du: fts_read failed: $t/3/a/b: No such file or directory\n" > exp \ - || fail=1 -compare exp err || fail=1 +# check that it doesn't crash +grep -Pq "^du: cannot read directory '$t/3/a/b.*': No such file or directory" err || fail=1 - + Exit $fail diff --git a/util/gnu-patches/tests_invalid_opt.patch b/util/gnu-patches/tests_invalid_opt.patch index c23476674e7..2819071ccba 100644 --- a/util/gnu-patches/tests_invalid_opt.patch +++ b/util/gnu-patches/tests_invalid_opt.patch @@ -5,7 +5,7 @@ Index: gnu/tests/misc/invalid-opt.pl @@ -74,23 +74,13 @@ foreach my $prog (@built_programs) defined $out or $out = ''; - + - my $err = $expected_err{$prog}; - defined $err - or $err = $x == 0 ? '' : "$prog: invalid option -- /\n$try"; @@ -22,11 +22,11 @@ Index: gnu/tests/misc/invalid-opt.pl + # Strip all stderr output + # Our output is better and more consistent + my $err_subst = 's/(.|\n)*//ms'; - + my @Tests = (["$prog-invalid-opt", '-/', {OUT=>$out}, {ERR_SUBST => $err_subst}, - {EXIT=>$x}, {ERR=>$err}]); + {EXIT=>$x}]); - + my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/util/gnu-patches/tests_ls_no_cap.patch b/util/gnu-patches/tests_ls_no_cap.patch index c2f48ca21f3..62b836f7962 100644 --- a/util/gnu-patches/tests_ls_no_cap.patch +++ b/util/gnu-patches/tests_ls_no_cap.patch @@ -4,17 +4,17 @@ index 99f0563bc..f7b9e7885 100755 +++ b/tests/ls/no-cap.sh @@ -27,11 +27,11 @@ setcap 'cap_net_bind_service=ep' file || skip_ "setcap doesn't work" - + LS_COLORS=ca=1; export LS_COLORS -strace -e capget ls --color=always > /dev/null 2> out || fail=1 -$EGREP 'capget\(' out || skip_ "your ls doesn't call capget" +strace -e listxattr ls --color=always > /dev/null 2> out || fail=1 +$EGREP 'listxattr\(' out || skip_ "your ls doesn't call listxattr" - + LS_COLORS=ca=:; export LS_COLORS -strace -e capget ls --color=always > /dev/null 2> out || fail=1 -$EGREP 'capget\(' out && fail=1 +strace -e listxattr ls --color=always > /dev/null 2> out || fail=1 +$EGREP 'listxattr\(' out && fail=1 - + Exit $fail diff --git a/util/gnu-patches/tests_sort_merge.pl.patch b/util/gnu-patches/tests_sort_merge.pl.patch index d6db2e09c60..3a5982af156 100644 --- a/util/gnu-patches/tests_sort_merge.pl.patch +++ b/util/gnu-patches/tests_sort_merge.pl.patch @@ -8,25 +8,25 @@ Index: gnu/tests/sort/sort-merge.pl {ERR=>"$prog: invalid --batch-size argument '0'\n". - "$prog: minimum --batch-size argument is '2'\n"}, {EXIT=>2}], + "$prog: minimum --batch-size argument is '2'\nTry 'sort --help' for more information.\n"}, {EXIT=>2}], - + ['nmerge-1', "-m --batch-size=1", @inputs, {ERR=>"$prog: invalid --batch-size argument '1'\n". - "$prog: minimum --batch-size argument is '2'\n"}, {EXIT=>2}], + "$prog: minimum --batch-size argument is '2'\nTry 'sort --help' for more information.\n"}, {EXIT=>2}], - + ['nmerge-neg', "-m --batch-size=-1", @inputs, - {ERR=>"$prog: invalid --batch-size argument '-1'\n"}, {EXIT=>2}], + {ERR=>"$prog: invalid --batch-size argument '-1'\nTry 'sort --help' for more information.\n"}, {EXIT=>2}], - + ['nmerge-nan', "-m --batch-size=a", @inputs, - {ERR=>"$prog: invalid --batch-size argument 'a'\n"}, {EXIT=>2}], + {ERR=>"$prog: invalid --batch-size argument 'a'\nTry 'sort --help' for more information.\n"}, {EXIT=>2}], - + ['nmerge-big', "-m --batch-size=$bigint", @inputs, {ERR_SUBST=>'s/(current rlimit is) \d+/$1/'}, {ERR=>"$prog: --batch-size argument '$bigint' too large\n". - "$prog: maximum --batch-size argument with current rlimit is\n"}, + "$prog: maximum --batch-size argument with current rlimit is\nTry 'sort --help' for more information.\n"}, {EXIT=>2}], - + # This should work since nmerge >= the number of input files diff --git a/util/show-utils.BAT b/util/show-utils.BAT index 92f618160f5..00e9df5a1f4 100644 --- a/util/show-utils.BAT +++ b/util/show-utils.BAT @@ -1,32 +1,32 @@ -@setLocal -@echo off - -@rem ::# spell-checker:ignore (CMD) ERRORLEVEL -@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand -@rem ::# spell-checker:ignore (jq) deps startswith - -set "ME=%~0" -set "ME_dir=%~dp0." -set "ME_parent_dir=%~dp0.\.." - -@rem refs: , - -@rem :: default ("Tier 1" cross-platform) utility list -set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" - -set "project_dir=%ME_parent_dir%" -cd "%project_dir%" - -@:: `jq` available? -set "JQ=" -set "ERRORLEVEL=" -jq --version 1>NUL 2>&1 -if NOT ERRORLEVEL 1 ( set "JQ=jq" ) - -if NOT DEFINED JQ ( - echo WARN: missing `jq` ^(install with `scoop install jq`^)^; falling back to default ^(only fully cross-platform^) util list 1>&2 - echo %default_utils% -) else ( - cargo metadata %* --format-version 1 | jq -r "[.resolve.nodes[] | { id: .id, deps: [.deps[] | { name:.name, pkg:.pkg }] }] | .[] | select(.id|startswith(\"coreutils\")) | [.deps[] | select((.name|startswith(\"uu_\")) or (.pkg|startswith(\"uu_\")))] | [.[].pkg | match(\"^^\\w+\";\"g\")] | [.[].string | sub(\"^uu_\"; \"\")] | sort | join(\" \")" - REM cargo metadata %* --format-version 1 | jq -r "[.resolve.nodes[] | { id: .id, deps: [.deps[] | { name:.name, pkg:.pkg }] }] | .[] | select(.id|startswith(\"coreutils\")) | [.deps[] | select((.name|startswith(\"uu_\")) or (.pkg|startswith(\"uu_\")))] | [.[].pkg | match(\"^^\\w+\";\"g\")] | [.[].string] | sort | join(\" \")" -) +@setLocal +@echo off + +@rem ::# spell-checker:ignore (CMD) ERRORLEVEL +@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand +@rem ::# spell-checker:ignore (jq) deps startswith + +set "ME=%~0" +set "ME_dir=%~dp0." +set "ME_parent_dir=%~dp0.\.." + +@rem refs: , + +@rem :: default ("Tier 1" cross-platform) utility list +set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" + +set "project_dir=%ME_parent_dir%" +cd "%project_dir%" + +@:: `jq` available? +set "JQ=" +set "ERRORLEVEL=" +jq --version 1>NUL 2>&1 +if NOT ERRORLEVEL 1 ( set "JQ=jq" ) + +if NOT DEFINED JQ ( + echo WARN: missing `jq` ^(install with `scoop install jq`^)^; falling back to default ^(only fully cross-platform^) util list 1>&2 + echo %default_utils% +) else ( + cargo metadata %* --format-version 1 | jq -r "[.resolve.nodes[] | { id: .id, deps: [.deps[] | { name:.name, pkg:.pkg }] }] | .[] | select(.id|startswith(\"coreutils\")) | [.deps[] | select((.name|startswith(\"uu_\")) or (.pkg|startswith(\"uu_\")))] | [.[].pkg | match(\"^^\\w+\";\"g\")] | [.[].string | sub(\"^uu_\"; \"\")] | sort | join(\" \")" + REM cargo metadata %* --format-version 1 | jq -r "[.resolve.nodes[] | { id: .id, deps: [.deps[] | { name:.name, pkg:.pkg }] }] | .[] | select(.id|startswith(\"coreutils\")) | [.deps[] | select((.name|startswith(\"uu_\")) or (.pkg|startswith(\"uu_\")))] | [.[].pkg | match(\"^^\\w+\";\"g\")] | [.[].string] | sort | join(\" \")" +) diff --git a/util/size-experiment.py b/util/size-experiment.py old mode 100644 new mode 100755 diff --git a/util/test-repo-whitespace.BAT b/util/test-repo-whitespace.BAT index 6e2fce5574e..eb6f110c99e 100644 --- a/util/test-repo-whitespace.BAT +++ b/util/test-repo-whitespace.BAT @@ -1,93 +1,93 @@ -@setLocal -@echo off - -:: `test-repo-whitespace [DIR]...` v2022.01.01 -:: style inspector ~ whitespace: find nonconforming files in repository - -:: Copyright (C) 2016-2022 ~ Roy Ivy III -:: License: MIT/Apache-2.0 (see https://opensource.org/licenses/Apache-2.0 , https://opensource.org/licenses/MIT) -:: * this software is provided for free, WITHOUT ANY EXPRESS OR IMPLIED WARRANTY (see the license for details) - -:: spell-checker:ignore (shell/cmd) COMSPEC ERRORLEVEL -:: spell-checker:ignore () CTYPE POSIX Tval Tvar akefile makefile makefiles multiline testdata - -:config -set "_exclude_dirs_rx=(?i)[_.#]build|[.]git|[.]gpg|[.]obj|[.]vs|fixtures|node_modules|target|testdata|test-resources|vendor" -set "_exclude_files_rx=(?i)[.](cache|dll|exe|gif|gz|ico|png|zip)$" -set "_crlf_files_rx=(?i)[.](bat|cmd|csv)$" -set "_tabbed_files_rx=(?i)^^(.*[.]go|go[.](mod|sum)|(GNU)?[Mm]akefile([.].*)?)$" -:config_done - -set _dp0=%~dp0. -set _nx0=%~nx0 -set dirs=%* -if NOT DEFINED dirs if EXIST "%CD%\repo" ( set dirs="%CD%\repo" ) -if NOT DEFINED dirs if EXIST "%_dp0%\..\.git" ( set dirs="%_dp0%\.." ) -if NOT DEFINED dirs ( set "dirs=." ) - -set PCREGREP=pcregrep -if EXIST "%_dp0%\pcregrep.EXE" ( set "PCREGREP=%_dp0%\pcregrep.EXE" ) -"%PCREGREP%" --version >NUL 2>NUL || ( echo ERR!: Missing required `pcregrep` [try `scoop install pcregrep`] 1>&2 & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c exit 1 ) - -echo [ %dirs% ] - -if /i "%LC_CTYPE%"=="posix" (set "LC_CTYPE=C") &:: `pcregrep` doesn't understand the common "POSIX", replace with the equivalent "C" - -set "ERRORLEVEL=" -set "ERROR=" -:: 1. Test for TABs within leading whitespace (except go files makefiles) -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --exclude "%_tabbed_files_rx%" --count --files-with-matches --recursive "^\s*\t" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with TABs within leading whitespace [file:#lines_matched]) - -:: 2. Test for lines with internal TABs -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --count --files-with-matches --recursive "^.*[^\t]\t" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines containing internal TABs [file:#lines_matched]) - -:: 3. Test that makefiles have ONLY initial-TAB leading whitespace -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --include "(GNU)?[Mm]akefile([.].*)?" --exclude "[.](to|y)ml$" --recursive --line-number --invert-match "^([\t]\s*\S|\S|$)" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: Makefiles found with lines having non-TAB leading whitespace [file:line_number]) - -:: 4. Test for non-LF line endings -set "HAVE_NonLF_ERROR=" -"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" -NLF --files-with-matches --multiline --recursive "\r[^\n]" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CR line endings) -"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --exclude "%_crlf_files_rx%" -NLF --files-with-matches --multiline --recursive "\r\n" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CRLF line endings) -if DEFINED HAVE_NonLF_ERROR ( set ERROR=1 & echo ERROR: files found with non-LF line endings) - -:: 5. Test for files without trailing newline -:: "%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-without-match --multiline --recursive "\r?[\r\n]\z" %dirs% -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-with-matches --multiline --recursive "\z" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found without trailing newline) - -:: 6. Test for files with lines having trailing whitespace -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --recursive --line-number "\s$" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines having trailing whitespace [file:line_number]) - -:: 7. Test for files with BOM -"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-with-matches --multiline --recursive "\A[\xEF][\xBB][\xBF]" %dirs% -if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with leading BOM) - -:script_done -if NOT DEFINED ERROR ( - echo success: no file errors found - ) -call :#exit__title __exit_title "%COMSPEC%" -set "__exit_title=" && title %__exit_title% && set "ERRORLEVEL=" & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c "exit %ERROR%" - -@rem:::: -@rem:: FUNCTIONS -@goto :EOF - -:: -:#exit__title ( ref_RETURN PATH ) -:: RETURN == name of PATH -setLocal -set "_RETvar=%~1" -set "_RETval=%~2" -if NOT DEFINED _RETval ( set "_RETval=cmd" & goto :#exit__title_RETURN ) -set "_RETval=%~n2" -:#exit__title_RETURN -endLocal & set %_RETvar%^=%_RETval% -goto :EOF -:: +@setLocal +@echo off + +:: `test-repo-whitespace [DIR]...` v2022.01.01 +:: style inspector ~ whitespace: find nonconforming files in repository + +:: Copyright (C) 2016-2022 ~ Roy Ivy III +:: License: MIT/Apache-2.0 (see https://opensource.org/licenses/Apache-2.0 , https://opensource.org/licenses/MIT) +:: * this software is provided for free, WITHOUT ANY EXPRESS OR IMPLIED WARRANTY (see the license for details) + +:: spell-checker:ignore (shell/cmd) COMSPEC ERRORLEVEL +:: spell-checker:ignore () CTYPE POSIX Tval Tvar akefile makefile makefiles multiline testdata + +:config +set "_exclude_dirs_rx=(?i)[_.#]build|[.]git|[.]gpg|[.]obj|[.]vs|fixtures|node_modules|target|testdata|test-resources|vendor" +set "_exclude_files_rx=(?i)[.](cache|dll|exe|gif|gz|ico|png|zip)$" +set "_crlf_files_rx=(?i)[.](bat|cmd|csv)$" +set "_tabbed_files_rx=(?i)^^(.*[.]go|go[.](mod|sum)|(GNU)?[Mm]akefile([.].*)?)$" +:config_done + +set _dp0=%~dp0. +set _nx0=%~nx0 +set dirs=%* +if NOT DEFINED dirs if EXIST "%CD%\repo" ( set dirs="%CD%\repo" ) +if NOT DEFINED dirs if EXIST "%_dp0%\..\.git" ( set dirs="%_dp0%\.." ) +if NOT DEFINED dirs ( set "dirs=." ) + +set PCREGREP=pcregrep +if EXIST "%_dp0%\pcregrep.EXE" ( set "PCREGREP=%_dp0%\pcregrep.EXE" ) +"%PCREGREP%" --version >NUL 2>NUL || ( echo ERR!: Missing required `pcregrep` [try `scoop install pcregrep`] 1>&2 & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c exit 1 ) + +echo [ %dirs% ] + +if /i "%LC_CTYPE%"=="posix" (set "LC_CTYPE=C") &:: `pcregrep` doesn't understand the common "POSIX", replace with the equivalent "C" + +set "ERRORLEVEL=" +set "ERROR=" +:: 1. Test for TABs within leading whitespace (except go files makefiles) +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --exclude "%_tabbed_files_rx%" --count --files-with-matches --recursive "^\s*\t" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with TABs within leading whitespace [file:#lines_matched]) + +:: 2. Test for lines with internal TABs +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --count --files-with-matches --recursive "^.*[^\t]\t" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines containing internal TABs [file:#lines_matched]) + +:: 3. Test that makefiles have ONLY initial-TAB leading whitespace +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --include "(GNU)?[Mm]akefile([.].*)?" --exclude "[.](to|y)ml$" --recursive --line-number --invert-match "^([\t]\s*\S|\S|$)" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: Makefiles found with lines having non-TAB leading whitespace [file:line_number]) + +:: 4. Test for non-LF line endings +set "HAVE_NonLF_ERROR=" +"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" -NLF --files-with-matches --multiline --recursive "\r[^\n]" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CR line endings) +"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --exclude "%_crlf_files_rx%" -NLF --files-with-matches --multiline --recursive "\r\n" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CRLF line endings) +if DEFINED HAVE_NonLF_ERROR ( set ERROR=1 & echo ERROR: files found with non-LF line endings) + +:: 5. Test for files without trailing newline +:: "%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-without-match --multiline --recursive "\r?[\r\n]\z" %dirs% +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-with-matches --multiline --recursive "\z" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found without trailing newline) + +:: 6. Test for files with lines having trailing whitespace +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --recursive --line-number "\s$" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines having trailing whitespace [file:line_number]) + +:: 7. Test for files with BOM +"%PCREGREP%" -I --exclude-dir "%_exclude_dirs_rx%" --exclude "%_exclude_files_rx%" --files-with-matches --multiline --recursive "\A[\xEF][\xBB][\xBF]" %dirs% +if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with leading BOM) + +:script_done +if NOT DEFINED ERROR ( + echo success: no file errors found + ) +call :#exit__title __exit_title "%COMSPEC%" +set "__exit_title=" && title %__exit_title% && set "ERRORLEVEL=" & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c "exit %ERROR%" + +@rem:::: +@rem:: FUNCTIONS +@goto :EOF + +:: +:#exit__title ( ref_RETURN PATH ) +:: RETURN == name of PATH +setLocal +set "_RETvar=%~1" +set "_RETval=%~2" +if NOT DEFINED _RETval ( set "_RETval=cmd" & goto :#exit__title_RETURN ) +set "_RETval=%~n2" +:#exit__title_RETURN +endLocal & set %_RETvar%^=%_RETval% +goto :EOF +:: diff --git a/util/test_compare_test_results.py b/util/test_compare_test_results.py old mode 100644 new mode 100755