From bba9bc85a0226d4173cac9249c10fe3d66dbded0 Mon Sep 17 00:00:00 2001 From: Dries Schaumont <5946712+DriesSchaumont@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:34:49 +0200 Subject: [PATCH] BUG: make 'untar' work when extracting a single directory starting with './' (#6) --- src/io/untar/config.vsh.yaml | 6 +----- src/io/untar/script.sh | 17 ++++++++++++++--- src/io/untar/test.sh | 24 ++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/io/untar/config.vsh.yaml b/src/io/untar/config.vsh.yaml index 436d8e4..55eba97 100644 --- a/src/io/untar/config.vsh.yaml +++ b/src/io/untar/config.vsh.yaml @@ -33,8 +33,4 @@ test_resources: path: test.sh engines: - type: docker - image: alpine:latest - setup: - - type: apk - packages: - - bash \ No newline at end of file + image: debian:stable-slim \ No newline at end of file diff --git a/src/io/untar/script.sh b/src/io/untar/script.sh index 997f398..37e5012 100644 --- a/src/io/untar/script.sh +++ b/src/io/untar/script.sh @@ -4,17 +4,27 @@ set -eo pipefail extra_args=() +TMPDIR=$(mktemp -d "$meta_temp_dir/$meta_functionality_name-XXXXXX") +function clean_up { + [[ -d "$TMPDIR" ]] && rm -r "$TMPDIR" +} +trap clean_up EXIT # Check if tarball contains 1 top-level directory. If so, extract the contents of the # directory to the output directory instead of the directory itself. echo "Directory contents:" -tar -taf "${par_input}" +tar -taf "${par_input}" > "$TMPDIR/tar_contents.txt" +cat "$TMPDIR/tar_contents.txt" printf "Checking if tarball contains only a single top-level directory: " -if [[ $(tar -taf ${par_input} | grep -o -E "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then +if [[ $(grep -o -E "^.*?\\/" "$TMPDIR/tar_contents.txt" | uniq | wc -l) -eq 1 ]]; then echo "It does." echo "Extracting the contents of the top-level directory to the output directory instead of the directory itself." - extra_args+=("--strip-components=1") + # The directory can be both of the format './' (or ././) or just + # Adjust the number of stripped components accordingly by looking for './' at the beginning of the file. + starting_relative=$(grep -oP -m 1 '^(./)*' "$TMPDIR/tar_contents.txt" | tr -d '\n' | wc -c) + n_strips=$(( ($starting_relative / 2)+1 )) + extra_args+=("--strip-components=$n_strips") else echo "It does not." fi @@ -26,5 +36,6 @@ fi echo "Starting extraction of tarball '$par_input' to output directory '$par_output'." mkdir -p "$par_output" +echo "executing 'tar --directory=$par_output ${extra_args[@]} -xavf $par_input'" tar --directory="$par_output" ${extra_args[@]} -xavf "$par_input" diff --git a/src/io/untar/test.sh b/src/io/untar/test.sh index ef3fe1e..87a843d 100644 --- a/src/io/untar/test.sh +++ b/src/io/untar/test.sh @@ -8,6 +8,7 @@ TMPDIR=$(mktemp -d "$meta_temp_dir/$meta_functionality_name-XXXXXX") function clean_up { [[ -d "$TMPDIR" ]] && rm -r "$TMPDIR" } +trap clean_up EXIT echo ">>> Created temporary directory '$TMPDIR'." INPUT_FILE="$TMPDIR/test_file.txt" @@ -17,7 +18,7 @@ echo ">>> Created '$INPUT_FILE'." echo ">>> Creating tar.gz from '$INPUT_FILE'." TARFILE="${INPUT_FILE}.tar.gz" -tar czvf ${INPUT_FILE}.tar.gz $(basename "$INPUT_FILE") -C "$TMPDIR" +tar -C "$TMPDIR" -czvf ${INPUT_FILE}.tar.gz $(basename "$INPUT_FILE") [[ ! -f "$TARFILE" ]] && echo ">>> Test setup failed: could not create tarfile." && exit 1 echo ">>> '$TARFILE' created." @@ -50,7 +51,7 @@ echo ">>> Check whether excluded file was not extracted" echo ">>> Creating test tarball containing only 1 top-level directory." mkdir "$TMPDIR/input_test_3/" cp "$INPUT_FILE" "$TMPDIR/input_test_3/" -tar czvf "$TMPDIR/input_test_3.tar.gz" $(basename "$TMPDIR/input_test_3") -C "$TMPDIR" +tar -C "$TMPDIR" -czvf "$TMPDIR/input_test_3.tar.gz" $(basename "$TMPDIR/input_test_3") TARFILE_3="$TMPDIR/input_test_3.tar.gz" echo ">>> Creating temporary output directory for test 3." @@ -65,4 +66,23 @@ echo "Extracting '$TARFILE_3' to '$OUTPUT_DIR_3'". echo ">>> Check whether extracted file exists" [[ ! -f "$OUTPUT_DIR_3/test_file.txt" ]] && echo "Output file could not be found!" && exit 1 +echo ">>> Check for tar archive that contains a single directory starting with './'." +mkdir "$TMPDIR/input_test_4/" +cp "$INPUT_FILE" "$TMPDIR/input_test_4/" + +pushd "$TMPDIR/" +trap popd ERR +tar -czvf "$TMPDIR/input_test_4.tar.gz" ./input_test_4 +popd +trap - ERR + +OUTPUT_DIR_4="$TMPDIR/output_test_4/" +echo "Extracting '$TMPDIR/input_test_4.tar.gz' to '$OUTPUT_DIR_4'". +./$meta_functionality_name \ + --input "$TMPDIR/input_test_4.tar.gz" \ + --output "$OUTPUT_DIR_4" + +echo ">>> Check whether extracted file exists" +[[ ! -f "$OUTPUT_DIR_4/test_file.txt" ]] && echo "Output file could not be found!" && exit 1 + echo ">>> Test finished successfully"