From e82be287f4d04eeeebbc2a0adfa467a2dcf9552d Mon Sep 17 00:00:00 2001 From: headlessNode Date: Sat, 1 Mar 2025 12:51:46 +0500 Subject: [PATCH 1/3] build: git pre-push hook runs tests on source change --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: missing_dependencies - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- tools/git/hooks/pre-push | 110 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/tools/git/hooks/pre-push b/tools/git/hooks/pre-push index d7b5cb00f62c..44a709c3d9e6 100755 --- a/tools/git/hooks/pre-push +++ b/tools/git/hooks/pre-push @@ -448,10 +448,114 @@ 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 source files + js_source_files=$(echo "${changed_files}" | grep -E '/(lib)/.*\.js$') + c_source_files=$(echo "${changed_files}" | grep -E '/src/.*\.c$') + 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 source files and manifest files + if [[ -n "${c_source_files}" || -n "${manifest_files}" ]]; then + echo 'Identifying tests for changed C 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 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 both sources and remove duplicates + all_test_files=$(echo "${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 From fd9a4df7c67d0b41e82da58827d9052aa9fc1b27 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Sat, 1 Mar 2025 13:08:59 +0500 Subject: [PATCH 2/3] chore: remove empty line Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- tools/git/hooks/pre-push | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/git/hooks/pre-push b/tools/git/hooks/pre-push index 44a709c3d9e6..686078dbc613 100755 --- a/tools/git/hooks/pre-push +++ b/tools/git/hooks/pre-push @@ -452,7 +452,6 @@ main() { 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 From 88217bcb3919fbadacc583a1992cf248ddbd617b Mon Sep 17 00:00:00 2001 From: headlessNode Date: Sat, 1 Mar 2025 15:14:04 +0500 Subject: [PATCH 3/3] refactor: add support for fortran and fixtures/json changes --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: missing_dependencies - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- tools/git/hooks/pre-push | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/tools/git/hooks/pre-push b/tools/git/hooks/pre-push index 686078dbc613..e01d858b961b 100755 --- a/tools/git/hooks/pre-push +++ b/tools/git/hooks/pre-push @@ -473,9 +473,29 @@ main() { # 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="" @@ -493,9 +513,9 @@ main() { done <<< "${js_source_files}" fi - # Process C source files and manifest files - if [[ -n "${c_source_files}" || -n "${manifest_files}" ]]; then - echo 'Identifying tests for changed C source files and manifests...' >&2 + # 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 @@ -515,6 +535,24 @@ main() { 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 @@ -549,9 +587,8 @@ main() { fi fi - # Combine test files from both sources and remove duplicates - all_test_files=$(echo "${test_files} ${source_test_files}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ') - + # 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="${all_test_files}" test-javascript-files > /dev/null >&2