-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Remove clap for echo #7603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove clap for echo #7603
Conversation
…roblematic interactions with hyphens
GNU testsuite comparison:
|
GNU testsuite comparison:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes the dependency on clap for echo’s argument parsing and introduces a custom flag parsing logic alongside additional tests to verify handling of double hyphen and flag-like arguments.
- Removed clap-specific parsing code and replaced it with custom logic in echo.rs
- Updated the POSIXLY_CORRECT check to compare against "1"
- Added new tests in tests/by-util/test_echo.rs for various argument scenarios
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
File | Description |
---|---|
tests/by-util/test_echo.rs | Added tests covering parsing of flags and double hyphen cases |
src/uu/echo/src/echo.rs | Removed clap usage; implemented custom parsing and updated env var check |
Comments suppressed due to low confidence (2)
tests/by-util/test_echo.rs:296
- This test case omits a trailing newline in its expected output, which is inconsistent with similar tests that include a newline. Please verify whether a trailing newline should be expected here.
.stdout_only("- --");
src/uu/echo/src/echo.rs:101
- Changing the POSIXLY_CORRECT check from verifying the existence of the variable to comparing its value to "1" may affect behavior if the variable is set to any truthy value other than "1". Please confirm that this change aligns with the intended behavior.
posixly_correct == "1"
src/uu/echo/src/echo.rs
Outdated
fn is_echo_flag(arg: &OsString) -> bool { | ||
matches!(arg.to_str(), Some("-e" | "-E" | "-n")) | ||
struct EchoFlags { | ||
pub n: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please make this more explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes for the name but your comments are a bit hard to understand IMHO :)
GNU testsuite comparison:
|
GNU testsuite comparison:
|
src/uu/echo/src/echo.rs
Outdated
} | ||
|
||
#[uucore::main] | ||
pub fn uumain(args: impl uucore::Args) -> UResult<()> { | ||
let is_posixly_correct = env::var("POSIXLY_CORRECT").is_ok(); | ||
// Check POSIX compatibility mode | ||
let is_posixly_correct = if let Ok(posixly_correct) = env::var("POSIXLY_CORRECT") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain this change. As far as I know GNU checks whether the env var is defined not whether it's 1. Is echo
an exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't sure about this. I checked in the test files and there it was set to be equal to one.
If the POSIXLY_CORRECT environment variable is set
found this on gnu.org on echo man pages. So i just need to check if its set at all, not whether it is set to any true value like 1 or true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted the change to now only check if it is defined at all
GNU testsuite comparison:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I think this behavior is exactly correct.
src/uu/echo/src/echo.rs
Outdated
if bytes.first() == Some(&b'-') { | ||
let mut flags = EchoFlags { | ||
disable_newline: false, | ||
escape: false, | ||
is_single_hyphen: false, | ||
}; | ||
// Single hyphen case: "-" (stops flag processing, no other effect) | ||
if arg.len() == 1 { | ||
flags.is_single_hyphen = true; | ||
return Some(flags); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if bytes.first() == Some(&b'-') { | |
let mut flags = EchoFlags { | |
disable_newline: false, | |
escape: false, | |
is_single_hyphen: false, | |
}; | |
// Single hyphen case: "-" (stops flag processing, no other effect) | |
if arg.len() == 1 { | |
flags.is_single_hyphen = true; | |
return Some(flags); | |
} | |
if bytes.first() == Some(&b'-') && arg != "-" { | |
let mut flags = EchoFlags { | |
disable_newline: false, | |
escape: false, | |
}; |
Would this work? I think the is_single_hyphen
case is identical to the None
case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also correct. Changed this part too. Thanks!
src/uu/echo/src/echo.rs
Outdated
if echo_flags.disable_newline { | ||
trailing_newline = false; | ||
} | ||
escape = echo_flags.escape; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too aggressive since it means -e -n
disables escape
. Maybe is_echo_flag
can mutably borrow a single EchoFlags
value that's reused and returned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great observation. Indeed this was an issue. I fixed this and also added some test as there was no test in the test suite so far to check for this behaviour.
GNU testsuite comparison:
|
Enabling POSIXLY_CORRECT flag if value is not UTF-8 Co-authored-by: Jan Verbeek <jan.verbeek@posteo.nl>
GNU testsuite comparison:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I can't check right now whether this is truly equal to the GNU behavior, but it seems sound to me. Feel free to address the nitpick or not :)
} | ||
|
||
#[uucore::main] | ||
pub fn uumain(args: impl uucore::Args) -> UResult<()> { | ||
let is_posixly_correct = env::var("POSIXLY_CORRECT").is_ok(); | ||
// Check POSIX compatibility mode | ||
let is_posixly_correct = env::var_os("POSIXLY_CORRECT").is_some(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a subtle change in behavior here: POSIXLY_CORRECT=<non-utf8-sequence>
is now interpreted as true
, whereas before it was interpreted as false
. I assume this is a correct change. (I can't test GNU easily right now.)
$ POSIXLY_CORRECT=$'\377asd' cargo run echo 'asd\nqwe' # current main
asd\nqwe
$ POSIXLY_CORRECT=$'\377asd' cargo run echo 'asd\nqwe' # your PR
asd
qwe
Nitpick: If you fix subtleties like this, it would be extra awesome if you also add a test, so that we don't lose it later :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggested that change upthread when I saw this code at the edge of a diff 😅
The following test (in test_echo.rs
inside mod posixly_correct {}
) should do the trick:
#[cfg(unix)]
#[test]
fn non_utf8_variable() {
use std::{ffi::OsStr, os::unix::ffi::OsStrExt};
new_ucmd!()
.env("POSIXLY_CORRECT", OsStr::from_bytes(b"\xFF"))
.arg("-e")
.succeeds()
.stdout_only("-e\n");
}
(I can confirm that this matches GNU, GNU activates POSIX mode regardless of whether the variable's value is 1
or 0
or empty string or \xFF
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! But I would argue that if you change the behavior, then an old test cannot possibly correctly test for the new behavior :D
In particular, this test only tests whether -e
is interpreted or considered as part of the output. It does not test whether escape sequences are interpreted or taken literally, i.e. whether "escape mode" is initially set or not.
Like I said, it's not a major thing, and doesn't block this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not an old test, I meant that was where I'd put it. It fails if env::var(...).is_ok()
is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
@BenWiederhake since I baked this behaviour into uutils-args, this is a good candidate to port next. But nevertheless, it's great to have this implementation (and tests!) first.
We could also decide to take the behaviour out of uutils-args to simplify it.
I agree! The reason I tackled Btw, can't be merged currently due to merge conflicts. |
* Parsing echo flags manually without clap as clap introduced various problematic interactions with hyphens * fixed error where multiple flags would parse wrong * Spelling & formatting fixes * docu for EchoFlag struct * more extensive comment/documentation * revert POSIXLY_CORRECT check to only check if it is set * Fixed problem of overwriting flags. Added test for same issue * cargo fmt * cspell * Update src/uu/echo/src/echo.rs Enabling POSIXLY_CORRECT flag if value is not UTF-8 Co-authored-by: Jan Verbeek <jan.verbeek@posteo.nl> --------- Co-authored-by: Jan Verbeek <jan.verbeek@posteo.nl>
fixes #7595
removed clap as a parsing tool for echo. Added some tests from previous issues comment sections regarding double hyphen problematics.