diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index f91795cbf..58f9a21e4 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -1079,11 +1079,23 @@ jobs: RUSTDOCFLAGS: "-Cpanic=abort" # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - name: "`grcov` ~ install" - uses: actions-rs/install@v0.1 - with: - crate: grcov - version: latest - use-tool-cache: false + id: build_grcov + shell: bash + run: | + git clone https://github.com/mozilla/grcov.git ~/grcov/ + cd ~/grcov + # Hardcode the version of crossbeam-epoch. See + # https://github.com/uutils/coreutils/issues/3680 + sed -i -e "s|tempfile =|crossbeam-epoch = \"=0.9.8\"\ntempfile =|" Cargo.toml + cargo install --path . + cd - +# Uncomment when the upstream issue +# https://github.com/mozilla/grcov/issues/849 is fixed +# uses: actions-rs/install@v0.1 +# with: +# crate: grcov +# version: latest +# use-tool-cache: false - name: Generate coverage data (via `grcov`) id: coverage shell: bash @@ -1095,9 +1107,9 @@ jobs: # GRCOV_EXCLUDE_OPTION='--excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"' ## `grcov` ignores these params when passed as an environment variable (why?) mkdir -p "${COVERAGE_REPORT_DIR}" # display coverage files - grcov . --output-type files --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique + ~/.cargo/bin/grcov . --output-type files --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique # generate coverage report - grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" + ~/.cargo/bin/grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" echo ::set-output name=report::${COVERAGE_REPORT_FILE} - name: Upload coverage results (to Codecov.io) uses: codecov/codecov-action@v3 diff --git a/Cargo.lock b/Cargo.lock index e0413c73c..367360ea6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1280,9 +1280,9 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "onig" diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index 78ef4e5c2..24d089df4 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -33,7 +33,10 @@ mod options { fn mkdelim(col: usize, opts: &ArgMatches) -> String { let mut s = String::new(); - let delim = opts.value_of(options::DELIMITER).unwrap(); + let delim = match opts.value_of(options::DELIMITER).unwrap() { + "" => "\0", + delim => delim, + }; if col > 1 && !opts.is_present(options::COLUMN_1) { s.push_str(delim.as_ref()); diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index 49254cf8d..f5e461750 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -24,7 +24,7 @@ termsize = "0.1.6" glob = "0.3.0" lscolors = { version = "0.10.0", features = ["ansi_term"] } uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore", features = ["entries", "fs"] } -once_cell = "1.12.0" +once_cell = "1.13.0" atty = "0.2" selinux = { version="0.2", optional = true } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 961bcbb20..5d86b67a2 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ data-encoding = { version="2.1", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } libc = { version="0.2.126", optional=true } -once_cell = "1.12.0" +once_cell = "1.13.0" os_display = "0.1.3" [target.'cfg(unix)'.dependencies] diff --git a/tests/by-util/test_comm.rs b/tests/by-util/test_comm.rs index ebfc9c6f9..b470f708b 100644 --- a/tests/by-util/test_comm.rs +++ b/tests/by-util/test_comm.rs @@ -59,13 +59,12 @@ fn output_delimiter() { .stdout_only_fixture("ab_delimiter_word.expected"); } -#[cfg_attr(not(feature = "test_unimplemented"), ignore)] #[test] -fn output_delimiter_require_arg() { +fn output_delimiter_nul() { new_ucmd!() .args(&["--output-delimiter=", "a", "b"]) - .fails() - .stderr_only("error to be defined"); + .succeeds() + .stdout_only_fixture("ab_delimiter_nul.expected"); } // even though (info) documentation suggests this is an option diff --git a/tests/by-util/test_realpath.rs b/tests/by-util/test_realpath.rs index c469eb0da..6e413ce9e 100644 --- a/tests/by-util/test_realpath.rs +++ b/tests/by-util/test_realpath.rs @@ -219,7 +219,7 @@ fn test_realpath_when_symlink_is_absolute_and_enoent() { at.mkdir("dir1"); at.symlink_file("dir2/bar", "dir1/foo1"); at.symlink_file("/dir2/bar", "dir1/foo2"); - at.relative_symlink_file("dir2/baz", at.plus("dir1/foo3").to_str().unwrap()); + at.relative_symlink_file("../dir2/baz", "dir1/foo3"); #[cfg(unix)] ucmd.arg("dir1/foo1") @@ -228,7 +228,7 @@ fn test_realpath_when_symlink_is_absolute_and_enoent() { .run() .stdout_contains("/dir2/bar\n") .stdout_contains("/dir2/baz\n") - .stderr_is("realpath: dir1/foo2: No such file or directory"); + .stderr_is("realpath: dir1/foo2: No such file or directory\n"); #[cfg(windows)] ucmd.arg("dir1/foo1") @@ -239,3 +239,25 @@ fn test_realpath_when_symlink_is_absolute_and_enoent() { .stdout_contains("\\dir2\\baz\n") .stderr_is("realpath: dir1/foo2: No such file or directory"); } + +#[test] +#[ignore = "issue #3669"] +fn test_realpath_when_symlink_part_is_missing() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.mkdir("dir2"); + at.touch("dir2/bar"); + + at.mkdir("dir1"); + at.relative_symlink_file("../dir2/bar", "dir1/foo1"); + at.relative_symlink_file("dir2/bar", "dir1/foo2"); + at.relative_symlink_file("../dir2/baz", "dir1/foo3"); + at.symlink_file("dir3/bar", "dir1/foo4"); + + ucmd.args(&["dir1/foo1", "dir1/foo2", "dir1/foo3", "dir1/foo4"]) + .run() + .stdout_contains(at.plus_as_string("dir2/bar") + "\n") + .stdout_contains(at.plus_as_string("dir2/baz") + "\n") + .stderr_contains("realpath: dir1/foo2: No such file or directory\n") + .stderr_contains("realpath: dir1/foo4: No such file or directory\n"); +} diff --git a/tests/common/util.rs b/tests/common/util.rs index 97d435875..cae465d2b 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -702,8 +702,11 @@ impl AtPath { } pub fn relative_symlink_file(&self, original: &str, link: &str) { - log_info("symlink", &format!("{},{}", original, link)); - symlink_file(original, link).unwrap(); + log_info( + "symlink", + &format!("{},{}", original, &self.plus_as_string(link)), + ); + symlink_file(original, &self.plus(link)).unwrap(); } pub fn symlink_dir(&self, original: &str, link: &str) { @@ -718,6 +721,14 @@ impl AtPath { symlink_dir(&self.plus(original), &self.plus(link)).unwrap(); } + pub fn relative_symlink_dir(&self, original: &str, link: &str) { + log_info( + "symlink", + &format!("{},{}", original, &self.plus_as_string(link)), + ); + symlink_dir(original, &self.plus(link)).unwrap(); + } + pub fn is_symlink(&self, path: &str) -> bool { log_info("is_symlink", self.plus_as_string(path)); match fs::symlink_metadata(&self.plus(path)) { diff --git a/tests/fixtures/comm/ab_delimiter_nul.expected b/tests/fixtures/comm/ab_delimiter_nul.expected new file mode 100644 index 000000000..e56ec5cd7 Binary files /dev/null and b/tests/fixtures/comm/ab_delimiter_nul.expected differ