Compare commits

37 Commits

Author SHA1 Message Date
Sylvestre Ledru 9db1eab1d0 Revert "cargo-dist: generate more targets"
This reverts commit 80b993141b.
2024-09-12 10:10:47 +02:00
Sylvestre Ledru 2392acfad1 Merge pull request #84 from cakebaker/fix_clippy_warnings
Fix clippy warnings in tests
2024-09-06 10:05:13 +02:00
Daniel Hofstetter 2a899a9fc7 Fix clippy warnings in tests
from needless_borrows_for_generic_args lint
2024-09-06 09:27:53 +02:00
Sylvestre Ledru 6ec8370b4b Merge pull request #70 from oSoMoN/grcov-instrumentation-based-coverage
Use the instrumentation-based code coverage implementation
2024-09-06 08:54:32 +02:00
Olivier Tilloy dbabf399d5 Use the instrumentation-based code coverage implementation 2024-08-16 00:35:46 +02:00
Daniel Hofstetter b815162b80 Merge pull request #83 from uutils/renovate/assert_cmd-2.x-lockfile
Update Rust crate assert_cmd to v2.0.16
2024-08-09 08:08:54 +02:00
renovate[bot] 12b205e655 Update Rust crate assert_cmd to v2.0.16 2024-08-09 03:18:54 +00:00
Daniel Hofstetter 8a6504dd83 Merge pull request #82 from uutils/renovate/tempfile-3.x-lockfile
Update Rust crate tempfile to v3.12.0
2024-08-07 08:08:29 +02:00
renovate[bot] 67ef43083a Update Rust crate tempfile to v3.12.0 2024-08-06 23:23:06 +00:00
Daniel Hofstetter b1738538a8 Merge pull request #81 from uutils/renovate/tempfile-3.x-lockfile
Update Rust crate tempfile to v3.11.0
2024-08-03 07:01:16 +02:00
renovate[bot] eea6b62b20 Update Rust crate tempfile to v3.11.0 2024-08-02 22:18:35 +00:00
Daniel Hofstetter f08a3bf512 Merge pull request #80 from uutils/renovate/regex-1.x-lockfile
Update Rust crate regex to v1.10.6
2024-08-02 18:41:22 +02:00
renovate[bot] e55ee893dd Update Rust crate regex to v1.10.6 2024-08-02 16:27:14 +00:00
Olivier Tilloy 24245ee098 Merge pull request #78 from uutils/renovate/assert_cmd-2.x-lockfile
Update Rust crate assert_cmd to v2.0.15
2024-07-28 15:12:16 +00:00
Olivier Tilloy 11f815a7c2 Merge pull request #79 from uutils/renovate/predicates-3.x-lockfile
Update Rust crate predicates to v3.1.2
2024-07-28 15:11:13 +00:00
renovate[bot] e9a8141618 Update Rust crate predicates to v3.1.2 2024-07-25 17:59:30 +00:00
renovate[bot] c9a756eb43 Update Rust crate assert_cmd to v2.0.15 2024-07-25 14:28:54 +00:00
Sylvestre Ledru 468c4bf934 Merge pull request #63 from oSoMoN/io-error-msg
Make error message consistent with GNU diff's implementation when failing to read input file(s)
2024-06-27 14:16:10 +02:00
Daniel Hofstetter 1e8fdd58d9 Merge pull request #77 from uutils/renovate/regex-1.x-lockfile
Update Rust crate regex to v1.10.5
2024-06-09 15:59:55 +02:00
renovate[bot] e98b5e179e Update Rust crate regex to v1.10.5 2024-06-09 13:30:51 +00:00
Sylvestre Ledru 1901982375 Merge pull request #76 from uutils/renovate/unicode-width-0.x-lockfile
Update Rust crate unicode-width to v0.1.13
2024-06-04 20:40:56 +02:00
renovate[bot] eee6f49920 Update Rust crate unicode-width to v0.1.13 2024-06-04 17:06:50 +00:00
Olivier Tilloy 8a3a977d2c Update the expected error message for Windows 2024-06-04 14:57:50 +02:00
Olivier Tilloy fa4e0c6097 Make error message consistent with GNU diff's implementation when failing to read input file(s) 2024-06-04 14:57:50 +02:00
Sylvestre Ledru d362046ae5 release v0.4.2 2024-05-19 19:09:05 +02:00
Daniel Hofstetter 7964afa336 Merge pull request #74 from uutils/cargo-dist
cargo-dist: generate more targets
2024-05-19 12:40:07 +02:00
Sylvestre Ledru 80b993141b cargo-dist: generate more targets 2024-05-19 11:59:26 +02:00
Daniel Hofstetter d922313c8c Merge pull request #71 from uutils/renovate/libfuzzer-sys-0.x
Update Rust crate libfuzzer-sys to 0.4.7
2024-05-01 13:37:01 +02:00
Daniel Hofstetter 3e246ab36c Merge pull request #72 from uutils/renovate/pretty_assertions-1.x
Update Rust crate pretty_assertions to 1.4.0
2024-05-01 13:29:09 +02:00
renovate[bot] 4b70969ff1 Update Rust crate pretty_assertions to 1.4.0 2024-05-01 09:56:55 +00:00
renovate[bot] 767c6f6c4a Update Rust crate libfuzzer-sys to 0.4.7 2024-05-01 09:56:50 +00:00
Sylvestre Ledru 1f896ca1ac Merge pull request #69 from oSoMoN/cargo-dist-version-0.13.3
CI: Update 'cargo dist' to version 0.13.3
2024-05-01 08:31:36 +02:00
Olivier Tilloy 713bd210ab CI: Update 'cargo dist' to version 0.13.3 2024-04-30 23:55:49 +02:00
Olivier Tilloy 61314eaf4e Merge pull request #65 from uutils/renovate/unicode-width-0.x
Update Rust crate unicode-width to 0.1.12
2024-04-30 18:47:39 +02:00
renovate[bot] bf9147733d Update Rust crate unicode-width to 0.1.12 2024-04-30 05:30:32 +00:00
Daniel Hofstetter ce8457cbdb Merge pull request #67 from oSoMoN/macos-ci-install-gpatch
CI: install GNU patch on MacOS (fixes #66)
2024-04-30 07:14:02 +02:00
Olivier Tilloy df778c610b CI: install GNU patch on MacOS (fixes #66) 2024-04-29 22:55:08 +02:00
12 changed files with 268 additions and 155 deletions
+11 -3
View File
@@ -28,6 +28,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: install GNU patch on MacOS
if: runner.os == 'macOS'
run: brew install gpatch
- name: set up PATH on Windows
# Needed to use GNU's patch.exe instead of Strawberry Perl patch
if: runner.os == 'Windows'
@@ -107,6 +110,10 @@ jobs:
- name: rust toolchain ~ install
uses: dtolnay/rust-toolchain@nightly
- run: rustup component add llvm-tools-preview
- name: install GNU patch on MacOS
if: runner.os == 'macOS'
run: brew install gpatch
- name: set up PATH on Windows
# Needed to use GNU's patch.exe instead of Strawberry Perl patch
if: runner.os == 'Windows'
@@ -116,8 +123,9 @@ jobs:
env:
CARGO_INCREMENTAL: "0"
RUSTC_WRAPPER: ""
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTFLAGS: "-Cinstrument-coverage -Zcoverage-options=branch -Ccodegen-units=1 -Copt-level=0 -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTDOCFLAGS: "-Cpanic=abort"
LLVM_PROFILE_FILE: "diffutils-%p-%m.profraw"
- name: "`grcov` ~ install"
id: build_grcov
shell: bash
@@ -145,9 +153,9 @@ jobs:
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
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
grcov . --output-type files --binary-path "${COVERAGE_REPORT_DIR}" | 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\()"
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --binary-path "${COVERAGE_REPORT_DIR}" --branch
echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@v4
+18 -13
View File
@@ -1,4 +1,4 @@
# Copyright 2022-2023, axodotdev
# Copyright 2022-2024, axodotdev
# SPDX-License-Identifier: MIT or Apache-2.0
#
# CI that:
@@ -6,9 +6,9 @@
# * checks for a Git Tag that looks like a release
# * builds artifacts with cargo-dist (archives, installers, hashes)
# * uploads those artifacts to temporary workflow zip
# * on success, uploads the artifacts to a Github Release
# * on success, uploads the artifacts to a GitHub Release
#
# Note that the Github Release will be created with a generated
# Note that the GitHub Release will be created with a generated
# title/body based on your changelogs.
name: Release
@@ -31,7 +31,7 @@ permissions:
# packages versioned/released in lockstep).
#
# If you push multiple tags at once, separate instances of this workflow will
# spin up, creating an independent announcement for each one. However Github
# spin up, creating an independent announcement for each one. However, GitHub
# will hard limit this to 3 tags per commit, as it will assume more tags is a
# mistake.
#
@@ -62,7 +62,7 @@ jobs:
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.13.3/cargo-dist-installer.sh | sh"
# sure would be cool if github gave us proper conditionals...
# so here's a doubly-nested ternary-via-truthiness to try to provide the best possible
# functionality based on whether this is a pull_request, and whether it's from a fork.
@@ -105,10 +105,15 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json
steps:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: swatinem/rust-cache@v2
with:
key: ${{ join(matrix.targets, '-') }}
- name: Install cargo-dist
run: ${{ matrix.install_dist }}
# Get the dist-manifest
@@ -135,7 +140,7 @@ jobs:
run: |
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
@@ -162,7 +167,7 @@ jobs:
submodules: recursive
- name: Install cargo-dist
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.13.3/cargo-dist-installer.sh | sh"
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v4
@@ -178,7 +183,7 @@ jobs:
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
@@ -207,7 +212,7 @@ jobs:
with:
submodules: recursive
- name: Install cargo-dist
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.13.3/cargo-dist-installer.sh | sh"
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v4
@@ -215,7 +220,7 @@ jobs:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
# This is a harmless no-op for Github Releases, hosting for that happens in "announce"
# This is a harmless no-op for GitHub Releases, hosting for that happens in "announce"
- id: host
shell: bash
run: |
@@ -230,7 +235,7 @@ jobs:
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a Github Release while uploading all files to it
# Create a GitHub Release while uploading all files to it
announce:
needs:
- plan
@@ -246,7 +251,7 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: "Download Github Artifacts"
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
@@ -256,7 +261,7 @@ jobs:
run: |
# Remove the granular manifests
rm -f artifacts/*-dist-manifest.json
- name: Create Github Release
- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
tag: ${{ needs.plan.outputs.tag }}
Generated
+49 -31
View File
@@ -34,13 +34,14 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "assert_cmd"
version = "2.0.14"
version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8"
checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d"
dependencies = [
"anstyle",
"bstr",
"doc-comment",
"libc",
"predicates",
"predicates-core",
"predicates-tree",
@@ -122,7 +123,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "diffutils"
version = "0.4.1"
version = "0.4.2"
dependencies = [
"assert_cmd",
"chrono",
@@ -148,7 +149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.52.0",
]
[[package]]
@@ -245,9 +246,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "predicates"
version = "3.1.0"
version = "3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97"
dependencies = [
"anstyle",
"difflib",
@@ -303,9 +304,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.4"
version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
@@ -340,7 +341,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.52.0",
]
[[package]]
@@ -385,14 +386,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.10.1"
version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@@ -409,9 +411,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.11"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "wait-timeout"
@@ -526,14 +528,24 @@ dependencies = [
]
[[package]]
name = "windows-targets"
version = "0.52.2"
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98532992affa02e52709d5b4d145a3668ae10d9081eea4a7f26f719a8476f71"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
@@ -542,45 +554,51 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7269c1442e75af9fa59290383f7665b828efc76c429cc0b7f2ecb33cf51ebae"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f70ab2cebf332b7ecbdd98900c2da5298a8c862472fb35c75fc297eabb9d89b8"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "679f235acf6b1639408c0f6db295697a19d103b0cdc88146aa1b992c580c647d"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3480ac194b55ae274a7e135c21645656825da4a7f5b6e9286291b2113c94a78b"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42c46bab241c121402d1cb47d028ea3680ee2f359dcc287482dcf7fdddc73363"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc885a4332ee1afb9a1bacf11514801011725570d35675abc229ce7e3afe4d20"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.1"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e440c60457f84b0bee09208e62acc7ade264b38c4453f6312b8c9ab1613e73c"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "yansi"
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "diffutils"
version = "0.4.1"
version = "0.4.2"
edition = "2021"
description = "A CLI app for generating diff files"
license = "MIT OR Apache-2.0"
@@ -19,10 +19,10 @@ chrono = "0.4.38"
diff = "0.1.13"
regex = "1.10.4"
same-file = "1.0.6"
unicode-width = "0.1.11"
unicode-width = "0.1.12"
[dev-dependencies]
pretty_assertions = "1"
pretty_assertions = "1.4.0"
assert_cmd = "2.0.14"
predicates = "3.1.0"
tempfile = "3.10.1"
@@ -35,7 +35,7 @@ lto = "thin"
# Config for 'cargo dist'
[workspace.metadata.dist]
# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax)
cargo-dist-version = "0.12.0"
cargo-dist-version = "0.13.3"
# CI backends to support
ci = ["github"]
# The installers to generate for each app
+1 -1
View File
@@ -9,7 +9,7 @@ edition = "2018"
cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
libfuzzer-sys = "0.4.7"
diffutils = { path = "../" }
# Prevent this from interfering with workspaces
+20 -20
View File
@@ -439,26 +439,26 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/ab.diff"))
File::create(format!("{target}/ab.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef")).unwrap();
let mut fa = File::create(format!("{target}/alef")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet")).unwrap();
let mut fb = File::create(format!("{target}/bet")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg("--context")
.stdin(File::open(&format!("{target}/ab.diff")).unwrap())
.stdin(File::open(format!("{target}/ab.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alef")).unwrap();
let alef = fs::read(format!("{target}/alef")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -520,26 +520,26 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/ab_.diff"))
File::create(format!("{target}/ab_.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef_")).unwrap();
let mut fa = File::create(format!("{target}/alef_")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet_")).unwrap();
let mut fb = File::create(format!("{target}/bet_")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg("--context")
.stdin(File::open(&format!("{target}/ab_.diff")).unwrap())
.stdin(File::open(format!("{target}/ab_.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alef_")).unwrap();
let alef = fs::read(format!("{target}/alef_")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -604,26 +604,26 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/abx.diff"))
File::create(format!("{target}/abx.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefx")).unwrap();
let mut fa = File::create(format!("{target}/alefx")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betx")).unwrap();
let mut fb = File::create(format!("{target}/betx")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg("--context")
.stdin(File::open(&format!("{target}/abx.diff")).unwrap())
.stdin(File::open(format!("{target}/abx.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefx")).unwrap();
let alef = fs::read(format!("{target}/alefx")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -691,26 +691,26 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/abr.diff"))
File::create(format!("{target}/abr.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefr")).unwrap();
let mut fa = File::create(format!("{target}/alefr")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betr")).unwrap();
let mut fb = File::create(format!("{target}/betr")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg("--context")
.stdin(File::open(&format!("{target}/abr.diff")).unwrap())
.stdin(File::open(format!("{target}/abr.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefr")).unwrap();
let alef = fs::read(format!("{target}/alefr")).unwrap();
assert_eq!(alef, bet);
}
}
+18 -18
View File
@@ -225,13 +225,13 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff_w(&alef, &bet, &format!("{target}/alef")).unwrap();
File::create(&format!("{target}/ab.ed"))
File::create(format!("{target}/ab.ed"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef")).unwrap();
let mut fa = File::create(format!("{target}/alef")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet")).unwrap();
let mut fb = File::create(format!("{target}/bet")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
@@ -239,14 +239,14 @@ mod tests {
{
use std::process::Command;
let output = Command::new("ed")
.arg(&format!("{target}/alef"))
.stdin(File::open(&format!("{target}/ab.ed")).unwrap())
.arg(format!("{target}/alef"))
.stdin(File::open(format!("{target}/ab.ed")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = std::fs::read(&format!("{target}/alef")).unwrap();
let alef = std::fs::read(format!("{target}/alef")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -299,13 +299,13 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff_w(&alef, &bet, &format!("{target}/alef_")).unwrap();
File::create(&format!("{target}/ab_.ed"))
File::create(format!("{target}/ab_.ed"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef_")).unwrap();
let mut fa = File::create(format!("{target}/alef_")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet_")).unwrap();
let mut fb = File::create(format!("{target}/bet_")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
@@ -313,14 +313,14 @@ mod tests {
{
use std::process::Command;
let output = Command::new("ed")
.arg(&format!("{target}/alef_"))
.stdin(File::open(&format!("{target}/ab_.ed")).unwrap())
.arg(format!("{target}/alef_"))
.stdin(File::open(format!("{target}/ab_.ed")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = std::fs::read(&format!("{target}/alef_")).unwrap();
let alef = std::fs::read(format!("{target}/alef_")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -379,13 +379,13 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff_w(&alef, &bet, &format!("{target}/alefr")).unwrap();
File::create(&format!("{target}/abr.ed"))
File::create(format!("{target}/abr.ed"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefr")).unwrap();
let mut fa = File::create(format!("{target}/alefr")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betr")).unwrap();
let mut fb = File::create(format!("{target}/betr")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
@@ -393,14 +393,14 @@ mod tests {
{
use std::process::Command;
let output = Command::new("ed")
.arg(&format!("{target}/alefr"))
.stdin(File::open(&format!("{target}/abr.ed")).unwrap())
.arg(format!("{target}/alefr"))
.stdin(File::open(format!("{target}/abr.ed")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = std::fs::read(&format!("{target}/alefr")).unwrap();
let alef = std::fs::read(format!("{target}/alefr")).unwrap();
assert_eq!(alef, bet);
}
}
+29 -4
View File
@@ -4,6 +4,7 @@
// files that was distributed with this source code.
use crate::params::{parse_params, Format};
use regex::Regex;
use std::env;
use std::ffi::OsString;
use std::fs;
@@ -18,6 +19,22 @@ mod params;
mod unified_diff;
mod utils;
fn report_failure_to_read_input_file(
executable: &OsString,
filepath: &OsString,
error: &std::io::Error,
) {
// std::io::Error's display trait outputs "{detail} (os error {code})"
// but we want only the {detail} (error string) part
let error_code_re = Regex::new(r"\ \(os\ error\ \d+\)$").unwrap();
eprintln!(
"{}: {}: {}",
executable.to_string_lossy(),
filepath.to_string_lossy(),
error_code_re.replace(error.to_string().as_str(), ""),
);
}
// Exit codes are documented at
// https://www.gnu.org/software/diffutils/manual/html_node/Invoking-diff.html.
// An exit status of 0 means no differences were found,
@@ -45,6 +62,7 @@ fn main() -> ExitCode {
maybe_report_identical_files();
return ExitCode::SUCCESS;
}
// read files
fn read_file_contents(filepath: &OsString) -> io::Result<Vec<u8>> {
if filepath == "-" {
@@ -54,20 +72,27 @@ fn main() -> ExitCode {
fs::read(filepath)
}
}
let mut io_error = false;
let from_content = match read_file_contents(&params.from) {
Ok(from_content) => from_content,
Err(e) => {
eprintln!("Failed to read from-file: {e}");
return ExitCode::from(2);
report_failure_to_read_input_file(&params.executable, &params.from, &e);
io_error = true;
vec![]
}
};
let to_content = match read_file_contents(&params.to) {
Ok(to_content) => to_content,
Err(e) => {
eprintln!("Failed to read to-file: {e}");
return ExitCode::from(2);
report_failure_to_read_input_file(&params.executable, &params.to, &e);
io_error = true;
vec![]
}
};
if io_error {
return ExitCode::from(2);
}
// run diff
let result: Vec<u8> = match params.format {
Format::Normal => normal_diff::diff(&from_content, &to_content, &params),
+24 -24
View File
@@ -275,26 +275,26 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, &Params::default());
File::create(&format!("{target}/ab.diff"))
File::create(format!("{target}/ab.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef")).unwrap();
let mut fa = File::create(format!("{target}/alef")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet")).unwrap();
let mut fb = File::create(format!("{target}/bet")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg(&format!("{target}/alef"))
.stdin(File::open(&format!("{target}/ab.diff")).unwrap())
.arg(format!("{target}/alef"))
.stdin(File::open(format!("{target}/ab.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alef")).unwrap();
let alef = fs::read(format!("{target}/alef")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -367,27 +367,27 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, &Params::default());
File::create(&format!("{target}/abn.diff"))
File::create(format!("{target}/abn.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefn")).unwrap();
let mut fa = File::create(format!("{target}/alefn")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betn")).unwrap();
let mut fb = File::create(format!("{target}/betn")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg("--normal")
.arg(&format!("{target}/alefn"))
.stdin(File::open(&format!("{target}/abn.diff")).unwrap())
.arg(format!("{target}/alefn"))
.stdin(File::open(format!("{target}/abn.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefn")).unwrap();
let alef = fs::read(format!("{target}/alefn")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -441,26 +441,26 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, &Params::default());
File::create(&format!("{target}/ab_.diff"))
File::create(format!("{target}/ab_.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef_")).unwrap();
let mut fa = File::create(format!("{target}/alef_")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet_")).unwrap();
let mut fb = File::create(format!("{target}/bet_")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg(&format!("{target}/alef_"))
.stdin(File::open(&format!("{target}/ab_.diff")).unwrap())
.arg(format!("{target}/alef_"))
.stdin(File::open(format!("{target}/ab_.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alef_")).unwrap();
let alef = fs::read(format!("{target}/alef_")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -519,26 +519,26 @@ mod tests {
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, &Params::default());
File::create(&format!("{target}/abr.diff"))
File::create(format!("{target}/abr.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefr")).unwrap();
let mut fa = File::create(format!("{target}/alefr")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betr")).unwrap();
let mut fb = File::create(format!("{target}/betr")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.arg(&format!("{target}/alefr"))
.stdin(File::open(&format!("{target}/abr.diff")).unwrap())
.arg(format!("{target}/alefr"))
.stdin(File::open(format!("{target}/abr.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefr")).unwrap();
let alef = fs::read(format!("{target}/alefr")).unwrap();
assert_eq!(alef, bet);
}
}
+49 -6
View File
@@ -14,6 +14,7 @@ pub enum Format {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Params {
pub executable: OsString,
pub from: OsString,
pub to: OsString,
pub format: Format,
@@ -27,6 +28,7 @@ pub struct Params {
impl Default for Params {
fn default() -> Self {
Self {
executable: OsString::default(),
from: OsString::default(),
to: OsString::default(),
format: Format::default(),
@@ -43,10 +45,13 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
let mut opts = opts.into_iter().peekable();
// parse CLI
let Some(exe) = opts.next() else {
let Some(executable) = opts.next() else {
return Err("Usage: <exe> <from> <to>".to_string());
};
let mut params = Params::default();
let mut params = Params {
executable,
..Default::default()
};
let mut from = None;
let mut to = None;
let mut format = None;
@@ -63,7 +68,10 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
} else if to.is_none() {
to = Some(param);
} else {
return Err(format!("Usage: {} <from> <to>", exe.to_string_lossy()));
return Err(format!(
"Usage: {} <from> <to>",
params.executable.to_string_lossy()
));
}
continue;
}
@@ -155,7 +163,10 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
} else if to.is_none() {
to = Some(param);
} else {
return Err(format!("Usage: {} <from> <to>", exe.to_string_lossy()));
return Err(format!(
"Usage: {} <from> <to>",
params.executable.to_string_lossy()
));
}
}
params.from = if let Some(from) = from {
@@ -163,14 +174,20 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
} else if let Some(param) = opts.next() {
param
} else {
return Err(format!("Usage: {} <from> <to>", exe.to_string_lossy()));
return Err(format!(
"Usage: {} <from> <to>",
params.executable.to_string_lossy()
));
};
params.to = if let Some(to) = to {
to
} else if let Some(param) = opts.next() {
param
} else {
return Err(format!("Usage: {} <from> <to>", exe.to_string_lossy()));
return Err(format!(
"Usage: {} <from> <to>",
params.executable.to_string_lossy()
));
};
// diff DIRECTORY FILE => diff DIRECTORY/FILE FILE
@@ -301,6 +318,7 @@ mod tests {
fn basics() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -309,6 +327,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -325,6 +344,7 @@ mod tests {
for arg in ["-e", "--ed"] {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Ed,
@@ -342,6 +362,7 @@ mod tests {
params.extend(["foo", "bar"]);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Context,
@@ -362,6 +383,7 @@ mod tests {
params.extend(["foo", "bar"]);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Context,
@@ -399,6 +421,7 @@ mod tests {
params.extend(["foo", "bar"]);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Unified,
@@ -419,6 +442,7 @@ mod tests {
params.extend(["foo", "bar"]);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Unified,
@@ -452,6 +476,7 @@ mod tests {
fn context_count() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Unified,
@@ -466,6 +491,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Unified,
@@ -480,6 +506,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Unified,
@@ -494,6 +521,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
format: Format::Context,
@@ -511,6 +539,7 @@ mod tests {
fn report_identical_files() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -519,6 +548,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
report_identical_files: true,
@@ -528,6 +558,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
report_identical_files: true,
@@ -549,6 +580,7 @@ mod tests {
fn brief() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -557,6 +589,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
brief: true,
@@ -566,6 +599,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
brief: true,
@@ -582,6 +616,7 @@ mod tests {
fn expand_tabs() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -591,6 +626,7 @@ mod tests {
for option in ["-t", "--expand-tabs"] {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
expand_tabs: true,
@@ -608,6 +644,7 @@ mod tests {
fn tabsize() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
..Default::default()
@@ -616,6 +653,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
tabsize: 0,
@@ -629,6 +667,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("bar"),
tabsize: 42,
@@ -686,6 +725,7 @@ mod tests {
fn double_dash() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("-g"),
to: os("-h"),
..Default::default()
@@ -697,6 +737,7 @@ mod tests {
fn default_to_stdin() {
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("foo"),
to: os("-"),
..Default::default()
@@ -705,6 +746,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("-"),
to: os("bar"),
..Default::default()
@@ -713,6 +755,7 @@ mod tests {
);
assert_eq!(
Ok(Params {
executable: os("diff"),
from: os("-"),
to: os("-"),
..Default::default()
+25 -25
View File
@@ -466,13 +466,13 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/ab.diff"))
File::create(format!("{target}/ab.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef")).unwrap();
let mut fa = File::create(format!("{target}/alef")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet")).unwrap();
let mut fb = File::create(format!("{target}/bet")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
@@ -494,13 +494,13 @@ mod tests {
let output = Command::new("patch")
.arg("-p0")
.stdin(File::open(&format!("{target}/ab.diff")).unwrap())
.stdin(File::open(format!("{target}/ab.diff")).unwrap())
.output()
.unwrap();
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("{}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success(), "{output:?}");
let alef = fs::read(&format!("{target}/alef")).unwrap();
let alef = fs::read(format!("{target}/alef")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -582,25 +582,25 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/abn.diff"))
File::create(format!("{target}/abn.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefn")).unwrap();
let mut fa = File::create(format!("{target}/alefn")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betn")).unwrap();
let mut fb = File::create(format!("{target}/betn")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.stdin(File::open(&format!("{target}/abn.diff")).unwrap())
.stdin(File::open(format!("{target}/abn.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefn")).unwrap();
let alef = fs::read(format!("{target}/alefn")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -678,25 +678,25 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/ab_.diff"))
File::create(format!("{target}/ab_.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alef_")).unwrap();
let mut fa = File::create(format!("{target}/alef_")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/bet_")).unwrap();
let mut fb = File::create(format!("{target}/bet_")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.stdin(File::open(&format!("{target}/ab_.diff")).unwrap())
.stdin(File::open(format!("{target}/ab_.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alef_")).unwrap();
let alef = fs::read(format!("{target}/alef_")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -759,25 +759,25 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/abx.diff"))
File::create(format!("{target}/abx.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefx")).unwrap();
let mut fa = File::create(format!("{target}/alefx")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betx")).unwrap();
let mut fb = File::create(format!("{target}/betx")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.stdin(File::open(&format!("{target}/abx.diff")).unwrap())
.stdin(File::open(format!("{target}/abx.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefx")).unwrap();
let alef = fs::read(format!("{target}/alefx")).unwrap();
assert_eq!(alef, bet);
}
}
@@ -845,25 +845,25 @@ mod tests {
..Default::default()
},
);
File::create(&format!("{target}/abr.diff"))
File::create(format!("{target}/abr.diff"))
.unwrap()
.write_all(&diff)
.unwrap();
let mut fa = File::create(&format!("{target}/alefr")).unwrap();
let mut fa = File::create(format!("{target}/alefr")).unwrap();
fa.write_all(&alef[..]).unwrap();
let mut fb = File::create(&format!("{target}/betr")).unwrap();
let mut fb = File::create(format!("{target}/betr")).unwrap();
fb.write_all(&bet[..]).unwrap();
let _ = fa;
let _ = fb;
let output = Command::new("patch")
.arg("-p0")
.stdin(File::open(&format!("{target}/abr.diff")).unwrap())
.stdin(File::open(format!("{target}/abr.diff")).unwrap())
.output()
.unwrap();
assert!(output.status.success(), "{output:?}");
//println!("{}", String::from_utf8_lossy(&output.stdout));
//println!("{}", String::from_utf8_lossy(&output.stderr));
let alef = fs::read(&format!("{target}/alefr")).unwrap();
let alef = fs::read(format!("{target}/alefr")).unwrap();
assert_eq!(alef, bet);
}
}
+20 -6
View File
@@ -31,26 +31,40 @@ fn cannot_read_files() -> Result<(), Box<dyn std::error::Error>> {
let nopath = nofile.into_temp_path();
std::fs::remove_file(&nopath)?;
#[cfg(not(windows))]
let error_message = "No such file or directory";
#[cfg(windows)]
let error_message = "The system cannot find the file specified.";
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg(&nopath).arg(file.path());
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::starts_with("Failed to read from-file"));
.stderr(predicate::str::ends_with(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
)));
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg(file.path()).arg(&nopath);
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::starts_with("Failed to read to-file"));
.stderr(predicate::str::ends_with(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
)));
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg(&nopath).arg(&nopath);
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::starts_with("Failed to read from-file"));
cmd.assert().code(predicate::eq(2)).failure().stderr(
predicate::str::contains(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
))
.count(2),
);
Ok(())
}