Skip to content
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions .github/workflows/lint_changed_files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ jobs:
run: |
. "$GITHUB_WORKSPACE/.github/workflows/scripts/common/lint_package_json_files" "${{ steps.changed-files.outputs.files }}"

# Lint package.json metadata:
- name: 'Lint package.json metadata'
if: success() || failure()
run: |
make lint-pkgs-metadata-files FILES="${{ steps.changed-files.outputs.files }}"

# Lint REPL help files...
- name: 'Lint REPL help files'
if: success() || failure()
Expand Down
49 changes: 1 addition & 48 deletions .github/workflows/scripts/common/lint_package_json_files
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Script to lint package.json files and check/update metadata fields.
# Script to lint package.json files.
#
# Usage: lint_package_json_files file1 [file2 file3 ...]
#
Expand All @@ -32,61 +32,14 @@ root=$(git rev-parse --show-toplevel)
# Define the path to a utility for linting package.json files:
lint_package_json="${root}/lib/node_modules/@stdlib/_tools/lint/pkg-json/bin/cli"

# Define the path to the package name validation tool:
validate_package_names="${root}/lib/node_modules/@stdlib/_tools/lint/pkg-json-names/bin/cli"

# Define paths to utilities for updating package.json metadata fields:
update_package_json_directories="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_directories"
update_package_json_gypfile="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_gypfile"

# Files to process:
files_to_process="$*"

# Initialize needs_changes flag:
needs_changes=0

# Lint package.json files:
files=$(echo "${files_to_process}" | tr ' ' '\n' | awk -F/ '$NF=="package.json"' | tr '\n' ' ' | sed 's/ $//')
if [ -n "${files}" ]; then
echo "Linting package.json files..."
printf '%s' "${files}" | "${lint_package_json}" --split=" "

echo "Validating package names..."
if ! printf '%s' "${files}" | "${validate_package_names}" --split=" "; then
echo "ERROR: Package name validation failed"
needs_changes=1
fi
else
echo "No package.json files to lint."
fi

# Check if metadata fields need to be updated in package.json files of affected packages:
dirs=$(echo "${files_to_process}" | tr ' ' '\n' | \
xargs dirname | \
sed -E 's/\/(benchmark|bin|data|docs|etc|examples|include|lib|scripts|src|test)(\/.*)?$//' | \
sort -u)

echo "Checking package.json files in directories: ${dirs}"
for dir in ${dirs}; do
echo "Checking package.json in ${dir}..."
package_json="${dir}/package.json"
if [ ! -f "${package_json}" ]; then
continue
fi
original_content=$(cat "${package_json}")

"${update_package_json_directories}" "${dir}"
"${update_package_json_gypfile}" "${dir}"

new_content=$(cat "${package_json}")
if [ "$original_content" != "$new_content" ]; then
echo "ERROR: package.json in ${dir} needs updates to directories and/or gypfile fields"
git --no-pager diff "${package_json}"
needs_changes=1
fi
done

# Exit with failure if any needed changes were detected:
if [ $needs_changes -eq 1 ]; then
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
#
# @license Apache-2.0
#
# Copyright (c) 2026 The Stdlib Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Script to validate package.json metadata fields.
#
# Usage: validate_package_json_files file1 [file2 file3 ...]
#
# Arguments:
#
# file1 File path.
# file2 File path.
# file3 File path.

# Determine root directory:
root=$(git rev-parse --show-toplevel)

# Define the path to the package name validation tool:
validate_package_names="${root}/lib/node_modules/@stdlib/_tools/lint/pkg-json-names/bin/cli"

# Define paths to utilities for updating package.json metadata fields:
update_package_json_directories="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_directories"
update_package_json_gypfile="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_gypfile"

# Files to process:
files_to_process="$*"

# Initialize needs_changes flag:
needs_changes=0

# Validate package.json package names:
files=$(echo "${files_to_process}" | tr ' ' '\n' | awk -F/ '$NF=="package.json"' | tr '\n' ' ' | sed 's/ $//')
if [ -n "${files}" ]; then
echo "Validating package names..."
if ! printf '%s' "${files}" | "${validate_package_names}" --split=" "; then
echo "ERROR: Package name validation failed"
needs_changes=1
fi
else
echo "No package.json files to validate."
fi

# Check if metadata fields need to be updated in package.json files of affected packages:
dirs=$(echo "${files_to_process}" | tr ' ' '\n' | \
xargs dirname | \
sed -E 's/\/(benchmark|bin|data|docs|etc|examples|include|lib|scripts|src|test)(\/[^@]*)?$//' | \
Comment thread
Planeshifter marked this conversation as resolved.
sort -u)

echo "Checking package.json files in directories: ${dirs}"
for dir in ${dirs}; do
echo "Checking package.json in ${dir}..."
package_json="${dir}/package.json"
if [ ! -f "${package_json}" ]; then
continue
fi
original_content=$(cat "${package_json}")

"${update_package_json_directories}" "${dir}"
"${update_package_json_gypfile}" "${dir}"

new_content=$(cat "${package_json}")
if [ "$original_content" != "$new_content" ]; then
echo "ERROR: package.json in ${dir} needs updates to directories and/or gypfile fields"
git --no-pager diff "${package_json}"
needs_changes=1
fi
done

# Exit with failure if any needed changes were detected:
if [ $needs_changes -eq 1 ]; then
exit 1
fi
15 changes: 15 additions & 0 deletions tools/git/hooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,21 @@ run_lint() {
else
task_status 'skipped'
fi
# Lint package.json metadata...
add_task 'lint_pkgs_metadata'
Comment thread
Planeshifter marked this conversation as resolved.
if [[ -z "${skip_package_json}" ]]; then
files=$(echo "${changed_files}" | tr '\n' ' ')
make FILES="${files}" lint-pkgs-metadata-files > /dev/null >&2
if [[ "$?" -ne 0 ]]; then
task_status 'failed'
echo '' >&2
echo 'package.json metadata out of date.' >&2
return 1
fi
task_status 'passed'
else
task_status 'skipped'
fi
# Lint REPL help files...
add_task 'lint_repl_help'
if [[ -z "${skip_repl_help}" ]]; then
Expand Down
20 changes: 20 additions & 0 deletions tools/make/lib/lint/pkgs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
# limitations under the License.
#/

# VARIABLES #

# Define the path for script validating `package.json` metadata:
VALIDATE_PKG_JSON ?= $(TOOLS_PKGS_DIR)/package-json/scripts/validate_package_json_files


# RULES #

# TODO: support linting filenames, package.json, REPL help, JavaScript CLI files (see pre-commit hook), license headers
Expand Down Expand Up @@ -44,3 +50,17 @@ lint-pkgs: lint-editorconfig
$(QUIET) $(MAKE) -f $(this_file) lint-typescript TYPESCRIPT_DECLARATIONS_FILTER=$(PACKAGES_FILTER) TYPESCRIPT_DECLARATIONS_TESTS_FILTER=$(PACKAGES_FILTER)

.PHONY: lint-pkgs

#/
# Lints `package.json` metadata associated with a list of files.
#
# @param {string} FILES - list of file paths
#
# @example
# make lint-pkgs-metadata-files FILES='/foo/lib/index.js /bar/package.json'
#/
lint-pkgs-metadata-files: $(NODE_MODULES)
$(QUIET) echo 'Linting package.json metadata...'
$(QUIET) $(VALIDATE_PKG_JSON) $(FILES)

.PHONY: lint-pkgs-metadata-files