289 Commits
Author SHA1 Message Date
Sylvestre Ledru 2ce633cb8d prepare version 0.2.0 (#519) 2026-08-09 01:57:25 +02:00
Mukunda Rao Katta 91465e566b fix: identify uutils in cli output (#435) 2026-08-09 00:55:37 +02:00
Sylvestre Ledru d842aa305e sed: fix clippy cast_possible_truncation errors (#518) 2026-08-09 00:52:26 +02:00
xtqqczze d28a1f8e73 chore(cargo): remove deprecated package authors field (#444) 2026-08-08 23:28:22 +02:00
renovate[bot] af5f8afdcb Update Rust crate clap_complete to v4.6.9 2026-08-07 08:07:56 +02:00
renovate[bot] 8f3f126816 Update Rust crate clap_mangen to v0.3.2 2026-08-07 08:05:08 +02:00
renovate[bot] c771318a7a Update Rust crate clap to v4.6.6 2026-08-07 08:03:52 +02:00
renovate[bot] 36a1cf4954 Update Rust crate uucore to 0.10.0 2026-08-06 09:02:46 +02:00
renovate[bot] 13bb82ba13 Update Rust crate clap_mangen to v0.3.1 2026-08-06 08:32:10 +02:00
renovate[bot] cb9eb1da42 Update Rust crate uufuzz to 0.10.0 2026-08-06 08:15:55 +02:00
renovate[bot] b101462d1b Update Rust crate uutests to 0.10.0 2026-08-06 08:10:31 +02:00
oech3 9f2e1a1ad4 remove sysinfo dep 2026-08-05 14:18:30 +02:00
Franklin-Qi 2b092d53b0 fast_io.rs: replace the unsafe libc::copy_file_range call by rustix (#458)
Replace the unsafe `libc::copy_file_range` call with the safe `rustix::fs::copy_file_range`.

Closes: #442
2026-08-05 13:32:45 +02:00
renovate[bot] 550d545d72 Update Rust crate similar to v3.1.2 2026-08-05 08:01:27 +02:00
Diomidis Spinellisandmukunda katta a5d219764f feat: add T command (branch on no-substitution) (#508)
* feat: add T command (branch on no-substitution)

Implements the GNU `T LABEL` command: branch to LABEL if no s///
substitution has succeeded since the last input line was read or the
last t/T was taken. It is the inverse of `t` and shares the same
address and label parsing.

Wires 'T' into get_cmd_spec, resolve_branch_targets, and the processor
branch logic, resetting the substitution flag on evaluation just like
't'. Adds integration tests (simple branch + flag-clear) and a cmd-spec
unit test.

Closes #395

Co-authored-by: Diomidis Spinellis <dds@aueb.gr>

* ci: re-trigger checks (windows runner crates.io download flake)

* Disable T in POSIX mode

---------

Co-authored-by: mukunda katta <mukunda.vjcs6@gmail.com>
2026-08-02 17:47:18 +03:00
Develandpre-commit-ci[bot] 397ab86302 Implement v command #397 (#420)
* implement version command

* add tests for version option

* fix patch comparsion

* absurd extreme comparsion fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* accept missing minor or patch

* guard 'v' with if posix

* add a few tests

* add test_default_version

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* check if minor is empty and push zero instead of shadowing

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-08-01 18:18:05 +03:00
Mukunda Rao Katta 2288789f33 fix: allow closing brace as command terminator (#427) 2026-08-01 14:03:34 +03:00
Pranav Ram Joshi 84ae1b07a7 Implement e (execute) command (#481)
* chore: fix typo

* add: standalone e command

Implement the 'e' command. No argument implies execution of pattern space and any respective argument is to run with the output written to stream. Rejected under --posix and --sandbox.

Also stop silently swallowing shell stderr for e and s///e.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* add: e command tests

Includes 17 new tests. Cover both forms of the new 'e' command: with-argument execution (including shell side effects, addressing, ';' not separating the argument, escape decoding, and backslash continuation) and the no-argument pattern-space form. Also cover --posix/--sandbox rejection and stderr surfacing on command failure.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: gate LF-related tests to UNIIX only

* address e command review

Validate shell output as utf-8 and error out instead of lossily converting it. Make CRLF strip conditionally compile to Windows only. Rename execute_pattern_as_shell to execute_pattern_as_shell_command. Add tests for non-utf-8 error paths.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* add: Windows tests for e command with argument

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* fix: broken pipe race in sandbox e command test

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* Apply s/// p and e flags in written order

GNU sed applies the 'p' and 'e' substitution flags in the order they appear. 'pe' prints the pre-execution text then executes, while 'ep' executes then prints the result. Record whether 'p' precedes 'e' and apply them accordingly.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

---------

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>
2026-08-01 13:29:42 +03:00
renovate[bot] f32296fc22 Update Rust crate clap to v4.6.5 2026-08-01 07:12:40 +02:00
renovate[bot] 7239fb0e08 Update Rust crate ctor to v1.0.12 2026-07-30 07:57:26 +02:00
renovate[bot] c7e1f78486 Update mozilla-actions/sccache-action action to v0.0.11 2026-07-29 15:19:54 +02:00
renovate[bot] fb907703a0 Update CodSpeedHQ/action action to v5 2026-07-29 14:01:03 +02:00
renovate[bot] 3d52077d7f Update Rust crate clap_complete to v4.6.8 2026-07-27 17:37:39 +02:00
Diomidis Spinellis e9792a8ef9 Improve GNU compatibility through byte processing (#487)
The original Rust implementation assummed a UTF-8 environment, as is
common in modern systems.  This commit improves GNU sed compatibility
by changing most processing to run on bytes rather than Rust's Unicode
characters and strings. This change also improves the handling of binary
files. The commit adds a simple POSIX-compatible locale configuration
to support UTF-8 processing when specified. While at it, also fix
script-specified file handling to take place through OsString and
add a few missing unit tests.

The change fixes two failing GNU test suite cases.
2026-07-26 19:44:54 +02:00
renovate[bot] c732b60cfc Update Rust crate ctor to v1.0.11 (#501)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-26 19:43:52 +02:00
renovate[bot] c1e5d8ea08 Update Rust crate ctor to v1.0.10 2026-07-22 08:23:11 +02:00
renovate[bot] 6887201cce Update Rust crate clap to v4.6.4 2026-07-22 08:09:28 +02:00
renovate[bot] 75d856e4c2 Update Rust crate libc to v0.2.189 2026-07-22 08:00:30 +02:00
renovate[bot] d7a2106258 Update Rust crate libc to v0.2.188 2026-07-21 14:00:30 +02:00
renovate[bot] a726ac6959 Update Rust crate clap to v4.6.3 2026-07-21 08:13:36 +02:00
renovate[bot] 49590e63be Update Rust crate libc to v0.2.187 2026-07-21 08:03:39 +02:00
renovate[bot] 99a9957e89 Update Rust crate ctor to v1.0.9 2026-07-16 08:48:11 +02:00
renovate[bot] c521271ca8 Update Rust crate regex to v1.13.1 2026-07-16 08:19:19 +02:00
renovate[bot] 7830c20bc1 Update Rust crate clap to v4.6.2 2026-07-16 08:08:20 +02:00
renovate[bot] b37e23fa98 Update Rust crate regex to v1.13.0 2026-07-10 10:55:46 +02:00
Daniel Hofstetter 07eada8531 Bump crossbeam-epoch from 0.9.18 to 0.9.20 (#486)
https://rustsec.org/advisories/RUSTSEC-2026-0204
2026-07-08 18:57:10 +03:00
renovate[bot] 15def35a2a chore(deps): update rust crate memchr to v2.8.3 2026-07-08 07:50:55 +02:00
renovate[bot] 30607c4ddc chore(deps): update rust crate ctor to v1.0.8 2026-07-06 08:07:50 +02:00
Diomidis Spinellis 01c8412327 Optimize multiline matching (#483)
The multiline matching resulted in a large performance regression due to
the indiscriminate use of the dotall (?s) flag.  Change the regex
selection process to use only the flag when probably needed.
2026-07-05 15:13:53 +02:00
Diomidis SpinellisandMukunda Katta f3a79c5847 Support multiline substitution flag (#482)
While at it fix . matching of embedded newlines.

This commit increases GNU passed tests by 2.

Co-authored-by: Mukunda Katta <mukunda.vjcs6@gmail.com>
2026-07-05 10:48:39 +02:00
Diomidis Spinellis a9e5fe778c Add sandbox checks (#477)
Following the introduction of the first sandbox check in b14272c1
complete the checks for the remaining commands.
2026-07-03 16:55:50 +02:00
renovate[bot] 02d0239447 chore(deps): update rust crate rand to v0.10.2 2026-07-02 16:50:42 +02:00
renovate[bot] 8b5dea703a chore(deps): update rust crate console to v0.16.4 2026-07-02 08:05:54 +02:00
renovate[bot] 34dfbc2ef1 chore(deps): update rust crate clap_complete to v4.6.7 2026-07-02 08:05:18 +02:00
Develandpre-commit-ci[bot] 8cb7090bbc --posix should reject GNU substitute flags i/I #401 (#419)
* reject 'i', 'I', 'm', 'M' and 'E' when --posix flag is set

* add test for issue 401

* formatting

* add a test for 'm' flag in test_posix_reject_flags

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update compiler.rs

* cargo fmt

* add a const variable with the err msg

* Update compiler.rs

* cargo fmt

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-01 19:30:25 +03:00
Mukunda Rao Katta 2a5ab5a9a2 feat: add z command (#428)
* feat: add z command

* test: avoid stdin race in z POSIX rejection
2026-07-01 12:51:11 +03:00
Pranav Ram Joshi b14272c1d7 Add e substitution flag
* feat: introduce e substituion for sed

When the s command is requested for sed, the e substitution flag enables execution of the result of substitution as a shell command. It matches the GNU sed behavior.

On src/sed/command.rs, add 'execute' field to 'Substitution' structure.

On src/sed/compiler.rs, handle 'e' in 'compile_subst_flags' and reject it if --posix or --sandbox flag is used in sed.

On src/sed/processor.rs, spawn /bin/sh with -c flag for a successful match and replace the pattern space with the command's standard output stream.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: comply with rustfmt

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: support for Windows command-line

Instead of calling bourne shell, define a new function: shell_command() with two definitions; conditionally compiling to UNIX-like and Windows. On UNIX-like, executes the bourne shell, whereas command prompt is executed on Windows.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: check newline for Windows

Unix-like system only uses the newline character whereas Windows uses the carriage return as well as newline. Hence, when working on Windows, we need to truncate the last two characters.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* add: 'e' flag tests

Nine new tests have been introduced in regards to new 'e' substitution option. 'test_subst_e_flag_multiline_outuput' is conditionally compiled as printf command is not guaranteed to be present on all Windows systems.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: fallback for shell_command

Executing a shell or a command prompt requires appropriate platforms. WASM does not currently support it.

Also fix a linting issue.

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* chore: linting cleanup

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

---------

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>
2026-07-01 11:18:02 +03:00
Diomidis Spinellis cd3b10db48 Document uutils Playground 2026-07-01 10:48:54 +03:00
Diomidis Spinellis 48c2f56358 Document r command extension 2026-07-01 10:42:22 +03:00
Diomidis SpinellisandPranavRJoshi dcd2df848a Implement zero-address r command to insert file before first line (#474)
* feat: support zero-address file insertion

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>

* Polish the handling of 0r

- Use common constant for error message.
- Simplify command check at compile and runtime.
- Separate runtime handling into a function.

---------

Signed-off-by: PranavRJoshi <pranavrjoshi1@gmail.com>
Co-authored-by: PranavRJoshi <pranavrjoshi1@gmail.com>
2026-07-01 08:36:03 +02:00
renovate[bot] 9efab796be chore(deps): update rust crate clap_complete to v4.6.6 2026-07-01 07:05:51 +02:00
Daniel Hofstetter b74925283f Bump anyhow from 1.0.102 to 1.0.103 (#473) 2026-06-30 11:20:26 +02:00
renovate[bot] 8baab710c3 chore(deps): update rust crate divan to v5.0.1 2026-06-27 10:53:11 +02:00
renovate[bot] 5ca2636ce3 chore(deps): update actions/cache action to v6 2026-06-24 09:09:57 +02:00
renovate[bot] 8d28215c1b chore(deps): update rust crate divan to v5 2026-06-23 15:08:10 +02:00
renovate[bot] 88d188aa03 chore(deps): update rust crate memmap2 to v0.9.11 2026-06-23 07:59:32 +02:00
renovate[bot] 5e5281be03 chore(deps): update rust crate phf_codegen to 0.14.0 2026-06-22 11:21:53 +02:00
renovate[bot] 4eda475d5c chore(deps): update rust crate phf to 0.14.0 2026-06-21 10:08:39 +02:00
renovate[bot] 9b388fca34 chore(deps): update actions/checkout action to v7 2026-06-19 08:13:11 +02:00
Sylvestre Ledru b90c599fac sed: fix brace quantifier delimiter and {,n} bound edge cases (#463) 2026-06-14 16:09:18 +02:00
Loukas Papadopoulos d9cd53883c Add validations for brace quantifiers {m}, {m,} and {m,n} (#328) 2026-06-14 12:08:11 +02:00
renovate[bot] 3eb27c7831 chore(deps): update rust crate memchr to v2.8.2 2026-06-12 07:08:51 +02:00
renovate[bot] 3c7488ba1f chore(deps): update rust crate regex to v1.12.4 2026-06-10 07:21:44 +02:00
renovate[bot] 5122acc896 chore(deps): update codecov/codecov-action action to v7 2026-06-07 09:05:21 +02:00
renovate[bot] a9a332af1c chore(deps): update rust crate libfuzzer-sys to v0.4.13 2026-06-05 07:20:26 +02:00
renovate[bot] b765a4b0c1 chore(deps): update rust crate chrono to v0.4.45 2026-06-04 17:05:21 +02:00
Devel 508d74fe4a Show usage when invoked without argments
* exit with code 1 when no arguments
* add a test for no arguments.
* Update test_sed.rs
* cargo fmt
* pass -n for missing script arguments test

Issue: #274
PR: #409
2026-06-02 18:37:35 +03:00
Diomidis Spinellis c45b2f5516 Merge pull request #437 from MukundaKatta/codex/reject-empty-text-command
fix: reject empty text commands
2026-06-01 22:49:16 +03:00
Diomidis Spinellis 3b846498f4 Add current POSIX specification link
Link to POSIX document to help contributors.
2026-06-01 21:41:25 +03:00
renovate[bot] 238648ddbf chore(deps): update rust crate uutests to 0.9.0 2026-05-31 14:41:47 +02:00
renovate[bot] d37963afcb fix(deps): update rust crate uucore to 0.9.0 2026-05-31 10:38:54 +02:00
renovate[bot] 9ebf4e2ba2 fix(deps): update rust crate uufuzz to 0.9.0 2026-05-31 10:13:44 +02:00
Sylvestre Ledru 9d0d86a8f1 Add CONTRIBUTING.md pointing to the review guidelines 2026-05-30 10:41:37 +02:00
renovate[bot] 7c6cbf9dba chore(deps): update rust crate ctor to v1.0.7 2026-05-29 08:29:01 +02:00
renovate[bot] a65af95b5c chore(deps): update rust crate memchr to v2.8.1 2026-05-27 08:10:43 +02:00
renovate[bot] 47cebdd562 chore(deps): update rust crate assert_fs to v1.1.4 2026-05-27 07:53:21 +02:00
mukunda katta f6e69e734b fix: preserve latest binary executable mode 2026-05-24 17:57:32 +02:00
renovate[bot] 2dbeaea2e1 chore(deps): update rust crate similar to v3.1.1 2026-05-24 13:02:25 +02:00
renovate[bot] 5cef1c4327 chore(deps): update rust crate divan to v4.7.0 2026-05-23 07:09:32 +02:00
renovate[bot] 4171a7fe61 chore(deps): update rust crate ctor to v1.0.6 2026-05-17 10:35:56 +02:00
mukunda katta 142e70bd13 fix: reject empty text commands 2026-05-15 13:11:51 -07:00
renovate[bot] f083fa0634 chore(deps): update rust crate ctor to v1.0.5 2026-05-12 07:12:43 +02:00
renovate[bot] ff28e7d83d chore(deps): update rust crate clap_complete to v4.6.5 2026-05-12 07:08:52 +02:00
renovate[bot] 6c00065099 chore(deps): update rust crate clap_complete to v4.6.4 2026-05-10 10:11:34 +02:00
renovate[bot] cd2e3cba30 chore(deps): update rust crate ctor to v1.0.4 2026-05-09 16:14:15 +02:00
Daniel Hofstetter 7f00ab2f16 Remove trailing whitespace 2026-05-09 16:05:32 +02:00
Daniel Hofstetter 249a4f4a26 Add newline at the end of two files 2026-05-09 16:05:32 +02:00
Daniel Hofstetter 5fcb15dba5 Make test_compare_test_results.py executable 2026-05-09 16:05:32 +02:00
Sylvestre Ledru f783eb975c add a precommit conf 2026-05-06 09:50:57 +02:00
renovate[bot] 5856b37cea chore(deps): update rust crate ctor to v1.0.1 2026-05-05 07:19:02 +02:00
renovate[bot] 84c32f8ef0 chore(deps): update rust crate ctor to v1 2026-05-04 07:35:50 +02:00
LoukasPap 433635b583 Fix --separate flag 2026-05-03 13:28:03 +02:00
xtqqczze c5cbd62f9b clippy: fix redundant_else lint
https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#redundant_else
2026-05-03 13:27:20 +02:00
xtqqczze b94b148638 clippy: update Cargo.toml 2026-05-03 13:27:20 +02:00
Daniel Hofstetter a6c028b782 Move ctor to dev-dependencies 2026-05-03 13:22:23 +02:00
Daniel Hofstetter 7e7abc9407 tests.rs: adapt to ctor change 2026-05-03 13:22:23 +02:00
Daniel Hofstetter fef7a40433 Bump ctor from 0.12.0 to 0.13.0 2026-05-03 13:22:23 +02:00
xtqqczze 60243b4fa7 clippy: fix assigning_clones lint
https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#assigning_clones
2026-04-30 22:59:01 +02:00
LoukasPap b7072cb4a5 Fix \?, \+ and \| to be treated as ERE in BRE mode 2026-04-30 22:05:25 +02:00
xtqqczze 6215664b2e actions: add security audit workflow 2026-04-30 22:03:29 +02:00
renovate[bot] ffe4130654 fix(deps): update rust crate ctor to 0.12.0 2026-04-30 22:02:17 +02:00
renovate[bot] e435b9be6c chore(deps): update rust crate divan to v4.6.0 2026-04-29 07:32:05 +02:00
renovate[bot] 5d9f08af1c fix(deps): update rust crate ctor to 0.11.0 2026-04-29 07:28:37 +02:00
renovate[bot] 14b156995e chore(deps): update dawidd6/action-download-artifact action to v21 2026-04-28 13:31:38 +02:00
renovate[bot] 187ae761b1 chore(deps): update rust crate clap_complete to v4.6.3 2026-04-27 18:34:32 +02:00
renovate[bot] b96e0e78d8 chore(deps): update rust crate fancy-regex to 0.18.0 2026-04-24 07:34:42 +02:00
renovate[bot] 442c2ed0b9 chore(deps): update rust crate libc to v0.2.186 2026-04-24 07:10:01 +02:00
pocopepe d7a713e3c8 fix: correct newline handling for p and x commands 2026-04-23 08:44:58 +02:00
renovate[bot] 0cf23a8e34 chore(deps): update mozilla-actions/sccache-action action to v0.0.10 2026-04-23 07:28:32 +02:00
renovate[bot] 2724f4ad75 chore(deps): update rust crate ctor to v0.10.1 2026-04-23 07:14:50 +02:00
oech3 ebb321e90e Add CI for wasm32 2026-04-21 14:20:02 +02:00
xtqqczze 17a2fece6f chore(deps): update rust crates 2026-04-21 11:27:56 +02:00
d389e51925 Add SECURITY.md
Copied from https://github.com/uutils/coreutils/blob/5e974797bd8050c2d425a706670254ad0323404d/SECURITY.md

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2026-04-21 11:21:45 +02:00
pocopepe a2da4c1a3b assert_fs belongs in dev-dependencies 2026-04-21 11:12:10 +02:00
renovate[bot] 7b204c022b chore(deps): update rust crate divan to v4.5.0 2026-04-17 14:00:06 +02:00
Daniel Hofstetter af30aa40a4 clippy: fix warnings from collapsible_match lint 2026-04-17 13:37:02 +02:00
renovate[bot] 4cd9858bfd chore(deps): update rust crate clap to v4.6.1 2026-04-16 14:51:38 +02:00
renovate[bot] b4c567e43e chore(deps): update rust crate clap_complete to v4.6.2 2026-04-14 07:16:04 +02:00
renovate[bot] fc2db1e335 chore(deps): update rust crate libc to v0.2.185 2026-04-13 15:59:24 +02:00
renovate[bot] 35bc81a5cf fix(deps): update rust crate ctor to 0.10.0 2026-04-13 07:11:26 +02:00
YumeYuka 59d24ac8dd ci: add Android build check for 32-bit and 64-bit targets 2026-04-12 17:29:50 +02:00
白彩恋 37df236504 fix: fix integer type conversion to support Android and 32-bit
Signed-off-by: 白彩恋 <shiro@oom-wg.dev>
(cherry picked from commit 48e6431869424d6d2d39aaf4c0ad08a07a46bfe0)
2026-04-12 17:29:50 +02:00
renovate[bot] 2e76232e05 chore(deps): update rust crate similar to v3.1.0 2026-04-12 10:24:00 +02:00
renovate[bot] b72279afb3 chore(deps): update softprops/action-gh-release action to v3 2026-04-12 10:20:28 +02:00
renovate[bot] 08d3454b8c chore(deps): update rust crate rand to v0.10.1 2026-04-11 15:17:59 +02:00
renovate[bot] 17f36e91c1 chore(deps): update rust crate clap_complete to v4.6.1 2026-04-11 07:17:20 +02:00
renovate[bot] 5e2eb59959 fix(deps): update rust crate ctor to 0.9.0 2026-04-10 07:06:31 +02:00
renovate[bot] e3ff6cc268 chore(deps): update actions/github-script action to v9 2026-04-10 07:04:56 +02:00
renovate[bot] e012c4b5c0 chore(deps): update rust crate uutests to 0.8.0 2026-04-07 08:02:43 +02:00
renovate[bot] 59551c580b fix(deps): update rust crate uucore to 0.8.0 2026-04-07 07:52:39 +02:00
renovate[bot] deb64e0ccd fix(deps): update rust crate uufuzz to 0.8.0 2026-04-07 07:12:53 +02:00
oech3 68b5883b0e Override latest-commit's body with corresponding commit 2026-04-03 11:23:13 +02:00
renovate[bot] 1b747a66a8 chore(deps): update dawidd6/action-download-artifact action to v20 2026-04-03 07:15:16 +02:00
renovate[bot] 7fade42bb5 fix(deps): update rust crate similar to v3 2026-04-02 07:05:23 +02:00
renovate[bot] f334e1000c chore(deps): update rust crate libc to v0.2.184 2026-04-01 15:56:01 +02:00
renovate[bot] ed6869944f chore(deps): update rust crate clap_mangen to 0.3 2026-03-28 07:18:48 +01:00
renovate[bot] ad01bedff8 fix(deps): update rust crate ctor to 0.8.0 2026-03-28 07:07:46 +01:00
renovate[bot] 34651493c1 chore(deps): update codecov/codecov-action action to v6 2026-03-27 07:24:50 +01:00
renovate[bot] bf7bed170a chore(deps): update rust crate sha2 to 0.11 2026-03-25 18:36:34 +01:00
renovate[bot] 1469cccfde chore(deps): update rust crate terminal_size to v0.4.4 2026-03-24 07:29:39 +01:00
LoukasPap 5e9b821d80 Set max addresses to 2 for a, i and = and make n_addr conditional, based on POSIX flag
- Update `get_cmd_spec()` and `get_verified_cmd_spec()` to accept a boolean POSIX param
- Add unit and high level tests
- Update README.md
2026-03-19 22:21:56 +01:00
xtqqczze 27da0276ec clippy: fix single_match_else lint 2026-03-19 22:05:47 +01:00
xtqqczze 2836cb7257 clippy: fix map_unwrap_or lint 2026-03-19 22:05:47 +01:00
xtqqczze 8c09b0f5a5 clippy: fix manual_assert lint 2026-03-19 22:05:47 +01:00
xtqqczze 5f85e267db clippy: fix ptr_as_ptr lint 2026-03-19 22:05:47 +01:00
xtqqczze 1535cfdd9b clippy: fix ref_option lint 2026-03-19 22:05:47 +01:00
xtqqczze 8772c166d9 clippy: fix manual_let_else lint 2026-03-19 22:05:47 +01:00
xtqqczze 6b6067075b clippy: fix if_not_else lint 2026-03-19 22:05:47 +01:00
xtqqczze dc9be6018c clippy: fix cast_lossless lint 2026-03-19 22:05:47 +01:00
xtqqczze b295d213e8 clippy: fix borrow_as_ptr 2026-03-19 22:05:47 +01:00
xtqqczze d3ca9d27b4 clippy: warn pedantic lints by default 2026-03-19 22:05:47 +01:00
Kevin BurkeandClaude Opus 4.6 16f11456b3 fix: rewrite GNU testsuite harness to run upstream test scripts directly
The previous harness tried to extract sed commands from GNU test scripts
via regex pattern matching, which produced false negatives (comparing
against empty expected output) and false positives. This led to inflated
test counts and unreliable pass/fail signals.

The new approach:
- Provides a lightweight shim for the gnulib test framework (init.sh)
  with implementations of compare_, returns_, skip_, framework_failure_,
  and all require_* functions
- Executes each .sh test script from the GNU testsuite directly,
  injecting our Rust sed binary via PATH
- Uses a clean srcdir with symlinks to real test data files
- Adds per-test timeout (10s) to catch infinite loops, with SIGTERM
  isolation so timeout signals don't kill the parent script
- Properly propagates exit codes (0=pass, 77=skip, 99=framework failure)

Results are now consistent with CI tracking (~12% pass rate) with
clear PASS/FAIL/SKIP/timeout categorization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 22:04:56 +01:00
renovate[bot] 81d98b9049 chore(deps): update dawidd6/action-download-artifact action to v19 2026-03-18 10:55:40 +01:00
renovate[bot] 25efbc0ab7 chore(deps): update dawidd6/action-download-artifact action to v18 2026-03-15 10:47:13 +01:00
renovate[bot] ad1f3d22dc chore(deps): update rust crate console to v0.16.3 2026-03-13 11:26:07 +01:00
renovate[bot] 3f3dd1270e chore(deps): update rust crate clap_mangen to v0.2.33 2026-03-13 07:08:17 +01:00
renovate[bot] af7131fdb2 chore(deps): update rust crate clap_complete to v4.6.0 2026-03-13 07:07:41 +01:00
renovate[bot] 97e70434b9 chore(deps): update rust crate clap to v4.6.0 2026-03-13 07:07:07 +01:00
renovate[bot] 19363fa810 chore(deps): update dawidd6/action-download-artifact action to v17 2026-03-12 15:33:11 +01:00
renovate[bot] 56e6ef5d2f chore(deps): update rust crate divan to v4.4.1 2026-03-12 15:32:38 +01:00
renovate[bot] fadc36512d chore(deps): update rust crate tempfile to v3.27.0 2026-03-11 07:04:15 +01:00
oech3 61152af62b Quick codspeed setup 2026-03-10 09:06:10 +01:00
renovate[bot] 7f16a008c9 fix(deps): update rust crate uucore to 0.7.0 2026-03-10 07:41:48 +01:00
renovate[bot] a6d85d8e42 chore(deps): update rust crate sysinfo to v0.38.4 2026-03-10 07:24:50 +01:00
renovate[bot] dc91d3709c chore(deps): update rust crate uutests to 0.7.0 2026-03-10 07:16:06 +01:00
renovate[bot] 8a3f63db27 fix(deps): update rust crate uufuzz to 0.7.0 2026-03-10 07:10:06 +01:00
renovate[bot] 1bb2f89e8d chore(deps): update rust crate libc to v0.2.183 2026-03-08 14:18:24 +01:00
renovate[bot] b7df132ba1 chore(deps): update rust crate sysinfo to v0.38.3 2026-03-02 14:36:11 +01:00
renovate[bot] 9f6f052c27 chore(deps): update github artifact actions 2026-02-27 06:57:50 +01:00
renovate[bot] 569ec711ac chore(deps): update dawidd6/action-download-artifact action to v16 2026-02-26 07:08:58 +01:00
renovate[bot] e075bff043 chore(deps): update rust crate tempfile to v3.26.0 2026-02-24 11:04:35 +01:00
renovate[bot] 628d320e5b chore(deps): update rust crate chrono to v0.4.44 2026-02-23 14:11:54 +01:00
oech3 d102d0be73 reproducible fuzzing, fast setup 2026-02-20 10:50:47 +01:00
renovate[bot] 01b190c59a chore(deps): update rust crate clap to v4.5.60 2026-02-20 07:21:35 +01:00
renovate[bot] 5ecd6afedb chore(deps): update dawidd6/action-download-artifact action to v15 2026-02-18 13:38:50 +01:00
renovate[bot] 81e71bcb49 chore(deps): update rust crate clap to v4.5.59 2026-02-17 07:06:36 +01:00
renovate[bot] b169b4dfc2 chore(deps): update rust crate sysinfo to v0.38.2 2026-02-15 18:47:48 +01:00
renovate[bot] 049e149ea5 chore(deps): update rust crate memmap2 to v0.9.10 2026-02-15 13:47:06 +01:00
Sylvestre Ledru 91affcf90b Update CodeCov badge to point to main branch 2026-02-15 12:11:40 +01:00
oech3 99c8574fc5 Reduce codegen-units to 7 2026-02-15 11:24:26 +01:00
oech3 b5b4cefb77 Drop apt-get 2026-02-13 14:36:53 +01:00
renovate[bot] fee1ff33ae chore(deps): update rust crate libc to v0.2.182 2026-02-13 10:48:45 +01:00
Alexander Wang 22abe5ea6c Preserve new line on exchanges (x) with empty hold spaces. (#259)
* fix: remove newline swap in exchange and swap content only

* fix: support non empty hold spaces and newline appended hold spaces

* nit: period in comment

* nit: useless comment removal

* chore: clarify newline swap logic for `x`
2026-02-13 10:36:51 +01:00
Daniel Hofstetter c0c85e65fa Bump bigdecimal from 0.4.8 to 0.4.10 2026-02-13 09:46:20 +01:00
Daniel Hofstetter ab6f9d9810 Bump uufuzz from 0.5.0 to 0.6.0 2026-02-13 09:46:20 +01:00
renovate[bot] 1d04c82eb8 chore(deps): update rust crate clap_complete to v4.5.66 2026-02-12 07:17:08 +01:00
renovate[bot] cdae35308d chore(deps): update rust crate clap to v4.5.58 2026-02-12 07:16:55 +01:00
renovate[bot] b926499ed4 chore(deps): update rust crate predicates to v3.1.4 2026-02-12 07:09:00 +01:00
renovate[bot] 4be480767c chore(deps): update rust crate libfuzzer-sys to v0.4.12 2026-02-11 07:01:08 +01:00
renovate[bot] aeac7d1e63 chore(deps): update rust crate tempfile to v3.25.0 2026-02-10 07:18:27 +01:00
renovate[bot] 3c7b8ff4ba chore(deps): update rust crate libc to v0.2.181 2026-02-10 07:09:28 +01:00
Daniel Hofstetter a177e97cfb Bump rand from 0.9.0 to 0.10.0 2026-02-09 16:42:11 +01:00
LoukasPap 361c45e6c3 Add test cases 2026-02-08 18:48:17 +01:00
LoukasPap 1c57aaa8e2 Add check for empty text with a, c and i commands in posix mode 2026-02-08 18:48:17 +01:00
renovate[bot] 1bb2609f16 fix(deps): update rust crate uucore to 0.6.0 2026-02-08 15:18:37 +01:00
LoukasPap e3684f0029 Add test case 2026-02-08 15:17:59 +01:00
LoukasPap f27060898a Allow multiple uses of same CLI argument 2026-02-08 15:17:59 +01:00
Daniel Hofstetter 1dc91b0082 Merge pull request #292 from uutils/renovate/memchr-2.x-lockfile
chore(deps): update rust crate memchr to v2.8.0
2026-02-07 07:12:24 +01:00
Daniel Hofstetter c3bbd572e9 Merge pull request #293 from uutils/renovate/sysinfo-0.x-lockfile
chore(deps): update rust crate sysinfo to v0.38.1
2026-02-07 07:09:05 +01:00
renovate[bot] 8d7559b52d chore(deps): update rust crate sysinfo to v0.38.1 2026-02-07 01:49:07 +00:00
renovate[bot] 995e32a70d chore(deps): update rust crate memchr to v2.8.0 2026-02-06 20:46:42 +00:00
Daniel Hofstetter 3f26fc2936 Merge pull request #291 from uutils/dependabot/cargo/time-0.3.47
Bump time from 0.3.44 to 0.3.47
2026-02-06 09:03:05 +01:00
dependabot[bot] 907d01b847 Bump time from 0.3.44 to 0.3.47
Bumps [time](https://github.com/time-rs/time) from 0.3.44 to 0.3.47.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.44...v0.3.47)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.47
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-05 18:59:26 +00:00
Daniel Hofstetter 3504109373 Merge pull request #285 from uutils/renovate/clap-4.x-lockfile
chore(deps): update rust crate clap to v4.5.57
2026-02-04 07:17:02 +01:00
Daniel Hofstetter 837f2cd2ea Merge pull request #286 from uutils/renovate/regex-1.x-lockfile
chore(deps): update rust crate regex to v1.12.3
2026-02-04 07:14:01 +01:00
renovate[bot] 0a09d32b00 chore(deps): update rust crate regex to v1.12.3 2026-02-03 18:31:23 +00:00
renovate[bot] da2715dcb5 chore(deps): update rust crate clap to v4.5.57 2026-02-03 18:31:18 +00:00
Daniel Hofstetter 40925c8b4f Merge pull request #283 from uutils/renovate/uutests-0.x
chore(deps): update rust crate uutests to 0.6.0
2026-02-03 14:56:16 +01:00
renovate[bot] 2eeaa80c3b chore(deps): update rust crate uutests to 0.6.0 2026-02-03 13:35:42 +00:00
Daniel Hofstetter a6207cbebc Bump rlimit from 0.10.1 to 0.11.0 2026-02-02 08:57:25 +01:00
Daniel Hofstetter 98f7338960 Merge pull request #280 from uutils/renovate/dawidd6-action-download-artifact-14.x
chore(deps): update dawidd6/action-download-artifact action to v14
2026-02-01 16:14:38 +01:00
renovate[bot] 003b579967 chore(deps): update dawidd6/action-download-artifact action to v14 2026-02-01 15:00:12 +00:00
Daniel Hofstetter d497e881af Merge pull request #279 from uutils/renovate/dawidd6-action-download-artifact-13.x
chore(deps): update dawidd6/action-download-artifact action to v13
2026-01-30 16:21:32 +01:00
renovate[bot] 98c4dab5dd chore(deps): update dawidd6/action-download-artifact action to v13 2026-01-30 15:15:24 +00:00
Daniel Hofstetter 8e8c2bf9f7 Merge pull request #278 from uutils/renovate/clap-4.x-lockfile
chore(deps): update rust crate clap to v4.5.56
2026-01-30 07:17:31 +01:00
renovate[bot] 3cf5ea5beb chore(deps): update rust crate clap to v4.5.56 2026-01-29 18:36:39 +00:00
oech3 1617d32d5d README.md: Link tag/latest-commit 2026-01-28 11:12:45 +01:00
Sylvestre Ledru b3350a21c4 python coding style on the file 2026-01-28 09:32:24 +01:00
Sylvestre Ledru 8c46bec97f Skip PR comments when test results are identical 2026-01-28 09:32:24 +01:00
oech3 d23df4c400 Publish binary from main instead of discarding 2026-01-28 08:55:25 +01:00
Diomidis Spinellis 8039955354 Add support for GNU ~step address ranges 2026-01-28 08:40:54 +01:00
Diomidis Spinellis 8a2934e519 Refactor struct + enum pair into a tagged enum
This removes invalid states and simplifies pattern matching.
It also makes it easier to add further address extensions.
2026-01-28 08:40:54 +01:00
Diomidis Spinellis a0d82d678d Support ranges starting from line 0
This is a GNU extension that starts the range as latched.
While at it, also fix the handling of ranges straddling independent
files.
2026-01-28 08:40:54 +01:00
Diomidis Spinellis 31de5d5ea0 Improve interactive output
Before this commit, the output of sed was lagging one line behind, as it
was always checking whether each line was the last one ($).  This change
modifies the behavior to make this check only when actually needed.
This brings sed's interactive behavior (when reading from a terminal) in
line with the GNU and FreeBSD implementations.
2026-01-28 08:40:54 +01:00
Daniel Hofstetter 78d3b3acf7 Merge pull request #273 from uutils/renovate/clap-4.x-lockfile
chore(deps): update rust crate clap to v4.5.55
2026-01-28 07:04:43 +01:00
renovate[bot] d9a1cdb9a2 chore(deps): update rust crate clap to v4.5.55 2026-01-27 21:29:27 +00:00
Daniel Hofstetter 1ccd8d069a Merge pull request #272 from uutils/renovate/sysinfo-0.x
chore(deps): update rust crate sysinfo to 0.38
2026-01-25 10:55:28 +01:00
renovate[bot] 4fb1046c54 chore(deps): update rust crate sysinfo to 0.38 2026-01-24 17:35:06 +00:00
Sylvestre Ledru b0e7940484 Merge pull request #271 from oech3/patch-1
Don't apt-get runner preinstalled utils
2026-01-24 13:27:18 +01:00
oech3 89b7a039c9 Don't apt-get runner preinstalled utils 2026-01-24 21:18:16 +09:00
Daniel Hofstetter 398ee76b79 Merge pull request #269 from uutils/renovate/divan-4.x-lockfile
chore(deps): update rust crate divan to v4.3.0
2026-01-22 07:02:10 +01:00
renovate[bot] ea5a3e45df chore(deps): update rust crate divan to v4.3.0 2026-01-21 17:51:43 +00:00
Sylvestre Ledru c5e6348825 Merge pull request #268 from e-kwsm/run-gnu-testsuite.sh
fix spurious failure in run-gnu-testsuite.sh
2026-01-21 13:36:21 +01:00
Eisuke Kawashima fc39ff7329 fix(run-gnu-testsuite.sh): unquote sed_script 2026-01-19 15:48:31 +09:00
Eisuke Kawashima f6d26ff00f fix(run-gnu-testsuite.sh): correct input and expected output strings
use ANSI-C strings to interpret `\n`
2026-01-19 14:55:24 +09:00
Daniel Hofstetter c6479b44ad Merge pull request #264 from uutils/renovate/chrono-0.x-lockfile
chore(deps): update rust crate chrono to v0.4.43
2026-01-15 07:10:56 +01:00
renovate[bot] 8e3d3985e1 chore(deps): update rust crate chrono to v0.4.43 2026-01-14 22:41:30 +00:00
Sylvestre Ledru 1710d9cc56 Merge pull request #255 from sylvestre/run-gnu
run testsuite: make sure that everything is run
2026-01-11 22:36:37 +01:00
Sylvestre Ledru b26f59ab2f run testsuite: make sure that everything is run 2026-01-11 22:34:33 +01:00
Sylvestre Ledru 5d452d4174 link to the sed tracking project 2026-01-11 21:12:00 +01:00
Sylvestre Ledru ff0c1cdd06 remove artifact 2026-01-11 17:30:22 +01:00
Sylvestre Ledru 4e024a9576 Merge pull request #247 from sylvestre/gnu-ci-info
Publish comments in case of changes with the GNU test suite
2026-01-11 17:29:41 +01:00
Sylvestre Ledru d89243bdb9 Improve comparison output to show both current and reference numbers 2026-01-11 17:12:41 +01:00
Sylvestre Ledru 270f3fdce8 Add comprehensive unit tests for comparison script 2026-01-11 16:50:14 +01:00
Sylvestre Ledru 69ddd044c5 Integrate test result comparison in CI workflow 2026-01-11 16:24:17 +01:00
Sylvestre Ledru 5ff4a7c0c2 Add ignore list for intermittent test failures 2026-01-11 16:24:17 +01:00
Sylvestre Ledru ce3e4b33b5 Add automatic PR comment workflow for test comparisons 2026-01-11 16:24:17 +01:00
Sylvestre Ledru 35ea457759 Add test result comparison script 2026-01-11 16:24:17 +01:00
Sylvestre Ledru 35b6e84c16 Add unit test for issue #143 (newline behavior with -e p command) 2026-01-11 15:11:56 +01:00
veju faea122f87 fixes newline bug 2026-01-11 14:54:50 +01:00
Daniel Hofstetter db58849440 Merge pull request #244 from uutils/renovate/libc-0.x-lockfile
chore(deps): update rust crate libc to v0.2.180
2026-01-08 14:37:25 +01:00
renovate[bot] 94bd9b4f14 chore(deps): update rust crate libc to v0.2.180 2026-01-08 13:15:20 +00:00
Daniel Hofstetter d0ad8eb95d Merge pull request #246 from uutils/renovate/clap_complete-4.x-lockfile
chore(deps): update rust crate clap_complete to v4.5.65
2026-01-08 07:12:04 +01:00
renovate[bot] df06ef663d chore(deps): update rust crate clap_complete to v4.5.65 2026-01-07 18:01:54 +00:00
Daniel Hofstetter e82023054e Merge pull request #245 from uutils/renovate/divan-4.x-lockfile
chore(deps): update rust crate divan to v4.2.1
2026-01-07 14:12:19 +01:00
renovate[bot] 9b7b509268 chore(deps): update rust crate divan to v4.2.1 2026-01-07 12:57:56 +00:00
Daniel Hofstetter 70ce8fe410 Merge pull request #243 from uutils/renovate/clap-4.x-lockfile
chore(deps): update rust crate clap to v4.5.54
2026-01-03 07:17:31 +01:00
renovate[bot] e16a49bb93 chore(deps): update rust crate clap to v4.5.54 2026-01-03 00:43:09 +00:00
Daniel Hofstetter a8887f83dd Merge pull request #242 from uutils/renovate/clap_complete-4.x-lockfile
chore(deps): update rust crate clap_complete to v4.5.64
2025-12-31 07:02:52 +01:00
renovate[bot] 9667ebe8c3 chore(deps): update rust crate clap_complete to v4.5.64 2025-12-30 17:32:56 +00:00
Sylvestre Ledru 5ed30bd344 Merge pull request #226 from oech3/patch-1
Cargo.toml: Remove non standard profile
2025-12-30 11:58:51 +01:00
Sylvestre Ledru 1996ac2ae3 Merge pull request #241 from dspinellis/integration-tests
Add two complex scripts as integration tests
2025-12-30 11:58:28 +01:00
Diomidis Spinellis e40ddb1c99 Add Mandelbrot set drawing 2025-12-30 11:40:09 +02:00
Diomidis Spinellis 8c840078c5 Add Bach prelude as an integration test
Thanks to: Olga Ustiuzhanina @laserbat for providing a suitable license.
2025-12-30 11:40:09 +02:00
Diomidis Spinellis 4029ae5aba Incorporate variables in format messages
This addresses clippy warnings.
2025-12-30 11:40:09 +02:00
Daniel Hofstetter 3479e9b580 Merge pull request #240 from uutils/renovate/clap_complete-4.x-lockfile
chore(deps): update rust crate clap_complete to v4.5.63
2025-12-30 07:16:23 +01:00
renovate[bot] 0109b369a6 chore(deps): update rust crate clap_complete to v4.5.63 2025-12-29 18:06:46 +00:00
oech3 77e1abd18e Cargo.toml: Remove non standard profile 2025-12-29 13:02:06 +01:00
Daniel Hofstetter 17575017d8 Merge pull request #239 from uutils/renovate/dawidd6-action-download-artifact-12.x
chore(deps): update dawidd6/action-download-artifact action to v12
2025-12-25 14:30:49 +01:00
renovate[bot] 902611caf1 chore(deps): update dawidd6/action-download-artifact action to v12 2025-12-25 13:23:56 +00:00
Daniel Hofstetter b5a8444f88 Merge pull request #238 from uutils/renovate/tempfile-3.x-lockfile
chore(deps): update rust crate tempfile to v3.24.0
2025-12-24 07:17:40 +01:00
renovate[bot] 200bc978b4 chore(deps): update rust crate tempfile to v3.24.0 2025-12-24 00:25:44 +00:00
Daniel Hofstetter d58547195b Merge pull request #237 from uutils/renovate/divan-4.x-lockfile
chore(deps): update rust crate divan to v4.2.0
2025-12-23 07:23:16 +01:00
renovate[bot] ef7f8ad361 chore(deps): update rust crate divan to v4.2.0 2025-12-22 22:14:06 +00:00
Daniel Hofstetter 19f02d5683 Merge pull request #233 from uutils/renovate/major-github-artifact-actions
chore(deps): update github artifact actions (major)
2025-12-22 07:13:27 +01:00
renovate[bot] d253a5808a chore(deps): update github artifact actions 2025-12-21 17:50:14 +00:00
Daniel Hofstetter bf47d12e37 Merge pull request #230 from uutils/renovate/actions-checkout-6.x
chore(deps): update actions/checkout action to v6
2025-12-21 13:21:44 +01:00
Daniel Hofstetter 0ea19a6fd5 Merge pull request #231 from uutils/renovate/dawidd6-action-download-artifact-11.x
chore(deps): update dawidd6/action-download-artifact action to v11
2025-12-21 13:20:43 +01:00
renovate[bot] 55177aeca4 chore(deps): update dawidd6/action-download-artifact action to v11 2025-12-21 12:06:08 +00:00
renovate[bot] c8b9173752 chore(deps): update actions/checkout action to v6 2025-12-21 12:06:05 +00:00
Sylvestre Ledru 3fa2227ebf Run against the GNU implementation (#223)
* Add a script to run the sed testsuite

* run the gnu testsuite in the ci

* remove useless comment
2025-12-21 13:05:37 +01:00
Sylvestre Ledru 2df1e00d8e Merge pull request #225 from cakebaker/remove_once_cell
Replace `Lazy` from `once_cell` with `LazyLock` from std
2025-12-18 17:14:06 +01:00
Sylvestre Ledru 61c405c549 Merge pull request #227 from cakebaker/test_use_tempfolder
test: write file to temp folder
2025-12-18 17:00:37 +01:00
Daniel Hofstetter 3336f93514 Merge pull request #228 from uutils/renovate/clap_complete-4.x-lockfile
chore(deps): update rust crate clap_complete to v4.5.62
2025-12-18 16:04:56 +01:00
renovate[bot] 569f3557e5 chore(deps): update rust crate clap_complete to v4.5.62 2025-12-18 14:43:10 +00:00
Daniel Hofstetter 9ae154a26d test: write file to temp folder 2025-12-18 14:50:07 +01:00
Daniel Hofstetter 2ae5b782c7 Replace Lazy from once_cell with LazyLock from std 2025-12-18 10:18:29 +01:00
Sylvestre Ledru eddee66b6c Merge pull request #224 from cakebaker/move_lints_to_cargo_toml
Move lints from CI to `Cargo.toml`
2025-12-18 09:54:10 +01:00
Daniel Hofstetter b3ee5bfa9d Move lints from CI to Cargo.toml 2025-12-18 09:40:50 +01:00
57 changed files with 8031 additions and 2397 deletions

No files matched your search

+80
View File
@@ -0,0 +1,80 @@
name: GnuComment
on:
workflow_run:
workflows: ["GnuTests"]
types:
- completed
permissions: {}
jobs:
post-comment:
permissions:
actions: read # to list workflow runs artifacts
pull-requests: write # to comment on pr
runs-on: ubuntu-latest
if: >
github.event.workflow_run.event == 'pull_request'
steps:
- name: 'Download artifact'
uses: actions/github-script@v9
with:
script: |
// List all artifacts from GnuTests
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});
// Download the "comment" artifact, which contains a PR number (NR) and result.txt
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "comment"
})[0];
if (!matchArtifact) {
console.log('No comment artifact found');
return;
}
var download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
var fs = require('fs');
fs.writeFileSync('${{ github.workspace }}/comment.zip', Buffer.from(download.data));
- run: unzip comment.zip || echo "Failed to unzip comment artifact"
- name: 'Comment on PR'
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
var fs = require('fs');
// Check if files exist
if (!fs.existsSync('./NR')) {
console.log('No NR file found, skipping comment');
return;
}
if (!fs.existsSync('./result.txt')) {
console.log('No result.txt file found, skipping comment');
return;
}
var issue_number = Number(fs.readFileSync('./NR'));
var content = fs.readFileSync('./result.txt');
if (content.toString().trim().length > 7) { // 7 because we have backquote + \n
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: 'GNU sed testsuite comparison:\n```\n' + content + '```'
});
} else {
console.log('Comment content too short, skipping');
}
+286
View File
@@ -0,0 +1,286 @@
name: GnuTests
# Run GNU sed testsuite against the Rust sed implementation
# This workflow extracts and runs tests from the GNU sed testsuite to ensure compatibility
on:
pull_request:
push:
branches:
- '*'
permissions:
contents: write # Publish sed instead of discarding
# End the current execution if there is a new changeset in the PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
TEST_FULL_SUMMARY_FILE: 'sed-gnu-full-result.json'
jobs:
native:
name: Run GNU sed testsuite
runs-on: ubuntu-24.04
steps:
#### Get the code, setup cache
- name: Checkout code (sed)
uses: actions/checkout@v7
with:
path: 'sed'
persist-credentials: false
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: rustfmt
- uses: Swatinem/rust-cache@v2
with:
workspaces: "./sed -> target"
- name: Checkout code (GNU sed testsuite)
uses: actions/checkout@v7
with:
repository: 'mirror/sed'
path: 'gnu.sed'
ref: 'master'
persist-credentials: false
# Omit installing part of https://github.com/actions/runner-images/tree/main/images/ubuntu
### Build
- name: Build Rust sed binary
shell: bash
run: |
## Build Rust sed binary
cd 'sed'
cargo build --config=profile.release.strip=true --profile=release #-fast
tar -C target/release -cf - sed | zstd -19 -o ../sed-x86_64-unknown-linux-gnu.tar.zst
- name: Publish latest commit
uses: softprops/action-gh-release@v3
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
with:
tag_name: latest-commit
body: |
commit: ${{ github.sha }}
draft: false
prerelease: true
files: |
sed-x86_64-unknown-linux-gnu.tar.zst
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
### Run tests
- name: Run GNU sed testsuite
shell: bash
run: |
## Run GNU sed testsuite using our script
cd 'sed'
# Set GNU sed source directory (testsuite is at gnu.sed/testsuite/)
export GNU_SED_DIR="../gnu.sed"
# Run tests with JSON output
./util/run-gnu-testsuite.sh --json-output "${{ env.TEST_FULL_SUMMARY_FILE }}" || true
### Upload artifacts
- name: Check for JSON results file
shell: bash
run: |
echo "Checking for JSON results file..."
ls -la sed/ || true
ls -la sed/${{ env.TEST_FULL_SUMMARY_FILE }} || echo "JSON file not found at sed/${{ env.TEST_FULL_SUMMARY_FILE }}"
ls -la ${{ env.TEST_FULL_SUMMARY_FILE }} || echo "JSON file not found at ${{ env.TEST_FULL_SUMMARY_FILE }}"
find . -name "*json*" -type f || echo "No JSON files found"
- name: Upload full json results
uses: actions/upload-artifact@v7
with:
name: sed-gnu-full-result
path: sed/${{ env.TEST_FULL_SUMMARY_FILE }}
if-no-files-found: warn
- name: Upload test logs
if: always()
uses: actions/upload-artifact@v7
with:
name: test-logs
path: |
sed/test-logs/*.log
sed/test-results/*.json
aggregate:
needs: [native]
permissions:
actions: read
contents: read
pull-requests: read
name: Aggregate GNU test results
runs-on: ubuntu-24.04
steps:
- name: Initialize workflow variables
id: vars
shell: bash
run: |
## VARs setup
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
TEST_SUMMARY_FILE='sed-gnu-result.json'
outputs TEST_SUMMARY_FILE
- name: Checkout code (sed)
uses: actions/checkout@v7
with:
path: 'sed'
persist-credentials: false
- name: Retrieve reference artifacts
uses: dawidd6/action-download-artifact@v21
continue-on-error: true
with:
workflow: GnuTests.yml
branch: "${{ env.DEFAULT_BRANCH }}"
workflow_conclusion: completed
path: "reference"
if_no_artifact_found: warn
- name: Download full json results
uses: actions/download-artifact@v8
with:
name: sed-gnu-full-result
path: results
- name: Extract/summarize testing info
id: summary
shell: bash
run: |
## Extract/summarize testing info
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
# Check if results directory exists and has JSON files
json_count=0
if [[ -d "results" ]]; then
json_count=$(find results -name "*.json" | wc -l)
fi
if [[ "$json_count" -lt 1 ]]; then
echo "::error ::Failed to download results json files; failing early"
echo "::error ::Contents of results directory:"
ls -lR results || echo "::error ::Results directory does not exist"
exit 1
fi
# Extract summary from JSON results
RESULT_FILE="results/${{ env.TEST_FULL_SUMMARY_FILE }}"
if [[ -f "$RESULT_FILE" ]]; then
TOTAL=$(jq -r '.summary.total // 0' "$RESULT_FILE")
PASS=$(jq -r '.summary.passed // 0' "$RESULT_FILE")
FAIL=$(jq -r '.summary.failed // 0' "$RESULT_FILE")
SKIP=$(jq -r '.summary.skipped // 0' "$RESULT_FILE")
ERROR=0 # Our format doesn't distinguish errors from failures
else
echo "::error ::Result file $RESULT_FILE not found"
echo "::error ::Available files in results:"
find results -type f || true
TOTAL=0; PASS=0; FAIL=0; SKIP=0; ERROR=0
fi
output="GNU sed tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / SKIP: $SKIP"
echo "${output}"
if [[ "$FAIL" -gt 0 ]]; then
echo "::warning ::${output}"
fi
jq -n \
--arg date "$(date --rfc-email)" \
--arg sha "$GITHUB_SHA" \
--arg total "$TOTAL" \
--arg pass "$PASS" \
--arg skip "$SKIP" \
--arg fail "$FAIL" \
--arg error "$ERROR" \
'{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, error: $error }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}'
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
outputs HASH TOTAL PASS FAIL SKIP
- name: Upload SHA1/ID of 'test-summary'
uses: actions/upload-artifact@v7
with:
name: "${{ steps.summary.outputs.HASH }}"
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
- name: Upload test results summary
uses: actions/upload-artifact@v7
with:
name: test-summary
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
- name: Compare test failures VS reference
shell: bash
run: |
## Compare test failures VS reference using JSON files
REF_SUMMARY_FILE='reference/sed-gnu-full-result/sed-gnu-full-result.json'
CURRENT_SUMMARY_FILE="results/${{ env.TEST_FULL_SUMMARY_FILE }}"
REPO_DEFAULT_BRANCH='${{ env.DEFAULT_BRANCH }}'
# Path to ignore file for intermittent issues
IGNORE_INTERMITTENT="sed/.github/workflows/ignore-intermittent.txt"
# Set up comment directory
COMMENT_DIR="reference/comment"
mkdir -p ${COMMENT_DIR}
echo ${{ github.event.number }} > ${COMMENT_DIR}/NR
COMMENT_LOG="${COMMENT_DIR}/result.txt"
COMPARISON_RESULT=0
if test -f "${CURRENT_SUMMARY_FILE}"; then
if test -f "${REF_SUMMARY_FILE}"; then
echo "Reference summary SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")"
echo "Current summary SHA1/ID: $(sha1sum -- "${CURRENT_SUMMARY_FILE}")"
python3 sed/util/compare_test_results.py \
--ignore-file "${IGNORE_INTERMITTENT}" \
--output "${COMMENT_LOG}" \
"${CURRENT_SUMMARY_FILE}" "${REF_SUMMARY_FILE}"
COMPARISON_RESULT=$?
else
echo "::warning ::Skipping test comparison; no prior reference summary is available at '${REF_SUMMARY_FILE}'."
fi
else
echo "::error ::Failed to find summary of test results (missing '${CURRENT_SUMMARY_FILE}'); failing early"
exit 1
fi
if [ ${COMPARISON_RESULT} -eq 1 ]; then
echo "ONLY_INTERMITTENT=false" >> $GITHUB_ENV
echo "::error ::Found new non-intermittent test failures"
exit 1
else
echo "ONLY_INTERMITTENT=true" >> $GITHUB_ENV
echo "::notice ::No new test failures detected"
fi
- name: Upload comparison log (for GnuComment workflow)
if: success() || failure()
uses: actions/upload-artifact@v7
with:
name: comment
path: reference/comment/
- name: Report test results
if: success() || failure()
shell: bash
run: |
## Report final results
echo "::notice ::GNU sed testsuite results:"
echo "::notice :: Total tests: ${{ steps.summary.outputs.TOTAL }}"
echo "::notice :: Passed: ${{ steps.summary.outputs.PASS }}"
echo "::notice :: Failed: ${{ steps.summary.outputs.FAIL }}"
echo "::notice :: Skipped: ${{ steps.summary.outputs.SKIP }}"
if [[ "${{ steps.summary.outputs.FAIL }}" -gt 0 ]]; then
PASS_RATE=$(( ${{ steps.summary.outputs.PASS }} * 100 / (${{ steps.summary.outputs.PASS }} + ${{ steps.summary.outputs.FAIL }}) ))
echo "::notice :: Pass rate: ${PASS_RATE}%"
fi
+17
View File
@@ -0,0 +1,17 @@
name: Security audit
# spell-checker:ignore (misc) rustsec
on:
schedule:
- cron: "0 0 * * *"
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
+7 -12
View File
@@ -25,25 +25,20 @@ jobs:
benchmark-target:
- { package: sed }
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Install system dependencies
shell: bash
run: |
sudo apt-get -y update
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.9
uses: mozilla-actions/sccache-action@v0.0.11
- name: Install cargo-codspeed
shell: bash
run: cargo install cargo-codspeed --locked
- name: Install tools
uses: taiki-e/install-action@v2
with:
tool: cargo-codspeed
- name: Build benchmarks for ${{ matrix.benchmark-target.package }}
shell: bash
@@ -52,7 +47,7 @@ jobs:
cargo codspeed build -p ${{ matrix.benchmark-target.package }}
- name: Run benchmarks for ${{ matrix.benchmark-target.package }}
uses: CodSpeedHQ/action@v4
uses: CodSpeedHQ/action@v5
env:
CODSPEED_LOG: debug
with:
+25 -4
View File
@@ -13,10 +13,31 @@ jobs:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- run: cargo check
check_android:
name: cargo check (Android ${{ matrix.target }})
runs-on: ubuntu-latest
strategy:
matrix:
target: [aarch64-linux-android, armv7-linux-androideabi]
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: android-actions/setup-android@v4
- name: Install Android NDK
run: sdkmanager "ndk;29.0.14206865"
- name: Install cargo-ndk
run: cargo install cargo-ndk
- name: Check Android target
run: cargo ndk --platform 21 --target ${{ matrix.target }} check
env:
ANDROID_NDK_HOME: ${{ env.ANDROID_SDK_ROOT }}/ndk/29.0.14206865
test:
name: cargo test
runs-on: ${{ matrix.os }}
@@ -28,7 +49,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --all
@@ -47,7 +68,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Initialize workflow variables
id: vars
shell: bash
@@ -109,7 +130,7 @@ jobs:
ls -al
echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ steps.coverage.outputs.report }}
+4 -5
View File
@@ -25,7 +25,7 @@ jobs:
name: cargo fmt --all -- --check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
@@ -44,14 +44,14 @@ jobs:
- { os: macos-latest }
- { os: windows-latest }
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.9
uses: mozilla-actions/sccache-action@v0.0.11
- name: Initialize workflow variables
id: vars
shell: bash
@@ -69,9 +69,8 @@ jobs:
run: |
## `cargo clippy` lint testing
unset fault
CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new -W clippy::cognitive_complexity -W clippy::implicit_clone -W clippy::range-plus-one -W clippy::redundant-clone -W clippy::match_bool -W clippy::semicolon_if_nothing_returned"
fault_type="${{ steps.vars.outputs.FAULT_TYPE }}"
fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]')
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
S=$(cargo clippy --all-targets --workspace -psed -- ${CLIPPY_FLAGS} -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; }
S=$(cargo clippy --all-targets --workspace -psed -- -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; }
if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi
+18 -14
View File
@@ -21,18 +21,20 @@ jobs:
name: Build the fuzzers
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@nightly
- name: Install `cargo-fuzz`
run: cargo install cargo-fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- uses: Swatinem/rust-cache@v2
with:
shared-key: "cargo-fuzz-cache-key"
cache-directories: "fuzz/target"
- name: Run `cargo-fuzz build`
run: cargo +nightly fuzz build
# https://github.com/rust-fuzz/cargo-fuzz/issues/398
run: env RUSTC_BOOTSTRAP=1 cargo fuzz build --target $(rustc --print host-tuple)
fuzz-run:
needs: fuzz-build
@@ -47,18 +49,19 @@ jobs:
- { name: fuzz_sed, should_pass: false }
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@nightly
- name: Install `cargo-fuzz`
run: cargo install cargo-fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- uses: Swatinem/rust-cache@v2
with:
shared-key: "cargo-fuzz-cache-key"
cache-directories: "fuzz/target"
- name: Restore Cached Corpus
uses: actions/cache/restore@v5
uses: actions/cache/restore@v6
with:
key: corpus-cache-${{ matrix.test-target.name }}
path: |
@@ -70,7 +73,8 @@ jobs:
run: |
mkdir -p fuzz/stats
STATS_FILE="fuzz/stats/${{ matrix.test-target.name }}.txt"
cargo +nightly fuzz run ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -timeout=${{ env.RUN_FOR }} -detect_leaks=0 -print_final_stats=1 2>&1 | tee "$STATS_FILE"
# https://github.com/rust-fuzz/cargo-fuzz/issues/398
env RUSTC_BOOTSTRAP=1 cargo fuzz run --target $(rustc --print host-tuple) ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -timeout=${{ env.RUN_FOR }} -detect_leaks=0 -print_final_stats=1 2>&1 | tee "$STATS_FILE"
# Extract key stats from the output
if grep -q "stat::number_of_executed_units" "$STATS_FILE"; then
@@ -140,13 +144,13 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
- name: Save Corpus Cache
uses: actions/cache/save@v5
uses: actions/cache/save@v6
with:
key: corpus-cache-${{ matrix.test-target.name }}
path: |
fuzz/corpus/${{ matrix.test-target.name }}
- name: Upload Stats
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: fuzz-stats-${{ matrix.test-target.name }}
path: |
@@ -159,11 +163,11 @@ jobs:
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Download all stats
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
path: fuzz/stats-artifacts
pattern: fuzz-stats-*
@@ -257,7 +261,7 @@ jobs:
run: |
cat fuzzing_summary.md
- name: Upload Summary
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: fuzzing-summary
path: fuzzing_summary.md
@@ -0,0 +1,7 @@
# List of intermittent test names to ignore in result comparisons
# Format: one test name per line, lines starting with # are comments
#
# Add test names that are known to be flaky or environment-dependent
# Example:
# basic_substitution
# line_address_test
+16 -16
View File
@@ -56,7 +56,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive
@@ -66,7 +66,7 @@ jobs:
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
@@ -82,7 +82,7 @@ jobs:
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
@@ -116,7 +116,7 @@ jobs:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive
@@ -131,7 +131,7 @@ jobs:
run: ${{ matrix.install_dist.run }}
# Get the dist-manifest
- name: Fetch local artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
pattern: artifacts-*
path: target/distrib/
@@ -158,7 +158,7 @@ jobs:
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
path: |
@@ -175,19 +175,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
pattern: artifacts-*
path: target/distrib/
@@ -205,7 +205,7 @@ jobs:
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: artifacts-build-global
path: |
@@ -225,19 +225,19 @@ jobs:
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
pattern: artifacts-*
path: target/distrib/
@@ -250,14 +250,14 @@ jobs:
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
pattern: artifacts-*
path: artifacts
@@ -290,7 +290,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive
+28
View File
@@ -0,0 +1,28 @@
# spell-checker:ignore wasip
name: WASI
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
# End the current execution if there is a new changeset in the PR.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
test_wasi:
name: Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-wasip1
- name: check
run: cargo check --target wasm32-wasip1
+55
View File
@@ -0,0 +1,55 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: ^tests/fixtures/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-executables-have-shebangs
- id: check-json
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
- id: check-toml
- id: check-yaml
args: [ --allow-multiple-documents ]
- id: destroyed-symlinks
- id: end-of-file-fixer
- id: mixed-line-ending
args: [ --fix=lf ]
- id: trailing-whitespace
- repo: local
hooks:
- id: rust-linting
name: Rust linting
description: Run cargo fmt on files included in the commit.
entry: cargo +stable fmt --
pass_filenames: true
types: [file, rust]
language: system
- id: rust-clippy
name: Rust clippy
description: Run cargo clippy on files included in the commit.
entry: cargo +stable clippy --workspace --all-targets --all-features -- -D warnings
pass_filenames: false
types: [file, rust]
language: system
- id: cargo-lock-check
name: Cargo.lock sync check
description: Ensure Cargo.lock and fuzz/Cargo.lock are up-to-date.
entry: bash -c 'for dir in . fuzz; do ( cd "$dir" && cargo fetch --quiet ); done'
pass_filenames: false
files: 'Cargo\.(toml|lock)$'
language: system
- id: cspell
name: Code spell checker (cspell)
description: Run cspell to check for spelling errors (if available).
entry: bash -c 'if command -v cspell >/dev/null 2>&1; then cspell --no-must-find-files -- "$@"; else echo "cspell not found, skipping spell check"; exit 0; fi' --
pass_filenames: true
language: system
ci:
skip: [rust-linting, rust-clippy, cargo-lock-check, cspell]
+32
View File
@@ -0,0 +1,32 @@
# Contributing to sed
Hi! Welcome to uutils/sed, and thanks for wanting to contribute!
This project follows the shared conventions of the [uutils](https://github.com/uutils)
organization. Before opening a pull request, please read:
- Our **[Review Guidelines](https://uutils.github.io/reviews/)** — what we expect
from a pull request and how reviews are carried out.
- Our community's [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md), if present.
Finally, feel free to join our [Discord](https://discord.gg/wQVJbvJ)!
> [!WARNING]
> uutils is original code and cannot contain any code from GNU or other
> strongly-licensed (GPL/LGPL) implementations. We **cannot** accept changes
> based on the GNU source code, and you **must not link** to it either. You may
> look at permissively-licensed implementations (MIT/BSD) and read the GNU
> *manuals* — never the GNU *source*.
## In short
- Discuss non-trivial changes in an issue **before** writing the code.
- Keep pull requests **small, self-contained, and descriptively titled**
(e.g. `sed: fix ...`).
- Make sure CI passes: tests are green, `rustfmt` is satisfied, and there are
no `clippy` warnings.
- Add tests for new behavior; don't let coverage regress.
- Write small, atomic commits annotated with the component you touched.
See the [Review Guidelines](https://uutils.github.io/reviews/) for the full
details.
Generated
+526 -543
View File
File diff suppressed because it is too large. Load diff
+60 -33
View File
@@ -5,8 +5,7 @@
[package]
name = "sed"
version = "0.1.1"
authors = ["uutils developers"]
version = "0.2.0"
license = "MIT"
description = "sed ~ implemented as universal (cross-platform) utils, written in Rust"
default-run = "sed"
@@ -29,67 +28,68 @@ sed = []
[workspace.dependencies]
assert_fs = "1.1.3"
bytesize = "2.0.0"
chrono = { version = "0.4.37", default-features = false, features = [
"clock",
] }
clap = { version = "4.4", features = ["wrap_help", "cargo"] }
clap_complete = "4.5"
clap_mangen = "0.2"
divan = { package = "codspeed-divan-compat", version = "4.0.5" }
fancy-regex = "0.17.0"
clap_mangen = "0.3"
divan = { package = "codspeed-divan-compat", version = "5.0.0" }
fancy-regex = "0.18.0"
hex = "0.4"
libc = "0.2.153"
memchr = "2.7.4"
memmap2 = "0.9"
once_cell = "1.21.3"
phf = "0.13.0"
phf_codegen = "0.13.0"
phf = "0.14.0"
phf_codegen = "0.14.0"
predicates = "3.1.3"
rand = { version = "0.9", features = ["small_rng"] }
rand = { version = "0.10.0" }
regex = "1.10.4"
sysinfo = "0.37"
sha2 = "0.11"
tempfile = "3.10.1"
textwrap = { version = "0.16.1", features = ["terminal_size"] }
terminal_size = "0.4.2"
uucore = { version = "0.5.0", features = ["libc"] }
textwrap = { version = "0.16.1", features = ["terminal_size"] }
uucore = { version = "0.10.0", features = ["libc"] }
rustix = "1.1.4"
xattr = "1.3.1"
[dependencies]
assert_fs = { workspace = true }
clap = { workspace = true }
clap_complete = { workspace = true }
clap_mangen = { workspace = true }
ctor = "0.6.0"
fancy-regex = { workspace = true }
memchr = { workspace = true }
memmap2.workspace = true
once_cell = { workspace = true }
phf = { workspace = true }
predicates = { workspace = true }
regex = { workspace = true }
sysinfo = { workspace = true }
tempfile = { workspace = true }
terminal_size = { workspace = true }
textwrap = { workspace = true }
uucore = { workspace = true }
rustix = { workspace = true }
[dev-dependencies]
assert_fs = { workspace = true }
chrono = { workspace = true }
ctor = "1.0.0"
divan = { workspace = true }
hex = { workspace = true }
libc = { workspace = true }
pretty_assertions = "1"
rand = { workspace = true }
regex = { workspace = true }
sha2 = { workspace = true }
tempfile = { workspace = true }
uucore = { workspace = true, features = ["entries", "process", "signals", "benchmark"] }
uutests = "0.5.0"
uutests = "0.10.0"
[target.'cfg(unix)'.dev-dependencies]
xattr = { workspace = true }
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dev-dependencies]
rlimit = "0.10.1"
rlimit = "0.11.0"
[build-dependencies]
phf_codegen = { workspace = true }
@@ -105,26 +105,53 @@ path = "src/bin/sed.rs"
name = "sed_bench"
harness = false
# The default release profile. It contains all optimizations, without
# sacrificing debug info. With this profile (like in the standard
# release profile), the debug info and the stack traces will still be available.
[profile.release]
lto = true
# A release-like profile that is tuned to be fast, even when being fast
# compromises on binary size. This includes aborting on panic.
[profile.release-fast]
inherits = "release"
panic = "abort"
codegen-units = 1
# should be dropped to 1 for binary size without performance drop
codegen-units = 7
# A release-like profile that is as small as possible.
[profile.release-small]
inherits = "release-fast"
inherits = "release"
opt-level = "z"
strip = true
# The profile that 'cargo dist' will build with
[profile.dist]
inherits = "release"
lto = "thin"
[lints.clippy]
all = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
# The counts were generated with this command:
# cargo +nightly clippy --all-targets --workspace --message-format=json --quiet \
# | jq -r '.message.code.code | select(. != null and startswith("clippy::"))' \
# | sort | uniq -c | sort -h -r
missing_errors_doc = "allow" # 69
doc_markdown = "allow" # 63
must_use_candidate = "allow" # 56
needless_raw_string_hashes = "allow" # 20
needless_pass_by_value = "allow" # 15
missing_panics_doc = "allow" # 12
# cast_possible_truncation = "allow" # 7
unnecessary_wraps = "allow" # 6
match_wildcard_for_single_variants = "allow" # 4
cast_sign_loss = "allow" # 4
cast_possible_wrap = "allow" # 4
uninlined_format_args = "allow" # 3
similar_names = "allow" # 3
used_underscore_binding = "allow" # 2
too_many_lines = "allow" # 2
struct_excessive_bools = "allow" # 2
match_same_arms = "allow" # 2
ignore_without_reason = "allow" # 2
format_push_string = "allow" # 2
should_panic_without_expect = "allow" # 1
many_single_char_names = "allow" # 1
comparison_chain = "allow"
multiple_crate_versions = "allow"
unnested_or_patterns = "allow"
restriction = { level = "allow", priority = -1 }
cognitive_complexity = "warn"
redundant_clone = "warn"
+71 -11
View File
@@ -3,7 +3,7 @@
[![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/uutils/sed/blob/main/LICENSE)
[![dependency status](https://deps.rs/repo/github/uutils/sed/status.svg)](https://deps.rs/repo/github/uutils/sed)
[![CodeCov](https://codecov.io/gh/uutils/sed/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/sed)
[![CodeCov](https://codecov.io/gh/uutils/sed/branch/main/graph/badge.svg)](https://codecov.io/gh/uutils/sed)
# sed
@@ -14,7 +14,7 @@ and other extensions.
## Status
At this state _sed_ implements all POSIX commands
At this state _sed_ implements all [POSIX features](https://pubs.opengroup.org/onlinepubs/9799919799/)
and can run correctly the two complex scripts of its integration tests:
[hanoi.sed](https://github.com/uutils/sed/blob/main/tests/fixtures/sed/script/hanoi.sed) (solves the Towers of Hanoi puzzle) and
[math.sed](https://github.com/uutils/sed/blob/main/tests/fixtures/sed/script/math.sed) (implements an arbitrary precision integer math calculator).
@@ -26,9 +26,12 @@ Further work aims to:
* Implement more GNU extensions,
* Improve performance where possible.
## Installation
## Installation and Use
Ensure you have Rust installed on your system. You can install Rust through [rustup](https://rustup.rs/).
We provide a Linux x86_64 binary archive from the main branch at
https://github.com/uutils/sed/releases/tag/latest-commit .
For other platforms, ensure you have Rust installed on your system. You can install Rust through [rustup](https://rustup.rs/).
Clone the repository and build the project using Cargo:
@@ -41,23 +44,66 @@ cargo run --release
The binary is named `sed` in `target/release/sed`.
You can also try *sed* on the web
through the [uutils Playground](https://uutils.org//playground/)
by clicking on the `Load sed` button.
## Testing
### GNU sed Compatibility Testing
Test compatibility against GNU sed by running the upstream testsuite shell scripts
with a lightweight gnulib test-framework shim:
```bash
# Clone GNU sed testsuite (one time setup)
git clone https://github.com/mirror/sed.git ../gnu.sed
# Run compatibility tests
./util/run-gnu-testsuite.sh
# Verbose mode shows failure details
./util/run-gnu-testsuite.sh -v
# Generate JSON results for CI
./util/run-gnu-testsuite.sh --json-output results.json
```
The harness executes each `.sh` test from the GNU sed testsuite directly, injecting
our Rust sed binary via `PATH` and providing shim implementations of the gnulib test
framework functions (`compare_`, `returns_`, `skip_`, etc.).
### Unit Tests
```bash
cargo test
```
## Extensions and incompatibilities
### Supported GNU extensions
* Command-line arguments can be specified in long (`--`) form.
* Spaces can precede a regular expression modifier.
* `I` can be used in as a synonym for the `i` (case insensitive) substitution
flag.
* `M` and `m` substitution flags allow multi-line matching.
* In addition to `\n`, other escape sequences (octal, hex, C) are supported
in the strings of the `y` command.
Under POSIX these yield undefined behavior.
* The `a`, `c`, and `i` commands do not require an initial backslash,
allow text to appear on the same line, and support escape sequences
in the specified text.
* The `a`, `i`, `=`, `l`, `q` and `r` commands support address range as an extension to POSIX.
* The substitution command replacement group `\0` is a synonym for &.
* A `Q` command (optionally followed by an exit code) quits immediately.
* The `q` command can be optionally followed by an exit code.
* The `l` command can be optionally followed by the output width.
* The `--follow-symlinks` flag for in-place editing.
* The `--follow-symlinks` option for in-place editing.
* The `--sandbox` option that limits potentially destructive commands.
* Address 0 can be used to specify an address range that is already
active on line 1 and can finish with the specified regular expression.
* Address steps can be specified in the form of start~step and start,~step
ranges.
* Address 0 can be used in the `r` command to prepend a file.
### Supported BSD and GNU extensions
* The second address in a range can be specified as a relative address with +N.
@@ -70,12 +116,19 @@ The binary is named `sed` in `target/release/sed`.
sequences.
### Incompatibilities
* The input is assumed to be valid UTF-8 (this includes 7-bit ASCII).
If the input is in another code page, consider converting it through UTF-8
in order to avoid errors on invalid UTF-8 sequences and for the correct
handling of regular expressions.
This _sed_ program can also handle arbitrary byte sequences if no part of the
input is treated as string.
* Similarly to GNU _sed_, input is processed as raw bytes or as valid UTF-8
(this includes 7-bit ASCII) based on the locale as specified by the
`LC_ALL`, `LC_CTYPE`, and `LANG` environment variables,
with the default being byte processing.
However, in contrast with GNU _sed_, other locales (e.g. ISO-8859-1)
are not supported. If the input is in another code page or encoding
and requires locale-specific processing (e.g. ignore/map case,
character classes), consider converting it through UTF-8 to ensure
the correct handling of locale-specific regular expressions.
This _sed_ program can also handle arbitrary byte sequences
if no part of the input requires treating it as a Rust String.
* Back-references aren't supported when input is processed as bytes
(`LC_ALL=C`).
* The command will report an error and fail if duplicate labels are found
in the script.
This matches the BSD behavior. The GNU version accepts duplicate labels.
@@ -87,6 +140,13 @@ The binary is named `sed` in `target/release/sed`.
* Labels are parsed for alphanumeric characters. The BSD version parses them
until the end of the line, preventing ; to be used as a separator.
## GNU test suite compatibility
Below is the evolution of how many GNU tests uutils passes.
![Evolution over time](https://github.com/uutils/sed-tracking/blob/main/gnu-results.svg?raw=true)
## License
sed is licensed under the MIT License - see the `LICENSE` file for details
+44
View File
@@ -0,0 +1,44 @@
# Security Policy
## Supported Versions
We provide security updates only for the latest released version of `uutils/sed`.
Older versions may not receive patches.
If you are using a version packaged by your Linux distribution, please check with your distribution maintainers for their update policy.
---
## Reporting a Vulnerability
**Do not open public GitHub issues for security vulnerabilities.**
This prevents accidental disclosure before a fix is available.
Instead, please use the following method:
- **Email:** [sylvestre@debian.org](mailto:Sylvestre@debian.org)
- **Encryption (optional):** You may encrypt your report using our PGP key:
Fingerprint: B60D B599 4D39 BEC4 D1A9 5CCF 7E65 28DA 752F 1BE1
---
### What to Include in Your Report
To help us investigate and resolve the issue quickly, please include as much detail as possible:
- **Type of issue:** e.g. privilege escalation, information disclosure.
- **Location in the source:** file path, commit hash, branch, or tag.
- **Steps to reproduce:** exact commands, test cases, or scripts.
- **Special configuration:** any flags, environment variables, or system setup required.
- **Affected systems:** OS/distribution and version(s) where the issue occurs.
- **Impact:** your assessment of the potential severity (DoS, RCE, data leak, etc.).
---
## Disclosure Policy
We follow a **Coordinated Vulnerability Disclosure (CVD)** process:
1. We will acknowledge receipt of your report within **10 days**.
2. We will investigate, reproduce, and assess the issue.
3. We will provide a timeline for developing and releasing a fix.
4. Once a fix is available, we will publish a GitHub Security Advisory.
5. You will be credited in the advisory unless you request anonymity.
+3 -3
View File
@@ -17,7 +17,7 @@ fn no_op_short(bencher: Bencher) {
let temp_dir = tempfile::tempdir().unwrap();
let mut data = Vec::new();
for i in 0..10_000_000 {
data.extend_from_slice(format!("{}\n", i).as_bytes());
data.extend_from_slice(format!("{i}\n").as_bytes());
}
let file_path = create_test_file(&data, temp_dir.path());
let file_path_str = file_path.to_str().unwrap();
@@ -192,7 +192,7 @@ fn remove_cr(bencher: Bencher) {
let temp_dir = tempfile::tempdir().unwrap();
let mut data = Vec::new();
for i in 0..500_000 {
let line = format!("line {} with windows endings\r\n", i);
let line = format!("line {i} with windows endings\r\n");
data.extend_from_slice(line.as_bytes());
}
let file_path = create_test_file(&data, temp_dir.path());
@@ -240,7 +240,7 @@ fn number_fix(bencher: Bencher) {
let cents = i % 100;
let thousands = euros / 1000;
let remainder = euros % 1000;
let line = format!("{}.{:03},{:02}\n", thousands, remainder, cents);
let line = format!("{thousands}.{remainder:03},{cents:02}\n");
data.extend_from_slice(line.as_bytes());
}
let file_path = create_test_file(&data, temp_dir.path());
+477 -585
View File
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -12,10 +12,10 @@ console = "0.16.0"
libfuzzer-sys = "0.4.7"
libc = "0.2.153"
tempfile = "3.15.0"
rand = { version = "0.9.0", features = ["small_rng"] }
similar = "2.5.0"
uucore = { version = "0.5.0", features = ["libc"] }
uufuzz = "0.5.0"
rand = { version = "0.10.0" }
similar = "3.0.0"
uucore = { version = "0.10.0", features = ["libc"] }
uufuzz = "0.10.0"
sed = { path = ".." }
+175 -98
View File
File diff suppressed because it is too large. Load diff
Loaded 20 of 57 files, more files were not shown because too many files have changed in this diff. Show more