Skip to content

Commit 6213840

Browse files
committed
build: move error log linting step to script file
--- 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: passed - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent 5b36b38 commit 6213840

File tree

2 files changed

+185
-90
lines changed

2 files changed

+185
-90
lines changed

.github/workflows/lint_random_files.yml

Lines changed: 11 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -302,98 +302,19 @@ jobs:
302302
- name: 'Lint JavaScript files'
303303
id: lint-javascript
304304
if: ( github.event.inputs.javascript != 'false' ) && ( success() || failure() )
305+
env:
306+
FIX: ${{ github.event.inputs.fix == 'true' && '1' || '0' }}
307+
QUIET: '0'
308+
ERR_FILE: ${{ github.workspace }}/lint_javascript_errors.txt
305309
run: |
306-
# If any command in a pipeline fails, the entire pipeline should fail:
307-
set -o pipefail
308-
309-
# Determine root directory:
310-
root=$(git rev-parse --show-toplevel)
310+
# Get JavaScript files to lint:
311+
files=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '\.js$' | tr '\n' ' ')
311312
312-
# Define the path to ESLint configuration file for linting examples:
313-
eslint_examples_conf="${root}/etc/eslint/.eslintrc.examples.js"
314-
315-
# Define the path to ESLint configuration file for linting tests:
316-
eslint_tests_conf="${root}/etc/eslint/.eslintrc.tests.js"
317-
318-
# Define the path to ESLint configuration file for linting benchmarks:
319-
eslint_benchmarks_conf="${root}/etc/eslint/.eslintrc.benchmarks.js"
320-
321-
# Set `FIX` variable to `1` to enable automatic fixing of lint errors, `0` to disable:
322-
if [ "${{ github.event.inputs.fix }}" == "true" ]; then
323-
FIX=1
313+
# Run the lint script:
314+
if [ -n "${files}" ]; then
315+
"$GITHUB_WORKSPACE/.github/workflows/scripts/lint_javascript_files_error_log" ${files}
324316
else
325-
FIX=0
326-
fi
327-
328-
# Combined error file:
329-
ERR_FILE="$GITHUB_WORKSPACE/lint_javascript_errors.txt"
330-
> "$ERR_FILE" # Initialize a clean file
331-
332-
# Initialize error flag:
333-
error_occurred=0
334-
335-
run_make_lint() {
336-
local files_to_lint="$1"
337-
local make_args="$2"
338-
local eslint_conf_arg="$3"
339-
local error_log_file="$4"
340-
341-
local make_cmd="make lint-javascript-files FIX=${FIX} FAST_FAIL=0 FILES=\"${files_to_lint}\" ${make_args} ${eslint_conf_arg}"
342-
343-
echo "Running: ${make_cmd}"
344-
if ! eval "${make_cmd}"; then
345-
echo "Initial linting failed. Retrying with --quiet and logging errors..."
346-
347-
# Run again with --quiet flag and log output:
348-
eval "${make_cmd} ESLINT_FLAGS='--quiet'" >> "${error_log_file}" 2>&1
349-
error_occurred=1
350-
fi
351-
}
352-
353-
# Lint JavaScript source files:
354-
files=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '\.js$' | grep -v -e '/examples' -e '/test' -e '/benchmark' -e '^dist/' | tr '\n' ' ')
355-
356-
# Build native addons if present:
357-
packages=$(echo "${files}" | tr ' ' '\n' | sed 's/^lib\/node_modules\///g' | sed 's/\/lib\/.*//g' | sort | uniq)
358-
for pkg in ${packages}; do
359-
if [ -f "lib/node_modules/${pkg}/binding.gyp" ]; then
360-
NODE_ADDONS_PATTERN="${pkg}" make install-node-addons
361-
fi
362-
done
363-
364-
if [[ -n "${files}" ]]; then
365-
run_make_lint "${files}" "" "" "${ERR_FILE}"
366-
fi
367-
368-
# Lint JavaScript command-line interfaces:
369-
file=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '\.js$' | grep -E '/bin/cli$' | tr '\n' ' ')
370-
if [[ -n "${file}" ]]; then
371-
run_make_lint "${file}" "" "" "${ERR_FILE}"
372-
fi
373-
374-
# Lint JavaScript example files:
375-
files=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '/examples/.*\.js$' | tr '\n' ' ')
376-
if [[ -n "${files}" ]]; then
377-
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_examples_conf}\"" "${ERR_FILE}"
378-
fi
379-
380-
# Lint JavaScript test files:
381-
files=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '/test/.*\.js$' | tr '\n' ' ')
382-
if [[ -n "${files}" ]]; then
383-
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_tests_conf}\"" "${ERR_FILE}"
384-
fi
385-
386-
# Lint JavaScript benchmark files:
387-
files=$(echo "${{ steps.random-files.outputs.files }}" | tr ',' '\n' | grep '/benchmark/.*\.js$' | tr '\n' ' ')
388-
if [[ -n "${files}" ]]; then
389-
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_benchmarks_conf}\"" "${ERR_FILE}"
390-
fi
391-
392-
# Check if any errors occurred during linting:
393-
if [[ "$error_occurred" -eq 1 ]]; then
394-
echo "JavaScript linting errors occurred. See details below or in the artifact."
395-
cat "$ERR_FILE" # Print errors to the workflow log
396-
exit 1
317+
echo "No JavaScript files to lint."
397318
fi
398319
399320
# Create sub-issue for JavaScript lint failures:
@@ -432,7 +353,7 @@ jobs:
432353
"5377" \
433354
"Good First Issue"
434355
435-
rm "$BODY_FILE" "$ERR_FILE"
356+
rm "$BODY_FILE"
436357
437358
# Lint Python files:
438359
- name: 'Lint Python files'
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/usr/bin/env bash
2+
#
3+
# @license Apache-2.0
4+
#
5+
# Copyright (c) 2025 The Stdlib Authors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# Script to lint JavaScript files with extended error handling and reporting.
20+
#
21+
# Usage: lint_javascript_files_extended file1 [file2 file3 ...]
22+
#
23+
# Arguments:
24+
#
25+
# file1 File path.
26+
# file2 File path.
27+
# file3 File path.
28+
#
29+
# Environment variables:
30+
#
31+
# FIX 0 or 1 indicating whether to automatically fix errors.
32+
# QUIET 0 or 1 indicating whether to run in quiet mode (errors only).
33+
# ERR_FILE Path to error output file (optional).
34+
#
35+
36+
# shellcheck disable=SC2086
37+
38+
# Ensure that the exit status of pipelines is non-zero in the event that at least one of the commands in a pipeline fails:
39+
set -o pipefail
40+
41+
42+
# VARIABLES #
43+
44+
# Determine root directory:
45+
root=$(git rev-parse --show-toplevel)
46+
47+
# Flag indicating whether to automatically fix errors:
48+
fix="${FIX:-0}"
49+
50+
# Flag indicating whether to run in quiet mode:
51+
quiet="${QUIET:-0}"
52+
53+
# Error output file:
54+
err_file="${ERR_FILE:-${TMPDIR:-/tmp}/lint_javascript_errors_$$.txt}"
55+
56+
# Files to lint:
57+
files_to_lint="$*"
58+
59+
# Define the path to ESLint configuration file for linting examples:
60+
eslint_examples_conf="${root}/etc/eslint/.eslintrc.examples.js"
61+
62+
# Define the path to ESLint configuration file for linting tests:
63+
eslint_tests_conf="${root}/etc/eslint/.eslintrc.tests.js"
64+
65+
# Define the path to ESLint configuration file for linting benchmarks:
66+
eslint_benchmarks_conf="${root}/etc/eslint/.eslintrc.benchmarks.js"
67+
68+
# Initialize error flag:
69+
error_occurred=0
70+
71+
72+
# FUNCTIONS #
73+
74+
# Runs make lint command with error handling.
75+
#
76+
# $1 - files to lint
77+
# $2 - additional make arguments
78+
# $3 - ESLint configuration argument
79+
run_make_lint() {
80+
local files_to_lint="$1"
81+
local make_args="$2"
82+
local eslint_conf_arg="$3"
83+
84+
local eslint_flags=""
85+
if [ "${quiet}" -eq 1 ]; then
86+
eslint_flags="ESLINT_FLAGS='--quiet'"
87+
fi
88+
89+
local make_cmd="make lint-javascript-files FIX=${fix} FAST_FAIL=0 FILES=\"${files_to_lint}\" ${make_args} ${eslint_conf_arg} ${eslint_flags}"
90+
91+
echo "Running: ${make_cmd}"
92+
if ! eval "${make_cmd}"; then
93+
if [ "${quiet}" -eq 0 ]; then
94+
echo "Initial linting failed. Retrying with --quiet and logging errors..."
95+
eval "make lint-javascript-files FIX=${fix} FAST_FAIL=0 FILES=\"${files_to_lint}\" ${make_args} ${eslint_conf_arg} ESLINT_FLAGS='--quiet'" >> "${err_file}" 2>&1
96+
else
97+
# Already running with --quiet, just log the error
98+
echo "Linting failed for files." >> "${err_file}"
99+
fi
100+
error_occurred=1
101+
fi
102+
}
103+
104+
105+
# MAIN #
106+
107+
# Initialize error file:
108+
: > "${err_file}"
109+
110+
# Build native addons if present:
111+
packages=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '^lib/node_modules/' | sed 's/^lib\/node_modules\///g' | sed 's/\/lib\/.*//g' | sort | uniq)
112+
for pkg in ${packages}; do
113+
if [ -f "lib/node_modules/${pkg}/binding.gyp" ]; then
114+
echo "Building native addon for ${pkg}..."
115+
NODE_ADDONS_PATTERN="${pkg}" make install-node-addons
116+
fi
117+
done
118+
119+
# Lint JavaScript source files:
120+
files=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '\.js$' | grep -v -e '/examples' -e '/test' -e '/benchmark' -e '^dist/' | tr '\n' ' ' | sed 's/ $//')
121+
if [ -n "${files}" ]; then
122+
echo "Linting JavaScript source files..."
123+
run_make_lint "${files}" "" ""
124+
fi
125+
126+
# Lint JavaScript command-line interfaces:
127+
files=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '\.js$' | grep -E '/bin/cli$' | tr '\n' ' ' | sed 's/ $//')
128+
if [ -n "${files}" ]; then
129+
echo "Linting JavaScript CLI files..."
130+
run_make_lint "${files}" "" ""
131+
fi
132+
133+
# Lint JavaScript example files:
134+
files=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '/examples/.*\.js$' | tr '\n' ' ' | sed 's/ $//')
135+
if [ -n "${files}" ]; then
136+
echo "Linting JavaScript example files..."
137+
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_examples_conf}\""
138+
fi
139+
140+
# Lint JavaScript test files:
141+
files=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '/test/.*\.js$' | tr '\n' ' ' | sed 's/ $//')
142+
if [ -n "${files}" ]; then
143+
echo "Linting JavaScript test files..."
144+
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_tests_conf}\""
145+
fi
146+
147+
# Lint JavaScript benchmark files:
148+
files=$(echo "${files_to_lint}" | tr ' ' '\n' | grep '/benchmark/.*\.js$' | tr '\n' ' ' | sed 's/ $//')
149+
if [ -n "${files}" ]; then
150+
echo "Linting JavaScript benchmark files..."
151+
run_make_lint "${files}" "" "ESLINT_CONF=\"${eslint_benchmarks_conf}\""
152+
fi
153+
154+
# Report results:
155+
if [ "${error_occurred}" -eq 1 ]; then
156+
echo "JavaScript linting errors occurred. See details below:"
157+
cat "${err_file}"
158+
159+
# Clean up temp file ONLY if it was auto-generated (ERR_FILE not provided):
160+
if [ -z "${ERR_FILE}" ]; then
161+
rm -f "${err_file}"
162+
fi
163+
164+
exit 1
165+
else
166+
echo "JavaScript linting completed successfully."
167+
168+
# Clean up temp file ONLY if it was auto-generated (ERR_FILE not provided):
169+
if [ -z "${ERR_FILE}" ]; then
170+
rm -f "${err_file}"
171+
fi
172+
173+
exit 0
174+
fi

0 commit comments

Comments
 (0)