diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml new file mode 100644 index 0000000..63b8a4d --- /dev/null +++ b/.github/workflows/GnuTests.yml @@ -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 diff --git a/util/build-gnu.sh b/util/build-gnu.sh new file mode 100755 index 0000000..f91490a --- /dev/null +++ b/util/build-gnu.sh @@ -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) diff --git a/util/run-gnu-test.sh b/util/run-gnu-test.sh new file mode 100755 index 0000000..770c796 --- /dev/null +++ b/util/run-gnu-test.sh @@ -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