Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/GnuTests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: GnuTests

on:
pull_request:
push:
branches:
- '*'

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
native:
name: Run GNU tests (native)
runs-on: ubuntu-24.04
steps:
- name: Checkout code (uutils)
uses: actions/checkout@v4
with:
path: 'uutils'
persist-credentials: false

- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: rustfmt

- uses: Swatinem/rust-cache@v2
with:
workspaces: "./uutils -> target"

- name: Install dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y autoconf autopoint bison texinfo gperf gcc g++ gdb python3-pyinotify jq valgrind libacl1-dev libattr1-dev libcap-dev libselinux1-dev attr quilt gettext

- name: Build binaries and GNU tar
shell: bash
run: |
cd 'uutils'
# This script will clone GNU tar and build everything
bash util/build-gnu.sh --release-build

- name: Run GNU tests
shell: bash
run: |
cd 'uutils'
bash util/run-gnu-test.sh
60 changes: 60 additions & 0 deletions util/build-gnu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
set -e

ME="${0}"
ME_dir="$(dirname -- "$("${READLINK:-readlink}" -fm -- "${ME}")")"
REPO_main_dir="$(dirname -- "${ME_dir}")"

# Default profile is 'debug'
UU_MAKE_PROFILE='debug'

for arg in "$@"
do
if [ "$arg" == "--release-build" ]; then
UU_MAKE_PROFILE='release'
break
fi
done

path_UUTILS=${path_UUTILS:-${REPO_main_dir}}
path_GNU="${path_GNU:-${path_UUTILS}/../gnu}"

echo "Building uutils tar..."
cd "${path_UUTILS}"
cargo build --profile "${UU_MAKE_PROFILE}" --bin tarapp

if [[ ! -z "$CARGO_TARGET_DIR" ]]; then
UU_BUILD_DIR="${CARGO_TARGET_DIR}/${UU_MAKE_PROFILE}"
else
UU_BUILD_DIR="${path_UUTILS}/target/${UU_MAKE_PROFILE}"
fi

# Symlink tarapp to tar so tests find it as 'tar'
ln -sf "${UU_BUILD_DIR}/tarapp" "${UU_BUILD_DIR}/tar"
echo "Created symlink ${UU_BUILD_DIR}/tar -> tarapp"

# Clone GNU tar if needed
if test ! -d "${path_GNU}/.git"; then
echo "Cloning GNU tar..."
git clone --recurse-submodules https://git.savannah.gnu.org/git/tar.git "${path_GNU}"
cd "${path_GNU}"
# Checkout v1.35
git checkout v1.35

# Bootstrap requires gnulib.
# If git clone --recurse-submodules was used it might be there, but standard bootstrap fetches it.
# We need to make sure we have dependencies.
# FORCE_UNSAFE_CONFIGURE=1 might be needed if running as root in some envs, but usually fine.
./bootstrap --skip-po
fi

cd "${path_GNU}"

if [ ! -f Makefile ]; then
echo "Configuring GNU tar..."
# Configure to build native tar (needed for test suite generation)
./configure --quiet
fi

echo "Building GNU tar (for test suite)..."
make -j$(nproc)
52 changes: 52 additions & 0 deletions util/run-gnu-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
set -e

# Use GNU version for make, nproc, readlink on *BSD
case "$OSTYPE" in
*bsd*)
MAKE="gmake"
NPROC="gnproc"
READLINK="greadlink"
;;
*)
MAKE="make"
NPROC="nproc"
READLINK="readlink"
;;
esac

ME="${0}"
ME_dir="$(dirname -- "$("${READLINK:-readlink}" -fm -- "${ME}")")"
REPO_main_dir="$(dirname -- "${ME_dir}")"

path_UUTILS=${path_UUTILS:-${REPO_main_dir}}
path_GNU="${path_GNU:-${path_UUTILS}/../gnu}"

# Determine profile
if [[ -d "${path_UUTILS}/target/release" ]]; then
UU_BUILD_DIR="${path_UUTILS}/target/release"
elif [[ -d "${path_UUTILS}/target/debug" ]]; then
UU_BUILD_DIR="${path_UUTILS}/target/debug"
else
echo "Could not find build directory in ${path_UUTILS}/target"
exit 1
fi

echo "Using uutils tar from: ${UU_BUILD_DIR}"

cd "${path_GNU}"

export RUST_BACKTRACE=1

# The GNU tar testsuite usually looks for 'tar' in the path or uses the one in src/
# We force it to use ours by putting it first in PATH.
export PATH="${UU_BUILD_DIR}:$PATH"
export TAR="${UU_BUILD_DIR}/tar"

echo "Running GNU tar tests..."

# Run with timeout and make check
# We use TAR to set the tar binary for the testsuite
# Then we use $* to pass any additional user arguments (specific tests)
cp "${TAR}" src/tar
timeout -sKILL 4h "${MAKE}" -j "$("${NPROC}")" check
Loading