Skip to content
Merged
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
4 changes: 1 addition & 3 deletions .hooks/lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ print_usage() {
Usage: .hooks/pre-push [options]

Options:
--fix Run formatters (isort/black) for both environments and skip other checks.
--fix-primary Same as --fix but limited to the primary environment.
--fix-secondary Same as --fix but limited to the secondary environment.
--fix Run formatters (isort/black) and skip other checks.
-h, --help Show this help message.
EOF
}
Expand Down
98 changes: 0 additions & 98 deletions .hooks/lib/get_secondary_scope.py

This file was deleted.

91 changes: 11 additions & 80 deletions .hooks/lib/python_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,98 +16,33 @@ setup_python_environment() {
export PATH="$VIRTUAL_ENV/bin:$PATH"
}

load_secondary_scope_paths() {
if [ -n "${BLUEOS_SECONDARY_SCOPE:-}" ]; then
read -r -a SECONDARY_SCOPE_PATHS <<<"${BLUEOS_SECONDARY_SCOPE}"
return
fi

local pyproject="$SECONDARY_PROJECT_DIR/pyproject.toml"
if [ ! -f "$pyproject" ]; then
echo "Missing secondary pyproject: $pyproject" >&2
exit 1
fi

local scope_script="$ROOT_DIR/.hooks/lib/get_secondary_scope.py"
if [ ! -x "$scope_script" ]; then
echo "Missing scope helper: $scope_script"
exit 1
fi

local scope_output
if ! scope_output=$(
"$scope_script" --core-dir "$CORE_DIR" --pyproject "$pyproject"
); then
echo "Failed to load secondary scope; see errors above." >&2
exit 1
fi
mapfile -t SECONDARY_SCOPE_PATHS <<<"$scope_output"
if [ "${#SECONDARY_SCOPE_PATHS[@]}" -eq 1 ] && [ -z "${SECONDARY_SCOPE_PATHS[0]}" ]; then
SECONDARY_SCOPE_PATHS=()
fi
}

path_matches_any() {
local file="$1"
shift || true
local scope_path
for scope_path in "$@"; do
[[ -z "$scope_path" ]] && continue
[[ $file == "$scope_path" || $file == "$scope_path/"* ]] && return 0
done
return 1
}

collect_python_files() {
case "$1" in
primary|secondary) local scope="$1";;
*) echo "${FUNCNAME[0]}: scope must be 'primary' or 'secondary'" >&2; return 1;;
esac

git -C "$CORE_DIR" ls-files '*.py' |
while read -r file; do
[[ -z "$file" ]] && continue
if path_matches_any "$file" "${SECONDARY_SCOPE_PATHS[@]}"; then
[[ "$scope" == secondary ]] && echo "$file"
else
[[ "$scope" == primary ]] && echo "$file"
fi
echo "$file"
done
}

collect_mypy_targets() {
case "$1" in
primary|secondary) local scope="$1";;
*) echo "${FUNCNAME[0]}: scope must be 'primary' or 'secondary'" >&2; return 1;;
esac

