mirror of
https://github.com/uutils/diffutils.git
synced 2026-06-10 15:48:59 -07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c3b3f7dfa6 |
@@ -1,100 +0,0 @@
|
|||||||
name: GnuComment
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: ["GnuTests"]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
permissions: {}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
post-comment:
|
|
||||||
permissions:
|
|
||||||
actions: read # to list workflow runs artifacts
|
|
||||||
pull-requests: write # to comment on pr
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: >
|
|
||||||
github.event.workflow_run.event == 'pull_request'
|
|
||||||
steps:
|
|
||||||
- name: 'Download artifact'
|
|
||||||
uses: actions/github-script@v9
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
// List all artifacts from GnuTests
|
|
||||||
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
run_id: ${{ github.event.workflow_run.id }},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Download the "comment" artifact, which contains a PR number (NR) and result.txt
|
|
||||||
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
|
|
||||||
return artifact.name == "comment"
|
|
||||||
})[0];
|
|
||||||
|
|
||||||
if (!matchArtifact) {
|
|
||||||
console.log('No comment artifact found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var download = await github.rest.actions.downloadArtifact({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
artifact_id: matchArtifact.id,
|
|
||||||
archive_format: 'zip',
|
|
||||||
});
|
|
||||||
var fs = require('fs');
|
|
||||||
fs.writeFileSync('${{ github.workspace }}/comment.zip', Buffer.from(download.data));
|
|
||||||
|
|
||||||
- run: unzip comment.zip || echo "Failed to unzip comment artifact"
|
|
||||||
|
|
||||||
- name: 'Comment on PR'
|
|
||||||
uses: actions/github-script@v9
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
script: |
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
// Check if files exist
|
|
||||||
if (!fs.existsSync('./NR')) {
|
|
||||||
console.log('No NR file found, skipping comment');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!fs.existsSync('./result.txt')) {
|
|
||||||
console.log('No result.txt file found, skipping comment');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var issue_number = Number(fs.readFileSync('./NR'));
|
|
||||||
var content = fs.readFileSync('./result.txt');
|
|
||||||
|
|
||||||
if (content.toString().trim().length > 7) { // 7 because we have backquote + \n
|
|
||||||
// Update existing comment if present, otherwise create a new one
|
|
||||||
var marker = '<!-- gnu-tests-bot -->';
|
|
||||||
var body = marker + '\nGNU diffutils testsuite comparison:\n```\n' + content + '```';
|
|
||||||
var comments = await github.rest.issues.listComments({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
issue_number: issue_number,
|
|
||||||
});
|
|
||||||
var existing = comments.data.filter(c => c.body.includes(marker))[0];
|
|
||||||
if (existing) {
|
|
||||||
await github.rest.issues.updateComment({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
comment_id: existing.id,
|
|
||||||
body: body,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await github.rest.issues.createComment({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
issue_number: issue_number,
|
|
||||||
body: body,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Comment content too short, skipping');
|
|
||||||
}
|
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
name: GnuTests
|
|
||||||
|
|
||||||
# Run GNU diffutils testsuite against the Rust diffutils implementation
|
|
||||||
# and compare results against the main branch to catch regressions
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write # Publish diffutils instead of discarding
|
|
||||||
|
|
||||||
# End the current execution if there is a new changeset in the PR
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
||||||
|
|
||||||
env:
|
|
||||||
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
|
||||||
TEST_FULL_SUMMARY_FILE: 'diffutils-gnu-full-result.json'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
native:
|
|
||||||
name: Run GNU diffutils testsuite
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- uses: dtolnay/rust-toolchain@master
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
|
|
||||||
### Build
|
|
||||||
- name: Build Rust diffutils binary
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## Build Rust diffutils binary
|
|
||||||
cargo build --config=profile.release.strip=true --profile=release
|
|
||||||
zstd -19 target/release/diffutils -o diffutils-x86_64-unknown-linux-gnu.zst
|
|
||||||
|
|
||||||
- name: Publish latest commit
|
|
||||||
uses: softprops/action-gh-release@v3
|
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
||||||
with:
|
|
||||||
tag_name: latest-commit
|
|
||||||
body: |
|
|
||||||
commit: ${{ github.sha }}
|
|
||||||
draft: false
|
|
||||||
prerelease: true
|
|
||||||
files: |
|
|
||||||
diffutils-x86_64-unknown-linux-gnu.zst
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
### Run tests
|
|
||||||
- name: Run GNU diffutils testsuite
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## Run GNU diffutils testsuite
|
|
||||||
./tests/run-upstream-testsuite.sh release || true
|
|
||||||
env:
|
|
||||||
TERM: xterm
|
|
||||||
|
|
||||||
- name: Upload full json results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: diffutils-gnu-full-result
|
|
||||||
path: tests/test-results.json
|
|
||||||
if-no-files-found: warn
|
|
||||||
|
|
||||||
aggregate:
|
|
||||||
needs: [native]
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
pull-requests: read
|
|
||||||
name: Aggregate GNU test results
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
steps:
|
|
||||||
- name: Initialize workflow variables
|
|
||||||
id: vars
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## VARs setup
|
|
||||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
|
||||||
|
|
||||||
TEST_SUMMARY_FILE='diffutils-gnu-result.json'
|
|
||||||
outputs TEST_SUMMARY_FILE
|
|
||||||
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Retrieve reference artifacts
|
|
||||||
uses: dawidd6/action-download-artifact@v21
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
workflow: GnuTests.yml
|
|
||||||
branch: "${{ env.DEFAULT_BRANCH }}"
|
|
||||||
workflow_conclusion: completed
|
|
||||||
path: "reference"
|
|
||||||
if_no_artifact_found: warn
|
|
||||||
|
|
||||||
- name: Download full json results
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: diffutils-gnu-full-result
|
|
||||||
path: results
|
|
||||||
|
|
||||||
- name: Extract/summarize testing info
|
|
||||||
id: summary
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## Extract/summarize testing info
|
|
||||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
|
||||||
|
|
||||||
RESULT_FILE="results/test-results.json"
|
|
||||||
if [[ ! -f "$RESULT_FILE" ]]; then
|
|
||||||
echo "::error ::Missing test results at $RESULT_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TOTAL=$(jq '[.tests[]] | length' "$RESULT_FILE")
|
|
||||||
PASS=$(jq '[.tests[] | select(.result=="PASS")] | length' "$RESULT_FILE")
|
|
||||||
FAIL=$(jq '[.tests[] | select(.result=="FAIL")] | length' "$RESULT_FILE")
|
|
||||||
SKIP=$(jq '[.tests[] | select(.result=="SKIP")] | length' "$RESULT_FILE")
|
|
||||||
ERROR=0
|
|
||||||
|
|
||||||
output="GNU diffutils tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / SKIP: $SKIP"
|
|
||||||
echo "${output}"
|
|
||||||
|
|
||||||
if [[ "$FAIL" -gt 0 ]]; then
|
|
||||||
echo "::warning ::${output}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
jq -n \
|
|
||||||
--arg date "$(date --rfc-email)" \
|
|
||||||
--arg sha "$GITHUB_SHA" \
|
|
||||||
--arg total "$TOTAL" \
|
|
||||||
--arg pass "$PASS" \
|
|
||||||
--arg skip "$SKIP" \
|
|
||||||
--arg fail "$FAIL" \
|
|
||||||
--arg error "$ERROR" \
|
|
||||||
'{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, error: $error }}' > '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}'
|
|
||||||
|
|
||||||
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
|
|
||||||
outputs HASH TOTAL PASS FAIL SKIP
|
|
||||||
|
|
||||||
- name: Upload SHA1/ID of 'test-summary'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: "${{ steps.summary.outputs.HASH }}"
|
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
|
||||||
|
|
||||||
- name: Upload test results summary
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: test-summary
|
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
|
||||||
|
|
||||||
- name: Compare test failures VS reference
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## Compare test failures VS reference
|
|
||||||
REF_SUMMARY_FILE='reference/diffutils-gnu-full-result/test-results.json'
|
|
||||||
CURRENT_SUMMARY_FILE="results/test-results.json"
|
|
||||||
|
|
||||||
IGNORE_INTERMITTENT=".github/workflows/ignore-intermittent.txt"
|
|
||||||
|
|
||||||
COMMENT_DIR="reference/comment"
|
|
||||||
mkdir -p ${COMMENT_DIR}
|
|
||||||
echo ${{ github.event.number }} > ${COMMENT_DIR}/NR
|
|
||||||
COMMENT_LOG="${COMMENT_DIR}/result.txt"
|
|
||||||
|
|
||||||
COMPARISON_RESULT=0
|
|
||||||
if test -f "${CURRENT_SUMMARY_FILE}"; then
|
|
||||||
if test -f "${REF_SUMMARY_FILE}"; then
|
|
||||||
echo "Reference summary SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")"
|
|
||||||
echo "Current summary SHA1/ID: $(sha1sum -- "${CURRENT_SUMMARY_FILE}")"
|
|
||||||
|
|
||||||
python3 util/compare_test_results.py \
|
|
||||||
--ignore-file "${IGNORE_INTERMITTENT}" \
|
|
||||||
--output "${COMMENT_LOG}" \
|
|
||||||
"${CURRENT_SUMMARY_FILE}" "${REF_SUMMARY_FILE}"
|
|
||||||
|
|
||||||
COMPARISON_RESULT=$?
|
|
||||||
else
|
|
||||||
echo "::warning ::Skipping test comparison; no prior reference summary is available at '${REF_SUMMARY_FILE}'."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "::error ::Failed to find summary of test results (missing '${CURRENT_SUMMARY_FILE}'); failing early"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${COMPARISON_RESULT} -eq 1 ]; then
|
|
||||||
echo "::error ::Found new non-intermittent test failures"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "::notice ::No new test failures detected"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Upload comparison log (for GnuComment workflow)
|
|
||||||
if: success() || failure()
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: comment
|
|
||||||
path: reference/comment/
|
|
||||||
|
|
||||||
- name: Report test results
|
|
||||||
if: success() || failure()
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
## Report final results
|
|
||||||
echo "::notice ::GNU diffutils testsuite results:"
|
|
||||||
echo "::notice :: Total tests: ${{ steps.summary.outputs.TOTAL }}"
|
|
||||||
echo "::notice :: Passed: ${{ steps.summary.outputs.PASS }}"
|
|
||||||
echo "::notice :: Failed: ${{ steps.summary.outputs.FAIL }}"
|
|
||||||
echo "::notice :: Skipped: ${{ steps.summary.outputs.SKIP }}"
|
|
||||||
|
|
||||||
if [[ "${{ steps.summary.outputs.FAIL }}" -gt 0 ]]; then
|
|
||||||
PASS_RATE=$(( ${{ steps.summary.outputs.PASS }} * 100 / (${{ steps.summary.outputs.PASS }} + ${{ steps.summary.outputs.FAIL }}) ))
|
|
||||||
echo "::notice :: Pass rate: ${PASS_RATE}%"
|
|
||||||
fi
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: Security audit
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
jobs:
|
|
||||||
audit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- uses: rustsec/audit-check@v2
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
+175
-27
@@ -4,7 +4,6 @@ name: Basic CI
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
@@ -16,6 +15,7 @@ jobs:
|
|||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- run: cargo check
|
- run: cargo check
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@@ -27,14 +27,7 @@ jobs:
|
|||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: install GNU patch on MacOS
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
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'
|
|
||||||
run: echo "C:\Program Files\Git\usr\bin" >> $env:GITHUB_PATH
|
|
||||||
- run: cargo test
|
- run: cargo test
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
@@ -42,6 +35,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- run: rustup component add rustfmt
|
||||||
- run: cargo fmt --all -- --check
|
- run: cargo fmt --all -- --check
|
||||||
|
|
||||||
clippy:
|
clippy:
|
||||||
@@ -53,12 +48,111 @@ jobs:
|
|||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- run: rustup component add clippy
|
||||||
- run: cargo clippy -- -D warnings
|
- run: cargo clippy -- -D warnings
|
||||||
|
|
||||||
|
gnu-testsuite:
|
||||||
|
name: GNU test suite
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- run: cargo build --release
|
||||||
|
# do not fail, the report is merely informative (at least until all tests pass reliably)
|
||||||
|
- run: ./tests/run-upstream-testsuite.sh release || true
|
||||||
|
env:
|
||||||
|
TERM: xterm
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-results.json
|
||||||
|
path: tests/test-results.json
|
||||||
|
- run: ./tests/print-test-results.sh tests/test-results.json
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: build ${{ matrix.binary || 'findutils' }} ${{ matrix.target }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
container: ${{ fromJson(matrix.container || '{"image":null}') }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
target: x86_64-unknown-linux-musl
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
target: aarch64-unknown-linux-musl
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
target: armv7-unknown-linux-musleabi
|
||||||
|
container: '{"image": "messense/rust-musl-cross:armv7-musleabi"}'
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
target: i686-unknown-linux-musl
|
||||||
|
container: '{"image": "messense/rust-musl-cross:i686-musl"}'
|
||||||
|
- os: macOS-11
|
||||||
|
target: x86_64-apple-darwin
|
||||||
|
macosx_deployment_target: 10.13
|
||||||
|
developer_dir: /Applications/Xcode_11.7.app
|
||||||
|
sdkroot: /Applications/Xcode_11.7.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
|
||||||
|
- os: macos-14
|
||||||
|
target: aarch64-apple-darwin
|
||||||
|
macosx_deployment_target: 11.0
|
||||||
|
- os: windows-2019
|
||||||
|
target: x86_64-pc-windows-msvc
|
||||||
|
rustflags: -Ctarget-feature=+crt-static
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install rust
|
||||||
|
uses: ./.github/actions/rust-toolchain
|
||||||
|
with:
|
||||||
|
toolchain: ${{ matrix.target == 'aarch64-apple-darwin' && 'beta' || 'stable' }}
|
||||||
|
target: ${{ matrix.target }}
|
||||||
|
if: ${{ !matrix.container }}
|
||||||
|
|
||||||
|
- name: Install musl-tools (x86_64)
|
||||||
|
run: sudo apt-get install musl-tools
|
||||||
|
if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }}
|
||||||
|
|
||||||
|
- name: Install musl-tools (arm64)
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
sed 's/mirror+file:\/etc\/apt\/apt-mirrors\.txt/[arch=arm64] http:\/\/ports.ubuntu.com\/ubuntu-ports\//g' /etc/apt/sources.list | sudo tee /etc/apt/sources.list.d/ports.list
|
||||||
|
sudo dpkg --add-architecture arm64
|
||||||
|
sudo apt-get update || true
|
||||||
|
sudo apt-get install musl-dev:arm64 binutils-multiarch gcc-10-aarch64-linux-gnu libc6-dev-arm64-cross
|
||||||
|
apt-get download musl-tools:arm64
|
||||||
|
sudo dpkg-deb -x musl-tools_*_arm64.deb /
|
||||||
|
sed 2iREALGCC=aarch64-linux-gnu-gcc-10 /usr/bin/musl-gcc | sudo tee /usr/bin/aarch64-linux-musl-gcc > /dev/null
|
||||||
|
sudo chmod +x /usr/bin/aarch64-linux-musl-gcc
|
||||||
|
if: ${{ matrix.target == 'aarch64-unknown-linux-musl' }}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --locked --release --bin ${{ matrix.binary || 'findutils' }} --target ${{ matrix.target }} --features=openssl/vendored ${{ matrix.extra_args }}
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-musl-gcc
|
||||||
|
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
|
||||||
|
DEVELOPER_DIR: ${{ matrix.developer_dir }}
|
||||||
|
SDKROOT: ${{ matrix.sdkroot }}
|
||||||
|
RUSTFLAGS: ${{ matrix.rustflags }}
|
||||||
|
|
||||||
|
# Workaround for the lack of substring() function in github actions expressions.
|
||||||
|
- name: Id
|
||||||
|
id: id
|
||||||
|
shell: bash
|
||||||
|
run: echo "id=${ID#refs/tags/}" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
ID: ${{ startsWith(github.ref, 'refs/tags/') && github.ref || github.sha }}
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.binary || 'findutils' }}-${{ steps.id.outputs.id }}-${{ matrix.target }}
|
||||||
|
path: target/${{ matrix.target }}/release/${{ matrix.binary || 'findutils' }}${{ endsWith(matrix.target, '-msvc') && '.exe' || '' }}
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
name: Code Coverage
|
name: Code Coverage
|
||||||
env:
|
|
||||||
RUSTC_BOOTSTRAP: 1
|
|
||||||
runs-on: ${{ matrix.job.os }}
|
runs-on: ${{ matrix.job.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -75,26 +169,29 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
## VARs setup
|
## VARs setup
|
||||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||||
|
# toolchain
|
||||||
|
TOOLCHAIN="nightly" ## default to "nightly" toolchain (required for certain required unstable compiler flags) ## !maint: refactor when stable channel has needed support
|
||||||
|
# * specify gnu-type TOOLCHAIN for windows; `grcov` requires gnu-style code coverage data files
|
||||||
|
case ${{ matrix.job.os }} in windows-*) TOOLCHAIN="$TOOLCHAIN-x86_64-pc-windows-gnu" ;; esac;
|
||||||
|
# * use requested TOOLCHAIN if specified
|
||||||
|
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
|
||||||
|
outputs TOOLCHAIN
|
||||||
# target-specific options
|
# target-specific options
|
||||||
|
# * CARGO_FEATURES_OPTION
|
||||||
|
CARGO_FEATURES_OPTION='--all -- --check' ; ## default to '--all-features' for code coverage
|
||||||
# * CODECOV_FLAGS
|
# * CODECOV_FLAGS
|
||||||
CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' )
|
CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' )
|
||||||
outputs CODECOV_FLAGS
|
outputs CODECOV_FLAGS
|
||||||
|
|
||||||
- name: install GNU patch on MacOS
|
- name: rust toolchain ~ install
|
||||||
if: runner.os == 'macOS'
|
uses: dtolnay/rust-toolchain@nightly
|
||||||
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'
|
|
||||||
run: echo "C:\Program Files\Git\usr\bin" >> $env:GITHUB_PATH
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cargo test --all-features --no-fail-fast
|
run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast
|
||||||
env:
|
env:
|
||||||
|
CARGO_INCREMENTAL: "0"
|
||||||
RUSTC_WRAPPER: ""
|
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"
|
RUSTDOCFLAGS: "-Cpanic=abort"
|
||||||
LLVM_PROFILE_FILE: "diffutils-%p-%m.profraw"
|
|
||||||
- name: "`grcov` ~ install"
|
- name: "`grcov` ~ install"
|
||||||
id: build_grcov
|
id: build_grcov
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -122,16 +219,67 @@ jobs:
|
|||||||
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
|
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
|
||||||
mkdir -p "${COVERAGE_REPORT_DIR}"
|
mkdir -p "${COVERAGE_REPORT_DIR}"
|
||||||
# display coverage files
|
# 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
|
# 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
|
echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT
|
||||||
- name: Upload coverage results (to Codecov.io)
|
- name: Upload coverage results (to Codecov.io)
|
||||||
uses: codecov/codecov-action@v7
|
uses: codecov/codecov-action@v3
|
||||||
|
# if: steps.vars.outputs.HAS_CODECOV_TOKEN
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ${{ steps.coverage.outputs.report }}
|
file: ${{ steps.coverage.outputs.report }}
|
||||||
## flags: IntegrationTests, UnitTests, ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
## flags: IntegrationTests, UnitTests, ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
||||||
flags: ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
flags: ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
||||||
name: codecov-umbrella
|
name: codecov-umbrella
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [build, clippy, check, test]
|
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Check versions
|
||||||
|
run: |
|
||||||
|
tag_name=${GITHUB_REF#refs/tags/}
|
||||||
|
v=$(grep -m 1 "^version" Cargo.toml|sed -e "s|version = \"\(.*\)\"|\1|")
|
||||||
|
if ! echo $tag_name|grep -q $v; then
|
||||||
|
echo "Mistmatch of the version:"
|
||||||
|
echo "Cargo.toml says $v while the tag is $tag_name"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Get artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
|
||||||
|
- name: Create release assets
|
||||||
|
run: |
|
||||||
|
for d in findutils-*; do
|
||||||
|
chmod +x "$d/findutils"*
|
||||||
|
cp README.md LICENSE "$d/"
|
||||||
|
tar -zcvf "$d.tar.gz" "$d"
|
||||||
|
echo -n "$(shasum -ba 256 "$d.tar.gz" | cut -d " " -f 1)" > "$d.tar.gz.sha256"
|
||||||
|
if [[ $d =~ (findutils-)(.*)?(x86_64-pc-windows)(.*)? ]]; then
|
||||||
|
zip -r "$d.zip" "$d"
|
||||||
|
echo -n "$(shasum -ba 256 "$d.zip" | cut -d " " -f 1)" > "$d.zip.sha256"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
run: |
|
||||||
|
sudo apt-get update && sudo apt-get install -y hub
|
||||||
|
tag_name=${GITHUB_REF#refs/tags/}
|
||||||
|
for f in findutils-*.tar.gz* findutils-*.zip*; do
|
||||||
|
if [[ -f "$f" ]]; then
|
||||||
|
files="$files -a $f";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
hub release create -m $tag_name $tag_name $files
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
name: CodSpeed
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "main"
|
|
||||||
pull_request:
|
|
||||||
# `workflow_dispatch` allows CodSpeed to trigger backtest
|
|
||||||
# performance analysis in order to generate initial data.
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
codspeed:
|
|
||||||
name: Run benchmarks
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup rust toolchain, cache and cargo-codspeed binary
|
|
||||||
uses: moonrepo/setup-rust@v1
|
|
||||||
with:
|
|
||||||
channel: stable
|
|
||||||
cache-target: release
|
|
||||||
bins: cargo-codspeed
|
|
||||||
|
|
||||||
- name: Build the benchmark target(s)
|
|
||||||
run: cargo codspeed build -m simulation
|
|
||||||
|
|
||||||
- name: Run the benchmarks
|
|
||||||
uses: CodSpeedHQ/action@v4
|
|
||||||
with:
|
|
||||||
mode: simulation
|
|
||||||
run: cargo codspeed run
|
|
||||||
@@ -2,10 +2,6 @@ name: Fuzzing
|
|||||||
|
|
||||||
# spell-checker:ignore fuzzer
|
# spell-checker:ignore fuzzer
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
RUSTC_BOOTSTRAP: 1
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
@@ -25,15 +21,15 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
- name: Install `cargo-fuzz`
|
- name: Install `cargo-fuzz`
|
||||||
run: |
|
run: cargo install cargo-fuzz
|
||||||
cargo install cargo-fuzz --locked
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
shared-key: "cargo-fuzz-cache-key"
|
shared-key: "cargo-fuzz-cache-key"
|
||||||
cache-directories: "fuzz/target"
|
cache-directories: "fuzz/target"
|
||||||
- name: Run `cargo-fuzz build`
|
- name: Run `cargo-fuzz build`
|
||||||
run: cargo fuzz build
|
run: cargo +nightly fuzz build
|
||||||
|
|
||||||
fuzz-run:
|
fuzz-run:
|
||||||
needs: fuzz-build
|
needs: fuzz-build
|
||||||
@@ -45,34 +41,31 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
test-target:
|
test-target:
|
||||||
- { name: fuzz_cmp, should_pass: true }
|
|
||||||
- { name: fuzz_cmp_args, should_pass: true }
|
|
||||||
- { name: fuzz_ed, should_pass: true }
|
- { name: fuzz_ed, should_pass: true }
|
||||||
- { name: fuzz_normal, should_pass: true }
|
- { name: fuzz_normal, should_pass: true }
|
||||||
- { name: fuzz_patch, should_pass: true }
|
- { name: fuzz_patch, should_pass: true }
|
||||||
- { name: fuzz_side, should_pass: true }
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
- name: Install `cargo-fuzz`
|
- name: Install `cargo-fuzz`
|
||||||
run: |
|
run: cargo install cargo-fuzz
|
||||||
cargo install cargo-fuzz --locked
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
shared-key: "cargo-fuzz-cache-key"
|
shared-key: "cargo-fuzz-cache-key"
|
||||||
cache-directories: "fuzz/target"
|
cache-directories: "fuzz/target"
|
||||||
- name: Restore Cached Corpus
|
- name: Restore Cached Corpus
|
||||||
uses: actions/cache/restore@v5
|
uses: actions/cache/restore@v4
|
||||||
with:
|
with:
|
||||||
key: corpus-cache-${{ matrix.test-target.name }}
|
key: corpus-cache-${{ matrix.test-target.name }}
|
||||||
path: |
|
path: |
|
||||||
fuzz/corpus/${{ matrix.test-target.name }}
|
fuzz/corpus/${{ matrix.test-target.name }}
|
||||||
- name: Run ${{ matrix.test-target.name }} for XX seconds
|
- name: Run ${{ matrix.test-target.name }} for XX seconds
|
||||||
shell: bash
|
shell: bash
|
||||||
continue-on-error: ${{ !matrix.test-target.should_pass }}
|
continue-on-error: ${{ !matrix.test-target.name.should_pass }}
|
||||||
run: |
|
run: |
|
||||||
cargo fuzz run ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
|
cargo +nightly fuzz run ${{ matrix.test-target.name }} -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
|
||||||
- name: Save Corpus Cache
|
- name: Save Corpus Cache
|
||||||
uses: actions/cache/save@v5
|
uses: actions/cache/save@v4
|
||||||
with:
|
with:
|
||||||
key: corpus-cache-${{ matrix.test-target.name }}
|
key: corpus-cache-${{ matrix.test-target.name }}
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
@@ -1,296 +0,0 @@
|
|||||||
# This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist
|
|
||||||
#
|
|
||||||
# Copyright 2022-2024, axodotdev
|
|
||||||
# SPDX-License-Identifier: MIT or Apache-2.0
|
|
||||||
#
|
|
||||||
# CI that:
|
|
||||||
#
|
|
||||||
# * checks for a Git Tag that looks like a release
|
|
||||||
# * builds artifacts with dist (archives, installers, hashes)
|
|
||||||
# * uploads those artifacts to temporary workflow zip
|
|
||||||
# * on success, uploads the artifacts to a GitHub Release
|
|
||||||
#
|
|
||||||
# Note that the GitHub Release will be created with a generated
|
|
||||||
# title/body based on your changelogs.
|
|
||||||
|
|
||||||
name: Release
|
|
||||||
permissions:
|
|
||||||
"contents": "write"
|
|
||||||
|
|
||||||
# This task will run whenever you push a git tag that looks like a version
|
|
||||||
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
|
|
||||||
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
|
|
||||||
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
|
|
||||||
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
|
|
||||||
#
|
|
||||||
# If PACKAGE_NAME is specified, then the announcement will be for that
|
|
||||||
# package (erroring out if it doesn't have the given version or isn't dist-able).
|
|
||||||
#
|
|
||||||
# If PACKAGE_NAME isn't specified, then the announcement will be for all
|
|
||||||
# (dist-able) packages in the workspace with that version (this mode is
|
|
||||||
# intended for workspaces with only one dist-able package, or with all dist-able
|
|
||||||
# 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
|
|
||||||
# will hard limit this to 3 tags per commit, as it will assume more tags is a
|
|
||||||
# mistake.
|
|
||||||
#
|
|
||||||
# If there's a prerelease-style suffix to the version, then the release(s)
|
|
||||||
# will be marked as a prerelease.
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '**[0-9]+.[0-9]+.[0-9]+*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Run 'dist plan' (or host) to determine what tasks we need to do
|
|
||||||
plan:
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
outputs:
|
|
||||||
val: ${{ steps.plan.outputs.manifest }}
|
|
||||||
tag: ${{ !github.event.pull_request && github.ref_name || '' }}
|
|
||||||
tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }}
|
|
||||||
publishing: ${{ !github.event.pull_request }}
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
submodules: recursive
|
|
||||||
- name: Install dist
|
|
||||||
# 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.30.3/cargo-dist-installer.sh | sh"
|
|
||||||
- name: Cache dist
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cargo-dist-cache
|
|
||||||
path: ~/.cargo/bin/dist
|
|
||||||
# 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.
|
|
||||||
# (PRs run on the *source* but secrets are usually on the *target* -- that's *good*
|
|
||||||
# but also really annoying to build CI around when it needs secrets to work right.)
|
|
||||||
- id: plan
|
|
||||||
run: |
|
|
||||||
dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json
|
|
||||||
echo "dist ran successfully"
|
|
||||||
cat plan-dist-manifest.json
|
|
||||||
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: "Upload dist-manifest.json"
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: artifacts-plan-dist-manifest
|
|
||||||
path: plan-dist-manifest.json
|
|
||||||
|
|
||||||
# Build and packages all the platform-specific things
|
|
||||||
build-local-artifacts:
|
|
||||||
name: build-local-artifacts (${{ join(matrix.targets, ', ') }})
|
|
||||||
# Let the initial task tell us to not run (currently very blunt)
|
|
||||||
needs:
|
|
||||||
- plan
|
|
||||||
if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
# Target platforms/runners are computed by dist in create-release.
|
|
||||||
# Each member of the matrix has the following arguments:
|
|
||||||
#
|
|
||||||
# - runner: the github runner
|
|
||||||
# - dist-args: cli flags to pass to dist
|
|
||||||
# - install-dist: expression to run to install dist on the runner
|
|
||||||
#
|
|
||||||
# Typically there will be:
|
|
||||||
# - 1 "global" task that builds universal installers
|
|
||||||
# - N "local" tasks that build each platform's binaries and platform-specific installers
|
|
||||||
matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
container: ${{ matrix.container && matrix.container.image || null }}
|
|
||||||
env:
|
|
||||||
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:
|
|
||||||
persist-credentials: false
|
|
||||||
submodules: recursive
|
|
||||||
- name: Install Rust non-interactively if not already installed
|
|
||||||
if: ${{ matrix.container }}
|
|
||||||
run: |
|
|
||||||
if ! command -v cargo > /dev/null 2>&1; then
|
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
|
||||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
|
||||||
fi
|
|
||||||
- name: Install dist
|
|
||||||
run: ${{ matrix.install_dist.run }}
|
|
||||||
# Get the dist-manifest
|
|
||||||
- name: Fetch local artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: artifacts-*
|
|
||||||
path: target/distrib/
|
|
||||||
merge-multiple: true
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
${{ matrix.packages_install }}
|
|
||||||
- name: Build artifacts
|
|
||||||
run: |
|
|
||||||
# Actually do builds and make zips and whatnot
|
|
||||||
dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json
|
|
||||||
echo "dist ran successfully"
|
|
||||||
- id: cargo-dist
|
|
||||||
name: Post-build
|
|
||||||
# We force bash here just because github makes it really hard to get values up
|
|
||||||
# to "real" actions without writing to env-vars, and writing to env-vars has
|
|
||||||
# inconsistent syntax between shell and powershell.
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# Parse out what we just built and upload it to scratch storage
|
|
||||||
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
|
|
||||||
dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT"
|
|
||||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
|
|
||||||
- name: "Upload artifacts"
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
|
|
||||||
path: |
|
|
||||||
${{ steps.cargo-dist.outputs.paths }}
|
|
||||||
${{ env.BUILD_MANIFEST_NAME }}
|
|
||||||
|
|
||||||
# Build and package all the platform-agnostic(ish) things
|
|
||||||
build-global-artifacts:
|
|
||||||
needs:
|
|
||||||
- plan
|
|
||||||
- build-local-artifacts
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
submodules: recursive
|
|
||||||
- name: Install cached dist
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cargo-dist-cache
|
|
||||||
path: ~/.cargo/bin/
|
|
||||||
- run: chmod +x ~/.cargo/bin/dist
|
|
||||||
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
|
|
||||||
- name: Fetch local artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: artifacts-*
|
|
||||||
path: target/distrib/
|
|
||||||
merge-multiple: true
|
|
||||||
- id: cargo-dist
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json
|
|
||||||
echo "dist ran successfully"
|
|
||||||
|
|
||||||
# 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"
|
|
||||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
|
|
||||||
- name: "Upload artifacts"
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: artifacts-build-global
|
|
||||||
path: |
|
|
||||||
${{ steps.cargo-dist.outputs.paths }}
|
|
||||||
${{ env.BUILD_MANIFEST_NAME }}
|
|
||||||
# Determines if we should publish/announce
|
|
||||||
host:
|
|
||||||
needs:
|
|
||||||
- plan
|
|
||||||
- build-local-artifacts
|
|
||||||
- build-global-artifacts
|
|
||||||
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
|
|
||||||
if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
outputs:
|
|
||||||
val: ${{ steps.host.outputs.manifest }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
submodules: recursive
|
|
||||||
- name: Install cached dist
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cargo-dist-cache
|
|
||||||
path: ~/.cargo/bin/
|
|
||||||
- run: chmod +x ~/.cargo/bin/dist
|
|
||||||
# Fetch artifacts from scratch-storage
|
|
||||||
- name: Fetch artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: artifacts-*
|
|
||||||
path: target/distrib/
|
|
||||||
merge-multiple: true
|
|
||||||
- id: host
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json
|
|
||||||
echo "artifacts uploaded and released successfully"
|
|
||||||
cat dist-manifest.json
|
|
||||||
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: "Upload dist-manifest.json"
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
# Overwrite the previous copy
|
|
||||||
name: artifacts-dist-manifest
|
|
||||||
path: dist-manifest.json
|
|
||||||
# Create a GitHub Release while uploading all files to it
|
|
||||||
- name: "Download GitHub Artifacts"
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: artifacts-*
|
|
||||||
path: artifacts
|
|
||||||
merge-multiple: true
|
|
||||||
- name: Cleanup
|
|
||||||
run: |
|
|
||||||
# Remove the granular manifests
|
|
||||||
rm -f artifacts/*-dist-manifest.json
|
|
||||||
- name: Create GitHub Release
|
|
||||||
env:
|
|
||||||
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
|
|
||||||
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
|
|
||||||
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
|
|
||||||
RELEASE_COMMIT: "${{ github.sha }}"
|
|
||||||
run: |
|
|
||||||
# Write and read notes from a file to avoid quoting breaking things
|
|
||||||
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
|
|
||||||
|
|
||||||
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
|
|
||||||
|
|
||||||
announce:
|
|
||||||
needs:
|
|
||||||
- plan
|
|
||||||
- host
|
|
||||||
# use "always() && ..." to allow us to wait for all publish jobs while
|
|
||||||
# still allowing individual publish jobs to skip themselves (for prereleases).
|
|
||||||
# "host" however must run to completion, no skipping allowed!
|
|
||||||
if: ${{ always() && needs.host.result == 'success' }}
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
submodules: recursive
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# spell-checker:ignore wasip
|
|
||||||
name: WASI
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
# End the current execution if there is a new changeset in the PR.
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test_wasi:
|
|
||||||
name: Tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: wasm32-wasip1
|
|
||||||
- name: check
|
|
||||||
run: cargo check --target wasm32-wasip1
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# See https://pre-commit.com for more information
|
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
|
||||||
exclude: ^tests/fixtures/
|
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v6.0.0
|
|
||||||
hooks:
|
|
||||||
- id: check-added-large-files
|
|
||||||
- id: check-executables-have-shebangs
|
|
||||||
- id: check-json
|
|
||||||
exclude: '\.vscode/(cSpell|extensions)\.json' # cSpell.json and extensions.json use comments
|
|
||||||
- id: check-shebang-scripts-are-executable
|
|
||||||
exclude: '.+\.rs' # would be triggered by #![some_attribute]
|
|
||||||
- id: check-symlinks
|
|
||||||
- id: check-toml
|
|
||||||
- id: check-yaml
|
|
||||||
args: [ --allow-multiple-documents ]
|
|
||||||
- id: destroyed-symlinks
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
- id: mixed-line-ending
|
|
||||||
args: [ --fix=lf ]
|
|
||||||
- id: trailing-whitespace
|
|
||||||
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: rust-linting
|
|
||||||
name: Rust linting
|
|
||||||
description: Run cargo fmt on files included in the commit.
|
|
||||||
entry: cargo +stable fmt --
|
|
||||||
pass_filenames: true
|
|
||||||
types: [file, rust]
|
|
||||||
language: system
|
|
||||||
- id: rust-clippy
|
|
||||||
name: Rust clippy
|
|
||||||
description: Run cargo clippy on files included in the commit.
|
|
||||||
entry: cargo +stable clippy --workspace --all-targets --all-features -- -D warnings
|
|
||||||
pass_filenames: false
|
|
||||||
types: [file, rust]
|
|
||||||
language: system
|
|
||||||
- id: cspell
|
|
||||||
name: Code spell checker (cspell)
|
|
||||||
description: Run cspell to check for spelling errors (if available).
|
|
||||||
entry: bash -c 'if command -v cspell >/dev/null 2>&1; then cspell --no-must-find-files -- "$@"; else echo "cspell not found, skipping spell check"; exit 0; fi' --
|
|
||||||
pass_filenames: true
|
|
||||||
language: system
|
|
||||||
|
|
||||||
ci:
|
|
||||||
skip: [rust-linting, rust-clippy, cspell]
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Contributing to diffutils
|
|
||||||
|
|
||||||
Hi! Welcome to uutils/diffutils, and thanks for wanting to contribute!
|
|
||||||
|
|
||||||
This project follows the shared conventions of the [uutils](https://github.com/uutils)
|
|
||||||
organization. Before opening a pull request, please read:
|
|
||||||
|
|
||||||
- Our **[Review Guidelines](https://uutils.github.io/reviews/)** — what we expect
|
|
||||||
from a pull request and how reviews are carried out.
|
|
||||||
- Our community's [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md), if present.
|
|
||||||
|
|
||||||
Finally, feel free to join our [Discord](https://discord.gg/wQVJbvJ)!
|
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
> uutils is original code and cannot contain any code from GNU or other
|
|
||||||
> strongly-licensed (GPL/LGPL) implementations. We **cannot** accept changes
|
|
||||||
> based on the GNU source code, and you **must not link** to it either. You may
|
|
||||||
> look at permissively-licensed implementations (MIT/BSD) and read the GNU
|
|
||||||
> *manuals* — never the GNU *source*.
|
|
||||||
|
|
||||||
## In short
|
|
||||||
|
|
||||||
- Discuss non-trivial changes in an issue **before** writing the code.
|
|
||||||
- Keep pull requests **small, self-contained, and descriptively titled**
|
|
||||||
(e.g. `diffutils: fix ...`).
|
|
||||||
- Make sure CI passes: tests are green, `rustfmt` is satisfied, and there are
|
|
||||||
no `clippy` warnings.
|
|
||||||
- Add tests for new behavior; don't let coverage regress.
|
|
||||||
- Write small, atomic commits annotated with the component you touched.
|
|
||||||
|
|
||||||
See the [Review Guidelines](https://uutils.github.io/reviews/) for the full
|
|
||||||
details.
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
Copyright (c) Michael Howell
|
|
||||||
Copyright (c) uutils developers
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
option. All files in the project carrying such notice may not be
|
|
||||||
copied, modified, or distributed except according to those terms.
|
|
||||||
Generated
+108
-888
File diff suppressed because it is too large
Load Diff
+6
-31
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "diffutils"
|
name = "diffutils"
|
||||||
version = "0.5.0"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A CLI app for generating diff files"
|
description = "A CLI app for generating diff files"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@@ -15,38 +15,13 @@ name = "diffutils"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.38"
|
diff = "0.1.10"
|
||||||
diff = "0.1.13"
|
regex = "1.10.3"
|
||||||
itoa = "1.0.11"
|
|
||||||
regex = "1.10.4"
|
|
||||||
same-file = "1.0.6"
|
same-file = "1.0.6"
|
||||||
unicode-width = "0.2.0"
|
unicode-width = "0.1.11"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
pretty_assertions = "1"
|
||||||
assert_cmd = "2.0.14"
|
assert_cmd = "2.0.14"
|
||||||
divan = { version = "4.3.0", package = "codspeed-divan-compat" }
|
|
||||||
pretty_assertions = "1.4.0"
|
|
||||||
predicates = "3.1.0"
|
predicates = "3.1.0"
|
||||||
rand = "0.10.0"
|
tempfile = "3.10.0"
|
||||||
tempfile = "3.26.0"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
lto = "thin"
|
|
||||||
codegen-units = 1
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
# alias profile for 'dist'
|
|
||||||
[profile.dist]
|
|
||||||
inherits = "release"
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bench_diffutils"
|
|
||||||
path = "benches/bench-diffutils.rs"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[features]
|
|
||||||
# default = ["feat_bench_not_diff"]
|
|
||||||
# Turn bench for diffutils cmp off
|
|
||||||
feat_bench_not_cmp = []
|
|
||||||
# Turn bench for diffutils diff off
|
|
||||||
feat_bench_not_diff = []
|
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
[](https://discord.gg/wQVJbvJ)
|
[](https://discord.gg/wQVJbvJ)
|
||||||
[](https://github.com/uutils/diffutils/blob/main/LICENSE)
|
[](https://github.com/uutils/diffutils/blob/main/LICENSE)
|
||||||
[](https://deps.rs/repo/github/uutils/diffutils)
|
[](https://deps.rs/repo/github/uutils/diffutils)
|
||||||
[](https://codspeed.io/uutils/diffutils?utm_source=badge)
|
|
||||||
|
|
||||||
[](https://codecov.io/gh/uutils/diffutils)
|
[](https://codecov.io/gh/uutils/diffutils)
|
||||||
|
|
||||||
The goal of this package is to be a drop-in replacement for the [diffutils commands](https://www.gnu.org/software/diffutils/) (diff, cmp, diff3, sdiff) in Rust.
|
The goal of this package is to be a drop-in replacement for the [diffutils commands](https://www.gnu.org/software/diffutils/) in Rust.
|
||||||
|
|
||||||
Based on the incomplete diff generator in https://github.com/rust-lang/rust/blob/master/src/tools/compiletest/src/runtest.rs, and made to be compatible with GNU's diff and patch tools.
|
Based on the incomplete diff generator in https://github.com/rust-lang/rust/blob/master/src/tools/compiletest/src/runtest.rs, and made to be compatible with GNU's diff and patch tools.
|
||||||
|
|
||||||
@@ -54,8 +53,4 @@ $ cargo run -- -u fruits_old.txt fruits_new.txt
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is distributed under the terms of both the MIT license and the
|
diffutils is licensed under the MIT and Apache Licenses - see the `LICENSE-MIT` or `LICENSE-APACHE` files for details
|
||||||
Apache License (Version 2.0).
|
|
||||||
|
|
||||||
See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
|
|
||||||
[COPYRIGHT](COPYRIGHT) for details.
|
|
||||||
|
|||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
# Security Policy
|
|
||||||
|
|
||||||
## Supported Versions
|
|
||||||
|
|
||||||
We provide security updates only for the latest released version of `uutils/diffutils`.
|
|
||||||
Older versions may not receive patches.
|
|
||||||
If you are using a version packaged by your Linux distribution, please check with your distribution maintainers for their update policy.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
**Do not open public GitHub issues for security vulnerabilities.**
|
|
||||||
This prevents accidental disclosure before a fix is available.
|
|
||||||
|
|
||||||
Instead, please use the following method:
|
|
||||||
|
|
||||||
- **Email:** [sylvestre@debian.org](mailto:Sylvestre@debian.org)
|
|
||||||
- **Encryption (optional):** You may encrypt your report using our PGP key:
|
|
||||||
Fingerprint: B60D B599 4D39 BEC4 D1A9 5CCF 7E65 28DA 752F 1BE1
|
|
||||||
---
|
|
||||||
|
|
||||||
### What to Include in Your Report
|
|
||||||
|
|
||||||
To help us investigate and resolve the issue quickly, please include as much detail as possible:
|
|
||||||
|
|
||||||
- **Type of issue:** e.g. privilege escalation, information disclosure.
|
|
||||||
- **Location in the source:** file path, commit hash, branch, or tag.
|
|
||||||
- **Steps to reproduce:** exact commands, test cases, or scripts.
|
|
||||||
- **Special configuration:** any flags, environment variables, or system setup required.
|
|
||||||
- **Affected systems:** OS/distribution and version(s) where the issue occurs.
|
|
||||||
- **Impact:** your assessment of the potential severity (DoS, RCE, data leak, etc.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Disclosure Policy
|
|
||||||
|
|
||||||
We follow a **Coordinated Vulnerability Disclosure (CVD)** process:
|
|
||||||
|
|
||||||
1. We will acknowledge receipt of your report within **10 days**.
|
|
||||||
2. We will investigate, reproduce, and assess the issue.
|
|
||||||
3. We will provide a timeline for developing and releasing a fix.
|
|
||||||
4. Once a fix is available, we will publish a GitHub Security Advisory.
|
|
||||||
5. You will be credited in the advisory unless you request anonymity.
|
|
||||||
@@ -1,377 +0,0 @@
|
|||||||
// This file is part of the uutils diffutils package.
|
|
||||||
//
|
|
||||||
// For the full copyright and license information, please view the LICENSE-*
|
|
||||||
// files that was distributed with this source code.
|
|
||||||
|
|
||||||
//! Benches for all utils in diffutils.
|
|
||||||
//!
|
|
||||||
//! There is a file generator included to create files of different sizes for comparison. \
|
|
||||||
//! Set the TEMP_DIR const to keep the files. df_to_ files have small changes in them, search for '#'. \
|
|
||||||
//! File generation up to 1 GB is really fast, Benchmarking above 100 MB takes very long.
|
|
||||||
|
|
||||||
/// Generate test files with these sizes in KB.
|
|
||||||
const FILE_SIZE_KILO_BYTES: [u64; 4] = [100, 1 * MB, 10 * MB, 25 * MB];
|
|
||||||
// const FILE_SIZE_KILO_BYTES: [u64; 3] = [100, 1 * MB, 5 * MB];
|
|
||||||
// Empty String to use TempDir (files will be removed after test) or specify dir to keep generated files
|
|
||||||
const TEMP_DIR: &str = "";
|
|
||||||
const NUM_DIFF: u64 = 4;
|
|
||||||
// just for FILE_SIZE_KILO_BYTES
|
|
||||||
const MB: u64 = 1_000;
|
|
||||||
const CHANGE_CHAR: u8 = b'#';
|
|
||||||
|
|
||||||
#[cfg(not(feature = "feat_bench_not_cmp"))]
|
|
||||||
mod diffutils_cmp {
|
|
||||||
use std::hint::black_box;
|
|
||||||
|
|
||||||
use diffutilslib::cmp;
|
|
||||||
use divan::Bencher;
|
|
||||||
|
|
||||||
use crate::{binary, prepare::*, FILE_SIZE_KILO_BYTES};
|
|
||||||
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmp_compare_files_equal(bencher: Bencher, kb: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_equal(kb);
|
|
||||||
let cmd = format!("cmp {from} {to}");
|
|
||||||
let opts = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
let params = cmp::parse_params(opts).unwrap();
|
|
||||||
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| params.clone())
|
|
||||||
.bench_refs(|params| black_box(cmp::cmp(¶ms).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// bench the actual compare; cmp exits on first difference
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmp_compare_files_different(bencher: Bencher, bytes: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_different(bytes);
|
|
||||||
let cmd = format!("cmp {from} {to} -s");
|
|
||||||
let opts = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
let params = cmp::parse_params(opts).unwrap();
|
|
||||||
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| params.clone())
|
|
||||||
.bench_refs(|params| black_box(cmp::cmp(¶ms).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// bench original GNU cmp
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmd_cmp_gnu_equal(bencher: Bencher, bytes: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_equal(bytes);
|
|
||||||
let args_str = format!("{from} {to}");
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| args_str.clone())
|
|
||||||
.bench_refs(|cmd_args| binary::bench_binary("cmp", cmd_args));
|
|
||||||
}
|
|
||||||
|
|
||||||
// bench the compiled release version
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmd_cmp_release_equal(bencher: Bencher, bytes: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_equal(bytes);
|
|
||||||
let args_str = format!("cmp {from} {to}");
|
|
||||||
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| args_str.clone())
|
|
||||||
.bench_refs(|cmd_args| binary::bench_binary("target/release/diffutils", cmd_args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "feat_bench_not_diff"))]
|
|
||||||
mod diffutils_diff {
|
|
||||||
// use std::hint::black_box;
|
|
||||||
|
|
||||||
use crate::{binary, prepare::*, FILE_SIZE_KILO_BYTES};
|
|
||||||
// use diffutilslib::params;
|
|
||||||
use divan::Bencher;
|
|
||||||
|
|
||||||
// bench the actual compare
|
|
||||||
// TODO diff does not have a diff function
|
|
||||||
// #[divan::bench(args = [100_000,10_000])]
|
|
||||||
// fn diff_compare_files(bencher: Bencher, bytes: u64) {
|
|
||||||
// let (from, to) = gen_testfiles(lines, 0, "id");
|
|
||||||
// let cmd = format!("cmp {from} {to}");
|
|
||||||
// let opts = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
// let params = params::parse_params(opts).unwrap();
|
|
||||||
//
|
|
||||||
// bencher
|
|
||||||
// // .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
// .with_inputs(|| params.clone())
|
|
||||||
// .bench_refs(|params| diff::diff(¶ms).unwrap());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bench original GNU diff
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmd_diff_gnu_equal(bencher: Bencher, bytes: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_equal(bytes);
|
|
||||||
let args_str = format!("{from} {to}");
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| args_str.clone())
|
|
||||||
.bench_refs(|cmd_args| binary::bench_binary("diff", cmd_args));
|
|
||||||
}
|
|
||||||
|
|
||||||
// bench the compiled release version
|
|
||||||
#[divan::bench(args = FILE_SIZE_KILO_BYTES)]
|
|
||||||
fn cmd_diff_release_equal(bencher: Bencher, bytes: u64) {
|
|
||||||
let (from, to) = get_context().get_test_files_equal(bytes);
|
|
||||||
let args_str = format!("diff {from} {to}");
|
|
||||||
|
|
||||||
bencher
|
|
||||||
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
|
|
||||||
.with_inputs(|| args_str.clone())
|
|
||||||
.bench_refs(|cmd_args| binary::bench_binary("target/release/diffutils", cmd_args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod parser {
|
|
||||||
use std::hint::black_box;
|
|
||||||
|
|
||||||
use diffutilslib::{cmp, params};
|
|
||||||
use divan::Bencher;
|
|
||||||
|
|
||||||
use crate::prepare::str_to_options;
|
|
||||||
|
|
||||||
// bench the time it takes to parse the command line arguments
|
|
||||||
#[divan::bench]
|
|
||||||
fn cmp_parser(bencher: Bencher) {
|
|
||||||
let cmd = "cmd file_1.txt file_2.txt -bl n10M --ignore-initial=100KiB:1MiB";
|
|
||||||
let args = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
bencher
|
|
||||||
.with_inputs(|| args.clone())
|
|
||||||
.bench_values(|data| black_box(cmp::parse_params(data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// // test the impact on the benchmark if not converting the cmd to Vec<OsString> (doubles for parse)
|
|
||||||
// #[divan::bench]
|
|
||||||
// fn cmp_parser_no_prepare() {
|
|
||||||
// let cmd = "cmd file_1.txt file_2.txt -bl n10M --ignore-initial=100KiB:1MiB";
|
|
||||||
// let args = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
// let _ = cmp::parse_params(args);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bench the time it takes to parse the command line arguments
|
|
||||||
#[divan::bench]
|
|
||||||
fn diff_parser(bencher: Bencher) {
|
|
||||||
let cmd = "diff file_1.txt file_2.txt -s --brief --expand-tabs --width=100";
|
|
||||||
let args = str_to_options(&cmd).into_iter().peekable();
|
|
||||||
bencher
|
|
||||||
.with_inputs(|| args.clone())
|
|
||||||
.bench_values(|data| black_box(params::parse_params(data)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod prepare {
|
|
||||||
use std::{
|
|
||||||
ffi::OsString,
|
|
||||||
fs::{self, File},
|
|
||||||
io::{BufWriter, Write},
|
|
||||||
path::Path,
|
|
||||||
sync::OnceLock,
|
|
||||||
};
|
|
||||||
|
|
||||||
use rand::RngExt;
|
|
||||||
use tempfile::TempDir;
|
|
||||||
|
|
||||||
use crate::{CHANGE_CHAR, FILE_SIZE_KILO_BYTES, NUM_DIFF, TEMP_DIR};
|
|
||||||
|
|
||||||
// file lines and .txt will be added
|
|
||||||
const FROM_FILE: &str = "from_file";
|
|
||||||
const TO_FILE: &str = "to_file";
|
|
||||||
const LINE_LENGTH: usize = 60;
|
|
||||||
|
|
||||||
/// Contains test data (file names) which only needs to be created once.
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct BenchContext {
|
|
||||||
pub tmp_dir: Option<TempDir>,
|
|
||||||
pub dir: String,
|
|
||||||
pub files_equal: Vec<(String, String)>,
|
|
||||||
pub files_different: Vec<(String, String)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BenchContext {
|
|
||||||
pub fn get_path(&self) -> &Path {
|
|
||||||
match &self.tmp_dir {
|
|
||||||
Some(tmp) => tmp.path(),
|
|
||||||
None => Path::new(&self.dir),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_test_files_equal(&self, kb: u64) -> &(String, String) {
|
|
||||||
let p = FILE_SIZE_KILO_BYTES.iter().position(|f| *f == kb).unwrap();
|
|
||||||
&self.files_equal[p]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn get_test_files_different(&self, kb: u64) -> &(String, String) {
|
|
||||||
let p = FILE_SIZE_KILO_BYTES.iter().position(|f| *f == kb).unwrap();
|
|
||||||
&self.files_different[p]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since each bench function is separate in Divan it is more difficult to dynamically create test data.
|
|
||||||
// This keeps the TempDir alive until the program exits and generates the files only once.
|
|
||||||
static SHARED_CONTEXT: OnceLock<BenchContext> = OnceLock::new();
|
|
||||||
/// Creates the test files once and provides them to all tests.
|
|
||||||
pub fn get_context() -> &'static BenchContext {
|
|
||||||
SHARED_CONTEXT.get_or_init(|| {
|
|
||||||
let mut ctx = BenchContext::default();
|
|
||||||
if TEMP_DIR.is_empty() {
|
|
||||||
let tmp_dir = TempDir::new().expect("Failed to create temp dir");
|
|
||||||
ctx.tmp_dir = Some(tmp_dir);
|
|
||||||
} else {
|
|
||||||
// uses current directory, the generated files are kept
|
|
||||||
let path = Path::new(TEMP_DIR);
|
|
||||||
if !path.exists() {
|
|
||||||
fs::create_dir_all(path).expect("Path {path} could not be created");
|
|
||||||
}
|
|
||||||
ctx.dir = TEMP_DIR.to_string();
|
|
||||||
};
|
|
||||||
|
|
||||||
// generate test bytes
|
|
||||||
for kb in FILE_SIZE_KILO_BYTES {
|
|
||||||
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, 0, "eq")
|
|
||||||
.expect("generate_test_files failed");
|
|
||||||
ctx.files_equal.push(f);
|
|
||||||
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, NUM_DIFF, "df")
|
|
||||||
.expect("generate_test_files failed");
|
|
||||||
ctx.files_different.push(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn str_to_options(opt: &str) -> Vec<OsString> {
|
|
||||||
let s: Vec<OsString> = opt
|
|
||||||
.split(" ")
|
|
||||||
.into_iter()
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.map(|s| OsString::from(s))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates two test files for comparison with <bytes> size.
|
|
||||||
///
|
|
||||||
/// Each line consists of 10 words with 5 letters, giving a line length of 60 bytes.
|
|
||||||
/// If num_differences is set, '#' will be inserted between the first two words of a line,
|
|
||||||
/// evenly spaced in the file. 1 will add the change in the last line, so the comparison takes longest.
|
|
||||||
fn generate_test_files_bytes(
|
|
||||||
dir: &Path,
|
|
||||||
bytes: u64,
|
|
||||||
num_differences: u64,
|
|
||||||
id: &str,
|
|
||||||
) -> std::io::Result<(String, String)> {
|
|
||||||
let id = if id.is_empty() {
|
|
||||||
"".to_string()
|
|
||||||
} else {
|
|
||||||
format!("{id}_")
|
|
||||||
};
|
|
||||||
let f1 = format!("{id}{FROM_FILE}_{bytes}.txt");
|
|
||||||
let f2 = format!("{id}{TO_FILE}_{bytes}.txt");
|
|
||||||
let from_path = dir.join(f1);
|
|
||||||
let to_path = dir.join(f2);
|
|
||||||
|
|
||||||
generate_file_bytes(&from_path, &to_path, bytes, num_differences)?;
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
from_path.to_string_lossy().to_string(),
|
|
||||||
to_path.to_string_lossy().to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_file_bytes(
|
|
||||||
from_name: &Path,
|
|
||||||
to_name: &Path,
|
|
||||||
bytes: u64,
|
|
||||||
num_differences: u64,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
let file_from = File::create(from_name)?;
|
|
||||||
let file_to = File::create(to_name)?;
|
|
||||||
// for int division, lines will be smaller than requested bytes
|
|
||||||
let n_lines = bytes / LINE_LENGTH as u64;
|
|
||||||
let change_every_n_lines = if num_differences == 0 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
let c = n_lines / num_differences;
|
|
||||||
if c == 0 {
|
|
||||||
1
|
|
||||||
} else {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Use a larger 128KB buffer for massive files
|
|
||||||
let mut writer_from = BufWriter::with_capacity(128 * 1024, file_from);
|
|
||||||
let mut writer_to = BufWriter::with_capacity(128 * 1024, file_to);
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
|
|
||||||
// Each line: (5 chars * 10 words) + 9 spaces + 1 newline = 60 bytes
|
|
||||||
let mut line_buffer = [b' '; 60];
|
|
||||||
line_buffer[59] = b'\n'; // Set the newline once at the end
|
|
||||||
|
|
||||||
for i in (0..n_lines).rev() {
|
|
||||||
// Fill only the letter positions, skipping spaces and the newline
|
|
||||||
for word_idx in 0..10 {
|
|
||||||
let start = word_idx * 6; // Each word + space block is 6 bytes
|
|
||||||
for i in 0..5 {
|
|
||||||
line_buffer[start + i] = rng.random_range(b'a'..b'z' + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the raw bytes directly to both files
|
|
||||||
writer_from.write_all(&line_buffer)?;
|
|
||||||
// make changes in the file
|
|
||||||
if num_differences == 0 {
|
|
||||||
writer_to.write_all(&line_buffer)?;
|
|
||||||
} else {
|
|
||||||
if i % change_every_n_lines == 0 && n_lines - i > 2 {
|
|
||||||
line_buffer[5] = CHANGE_CHAR;
|
|
||||||
}
|
|
||||||
writer_to.write_all(&line_buffer)?;
|
|
||||||
line_buffer[5] = b' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create last line
|
|
||||||
let missing = (bytes - n_lines as u64 * LINE_LENGTH as u64) as usize;
|
|
||||||
if missing > 0 {
|
|
||||||
for word_idx in 0..10 {
|
|
||||||
let start = word_idx * 6; // Each word + space block is 6 bytes
|
|
||||||
for i in 0..5 {
|
|
||||||
line_buffer[start + i] = rng.random_range(b'a'..b'z' + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line_buffer[missing - 1] = b'\n';
|
|
||||||
writer_from.write_all(&line_buffer[0..missing])?;
|
|
||||||
writer_to.write_all(&line_buffer[0..missing])?;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer_from.flush()?;
|
|
||||||
writer_to.flush()?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod binary {
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use crate::prepare::str_to_options;
|
|
||||||
|
|
||||||
pub fn bench_binary(program: &str, cmd_args: &str) -> std::process::ExitStatus {
|
|
||||||
let args = str_to_options(cmd_args);
|
|
||||||
Command::new(program)
|
|
||||||
.args(args)
|
|
||||||
.status()
|
|
||||||
.expect("Failed to execute binary")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Run registered benchmarks.
|
|
||||||
divan::main();
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[workspace]
|
|
||||||
members = ["cargo:."]
|
|
||||||
|
|
||||||
# Config for 'dist'
|
|
||||||
[dist]
|
|
||||||
# The preferred dist version to use in CI (Cargo.toml SemVer syntax)
|
|
||||||
cargo-dist-version = "0.30.3"
|
|
||||||
# CI backends to support
|
|
||||||
ci = "github"
|
|
||||||
# The installers to generate for each app
|
|
||||||
installers = []
|
|
||||||
# Target platforms to build apps for (Rust target-triple syntax)
|
|
||||||
targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"]
|
|
||||||
Generated
-447
@@ -1,447 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "1.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android_system_properties"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arbitrary"
|
|
||||||
version = "1.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bumpalo"
|
|
||||||
version = "3.20.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.2.60"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
|
|
||||||
dependencies = [
|
|
||||||
"find-msvc-tools",
|
|
||||||
"jobserver",
|
|
||||||
"libc",
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
|
||||||
dependencies = [
|
|
||||||
"iana-time-zone",
|
|
||||||
"js-sys",
|
|
||||||
"num-traits",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "core-foundation-sys"
|
|
||||||
version = "0.8.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "diff"
|
|
||||||
version = "0.1.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "diffutils"
|
|
||||||
version = "0.5.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"diff",
|
|
||||||
"itoa",
|
|
||||||
"regex",
|
|
||||||
"same-file",
|
|
||||||
"unicode-width",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "find-msvc-tools"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getrandom"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"r-efi",
|
|
||||||
"wasip2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone"
|
|
||||||
version = "0.1.65"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
|
||||||
dependencies = [
|
|
||||||
"android_system_properties",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"iana-time-zone-haiku",
|
|
||||||
"js-sys",
|
|
||||||
"log",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone-haiku"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jobserver"
|
|
||||||
version = "0.1.34"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "js-sys"
|
|
||||||
version = "0.3.94"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.184"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libfuzzer-sys"
|
|
||||||
version = "0.4.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2"
|
|
||||||
dependencies = [
|
|
||||||
"arbitrary",
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.21.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.106"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "r-efi"
|
|
||||||
version = "5.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.12.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-automata",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-automata"
|
|
||||||
version = "0.4.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.8.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustversion"
|
|
||||||
version = "1.0.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "same-file"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.24"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unified-diff-fuzz"
|
|
||||||
version = "0.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"diffutils",
|
|
||||||
"libfuzzer-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasip2"
|
|
||||||
version = "1.0.2+wasi-0.2.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
|
|
||||||
dependencies = [
|
|
||||||
"wit-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen"
|
|
||||||
version = "0.2.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
"rustversion",
|
|
||||||
"wasm-bindgen-macro",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro"
|
|
||||||
version = "0.2.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"wasm-bindgen-macro-support",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro-support"
|
|
||||||
version = "0.2.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
|
|
||||||
dependencies = [
|
|
||||||
"bumpalo",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-shared"
|
|
||||||
version = "0.2.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-util"
|
|
||||||
version = "0.1.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-core"
|
|
||||||
version = "0.62.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
|
||||||
dependencies = [
|
|
||||||
"windows-implement",
|
|
||||||
"windows-interface",
|
|
||||||
"windows-link",
|
|
||||||
"windows-result",
|
|
||||||
"windows-strings",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-implement"
|
|
||||||
version = "0.60.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-interface"
|
|
||||||
version = "0.59.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-link"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.61.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wit-bindgen"
|
|
||||||
version = "0.51.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
|
||||||
+2
-18
@@ -9,25 +9,13 @@ edition = "2018"
|
|||||||
cargo-fuzz = true
|
cargo-fuzz = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libfuzzer-sys = "0.4.7"
|
libfuzzer-sys = "0.4"
|
||||||
diffutils = { path = "../" }
|
diffutils = { path = "../" }
|
||||||
|
|
||||||
# Prevent this from interfering with workspaces
|
# Prevent this from interfering with workspaces
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["."]
|
members = ["."]
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_cmp"
|
|
||||||
path = "fuzz_targets/fuzz_cmp.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_cmp_args"
|
|
||||||
path = "fuzz_targets/fuzz_cmp_args.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_patch"
|
name = "fuzz_patch"
|
||||||
path = "fuzz_targets/fuzz_patch.rs"
|
path = "fuzz_targets/fuzz_patch.rs"
|
||||||
@@ -47,8 +35,4 @@ path = "fuzz_targets/fuzz_ed.rs"
|
|||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_side"
|
|
||||||
path = "fuzz_targets/fuzz_side.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
"-l"
|
|
||||||
"--verbose"
|
|
||||||
"-b"
|
|
||||||
"--print-bytes"
|
|
||||||
"-lb"
|
|
||||||
"-bl"
|
|
||||||
"-n"
|
|
||||||
"--bytes"
|
|
||||||
"--bytes="
|
|
||||||
"--bytes=1024"
|
|
||||||
"--bytes=99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
|
||||||
"-i"
|
|
||||||
"--ignore-initial"
|
|
||||||
"--ignore-initial="
|
|
||||||
"--ignore-initial=1024"
|
|
||||||
"--ignore-initial=99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999:9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"
|
|
||||||
"-s"
|
|
||||||
"-q"
|
|
||||||
"--quiet"
|
|
||||||
"--silent"
|
|
||||||
"-"
|
|
||||||
"--"
|
|
||||||
"1kB"
|
|
||||||
"1G"
|
|
||||||
"1GB"
|
|
||||||
"1T"
|
|
||||||
"1TB"
|
|
||||||
"1P"
|
|
||||||
"1PB"
|
|
||||||
"1Z"
|
|
||||||
"1ZB"
|
|
||||||
"1Y"
|
|
||||||
"1YB"
|
|
||||||
"1Y"
|
|
||||||
"0"
|
|
||||||
"1:2"
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user