Skip to content

build: update pre-push hook to run package tests on source changes #5548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
146 changes: 143 additions & 3 deletions tools/git/hooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,150 @@ main() {
# Run JavaScript test files...
add_task 'run_javascript_tests'
if [[ -z "${skip_javascript_tests}" ]]; then
files=$(echo "${changed_files}" | grep '/test/.*\.js$' | grep -v '/test/fixtures/.*\.js$' | grep -v '/test/.*/fixtures/.*\.js$' | tr '\n' ' ')
if [[ -n "${files}" ]]; then
# Find test files for a given package directory
find_test_files() {
local pkg_dir="$1"
local pattern="$2"
if [[ -d "$pkg_dir/test" ]]; then
find "$pkg_dir/test" -name "$pattern" 2>/dev/null | grep -v 'fixtures'
fi
}

# Extract package directory from a file path
get_pkg_dir() {
dirname "$(dirname "$1")"
}

# Extract package pattern for compilation
get_pkg_pattern() {
local pkg_dir="$1"
local pkg_name=$(basename "$pkg_dir")
local pkg_parent=$(dirname "$pkg_dir")
echo "$(echo "$pkg_parent" | sed 's|.*/node_modules/@stdlib/||')/$pkg_name"
}

# Get changed test files directly
test_files=$(echo "${changed_files}" | grep '/test/.*\.js$' | grep -v '/test/fixtures/.*\.js$' | grep -v '/test/.*/fixtures/.*\.js$')

# Get changed test fixture JSON files
fixture_json_files=$(echo "${changed_files}" | grep '/test/fixtures/.*\.json$')

# For each changed JSON fixture, find the corresponding test files
fixture_test_files=""
if [[ -n "${fixture_json_files}" ]]; then
echo 'Identifying tests for changed JSON fixtures...' >&2
while IFS= read -r file; do
# Get the package directory (two levels up from fixtures directory)
pkg_dir=$(dirname "$(dirname "$(dirname "$file")")")

# Find all JS test files in the package
potential_tests=$(find "$pkg_dir/test" -name "*.js" 2>/dev/null | grep -v 'fixtures')
if [[ -n "${potential_tests}" ]]; then
fixture_test_files="${fixture_test_files} ${potential_tests}"
fi
done <<< "${fixture_json_files}"
fi

# Get changed source files
js_source_files=$(echo "${changed_files}" | grep -E '/(lib)/.*\.js$')
c_source_files=$(echo "${changed_files}" | grep -E '/src/.*\.c$')
fortran_source_files=$(echo "${changed_files}" | grep -E '/src/.*\.(f|f90|for|f77)$')
manifest_files=$(echo "${changed_files}" | grep 'manifest.json$')

source_test_files=""
packages_to_compile=""

# Process JavaScript source files
if [[ -n "${js_source_files}" ]]; then
echo 'Identifying tests for changed JavaScript source files...' >&2
while IFS= read -r file; do
pkg_dir=$(get_pkg_dir "$file")
potential_tests=$(find_test_files "$pkg_dir" "*.js")
if [[ -n "${potential_tests}" ]]; then
source_test_files="${source_test_files} ${potential_tests}"
fi
done <<< "${js_source_files}"
fi

# Process C and Fortran source files and manifest files
if [[ -n "${c_source_files}" || -n "${fortran_source_files}" || -n "${manifest_files}" ]]; then
echo 'Identifying tests for changed native source files and manifests...' >&2

# Process C source files
if [[ -n "${c_source_files}" ]]; then
while IFS= read -r file; do
pkg_dir=$(get_pkg_dir "$file")
pkg_pattern=$(get_pkg_pattern "$pkg_dir")

# Add to packages to compile
if [[ -n "$pkg_pattern" && "$packages_to_compile" != *"$pkg_pattern"* ]]; then
packages_to_compile="${packages_to_compile} ${pkg_pattern}"
fi

potential_tests=$(find_test_files "$pkg_dir" "*.native.js")
if [[ -n "${potential_tests}" ]]; then
source_test_files="${source_test_files} ${potential_tests}"
fi
done <<< "${c_source_files}"
fi

# Process Fortran source files
if [[ -n "${fortran_source_files}" ]]; then
while IFS= read -r file; do
pkg_dir=$(get_pkg_dir "$file")
pkg_pattern=$(get_pkg_pattern "$pkg_dir")

# Add to packages to compile
if [[ -n "$pkg_pattern" && "$packages_to_compile" != *"$pkg_pattern"* ]]; then
packages_to_compile="${packages_to_compile} ${pkg_pattern}"
fi

potential_tests=$(find_test_files "$pkg_dir" "*.native.js")
if [[ -n "${potential_tests}" ]]; then
source_test_files="${source_test_files} ${potential_tests}"
fi
done <<< "${fortran_source_files}"
fi

# Process manifest files
if [[ -n "${manifest_files}" ]]; then
while IFS= read -r file; do
pkg_dir=$(dirname "$file")
pkg_pattern=$(get_pkg_pattern "$pkg_dir")

# Add to packages to compile if it has a src directory with C files
if [[ -d "$pkg_dir/src" ]] && ls "$pkg_dir/src"/*.c >/dev/null 2>&1; then
if [[ -n "$pkg_pattern" && "$packages_to_compile" != *"$pkg_pattern"* ]]; then
packages_to_compile="${packages_to_compile} ${pkg_pattern}"
fi

potential_tests=$(find_test_files "$pkg_dir" "*.native.js")
if [[ -n "${potential_tests}" ]]; then
source_test_files="${source_test_files} ${potential_tests}"
fi
fi
done <<< "${manifest_files}"
fi

# Compile native add-ons if needed
if [[ -n "${packages_to_compile}" ]]; then
echo "Compiling native add-ons for: ${packages_to_compile}" >&2
for pkg in ${packages_to_compile}; do
make install-node-addons NODE_ADDONS_PATTERN="${pkg}" > /dev/null >&2
if [[ "$?" -ne 0 ]]; then
echo "Failed to compile native add-on for ${pkg}" >&2
task_status 'failed'
on_error 1
fi
done
fi
fi

# Combine test files from all sources and remove duplicates
all_test_files=$(echo "${test_files} ${fixture_test_files} ${source_test_files}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ')
if [[ -n "${all_test_files}" ]]; then
echo 'Running JavaScript test files...' >&2
make FILES="${files}" test-javascript-files > /dev/null >&2
make FILES="${all_test_files}" test-javascript-files > /dev/null >&2
if [[ "$?" -ne 0 ]]; then
task_status 'failed'
echo '' >&2
Expand Down