mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-27 01:57:41 +00:00
Merge pull request #15566 from keymanapp/fix/linux/15544_sourcepkg
fix(linux): include missing artifacts in source tarball 🗜️ With this change it's possible to build Keyman from the source tarball by running `./build.sh` from the Keyman root directory. When building Keyman as part of the Ubuntu/Debian packaging, we don't use the toplevel `build.sh` file but instead call the build scripts in the subdirectories. This omits building some components that are currently not needed for running Keyman for Linux. The `dist.sh` script only includes the necessary files in this case, distinguished by the `origdist` parameter. This results in a significantly smaller tarball (2.5MB vs 51MB). This change also enhances the `generate_tar_ignore_list` function so that it is now possible to add `build` to the exclude list to ignore all `build` subdirectories. Fixes: #15544
This commit is contained in:
commit
e776a2cf76
5 changed files with 687 additions and 75 deletions
|
|
@ -39,8 +39,9 @@ dch keyman --newversion "${KEYMAN_VERSION}" --force-bad-version --nomultimaint
|
|||
|
||||
# Create the tarball
|
||||
|
||||
# files and folders to include in the tarball
|
||||
# shellcheck disable=2034 # to_exclude appears to be unused
|
||||
# We always include these files which are the minimum files and
|
||||
# folder required for Ubuntu/Debian packaging
|
||||
# shellcheck disable=2034 # to_include appears to be unused
|
||||
to_include=(
|
||||
common/build.sh \
|
||||
common/cpp \
|
||||
|
|
@ -60,18 +61,61 @@ to_include=(
|
|||
|
||||
# files and subfolders to exclude from paths included in 'to_include',
|
||||
# i.e. the exceptions to 'to_include'.
|
||||
|
||||
# shellcheck disable=2034 # to_exclude appears to be unused
|
||||
to_exclude=(
|
||||
build \
|
||||
common/test/keyboards/baseline/kmcomp-*.zip \
|
||||
core/build \
|
||||
linux/build \
|
||||
linux/builddebs \
|
||||
linux/docs/help \
|
||||
linux/keyman-config/keyman_config/version.py \
|
||||
linux/keyman-config/buildtools/build-langtags.py \
|
||||
linux/keyman-system-service/build
|
||||
)
|
||||
|
||||
if [[ -z "${create_origdist+x}" ]]; then
|
||||
# If we build a full source tarball we include additional files
|
||||
# so that it's possible to run `${KEYMAN_ROOT}/build.sh` on Linux
|
||||
|
||||
# shellcheck disable=2034 # to_include appears to be unused
|
||||
to_include+=(
|
||||
common/tools/hextobin \
|
||||
common/web/keyman-version \
|
||||
common/web/langtags \
|
||||
common/web/types \
|
||||
common/windows/cpp \
|
||||
common/windows/include \
|
||||
developer/src/common/include \
|
||||
developer/src/common/web \
|
||||
developer/src/ext/json \
|
||||
developer/src/kmc \
|
||||
developer/src/kmc-analyze \
|
||||
developer/src/kmc-copy \
|
||||
developer/src/kmc-generate \
|
||||
developer/src/kmc-keyboard-info \
|
||||
developer/src/kmc-kmn \
|
||||
developer/src/kmc-ldml \
|
||||
developer/src/kmc-model \
|
||||
developer/src/kmc-model-info \
|
||||
developer/src/kmc-package \
|
||||
developer/src/kmcmplib \
|
||||
docs/minimum-versions.md.in
|
||||
resources/build \
|
||||
resources/standards-data \
|
||||
)
|
||||
|
||||
# additional files and subfolders to exclude from paths included in 'to_include',
|
||||
# i.e. the exceptions to 'to_include'.
|
||||
# shellcheck disable=2034 # to_exclude appears to be unused
|
||||
to_exclude+=(
|
||||
*.exe \
|
||||
resources/build/history \
|
||||
resources/build/l10n \
|
||||
resources/build/mac \
|
||||
resources/build/win \
|
||||
resources/build/*.lua \
|
||||
)
|
||||
fi
|
||||
|
||||
# array to store list of --tar-ignore parameters generated from to_include and to_exclude.
|
||||
ignored_files=()
|
||||
|
||||
|
|
@ -109,7 +153,7 @@ cd "${BASEDIR}"
|
|||
|
||||
# create orig.tar.gz
|
||||
if [[ ! -z "${create_origdist+x}" ]]; then
|
||||
cd dist
|
||||
cd "${KEYMAN_ROOT}/linux/dist"
|
||||
pkgvers="keyman-${KEYMAN_VERSION}"
|
||||
tar xfz keyman-"${KEYMAN_VERSION}".tar.gz
|
||||
mv -v keyman "${pkgvers}" 2>/dev/null || mv -v "$(find . -mindepth 1 -maxdepth 1 -type d)" "${pkgvers}"
|
||||
|
|
|
|||
|
|
@ -91,78 +91,135 @@ function generate_tar_ignore_list() {
|
|||
local list_var="$4"
|
||||
local prefix="$5"
|
||||
local includes_array="${includes_var}[@]"
|
||||
# shellcheck disable=SC2034
|
||||
local includes=("${!includes_array}")
|
||||
local excludes_array="${excludes_var}[@]"
|
||||
local excludes=("${!excludes_array}")
|
||||
local dir all_dirs found_match inc
|
||||
|
||||
mapfile -t all_dirs < <(find "${directory}" -mindepth 1 -maxdepth 1 -type d | sort)
|
||||
for dir in "${all_dirs[@]}"; do
|
||||
found_match=false
|
||||
for inc in "${includes[@]}"; do
|
||||
if [[ "./${inc}" =~ ^${dir} ]]; then
|
||||
found_match=true
|
||||
if [[ "./${inc}" != "${dir}" ]]; then
|
||||
# check subdirectories
|
||||
generate_tar_ignore_list "${dir}" "${includes_var}" "${excludes_var}" "${list_var}" "${prefix}"
|
||||
fi
|
||||
# check if files/subdir in $dir are in excludes list
|
||||
_generate_excludes_for_dir "${dir}" "${includes_var}" "${excludes_var}" "${list_var}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ! ${found_match}; then
|
||||
_add_to_list "${list_var}" "${dir}"
|
||||
# Loop through excludes and put all without path in single_excludes
|
||||
local single_excludes=()
|
||||
for item in "${excludes[@]}"; do
|
||||
if [[ ${item} != */* ]]; then
|
||||
single_excludes+=("${item}")
|
||||
fi
|
||||
done
|
||||
|
||||
local ignore_list=()
|
||||
_process_directory "${directory}" false
|
||||
|
||||
for item in "${ignore_list[@]}"; do
|
||||
eval "${list_var}+=(\"--tar-ignore=${item}\")"
|
||||
done
|
||||
}
|
||||
|
||||
function _generate_excludes_for_dir() {
|
||||
function _process_directory() {
|
||||
local directory="$1"
|
||||
local includes_var="$2"
|
||||
local excludes_var="$3"
|
||||
local list_var="$4"
|
||||
local includes_array="${includes_var}[@]"
|
||||
local includes=("${!includes_array}")
|
||||
local excludes_array="${excludes_var}[@]"
|
||||
local excludes=("${!excludes_array}")
|
||||
local file all_files excluded included is_match
|
||||
local isParentIncluded="$2"
|
||||
local all_items item
|
||||
|
||||
mapfile -t all_files < <(find "${directory}" -mindepth 1 -maxdepth 1 | sort)
|
||||
is_match=false
|
||||
for file in "${all_files[@]}"; do
|
||||
for included in "${includes[@]}"; do
|
||||
if [[ "${file}" == ./${included} ]]; then
|
||||
is_match=true
|
||||
break
|
||||
mapfile -t all_items < <(find "${directory}" -mindepth 1 -maxdepth 1 | sort)
|
||||
for item in "${all_items[@]}"; do
|
||||
debug "Checking item: ${item}"
|
||||
if _is_exact_match "includes" "${item}"; then
|
||||
debug " Including (full match): ${item}"
|
||||
if [[ -d "${item}" ]]; then
|
||||
_process_directory "${item}" true
|
||||
fi
|
||||
done
|
||||
if ${is_match} ; then
|
||||
if [[ "${file}" != ./${included} ]] && [[ -f "${file}" ]]; then
|
||||
_add_to_list "${list_var}" "${file}"
|
||||
elif _starts_with "includes" "${item}"; then
|
||||
debug " Including (partial match): ${item}"
|
||||
if [[ -d "${item}" ]]; then
|
||||
_process_directory "${item}" "${isParentIncluded}"
|
||||
fi
|
||||
elif _is_exact_match "excludes" "${item}"; then
|
||||
debug " Excluding (full match): ${item}"
|
||||
_add_to_list "${item}"
|
||||
elif _ends_with "single_excludes" "${item}" || _is_wildcard_match "single_excludes" "${item}"; then
|
||||
debug " Excluding (single exclude): ${item}"
|
||||
_add_to_list "${item}"
|
||||
elif [[ "${isParentIncluded}" == "false" ]]; then
|
||||
debug " Excluding (not included): ${item}"
|
||||
_add_to_list "${item}"
|
||||
else
|
||||
for excluded in "${excludes[@]}"; do
|
||||
if [[ "${file}" == ./${excluded} ]]; then
|
||||
_add_to_list "${list_var}" "${file}"
|
||||
break
|
||||
elif [[ "./${excluded}" =~ ^${file} ]]; then
|
||||
# check subdirectories
|
||||
_generate_excludes_for_dir "${file}" "${includes_var}" "${excludes_var}" "${list_var}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
debug " Including (parent included): ${item}"
|
||||
if [[ -d "${item}" ]]; then
|
||||
_process_directory "${item}" "${isParentIncluded}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function _add_to_list() {
|
||||
local list_var="$1"
|
||||
local filename="$2"
|
||||
|
||||
# Note: the files end up in subdirectories under `keyman` (or rather
|
||||
# the directory name of $KEYMAN_ROOT), so we can
|
||||
# include that when matching files and directories to ignore.
|
||||
# shellcheck disable=SC2154
|
||||
eval "${list_var}+=(\"--tar-ignore=${prefix}/${filename#./}\")"
|
||||
local item="$1"
|
||||
ignore_list+=("${prefix}/${item#./}")
|
||||
}
|
||||
|
||||
# Returns true if one of the values in the $1 array equals ${file} ($2)
|
||||
# Example: will return true for array=(path1/path2) file=./path1/path2
|
||||
function _is_exact_match() {
|
||||
local array_var="$1"
|
||||
local file="$2"
|
||||
local array_name="${array_var}[@]"
|
||||
local haystack=("${!array_name}")
|
||||
local item
|
||||
for item in "${haystack[@]}"; do
|
||||
if [[ "./${item#./}" == "${file}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Returns true if one of the values in the $1 array starts with ${file} ($2)
|
||||
# Example: will return true for array=(path1/path2) file=./path1
|
||||
function _starts_with() {
|
||||
local array_var="$1"
|
||||
local file="$2"
|
||||
local array_name="${array_var}[@]"
|
||||
local array_values=("${!array_name}")
|
||||
local array_item
|
||||
for array_item in "${array_values[@]}"; do
|
||||
if [[ "./${array_item#./}" == ${file}* ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Returns true if ${file} ($2) ends with one of the values in the $1 array
|
||||
# Example: will return true for array=(path2) file=./path1/path2
|
||||
function _ends_with() {
|
||||
local array_var="$1"
|
||||
local file="$2"
|
||||
local array_name="${array_var}[@]"
|
||||
local array_values=("${!array_name}")
|
||||
local array_item
|
||||
for array_item in "${array_values[@]}"; do
|
||||
if [[ "${file}" == */${array_item#./} ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Returns true if ${file} ($2) matches one of the values of the $1 array.
|
||||
# These values may contain wildcards.
|
||||
# Example: will return true for array=(*.sh) file=./path1/build.sh
|
||||
function _is_wildcard_match() {
|
||||
local array_var="$1"
|
||||
local file="$2"
|
||||
local array_name="${array_var}[@]"
|
||||
local array_values=("${!array_name}")
|
||||
local array_item
|
||||
for array_item in "${array_values[@]}"; do
|
||||
array_item=${array_item/./\\.}
|
||||
if [[ "${file}" =~ /${array_item/\*/.\*}$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function debug() {
|
||||
# echo "$@"
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,61 +16,105 @@ function setup_file() {
|
|||
# Create directory structure for testing
|
||||
# /
|
||||
# /subdir1
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /README.md
|
||||
# /path1
|
||||
# /abc.build
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /README.md
|
||||
# /x/z.txt
|
||||
# /xy/z.txt
|
||||
# /path2
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /path3
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /subdir2
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /path1
|
||||
# /build/foo
|
||||
# /subdir3
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /path1
|
||||
# /build/foo
|
||||
# /path2
|
||||
# /build/foo
|
||||
# /path3
|
||||
# /subdir4
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /path1
|
||||
# /build.sh
|
||||
# /path2
|
||||
# /subpath1
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /subpath2
|
||||
# /build/foo
|
||||
# /build.sh
|
||||
# /path3
|
||||
# /build.sh
|
||||
# /build.sh
|
||||
# subdir1/path2, subdir2, subdir4/path1, subdir4/path2/subpath1,
|
||||
# and subdir4/path3 will be ignored
|
||||
mkdir -p "${temp_dir}/subdir1/path1" # include
|
||||
touch "${temp_dir}/subdir1/build.sh"
|
||||
# all build/ directories will be ignored with the exception of
|
||||
# subdir3/build.
|
||||
mkdir -p "${temp_dir}/subdir1/build" # exclude
|
||||
touch "${temp_dir}/subdir1/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir1/path1/build"
|
||||
touch "${temp_dir}/subdir1/path1/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir1/path1/x"
|
||||
touch "${temp_dir}/subdir1/path1/x/z.txt"
|
||||
mkdir -p "${temp_dir}/subdir1/path1/xy"
|
||||
touch "${temp_dir}/subdir1/path1/xy/z.txt"
|
||||
touch "${temp_dir}/subdir1/build.sh" # include
|
||||
touch "${temp_dir}/subdir1/README.md" # exclude
|
||||
touch "${temp_dir}/subdir1/path1/abc.build"
|
||||
touch "${temp_dir}/subdir1/path1/build.sh" # include
|
||||
touch "${temp_dir}/subdir1/path1/README.md" # exclude
|
||||
mkdir -p "${temp_dir}/subdir1/path2" # exclude
|
||||
touch "${temp_dir}/subdir1/path2/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir1/path3" # include
|
||||
touch "${temp_dir}/subdir1/path3/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir2/path1" # exclude
|
||||
mkdir -p "${temp_dir}/subdir1/path2/build"
|
||||
touch "${temp_dir}/subdir1/path2/build/foo" # exclude
|
||||
touch "${temp_dir}/subdir1/path2/build.sh" # exclude
|
||||
mkdir -p "${temp_dir}/subdir1/path3/build"
|
||||
touch "${temp_dir}/subdir1/path2/build/foo" # exclude
|
||||
touch "${temp_dir}/subdir1/path3/build.sh" # include
|
||||
mkdir -p "${temp_dir}/subdir2/build" # exclude
|
||||
touch "${temp_dir}/subdir2/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir2/path1/build" # exclude
|
||||
touch "${temp_dir}/subdir2/path1/build/foo" # exclude
|
||||
touch "${temp_dir}/subdir2/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir3/build" # include
|
||||
touch "${temp_dir}/subdir3/build/foo" # include
|
||||
mkdir -p "${temp_dir}/subdir3/path1" # include
|
||||
touch "${temp_dir}/subdir3/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir3/path1/build" # exclude
|
||||
touch "${temp_dir}/subdir3/path1/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir3/path2" # include
|
||||
mkdir -p "${temp_dir}/subdir3/path2/build" # exclude
|
||||
touch "${temp_dir}/subdir3/path2/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir3/path3" # include
|
||||
mkdir -p "${temp_dir}/subdir4/build" # exclude
|
||||
touch "${temp_dir}/subdir4/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir4/path1" # exclude
|
||||
touch "${temp_dir}/subdir4/build.sh"
|
||||
touch "${temp_dir}/subdir4/path1/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir4/path2/subpath1" # exclude
|
||||
touch "${temp_dir}/subdir4/path2/subpath1/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir4/path2/subpath1/build" # exclude
|
||||
touch "${temp_dir}/subdir4/path2/subpath1/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir4/path2/subpath2" # include
|
||||
touch "${temp_dir}/subdir4/path2/subpath2/build.sh"
|
||||
mkdir -p "${temp_dir}/subdir4/path2/subpath2/build" # exclude
|
||||
touch "${temp_dir}/subdir4/path2/subpath2/build/foo" # exclude
|
||||
mkdir -p "${temp_dir}/subdir4/path3" # exclude
|
||||
touch "${temp_dir}/subdir4/path3/build.sh"
|
||||
touch "${temp_dir}/subdir4/path3/other.txt"
|
||||
touch "${temp_dir}/build.sh"
|
||||
}
|
||||
|
||||
function teardown_file() {
|
||||
|
|
@ -89,9 +133,14 @@ function test__generate_tar_ignore_list__basic() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=test1/build.sh
|
||||
--tar-ignore=test1/subdir1/build
|
||||
--tar-ignore=test1/subdir1/build.sh
|
||||
--tar-ignore=test1/subdir1/path2
|
||||
--tar-ignore=test1/subdir1/README.md
|
||||
--tar-ignore=test1/subdir2
|
||||
--tar-ignore=test1/subdir4/build
|
||||
--tar-ignore=test1/subdir4/build.sh
|
||||
--tar-ignore=test1/subdir4/path1
|
||||
--tar-ignore=test1/subdir4/path2/subpath1
|
||||
--tar-ignore=test1/subdir4/path3
|
||||
|
|
@ -113,6 +162,9 @@ function test__generate_tar_ignore_list__path_wildcard_in_exclude() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=foo/build.sh # not in include
|
||||
--tar-ignore=foo/subdir1/build # not in include
|
||||
--tar-ignore=foo/subdir1/build.sh # not in include
|
||||
--tar-ignore=foo/subdir1/path1/README.md # in exclude
|
||||
--tar-ignore=foo/subdir1/path2 # not in include
|
||||
--tar-ignore=foo/subdir1/README.md # not in include
|
||||
|
|
@ -136,10 +188,12 @@ function test__generate_tar_ignore_list__file_wildcard_in_exclude() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=keyman/build.sh # not in include
|
||||
--tar-ignore=keyman/subdir1/build # not in include
|
||||
--tar-ignore=keyman/subdir1/build.sh # not in include
|
||||
--tar-ignore=keyman/subdir1/path1/build.sh # in exclude
|
||||
--tar-ignore=keyman/subdir1/path2 # not in include
|
||||
--tar-ignore=keyman/subdir1/path3/build.sh # in exclude
|
||||
--tar-ignore=keyman/subdir1/build.sh # not in include
|
||||
--tar-ignore=keyman/subdir1/README.md # not in include
|
||||
--tar-ignore=keyman/subdir2 # not in include
|
||||
--tar-ignore=keyman/subdir3/build.sh # in exclude
|
||||
|
|
@ -162,13 +216,17 @@ function test__generate_tar_ignore_list__file_wildcard_in_include() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=xyz/build.sh # not in include
|
||||
--tar-ignore=xyz/subdir1/build # not in include
|
||||
--tar-ignore=xyz/subdir1/build.sh # not in include
|
||||
--tar-ignore=xyz/subdir1/path2 # not in include
|
||||
--tar-ignore=xyz/subdir1/README.md # in exclude
|
||||
--tar-ignore=xyz/subdir2 # not in include
|
||||
--tar-ignore=xyz/subdir4/build # not in include
|
||||
--tar-ignore=xyz/subdir4/build.sh # not in include
|
||||
--tar-ignore=xyz/subdir4/path1 # not in include
|
||||
--tar-ignore=xyz/subdir4/path2 # not in include
|
||||
--tar-ignore=xyz/subdir4/path3/other.txt # not in include
|
||||
--tar-ignore=xyz/subdir4/path2/subpath1 # not necessary, but in exclude
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
|
|
@ -187,9 +245,14 @@ function test__generate_tar_ignore_list__path_wildcard_in_include() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=bar/build.sh # not in include
|
||||
--tar-ignore=bar/subdir1/build # not in include
|
||||
--tar-ignore=bar/subdir1/build.sh # not in include
|
||||
--tar-ignore=bar/subdir1/path2 # not in include
|
||||
--tar-ignore=bar/subdir1/README.md # not in include
|
||||
--tar-ignore=bar/subdir2 # not in include
|
||||
--tar-ignore=bar/subdir4/build # not in include
|
||||
--tar-ignore=bar/subdir4/build.sh # not in include
|
||||
--tar-ignore=bar/subdir4/path1 # not in include
|
||||
--tar-ignore=bar/subdir4/path2/subpath1 # not in include
|
||||
--tar-ignore=bar/subdir4/path3 # not in include
|
||||
|
|
@ -210,15 +273,370 @@ function test__generate_tar_ignore_list__exclude_subsubdir() {
|
|||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=baz/subdir1
|
||||
--tar-ignore=baz/subdir2
|
||||
--tar-ignore=baz/subdir3
|
||||
--tar-ignore=baz/subdir4/path2/subpath2
|
||||
--tar-ignore=baz/build.sh # not in include
|
||||
--tar-ignore=baz/subdir1 # not in include
|
||||
--tar-ignore=baz/subdir2 # not in include
|
||||
--tar-ignore=baz/subdir3 # not in include
|
||||
--tar-ignore=baz/subdir4/path2/subpath2 # in exclude
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
}
|
||||
|
||||
function test__generate_tar_ignore_list__exclude_build_Dirs() {
|
||||
to_include=(subdir1/path1 subdir1/path3 subdir3 subdir3/build subdir4/path2)
|
||||
to_exclude=(subdir1/README.md subdir4/path2/subpath1 subdir4/path2/subpath3 build)
|
||||
|
||||
cd "${temp_dir}"
|
||||
ignored_files=()
|
||||
|
||||
# Execute
|
||||
generate_tar_ignore_list "./" to_include to_exclude ignored_files wildcard
|
||||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=wildcard/build.sh # not in include
|
||||
--tar-ignore=wildcard/subdir1/build # in exclude
|
||||
--tar-ignore=wildcard/subdir1/build.sh # not in include
|
||||
--tar-ignore=wildcard/subdir1/path1/build # in exclude
|
||||
--tar-ignore=wildcard/subdir1/path2 # not in include
|
||||
--tar-ignore=wildcard/subdir1/path3/build # in exclude
|
||||
--tar-ignore=wildcard/subdir1/README.md # in exclude
|
||||
--tar-ignore=wildcard/subdir2 # not in include
|
||||
--tar-ignore=wildcard/subdir3/path1/build # in exclude
|
||||
--tar-ignore=wildcard/subdir3/path2/build # in exclude
|
||||
--tar-ignore=wildcard/subdir4/build # in exclude
|
||||
--tar-ignore=wildcard/subdir4/build.sh # not in include
|
||||
--tar-ignore=wildcard/subdir4/path1 # not in include
|
||||
--tar-ignore=wildcard/subdir4/path2/subpath1 # in exclude
|
||||
--tar-ignore=wildcard/subdir4/path2/subpath2/build # in exclude
|
||||
--tar-ignore=wildcard/subdir4/path3 # not in include
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
}
|
||||
|
||||
function test__generate_tar_ignore_list__exclude_xy() {
|
||||
to_include=(subdir1 subdir2 subdir3 subdir4)
|
||||
to_exclude=(xy)
|
||||
|
||||
cd "${temp_dir}"
|
||||
ignored_files=()
|
||||
|
||||
# Execute
|
||||
generate_tar_ignore_list "./" to_include to_exclude ignored_files wildcard
|
||||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=wildcard/build.sh # not in include
|
||||
--tar-ignore=wildcard/subdir1/path1/xy # in exclude
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
}
|
||||
|
||||
function test__generate_tar_ignore_list__exclude_x_doesnot_exclude_xy() {
|
||||
to_include=(subdir1 subdir2 subdir3 subdir4)
|
||||
to_exclude=(x)
|
||||
|
||||
cd "${temp_dir}"
|
||||
ignored_files=()
|
||||
|
||||
# Execute
|
||||
generate_tar_ignore_list "./" to_include to_exclude ignored_files wildcard
|
||||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=wildcard/build.sh # not in include
|
||||
--tar-ignore=wildcard/subdir1/path1/x # in exclude
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
}
|
||||
|
||||
function test__generate_tar_ignore_list__can_include_toplevel_files() {
|
||||
to_include=(subdir1 subdir3 ./build.sh)
|
||||
to_exclude=(*.sh)
|
||||
|
||||
cd "${temp_dir}"
|
||||
ignored_files=()
|
||||
|
||||
# Execute
|
||||
generate_tar_ignore_list "./" to_include to_exclude ignored_files top
|
||||
|
||||
# Verify
|
||||
expected=(
|
||||
--tar-ignore=top/subdir1/build.sh # in exclude
|
||||
--tar-ignore=top/subdir1/path1/build.sh # in exclude
|
||||
--tar-ignore=top/subdir1/path2/build.sh # in exclude
|
||||
--tar-ignore=top/subdir1/path3/build.sh # in exclude
|
||||
--tar-ignore=top/subdir2 # not in include
|
||||
--tar-ignore=top/subdir3/build.sh # in exclude
|
||||
--tar-ignore=top/subdir4 # not in include
|
||||
)
|
||||
|
||||
assert-equal "${ignored_files[*]}" "${expected[*]}"
|
||||
}
|
||||
|
||||
# Tests for _starts_with function
|
||||
function test__starts_with__match_parent() {
|
||||
# Setup
|
||||
includes=(subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-true _starts_with includes ./subdir1
|
||||
}
|
||||
|
||||
function test__starts_with__exact_match() {
|
||||
# Setup
|
||||
includes=(subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-true _starts_with includes ./subdir1/path1
|
||||
}
|
||||
|
||||
function test__starts_with__exact_match_localdir() {
|
||||
# Setup
|
||||
includes=(./subdir1/path1 ./subdir3)
|
||||
|
||||
# Verify
|
||||
assert-true _starts_with includes ./subdir1/path1
|
||||
}
|
||||
|
||||
function test__starts_with__no_match() {
|
||||
# Setup
|
||||
includes=(subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-false _starts_with includes ./subdir2
|
||||
}
|
||||
|
||||
function test__starts_with__normalized_paths() {
|
||||
# Setup
|
||||
includes=(path1 path2)
|
||||
|
||||
# Verify
|
||||
assert-true _starts_with includes ./path1
|
||||
}
|
||||
|
||||
function test__starts_with__subdir() {
|
||||
# Setup
|
||||
includes=(path1 path2)
|
||||
|
||||
# Verify
|
||||
assert-false _starts_with includes ./path1/subdir
|
||||
}
|
||||
|
||||
function test__starts_with__no_match_different_name() {
|
||||
# Setup
|
||||
includes=(path1 path2)
|
||||
|
||||
# Verify
|
||||
assert-false _starts_with includes ./path3
|
||||
}
|
||||
|
||||
# Tests for _ends_with function
|
||||
function test__ends_with__exact_filename_first() {
|
||||
# Setup
|
||||
local array=(README.md test.txt)
|
||||
|
||||
# Verify
|
||||
assert-true _ends_with array ./subdir/README.md
|
||||
}
|
||||
|
||||
function test__ends_with__exact_filename_second() {
|
||||
# Setup
|
||||
local array=(README.md test.txt)
|
||||
|
||||
# Verify
|
||||
assert-true _ends_with array ./path/to/test.txt
|
||||
}
|
||||
|
||||
function test__ends_with__not_matching_similar_extension() {
|
||||
# Setup
|
||||
local array=(README.md test.txt)
|
||||
|
||||
# Verify
|
||||
assert-false _ends_with array ./README.md.bak
|
||||
}
|
||||
|
||||
function test__ends_with__no_match_other_filename() {
|
||||
# Setup
|
||||
local array=(README.md test.txt)
|
||||
|
||||
# Verify
|
||||
assert-false _ends_with array ./other.txt
|
||||
}
|
||||
|
||||
# Tests for _is_exact_match function
|
||||
function test__is_exact_match__full_path_first() {
|
||||
# Setup
|
||||
includes=(./subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-true _is_exact_match includes ./subdir1/path1
|
||||
}
|
||||
|
||||
function test__is_exact_match__full_path_second() {
|
||||
# Setup
|
||||
includes=(./subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-true _is_exact_match includes ./subdir3
|
||||
}
|
||||
|
||||
function test__is_exact_match__partial_path_no_match() {
|
||||
# Setup
|
||||
includes=(./subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-false _is_exact_match includes ./subdir1
|
||||
}
|
||||
|
||||
function test__is_exact_match__sibling_path_no_match() {
|
||||
# Setup
|
||||
includes=(./subdir1/path1 subdir3)
|
||||
|
||||
# Verify
|
||||
assert-false _is_exact_match includes ./subdir1/path2
|
||||
}
|
||||
|
||||
function test__is_exact_match__normalized_paths_first() {
|
||||
# Setup
|
||||
includes=(subdir1 subdir2)
|
||||
|
||||
# Verify
|
||||
assert-true _is_exact_match includes ./subdir1
|
||||
}
|
||||
|
||||
function test__is_exact_match__normalized_paths_second() {
|
||||
# Setup
|
||||
includes=(subdir1 subdir2)
|
||||
|
||||
# Verify
|
||||
assert-true _is_exact_match includes ./subdir2
|
||||
}
|
||||
|
||||
function test__is_exact_match__empty_array() {
|
||||
# Setup
|
||||
includes=()
|
||||
|
||||
# Verify
|
||||
assert-false _is_exact_match includes ./anything
|
||||
}
|
||||
|
||||
# Tests for _is_wildcard_match function
|
||||
function test__is_wildcard_match__file() {
|
||||
# Setup
|
||||
local array=(sh)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./config/sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__dot_file() {
|
||||
# Setup
|
||||
local array=(sh)
|
||||
|
||||
# Verify
|
||||
assert-false _is_wildcard_match array ./config/.sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__dot_files_nested() {
|
||||
# Setup
|
||||
local array=(.sh)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./deeply/nested/build/.sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__no_dot_prefix() {
|
||||
# Setup
|
||||
local array=(sh)
|
||||
|
||||
# Verify
|
||||
assert-false _is_wildcard_match array ./build.sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__toplevel_file() {
|
||||
# Setup
|
||||
local array=(sh)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__multiple_extensions_first() {
|
||||
# Setup
|
||||
local array=(tmp log)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/tmp
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__multiple_extensions_second() {
|
||||
# Setup
|
||||
local array=(tmp log)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/log
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__dot_in_wildcard_first() {
|
||||
# Setup
|
||||
local array=(.tmp .log)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/.tmp
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__dot_in_wildcard_second() {
|
||||
# Setup
|
||||
local array=(.tmp .log)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/.log
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__dot_in_wildcard_no_dotfile() {
|
||||
# Setup
|
||||
local array=(.tmp .log)
|
||||
|
||||
# Verify
|
||||
assert-false _is_wildcard_match array ./path/xtmp
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__wildcard_match_dotfile() {
|
||||
# Setup
|
||||
local array=(\*.sh)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/.sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__wildcard_match_file() {
|
||||
# Setup
|
||||
local array=(\*.sh)
|
||||
|
||||
# Verify
|
||||
assert-true _is_wildcard_match array ./path/subdir/build.sh
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__wildcard_no_matches_file() {
|
||||
# Setup
|
||||
local array=(\*.sh)
|
||||
|
||||
# Verify
|
||||
assert-false _is_wildcard_match array ./path/old
|
||||
}
|
||||
|
||||
function test__is_wildcard_match__wildcard_no_matches_path() {
|
||||
# Setup
|
||||
local array=(\*.sh)
|
||||
|
||||
# Verify
|
||||
assert-false _is_wildcard_match array ./path/build.sh/foo
|
||||
}
|
||||
|
||||
# shellcheck disable=2119
|
||||
run_tests
|
||||
|
|
|
|||
|
|
@ -77,6 +77,31 @@ assert-succeeded() {
|
|||
fi
|
||||
}
|
||||
|
||||
_callfunc() {
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
"${command}" "$@"
|
||||
}
|
||||
|
||||
assert-true() {
|
||||
# shellcheck disable=SC2310
|
||||
if ! _callfunc "$@"; then
|
||||
messages+=("- Expected test to return true but it returned false
|
||||
")
|
||||
((test_failures++))
|
||||
fi
|
||||
}
|
||||
|
||||
assert-false() {
|
||||
# shellcheck disable=SC2310
|
||||
if _callfunc "$@"; then
|
||||
messages+=("- Expected test to return false but it returned true
|
||||
")
|
||||
((test_failures++))
|
||||
fi
|
||||
}
|
||||
|
||||
# setup() will run before each test
|
||||
# can be overriden in test script
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -164,6 +164,74 @@ EOF
|
|||
assert-contains "${test_output_contents}" "PASS: test_succeeding1"
|
||||
}
|
||||
|
||||
# Helper functions for testing assert-true and assert-false
|
||||
function returns_true() {
|
||||
return 0
|
||||
}
|
||||
|
||||
function returns_false() {
|
||||
return 1
|
||||
}
|
||||
|
||||
## Tests for assert-true function
|
||||
|
||||
function test__assert_true__with_function_that_returns_true() {
|
||||
# Execute and Verify - should pass
|
||||
assert-true returns_true
|
||||
}
|
||||
|
||||
function test__assert_true__with_builtin_true() {
|
||||
# Execute and Verify - should pass
|
||||
assert-true true
|
||||
}
|
||||
|
||||
function test__assert_true__with_function_with_args_success() {
|
||||
# Execute and Verify - file exists
|
||||
assert-true test -f /etc/hostname
|
||||
}
|
||||
|
||||
function test__assert_true__increments_failure_on_false() {
|
||||
# Setup
|
||||
test_failures=0
|
||||
messages=()
|
||||
|
||||
# Execute function that returns false
|
||||
returns_false
|
||||
local result=$?
|
||||
|
||||
# Verify it failed
|
||||
assert-equal "${result}" "1"
|
||||
}
|
||||
|
||||
## Tests for assert-false function
|
||||
|
||||
function test__assert_false__with_function_that_returns_false() {
|
||||
# Execute and Verify - should pass
|
||||
assert-false returns_false
|
||||
}
|
||||
|
||||
function test__assert_false__with_builtin_false() {
|
||||
# Execute and Verify - should pass
|
||||
assert-false false
|
||||
}
|
||||
|
||||
function test__assert_false__with_function_with_args_success() {
|
||||
# Execute and Verify - file does not exist
|
||||
assert-false test -f /nonexistent/file/that/does/not/exist
|
||||
}
|
||||
|
||||
function test__assert_false__increments_failure_on_true() {
|
||||
# Setup
|
||||
test_failures=0
|
||||
messages=()
|
||||
|
||||
# Execute function that returns true
|
||||
returns_true
|
||||
local result=$?
|
||||
|
||||
# Verify it succeeded
|
||||
assert-equal "${result}" "0"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2031
|
||||
if [[ "${1:-}" != "--recursive" ]]; then
|
||||
Loading…
Add table
Reference in a new issue