1 Commits

Author SHA1 Message Date
Sylvestre Ledru fe605ff853 ed_diff::tests::test_permutations: disable temporary tests on Windows 2024-04-21 15:52:52 +02:00
16 changed files with 237 additions and 649 deletions
+3 -11
View File
@@ -28,9 +28,6 @@ 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'
@@ -110,10 +107,6 @@ 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'
@@ -123,9 +116,8 @@ jobs:
env:
CARGO_INCREMENTAL: "0"
RUSTC_WRAPPER: ""
RUSTFLAGS: "-Cinstrument-coverage -Zcoverage-options=branch -Ccodegen-units=1 -Copt-level=0 -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -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
@@ -153,9 +145,9 @@ jobs:
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
mkdir -p "${COVERAGE_REPORT_DIR}"
# display coverage files
grcov . --output-type files --binary-path "${COVERAGE_REPORT_DIR}" | sort --unique
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}" --binary-path "${COVERAGE_REPORT_DIR}" --branch
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 "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@v4
+13 -18
View File
@@ -1,4 +1,4 @@
# Copyright 2022-2024, axodotdev
# Copyright 2022-2023, 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.13.3/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/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,15 +105,10 @@ 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
@@ -140,7 +135,7 @@ jobs:
run: |
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
@@ -167,7 +162,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.13.3/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/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
@@ -183,7 +178,7 @@ jobs:
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
@@ -212,7 +207,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.13.3/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.12.0/cargo-dist-installer.sh | sh"
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v4
@@ -220,7 +215,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: |
@@ -235,7 +230,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
@@ -251,7 +246,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-*
@@ -261,7 +256,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
+30 -48
View File
@@ -34,14 +34,13 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "assert_cmd"
version = "2.0.16"
version = "2.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d"
checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8"
dependencies = [
"anstyle",
"bstr",
"doc-comment",
"libc",
"predicates",
"predicates-core",
"predicates-tree",
@@ -123,7 +122,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "diffutils"
version = "0.4.2"
version = "0.4.0"
dependencies = [
"assert_cmd",
"chrono",
@@ -149,7 +148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys",
]
[[package]]
@@ -246,9 +245,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "predicates"
version = "3.1.2"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97"
checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
dependencies = [
"anstyle",
"difflib",
@@ -304,9 +303,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.6"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
@@ -341,7 +340,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys",
]
[[package]]
@@ -386,15 +385,14 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.12.0"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
"windows-sys",
]
[[package]]
@@ -411,9 +409,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.13"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "wait-timeout"
@@ -527,25 +525,15 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
version = "0.52.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
checksum = "d98532992affa02e52709d5b4d145a3668ae10d9081eea4a7f26f719a8476f71"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
@@ -554,51 +542,45 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
checksum = "e7269c1442e75af9fa59290383f7665b828efc76c429cc0b7f2ecb33cf51ebae"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
checksum = "f70ab2cebf332b7ecbdd98900c2da5298a8c862472fb35c75fc297eabb9d89b8"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
checksum = "679f235acf6b1639408c0f6db295697a19d103b0cdc88146aa1b992c580c647d"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
checksum = "3480ac194b55ae274a7e135c21645656825da4a7f5b6e9286291b2113c94a78b"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
checksum = "42c46bab241c121402d1cb47d028ea3680ee2f359dcc287482dcf7fdddc73363"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
checksum = "dc885a4332ee1afb9a1bacf11514801011725570d35675abc229ce7e3afe4d20"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
version = "0.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
checksum = "9e440c60457f84b0bee09208e62acc7ade264b38c4453f6312b8c9ab1613e73c"
[[package]]
name = "yansi"
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "diffutils"
version = "0.4.2"
version = "0.4.0"
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.12"
unicode-width = "0.1.11"
[dev-dependencies]
pretty_assertions = "1.4.0"
pretty_assertions = "1"
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.13.3"
cargo-dist-version = "0.12.0"
# CI backends to support
ci = ["github"]
# The installers to generate for each app
-3
View File
@@ -1,6 +1,3 @@
Copyright (c) Michael Howell
Copyright (c) uutils developers
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
-3
View File
@@ -1,6 +1,3 @@
Copyright (c) Michael Howell
Copyright (c) uutils developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
+1 -1
View File
@@ -9,7 +9,7 @@ edition = "2018"
cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4.7"
libfuzzer-sys = "0.4"
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);
}
}
+21 -18
View File
@@ -178,6 +178,7 @@ mod tests {
}
#[test]
#[cfg(not(windows))]
fn test_permutations() {
let target = "target/ed-diff/";
// test all possible six-line files.
@@ -225,13 +226,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 +240,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);
}
}
@@ -258,6 +259,7 @@ mod tests {
}
#[test]
#[cfg(not(windows))]
fn test_permutations_empty_lines() {
let target = "target/ed-diff/";
// test all possible six-line files with missing newlines.
@@ -299,13 +301,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 +315,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);
}
}
@@ -332,6 +334,7 @@ mod tests {
}
#[test]
#[cfg(not(windows))]
fn test_permutations_reverse() {
let target = "target/ed-diff/";
// test all possible six-line files.
@@ -379,13 +382,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 +396,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);
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
// considering datetime varitations
//
// It replaces the modification time in the actual diff
// with placeholder "TIMESTAMP" and then asserts the equality
// with placeholer "TIMESTAMP" and then asserts the equality
//
// For eg.
// let brief = "*** fruits_old.txt\t2024-03-24 23:43:05.189597645 +0530\n
+4 -29
View File
@@ -4,7 +4,6 @@
// 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;
@@ -19,22 +18,6 @@ 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,
@@ -62,7 +45,6 @@ fn main() -> ExitCode {
maybe_report_identical_files();
return ExitCode::SUCCESS;
}
// read files
fn read_file_contents(filepath: &OsString) -> io::Result<Vec<u8>> {
if filepath == "-" {
@@ -72,27 +54,20 @@ 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) => {
report_failure_to_read_input_file(&params.executable, &params.from, &e);
io_error = true;
vec![]
eprintln!("Failed to read from-file: {e}");
return ExitCode::from(2);
}
};
let to_content = match read_file_contents(&params.to) {
Ok(to_content) => to_content,
Err(e) => {
report_failure_to_read_input_file(&params.executable, &params.to, &e);
io_error = true;
vec![]
eprintln!("Failed to read to-file: {e}");
return ExitCode::from(2);
}
};
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);
}
}
+79 -367
View File
File diff suppressed because it is too large Load Diff
+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);
}
}
+11 -76
View File
@@ -6,9 +6,8 @@
use assert_cmd::cmd::Command;
use diffutilslib::assert_diff_eq;
use predicates::prelude::*;
use std::fs::File;
use std::io::Write;
use tempfile::{tempdir, NamedTempFile};
use tempfile::NamedTempFile;
// Integration tests for the diffutils command
@@ -19,7 +18,7 @@ fn unknown_param() -> Result<(), Box<dyn std::error::Error>> {
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::starts_with("Unknown option: \"--foobar\""));
.stderr(predicate::str::starts_with("Usage: "));
Ok(())
}
@@ -27,44 +26,26 @@ fn unknown_param() -> Result<(), Box<dyn std::error::Error>> {
fn cannot_read_files() -> Result<(), Box<dyn std::error::Error>> {
let file = NamedTempFile::new()?;
let nofile = NamedTempFile::new()?;
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.arg("foo.txt").arg(file.path());
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::ends_with(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
)));
.stderr(predicate::str::starts_with("Failed to read from-file"));
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg(file.path()).arg(&nopath);
cmd.arg(file.path()).arg("foo.txt");
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::ends_with(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
)));
.stderr(predicate::str::starts_with("Failed to read to-file"));
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg(&nopath).arg(&nopath);
cmd.assert().code(predicate::eq(2)).failure().stderr(
predicate::str::contains(format!(
": {}: {error_message}\n",
&nopath.as_os_str().to_string_lossy()
))
.count(2),
);
cmd.arg("foo.txt").arg("foo.txt");
cmd.assert()
.code(predicate::eq(2))
.failure()
.stderr(predicate::str::starts_with("Failed to read from-file"));
Ok(())
}
@@ -253,49 +234,3 @@ fn read_from_stdin() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
#[test]
fn compare_file_to_directory() -> Result<(), Box<dyn std::error::Error>> {
let tmp_dir = tempdir()?;
let directory = tmp_dir.path().join("d");
let _ = std::fs::create_dir(&directory);
let a_path = tmp_dir.path().join("a");
let mut a = File::create(&a_path).unwrap();
a.write_all(b"a\n").unwrap();
let da_path = directory.join("a");
let mut da = File::create(&da_path).unwrap();
da.write_all(b"da\n").unwrap();
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg("-u").arg(&directory).arg(&a_path);
cmd.assert().code(predicate::eq(1)).failure();
let output = cmd.output().unwrap().stdout;
assert_diff_eq!(
output,
format!(
"--- {}\tTIMESTAMP\n+++ {}\tTIMESTAMP\n@@ -1 +1 @@\n-da\n+a\n",
da_path.display(),
a_path.display()
)
);
let mut cmd = Command::cargo_bin("diffutils")?;
cmd.arg("-u").arg(&a_path).arg(&directory);
cmd.assert().code(predicate::eq(1)).failure();
let output = cmd.output().unwrap().stdout;
assert_diff_eq!(
output,
format!(
"--- {}\tTIMESTAMP\n+++ {}\tTIMESTAMP\n@@ -1 +1 @@\n-a\n+da\n",
a_path.display(),
da_path.display()
)
);
Ok(())
}
+1 -1
View File
@@ -19,7 +19,7 @@
# By default it expects a release build of the diffutils binary, but a
# different build profile can be specified as an argument
# (e.g. 'dev' or 'test').
# Unless overridden by the $TESTS environment variable, all tests in the test
# Unless overriden by the $TESTS environment variable, all tests in the test
# suite will be run. Tests targeting a command that is not yet implemented
# (e.g. cmp, diff3 or sdiff) are skipped.