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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ venv*
**/node_modules
# Linter output files
diff.txt
.lint-failures

temp
__pycache__
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,17 @@ check-copyright-headers:
$(CMD_COPYRIGHT_HEADER_FIXER) --check

.PHONY: lint
lint: ## Run all linters (licenses, openapi, config docs, python style/types/sdk, vendored SDK, CLI, auth config)
lint: ## Run lint scripts in tools/lint; optionally pass LINTS="lint-openapi lint-python-style"
bash tools/lint/lint-all.sh

.PHONY: lint-fix
lint-fix: ## Auto-fix lint issues in dependency order (openapi → stainless → style → cli → vendor → licenses → config-docs)
lint-fix: ## Run corresponding lint-fix scripts in dependency order; optionally pass LINTS="lint-openapi"
bash tools/lint/lint-fix.sh

.PHONY: lint-fix-failed
lint-fix-failed: ## Run lint-fix scripts for failures recorded by the last make lint
bash tools/lint/lint-fix.sh --failed

.PHONY: vendor
vendor: ## Vendor packages into the SDK and generate wrapper metadata
uv run --no-sync nemo-platform-sdk-tools vendor all-from-configs \
Expand Down
77 changes: 31 additions & 46 deletions tools/lint/lint-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,31 @@
set -uo pipefail
# Run all lint scripts serially, report summary, exit with failure if any failed.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="${CI_PROJECT_DIR:-$(cd "${SCRIPT_DIR}/../.." && pwd)}"
source "${SCRIPT_DIR}/lint-common.sh"
cd "${PROJECT_ROOT}" || exit 1

declare -a scripts=(
"lint-licenses:tools/lint/lint-licenses.sh"
"lint-openapi:tools/lint/lint-openapi.sh"
"lint-config-reference-docs:tools/lint/lint-config-reference-docs.sh"
"lint-python-style:tools/lint/lint-python-style.sh"
"lint-python-types:tools/lint/lint-python-types.sh"
"lint-python-sdk:tools/lint/lint-python-sdk.sh"
"lint-sdk-vendored:tools/lint/lint-sdk-vendored.sh"
"lint-web-sdk:tools/lint/lint-web-sdk.sh"
"lint-cli:tools/lint/lint-cli.sh"
"lint-auth-config:tools/lint/lint-auth-config.sh"
"lint-merge-conflict:tools/lint/lint-merge-conflict.sh"
"lint-copyright-headers:tools/lint/lint-copyright-headers.sh"
)
validate_lint_fix_pairs || exit 1

is_no_fix_lint() {
local lint_name="$1"
case "${lint_name}" in
lint-python-types|lint-merge-conflict)
return 0
;;
*)
return 1
;;
esac
}
selected_output="$(selected_lint_names "${LINT_SCRIPT_NAMES[@]}")" || exit 1
declare -a lint_names=()
if [[ -n "${selected_output}" ]]; then
mapfile -t lint_names <<< "${selected_output}"
fi

if [[ ${#lint_names[@]} -eq 0 ]]; then
echo "No lint scripts selected."
write_lint_failures || exit 1
exit 0
fi

if [[ -n "${LINTS:-}" ]]; then
echo "Selected lints: ${lint_names[*]}"
fi

declare -a failed=()
declare -a timing_lines=()
for entry in "${scripts[@]}"; do
name="${entry%%:*}"
path="${entry#*:}"
for name in "${lint_names[@]}"; do
path="$(lint_script_path "${name}")"
start=$(date +%s)
if bash "${path}"; then
echo "[PASS] ${name}"
Expand All @@ -52,7 +42,7 @@ done

echo ""
echo "--- Lint summary ---"
echo "Passed: $((${#scripts[@]} - ${#failed[@]}))"
echo "Passed: $((${#lint_names[@]} - ${#failed[@]}))"
echo "Failed: ${#failed[@]}"
echo ""
echo "Timings:"
Expand All @@ -62,26 +52,21 @@ for line in "${timing_lines[@]}"; do
printf " %-40s %s\n" "${name}" "${details}"
done
if [[ ${#failed[@]} -gt 0 ]]; then
write_lint_failures "${failed[@]}" || exit 1
echo "Failed lints: ${failed[*]}"
echo "Recorded failed lints in $(lint_failure_file_display_path)."
echo ""
# Check if any failed lint has an auto-fix command
has_fix=false
for name in "${failed[@]}"; do
if ! is_no_fix_lint "${name}"; then
has_fix=true
break
fi
done
if [[ "${has_fix}" == "true" ]]; then
echo "To fix auto-fixable issues, run:"
echo " make lint-fix"
echo ""
fi
echo "To run fixes for the recorded failures in dependency order:"
echo " make lint-fix-failed"
echo ""
echo "To run fixes for a specific subset:"
echo " make lint-fix LINTS=\"${failed[*]}\""
echo ""
echo "Failed lint -> corresponding fix script:"
for name in "${failed[@]}"; do
if is_no_fix_lint "${name}"; then
echo " ${name}: (see output above for manual fix)"
fi
printf " %-30s %s\n" "${name}" "$(lint_fix_script_display_path "${name}")"
done
exit 1
fi
write_lint_failures || exit 1
exit 0
5 changes: 4 additions & 1 deletion tools/lint/lint-auth-config.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
# Verify auth static config and OpenAPI are in sync.
uv run python services/core/auth/scripts/auth-tools.py check
uv run python services/core/auth/scripts/auth-tools.py check || {
echo "Run 'tools/lint/lint-fix-auth-config.sh' to update auth config and generated auth docs."
exit 1
}
2 changes: 1 addition & 1 deletion tools/lint/lint-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ cd "${PROJECT_ROOT}"
make update-cli
git add "${PROJECT_ROOT}/sdk/python/"
git diff --cached --exit-code "${PROJECT_ROOT}/sdk/python/" > "${PROJECT_ROOT}/diff.txt" || {
echo "Run 'make update-cli' to update the CLI."
echo "Run 'tools/lint/lint-fix-cli.sh' to update the CLI."
exit 1
}
Loading
Loading