git -C "$CORE_DIR" ls-files '*/pyproject.toml' |
while read -r project; do
[[ $project == libs/* || $project == services/* ]] || continue

if path_matches_any "$project" "${SECONDARY_SCOPE_PATHS[@]}"; then
[[ $scope == secondary ]] && echo "$(dirname "$project")"
else
[[ $scope == primary ]] && echo "$(dirname "$project")"
fi
echo "$(dirname "$project")"
done
}

run_python_checks() {
local env_label="$1"
case "$2" in
primary|secondary) local scope="$2";;
*) echo "${FUNCNAME[0]}: scope must be 'primary' or 'secondary'" >&2; return 1;;
esac
local pytest_ignores_ref="$3"
local pytest_targets_ref="$4"
local pytest_ignores_ref="$2"
local pytest_targets_ref="$3"
local -n pytest_ignores="$pytest_ignores_ref"
local -n pytest_targets="$pytest_targets_ref"

echo "Running Python tooling for ${env_label}"

local python_files=()
mapfile -t python_files < <(collect_python_files "$scope")
mapfile -t python_files < <(collect_python_files)

if [ "${#python_files[@]}" -eq 0 ]; then
echo "No Python files found for ${env_label}, skipping."
Expand All @@ -134,7 +69,7 @@ run_python_checks() {
pylint "${python_files[@]}"

local mypy_targets=()
mapfile -t mypy_targets < <(collect_mypy_targets "$scope")
mapfile -t mypy_targets < <(collect_mypy_targets)
if [ "${#mypy_targets[@]}" -gt 0 ]; then
echo "Running mypy (${env_label}).."
local mypy_bin="${VIRTUAL_ENV:-}/bin/mypy"
Expand Down Expand Up @@ -168,14 +103,10 @@ run_python_checks() {
run_environment_phase() {
local env_label="$1"
local project_dir="$2"
case "$3" in
primary|secondary) local scope="$3";;
*) echo "${FUNCNAME[0]}: scope must be 'primary' or 'secondary'" >&2; return 1;;
esac
local pytest_ignores_ref="$4"
local pytest_targets_ref="$5"
local run_bootstrap="${6:-false}"
local coverage_threshold="${7:-}"
local pytest_ignores_ref="$3"
local pytest_targets_ref="$4"
local run_bootstrap="${5:-false}"
local coverage_threshold="${6:-}"

(
setup_python_environment "$env_label" "$project_dir"
Expand All @@ -187,6 +118,6 @@ run_environment_phase() {
else
unset COVERAGE_FAIL_UNDER_OVERRIDE
fi
run_python_checks "$env_label" "$scope" "$pytest_ignores_ref" "$pytest_targets_ref"
run_python_checks "$env_label" "$pytest_ignores_ref" "$pytest_targets_ref"
)
}
59 changes: 6 additions & 53 deletions .hooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ ROOT_DIR=$(git rev-parse --show-toplevel)
cd "$ROOT_DIR"

CORE_DIR="$ROOT_DIR/core"
PRIMARY_PROJECT_DIR="$CORE_DIR"
SECONDARY_PROJECT_DIR="$CORE_DIR/python-venv2"
declare -a SECONDARY_SCOPE_PATHS=()
# shellcheck disable=SC2034
declare -a EMPTY_PATHS=()
SECONDARY_COVERAGE_THRESHOLD="${SECONDARY_COVERAGE_THRESHOLD:-65}"

source "$ROOT_DIR/.hooks/lib/common.sh"
source "$ROOT_DIR/.hooks/lib/python_checks.sh"
Expand All @@ -26,16 +22,6 @@ isort_args=("${ISORT_CONFIG_ARGS[@]}" "${ISORT_CHECK_ARGS[@]}")
# shellcheck disable=SC2034
black_args=("${BLACK_CONFIG_ARGS[@]}" "${BLACK_CHECK_ARGS[@]}")
fixing=false
fix_primary=false
fix_secondary=false
should_run_primary=true
should_run_secondary=true

load_secondary_scope_paths
if [ "${#SECONDARY_SCOPE_PATHS[@]}" -eq 0 ]; then
echo "No secondary scope paths found; forcing secondary environment check to be skipped."
should_run_secondary=false
fi

for arg in "$@"; do
case $arg in
Expand All @@ -45,24 +31,6 @@ for arg in "$@"; do
# shellcheck disable=SC2034
black_args=("${BLACK_CONFIG_ARGS[@]}")
fixing=true
fix_primary=true
fix_secondary=true
;;
--fix-primary)
# shellcheck disable=SC2034
isort_args=("${ISORT_CONFIG_ARGS[@]}")
# shellcheck disable=SC2034
black_args=("${BLACK_CONFIG_ARGS[@]}")
fixing=true
fix_primary=true
;;
--fix-secondary)
# shellcheck disable=SC2034
isort_args=("${ISORT_CONFIG_ARGS[@]}")
# shellcheck disable=SC2034
black_args=("${BLACK_CONFIG_ARGS[@]}")
fixing=true
fix_secondary=true
;;
-h|--help)
print_usage
Expand All @@ -77,13 +45,7 @@ for arg in "$@"; do
done

if [ "$fixing" = true ]; then
should_run_primary=$fix_primary
should_run_secondary=$fix_secondary
if [ "$should_run_primary" = false ] && [ "$should_run_secondary" = false ]; then
should_run_primary=true
should_run_secondary=true
fi
echo "Fix mode enabled. Running isort/black only in the selected environments."
echo "Fix mode enabled. Running isort/black only."
fi

check_required_tools
Expand Down Expand Up @@ -124,19 +86,10 @@ run_bootstrap_checks() {
mypy --config-file "$CORE_DIR/pyproject.toml" "$bootstrap_dir"
}

if [ "$should_run_primary" = true ]; then
run_environment_phase "primary" "$PRIMARY_PROJECT_DIR" "primary" SECONDARY_SCOPE_PATHS EMPTY_PATHS true
# Bootstrap checks reuse the primary venv (run_environment_phase runs in a subshell so we re-activate)
# shellcheck disable=SC1091
source "$PRIMARY_PROJECT_DIR/.venv/bin/activate"
run_bootstrap_checks
fi
if [ "$should_run_secondary" = true ]; then
if [ "${#SECONDARY_SCOPE_PATHS[@]}" -eq 0 ]; then
echo "No services assigned to the secondary environment; skipping secondary run."
else
run_environment_phase "secondary" "$SECONDARY_PROJECT_DIR" "secondary" EMPTY_PATHS SECONDARY_SCOPE_PATHS true "$SECONDARY_COVERAGE_THRESHOLD"
fi
fi
run_environment_phase "core" "$CORE_DIR" EMPTY_PATHS EMPTY_PATHS true
# Bootstrap checks reuse the venv (run_environment_phase runs in a subshell so we re-activate)
# shellcheck disable=SC1091
source "$CORE_DIR/.venv/bin/activate"
run_bootstrap_checks

exit 0
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ When explaining:
Before adding ANY dependency, check all `pyproject.toml` files. Use exact versions if already specified:

```toml
aiohttp>=3.7.4,<=3.13.2
aiohttp==3.13.2
eclipse-zenoh==1.9.0
fastapi-versioning==0.9.1
fastapi==0.105.0
loguru==0.5.3
pydantic==1.10.12
uvicorn==0.18.0
fastapi-versioning==0.10.0
fastapi==0.125.0
loguru==0.7.3
pydantic==2.12.5
uvicorn==0.38.0
```

> Always sort dependencies alphabetically
Expand Down
Loading
Loading