lib-cli-exit-tools 1.5.0__tar.gz → 1.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lib_cli_exit_tools-1.6.0/.codacy/cli-config.yaml +1 -0
- lib_cli_exit_tools-1.6.0/.codacy/cli.sh +149 -0
- lib_cli_exit_tools-1.6.0/.codacy/codacy.yaml +15 -0
- lib_cli_exit_tools-1.6.0/.codacy/tools-configs/lizard.yaml +50 -0
- lib_cli_exit_tools-1.6.0/.codacy/tools-configs/trivy.yaml +10 -0
- lib_cli_exit_tools-1.6.0/.devcontainer/devcontainer.json +22 -0
- lib_cli_exit_tools-1.6.0/.devcontainer/settings.json +6 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/.github/workflows/ci.yml +78 -30
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/.github/workflows/release.yml +1 -1
- lib_cli_exit_tools-1.6.0/.qlty/qlty.toml +2 -0
- lib_cli_exit_tools-1.6.0/.snyk +5 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/AGENTS.md +9 -6
- lib_cli_exit_tools-1.6.0/CHANGELOG.md +110 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/CONTRIBUTING.md +16 -8
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/DEVELOPMENT.md +7 -1
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/INSTALL.md +5 -5
- lib_cli_exit_tools-1.6.0/Makefile +59 -0
- lib_cli_exit_tools-1.5.0/README.md → lib_cli_exit_tools-1.6.0/PKG-INFO +75 -4
- lib_cli_exit_tools-1.5.0/PKG-INFO → lib_cli_exit_tools-1.6.0/README.md +39 -35
- lib_cli_exit_tools-1.6.0/docs/system-design/module_reference.md +226 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/notebooks/Quickstart.ipynb +2 -2
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/packaging/brew/Formula/lib-cli-exit-tools.rb +7 -8
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/packaging/conda/recipe/meta.yaml +4 -4
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/packaging/nix/flake.nix +7 -7
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/pyproject.toml +45 -10
- lib_cli_exit_tools-1.6.0/scripts/__main__.py +7 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/_utils.py +148 -55
- lib_cli_exit_tools-1.6.0/scripts/build.py +78 -0
- lib_cli_exit_tools-1.6.0/scripts/bump.py +37 -0
- lib_cli_exit_tools-1.6.0/scripts/bump_major.py +24 -0
- lib_cli_exit_tools-1.6.0/scripts/bump_minor.py +24 -0
- lib_cli_exit_tools-1.6.0/scripts/bump_patch.py +24 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/bump_version.py +118 -57
- lib_cli_exit_tools-1.6.0/scripts/clean.py +48 -0
- lib_cli_exit_tools-1.6.0/scripts/cli.py +158 -0
- lib_cli_exit_tools-1.6.0/scripts/dev.py +25 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/generate_nix_flake.py +74 -34
- lib_cli_exit_tools-1.6.0/scripts/install.py +25 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/push.py +26 -14
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/release.py +41 -25
- lib_cli_exit_tools-1.6.0/scripts/run_cli.py +51 -0
- lib_cli_exit_tools-1.6.0/scripts/test.py +429 -0
- lib_cli_exit_tools-1.6.0/scripts/version_current.py +25 -0
- lib_cli_exit_tools-1.6.0/src/lib_cli_exit_tools/__init__.py +46 -0
- lib_cli_exit_tools-1.6.0/src/lib_cli_exit_tools/__init__conf__.py +220 -0
- lib_cli_exit_tools-1.6.0/src/lib_cli_exit_tools/adapters/signals.py +189 -0
- lib_cli_exit_tools-1.6.0/src/lib_cli_exit_tools/application/runner.py +490 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/cli.py +78 -47
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/core/configuration.py +68 -3
- lib_cli_exit_tools-1.6.0/src/lib_cli_exit_tools/core/exit_codes.py +344 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +7 -1
- lib_cli_exit_tools-1.6.0/tests/adapters/test_signals_poetry.py +119 -0
- lib_cli_exit_tools-1.6.0/tests/application/test_runner_poetry.py +385 -0
- lib_cli_exit_tools-1.6.0/tests/application/test_signal_poetry_posix.py +84 -0
- lib_cli_exit_tools-1.6.0/tests/application/test_signal_poetry_windows.py +93 -0
- lib_cli_exit_tools-1.6.0/tests/cli/test_cli_poetry.py +305 -0
- lib_cli_exit_tools-1.6.0/tests/conftest.py +28 -0
- lib_cli_exit_tools-1.6.0/tests/core/test_configuration.py +73 -0
- lib_cli_exit_tools-1.6.0/tests/core/test_exit_code_poetry.py +192 -0
- lib_cli_exit_tools-1.5.0/CHANGELOG.md +0 -93
- lib_cli_exit_tools-1.5.0/Makefile +0 -98
- lib_cli_exit_tools-1.5.0/docs/system-design/module_reference.md +0 -246
- lib_cli_exit_tools-1.5.0/notebooks/Quickstart.ipynb.Backup +0 -281
- lib_cli_exit_tools-1.5.0/qlty.toml +0 -2
- lib_cli_exit_tools-1.5.0/scripts/build.py +0 -66
- lib_cli_exit_tools-1.5.0/scripts/bump.py +0 -27
- lib_cli_exit_tools-1.5.0/scripts/bump_major.py +0 -17
- lib_cli_exit_tools-1.5.0/scripts/bump_minor.py +0 -17
- lib_cli_exit_tools-1.5.0/scripts/bump_patch.py +0 -17
- lib_cli_exit_tools-1.5.0/scripts/clean.py +0 -47
- lib_cli_exit_tools-1.5.0/scripts/dev.py +0 -18
- lib_cli_exit_tools-1.5.0/scripts/install.py +0 -19
- lib_cli_exit_tools-1.5.0/scripts/run_cli.py +0 -26
- lib_cli_exit_tools-1.5.0/scripts/test.py +0 -360
- lib_cli_exit_tools-1.5.0/scripts/version_current.py +0 -22
- lib_cli_exit_tools-1.5.0/src/lib_cli_exit_tools/__init__.py +0 -48
- lib_cli_exit_tools-1.5.0/src/lib_cli_exit_tools/__init__conf__.py +0 -230
- lib_cli_exit_tools-1.5.0/src/lib_cli_exit_tools/adapters/signals.py +0 -177
- lib_cli_exit_tools-1.5.0/src/lib_cli_exit_tools/application/runner.py +0 -324
- lib_cli_exit_tools-1.5.0/src/lib_cli_exit_tools/core/exit_codes.py +0 -149
- lib_cli_exit_tools-1.5.0/tests/adapters/test_signals.py +0 -75
- lib_cli_exit_tools-1.5.0/tests/application/test_runner.py +0 -247
- lib_cli_exit_tools-1.5.0/tests/cli/test_cli_entrypoints.py +0 -118
- lib_cli_exit_tools-1.5.0/tests/conftest.py +0 -36
- lib_cli_exit_tools-1.5.0/tests/core/test_exit_codes.py +0 -151
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/.env.example +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/.github/workflows/codeql.yml +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/.gitignore +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/LICENSE +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/codecov.yml +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/packaging/README.md +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/__init__.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/scripts/menu.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/__main__.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/application/__init__.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/core/__init__.py +0 -0
- {lib_cli_exit_tools-1.5.0 → lib_cli_exit_tools-1.6.0}/src/lib_cli_exit_tools/py.typed +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mode: local
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
set -e +o pipefail
|
|
5
|
+
|
|
6
|
+
# Set up paths first
|
|
7
|
+
bin_name="codacy-cli-v2"
|
|
8
|
+
|
|
9
|
+
# Determine OS-specific paths
|
|
10
|
+
os_name=$(uname)
|
|
11
|
+
arch=$(uname -m)
|
|
12
|
+
|
|
13
|
+
case "$arch" in
|
|
14
|
+
"x86_64")
|
|
15
|
+
arch="amd64"
|
|
16
|
+
;;
|
|
17
|
+
"x86")
|
|
18
|
+
arch="386"
|
|
19
|
+
;;
|
|
20
|
+
"aarch64"|"arm64")
|
|
21
|
+
arch="arm64"
|
|
22
|
+
;;
|
|
23
|
+
esac
|
|
24
|
+
|
|
25
|
+
if [ -z "$CODACY_CLI_V2_TMP_FOLDER" ]; then
|
|
26
|
+
if [ "$(uname)" = "Linux" ]; then
|
|
27
|
+
CODACY_CLI_V2_TMP_FOLDER="$HOME/.cache/codacy/codacy-cli-v2"
|
|
28
|
+
elif [ "$(uname)" = "Darwin" ]; then
|
|
29
|
+
CODACY_CLI_V2_TMP_FOLDER="$HOME/Library/Caches/Codacy/codacy-cli-v2"
|
|
30
|
+
else
|
|
31
|
+
CODACY_CLI_V2_TMP_FOLDER=".codacy-cli-v2"
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
version_file="$CODACY_CLI_V2_TMP_FOLDER/version.yaml"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
get_version_from_yaml() {
|
|
39
|
+
if [ -f "$version_file" ]; then
|
|
40
|
+
local version=$(grep -o 'version: *"[^"]*"' "$version_file" | cut -d'"' -f2)
|
|
41
|
+
if [ -n "$version" ]; then
|
|
42
|
+
echo "$version"
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
return 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get_latest_version() {
|
|
50
|
+
local response
|
|
51
|
+
if [ -n "$GH_TOKEN" ]; then
|
|
52
|
+
response=$(curl -Lq --header "Authorization: Bearer $GH_TOKEN" "https://api.github.com/repos/codacy/codacy-cli-v2/releases/latest" 2>/dev/null)
|
|
53
|
+
else
|
|
54
|
+
response=$(curl -Lq "https://api.github.com/repos/codacy/codacy-cli-v2/releases/latest" 2>/dev/null)
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
handle_rate_limit "$response"
|
|
58
|
+
local version=$(echo "$response" | grep -m 1 tag_name | cut -d'"' -f4)
|
|
59
|
+
echo "$version"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
handle_rate_limit() {
|
|
63
|
+
local response="$1"
|
|
64
|
+
if echo "$response" | grep -q "API rate limit exceeded"; then
|
|
65
|
+
fatal "Error: GitHub API rate limit exceeded. Please try again later"
|
|
66
|
+
fi
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
download_file() {
|
|
70
|
+
local url="$1"
|
|
71
|
+
|
|
72
|
+
echo "Downloading from URL: ${url}"
|
|
73
|
+
if command -v curl > /dev/null 2>&1; then
|
|
74
|
+
curl -# -LS "$url" -O
|
|
75
|
+
elif command -v wget > /dev/null 2>&1; then
|
|
76
|
+
wget "$url"
|
|
77
|
+
else
|
|
78
|
+
fatal "Error: Could not find curl or wget, please install one."
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
download() {
|
|
83
|
+
local url="$1"
|
|
84
|
+
local output_folder="$2"
|
|
85
|
+
|
|
86
|
+
( cd "$output_folder" && download_file "$url" )
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
download_cli() {
|
|
90
|
+
# OS name lower case
|
|
91
|
+
suffix=$(echo "$os_name" | tr '[:upper:]' '[:lower:]')
|
|
92
|
+
|
|
93
|
+
local bin_folder="$1"
|
|
94
|
+
local bin_path="$2"
|
|
95
|
+
local version="$3"
|
|
96
|
+
|
|
97
|
+
if [ ! -f "$bin_path" ]; then
|
|
98
|
+
echo "📥 Downloading CLI version $version..."
|
|
99
|
+
|
|
100
|
+
remote_file="codacy-cli-v2_${version}_${suffix}_${arch}.tar.gz"
|
|
101
|
+
url="https://github.com/codacy/codacy-cli-v2/releases/download/${version}/${remote_file}"
|
|
102
|
+
|
|
103
|
+
download "$url" "$bin_folder"
|
|
104
|
+
tar xzfv "${bin_folder}/${remote_file}" -C "${bin_folder}"
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Warn if CODACY_CLI_V2_VERSION is set and update is requested
|
|
109
|
+
if [ -n "$CODACY_CLI_V2_VERSION" ] && [ "$1" = "update" ]; then
|
|
110
|
+
echo "⚠️ Warning: Performing update with forced version $CODACY_CLI_V2_VERSION"
|
|
111
|
+
echo " Unset CODACY_CLI_V2_VERSION to use the latest version"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Ensure version.yaml exists and is up to date
|
|
115
|
+
if [ ! -f "$version_file" ] || [ "$1" = "update" ]; then
|
|
116
|
+
echo "ℹ️ Fetching latest version..."
|
|
117
|
+
version=$(get_latest_version)
|
|
118
|
+
mkdir -p "$CODACY_CLI_V2_TMP_FOLDER"
|
|
119
|
+
echo "version: \"$version\"" > "$version_file"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Set the version to use
|
|
123
|
+
if [ -n "$CODACY_CLI_V2_VERSION" ]; then
|
|
124
|
+
version="$CODACY_CLI_V2_VERSION"
|
|
125
|
+
else
|
|
126
|
+
version=$(get_version_from_yaml)
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Set up version-specific paths
|
|
131
|
+
bin_folder="${CODACY_CLI_V2_TMP_FOLDER}/${version}"
|
|
132
|
+
|
|
133
|
+
mkdir -p "$bin_folder"
|
|
134
|
+
bin_path="$bin_folder"/"$bin_name"
|
|
135
|
+
|
|
136
|
+
# Download the tool if not already installed
|
|
137
|
+
download_cli "$bin_folder" "$bin_path" "$version"
|
|
138
|
+
chmod +x "$bin_path"
|
|
139
|
+
|
|
140
|
+
run_command="$bin_path"
|
|
141
|
+
if [ -z "$run_command" ]; then
|
|
142
|
+
fatal "Codacy cli v2 binary could not be found."
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
if [ "$#" -eq 1 ] && [ "$1" = "download" ]; then
|
|
146
|
+
echo "Codacy cli v2 download succeeded"
|
|
147
|
+
else
|
|
148
|
+
eval "$run_command $*"
|
|
149
|
+
fi
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
patterns:
|
|
2
|
+
Lizard_ccn-medium:
|
|
3
|
+
category: Complexity
|
|
4
|
+
description: Checks if the cyclomatic complexity of a function or logic block exceeds the medium threshold (default is 8).
|
|
5
|
+
explanation: |-
|
|
6
|
+
# Medium Cyclomatic Complexity control
|
|
7
|
+
|
|
8
|
+
Check the Cyclomatic Complexity value of a function or logic block. If the threshold is not met, raise a Medium issue. The default threshold is 7.
|
|
9
|
+
id: Lizard_ccn-medium
|
|
10
|
+
level: Warning
|
|
11
|
+
severityLevel: Warning
|
|
12
|
+
threshold: 8
|
|
13
|
+
timeToFix: 10
|
|
14
|
+
title: Enforce Medium Cyclomatic Complexity Threshold
|
|
15
|
+
Lizard_file-nloc-medium:
|
|
16
|
+
category: Complexity
|
|
17
|
+
description: This rule checks if the number of lines of code (excluding comments) in a file exceeds a medium threshold, typically 500 lines.
|
|
18
|
+
explanation: ""
|
|
19
|
+
id: Lizard_file-nloc-medium
|
|
20
|
+
level: Warning
|
|
21
|
+
severityLevel: Warning
|
|
22
|
+
threshold: 500
|
|
23
|
+
timeToFix: 10
|
|
24
|
+
title: Enforce Medium File Length Limit Based on Number of Lines of Code
|
|
25
|
+
Lizard_nloc-medium:
|
|
26
|
+
category: Complexity
|
|
27
|
+
description: Checks if the number of lines of code (excluding comments) in a function exceeds a medium threshold (default 50 lines).
|
|
28
|
+
explanation: |-
|
|
29
|
+
# Medium NLOC control - Number of Lines of Code (without comments)
|
|
30
|
+
|
|
31
|
+
Check the number of lines of code (without comments) in a function. If the threshold is not met, raise a Medium issue. The default threshold is 50.
|
|
32
|
+
id: Lizard_nloc-medium
|
|
33
|
+
level: Warning
|
|
34
|
+
severityLevel: Warning
|
|
35
|
+
threshold: 50
|
|
36
|
+
timeToFix: 10
|
|
37
|
+
title: Enforce Medium Number of Lines of Code (NLOC) Limit
|
|
38
|
+
Lizard_parameter-count-medium:
|
|
39
|
+
category: Complexity
|
|
40
|
+
description: This rule checks the number of parameters passed to a function and raises an issue if it exceeds a medium threshold, which by default is 8 parameters.
|
|
41
|
+
explanation: |-
|
|
42
|
+
# Medium Parameter count control
|
|
43
|
+
|
|
44
|
+
Check the number of parameters sent to a function. If the threshold is not met, raise a Medium issue. The default threshold is 5.
|
|
45
|
+
id: Lizard_parameter-count-medium
|
|
46
|
+
level: Warning
|
|
47
|
+
severityLevel: Warning
|
|
48
|
+
threshold: 8
|
|
49
|
+
timeToFix: 10
|
|
50
|
+
title: Enforce Medium Parameter Count Limit
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.13",
|
|
3
|
+
|
|
4
|
+
"postCreateCommand": "bash -lc '\nPY=/usr/local/bin/python;\n$PY -m pip install -U pip && \\\n$PY -m pip install ipykernel && \\\n$PY -m pip install -e . && \\\n# register kernel using this exact interpreter\n$PY -m ipykernel install --name=python3 --display-name=\"Python 3 (3.13)\" --user && \\\n# patch the notebook to point to the python3 kernelspec (VS Code will bind to /usr/local/bin/python)\n$PY - <<\"PY\"\nimport json, pathlib\np = pathlib.Path(\"notebooks/Quickstart.ipynb\")\nif p.exists():\n nb = json.loads(p.read_text(encoding=\"utf-8\"))\n md = nb.setdefault(\"metadata\", {})\n md[\"kernelspec\"] = {\n \"name\": \"python3\",\n \"display_name\": \"Python 3 (3.13)\",\n \"language\": \"python\"\n }\n md[\"language_info\"] = {\"name\": \"python\"}\n p.write_text(json.dumps(nb, ensure_ascii=False, indent=1), encoding=\"utf-8\")\n print(\"Pinned kernelspec to python3 in\", p)\nelse:\n print(\"Notebook not found:\", p)\nPY'\n",
|
|
5
|
+
|
|
6
|
+
"customizations": {
|
|
7
|
+
"vscode": {
|
|
8
|
+
"extensions": ["ms-toolsai.jupyter", "ms-python.python"],
|
|
9
|
+
"settings": {
|
|
10
|
+
"workbench.startupEditor": "none",
|
|
11
|
+
"jupyter.alwaysTrustNotebooks": true,
|
|
12
|
+
"jupyter.kernelPickerType": "OnlyRecommended",
|
|
13
|
+
"python.defaultInterpreterPath": "/usr/local/bin/python"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"codespaces": {
|
|
17
|
+
"openFiles": ["README.md"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
"postAttachCommand": "bash -lc 'if [ -f notebooks/Quickstart.ipynb ]; then code -r notebooks/Quickstart.ipynb; fi'"
|
|
22
|
+
}
|
|
@@ -14,13 +14,31 @@ jobs:
|
|
|
14
14
|
fail-fast: false
|
|
15
15
|
matrix:
|
|
16
16
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
17
|
-
# Test against Python 3.
|
|
18
|
-
python: ["3.
|
|
17
|
+
# Test against Python 3.13 and the latest 3.x available on Actions runners
|
|
18
|
+
python: ["3.13", "3.x"]
|
|
19
19
|
steps:
|
|
20
20
|
- uses: actions/checkout@v4
|
|
21
21
|
- uses: actions/setup-python@v5
|
|
22
22
|
with:
|
|
23
23
|
python-version: ${{ matrix.python }}
|
|
24
|
+
- name: Extract project metadata
|
|
25
|
+
shell: python
|
|
26
|
+
run: |
|
|
27
|
+
import os
|
|
28
|
+
import tomllib
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
|
|
32
|
+
project = data['project']['name']
|
|
33
|
+
module = project.replace('-', '_')
|
|
34
|
+
dash = project.replace('_', '-')
|
|
35
|
+
scripts = list(data['project'].get('scripts', {}).keys())
|
|
36
|
+
cli_bin = scripts[0] if scripts else dash
|
|
37
|
+
|
|
38
|
+
with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as env:
|
|
39
|
+
env.write(f"PROJECT_NAME={project}\n")
|
|
40
|
+
env.write(f"PACKAGE_MODULE={module}\n")
|
|
41
|
+
env.write(f"CLI_BIN={cli_bin}\n")
|
|
24
42
|
- name: Install make on Windows
|
|
25
43
|
if: runner.os == 'Windows'
|
|
26
44
|
shell: pwsh
|
|
@@ -30,8 +48,7 @@ jobs:
|
|
|
30
48
|
- name: Install dev deps
|
|
31
49
|
shell: bash
|
|
32
50
|
run: |
|
|
33
|
-
python -m pip install --upgrade pip
|
|
34
|
-
python -m pip install --upgrade click rich rich-click
|
|
51
|
+
python -m pip install --upgrade "pip!=25.2"
|
|
35
52
|
pip install -e .[dev]
|
|
36
53
|
- name: Run full test suite (lint, types, tests, coverage, codecov)
|
|
37
54
|
shell: bash
|
|
@@ -45,7 +62,14 @@ jobs:
|
|
|
45
62
|
python -m venv .venv_wheel
|
|
46
63
|
. .venv_wheel/bin/activate 2>/dev/null || . .venv_wheel/Scripts/activate 2>/dev/null
|
|
47
64
|
pip install dist/*.whl
|
|
48
|
-
|
|
65
|
+
"$CLI_BIN" --version 2>/dev/null || python -m "$PACKAGE_MODULE" --version
|
|
66
|
+
- name: Verify sdist install in clean env
|
|
67
|
+
shell: bash
|
|
68
|
+
run: |
|
|
69
|
+
python -m venv .venv_sdist
|
|
70
|
+
. .venv_sdist/bin/activate 2>/dev/null || . .venv_sdist/Scripts/activate 2>/dev/null
|
|
71
|
+
pip install dist/*.tar.gz
|
|
72
|
+
"$CLI_BIN" --version 2>/dev/null || python -m "$PACKAGE_MODULE" --version
|
|
49
73
|
|
|
50
74
|
pipx-uv:
|
|
51
75
|
name: pipx/uv verification (ubuntu)
|
|
@@ -54,22 +78,43 @@ jobs:
|
|
|
54
78
|
- uses: actions/checkout@v4
|
|
55
79
|
- uses: actions/setup-python@v5
|
|
56
80
|
with:
|
|
57
|
-
python-version: "3.
|
|
81
|
+
python-version: "3.13"
|
|
82
|
+
- name: Extract project metadata
|
|
83
|
+
shell: python
|
|
84
|
+
run: |
|
|
85
|
+
import os
|
|
86
|
+
import tomllib
|
|
87
|
+
from pathlib import Path
|
|
88
|
+
|
|
89
|
+
data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
|
|
90
|
+
project = data['project']['name']
|
|
91
|
+
module = project.replace('-', '_')
|
|
92
|
+
dash = project.replace('_', '-')
|
|
93
|
+
scripts = list(data['project'].get('scripts', {}).keys())
|
|
94
|
+
cli_bin = scripts[0] if scripts else dash
|
|
95
|
+
|
|
96
|
+
with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as env:
|
|
97
|
+
env.write(f"PROJECT_NAME={project}\n")
|
|
98
|
+
env.write(f"PACKAGE_MODULE={module}\n")
|
|
99
|
+
env.write(f"CLI_BIN={cli_bin}\n")
|
|
58
100
|
- name: Build wheel
|
|
59
101
|
run: |
|
|
60
|
-
python -m pip install --upgrade pip
|
|
102
|
+
python -m pip install --upgrade "pip!=25.2"
|
|
103
|
+
python -m pip install --upgrade build
|
|
61
104
|
python -m build
|
|
62
105
|
- name: pipx install from wheel
|
|
63
106
|
run: |
|
|
64
107
|
python -m pip install pipx
|
|
65
108
|
pipx install dist/*.whl
|
|
66
|
-
|
|
109
|
+
"$CLI_BIN" --version 2>/dev/null || python -m "$PACKAGE_MODULE" --version
|
|
110
|
+
- name: Install uv
|
|
111
|
+
uses: astral-sh/setup-uv@v7
|
|
112
|
+
with:
|
|
113
|
+
enable-cache: true
|
|
67
114
|
- name: uv tool install
|
|
68
115
|
run: |
|
|
69
|
-
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
70
|
-
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$HOME/.local/share/uv/bin:$PATH"
|
|
71
116
|
uv tool install .
|
|
72
|
-
|
|
117
|
+
"$CLI_BIN" --version 2>/dev/null || python -m "$PACKAGE_MODULE" --version
|
|
73
118
|
|
|
74
119
|
# nix and conda packaging builds are disabled for now to keep CI green.
|
|
75
120
|
nix:
|
|
@@ -78,7 +123,7 @@ jobs:
|
|
|
78
123
|
steps:
|
|
79
124
|
- uses: actions/checkout@v4
|
|
80
125
|
- name: Install Nix (flakes)
|
|
81
|
-
uses: cachix/install-nix-action@
|
|
126
|
+
uses: cachix/install-nix-action@v31
|
|
82
127
|
with:
|
|
83
128
|
extra_nix_config: |
|
|
84
129
|
experimental-features = nix-command flakes
|
|
@@ -97,7 +142,7 @@ jobs:
|
|
|
97
142
|
uses: conda-incubator/setup-miniconda@v3
|
|
98
143
|
with:
|
|
99
144
|
auto-update-conda: true
|
|
100
|
-
python-version: "3.
|
|
145
|
+
python-version: "3.13"
|
|
101
146
|
- name: Build conda recipe (local source, no test)
|
|
102
147
|
shell: bash -l {0}
|
|
103
148
|
env:
|
|
@@ -109,16 +154,16 @@ jobs:
|
|
|
109
154
|
conda build packaging/conda/recipe --no-test -c conda-forge -c defaults
|
|
110
155
|
|
|
111
156
|
notebooks:
|
|
112
|
-
name: Execute notebooks (ubuntu, Python 3.
|
|
157
|
+
name: Execute notebooks (ubuntu, Python 3.13)
|
|
113
158
|
runs-on: ubuntu-latest
|
|
114
159
|
steps:
|
|
115
160
|
- uses: actions/checkout@v4
|
|
116
161
|
- uses: actions/setup-python@v5
|
|
117
162
|
with:
|
|
118
|
-
python-version: "3.
|
|
163
|
+
python-version: "3.13"
|
|
119
164
|
- name: Install notebook runner deps
|
|
120
165
|
run: |
|
|
121
|
-
python -m pip install --upgrade pip
|
|
166
|
+
python -m pip install --upgrade "pip!=25.2"
|
|
122
167
|
pip install nbclient nbformat ipykernel jupyter_client
|
|
123
168
|
python -m ipykernel install --user --name python3 --display-name "Python 3"
|
|
124
169
|
- name: Execute Quickstart notebook
|
|
@@ -178,21 +223,21 @@ jobs:
|
|
|
178
223
|
- name: Verify packaging matches pyproject
|
|
179
224
|
run: |
|
|
180
225
|
python - << 'PY'
|
|
181
|
-
import re, sys
|
|
226
|
+
import re, sys, tomllib
|
|
182
227
|
from pathlib import Path
|
|
183
228
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
print('requires-python must be like ">=3.X"'); sys.exit(1)
|
|
194
|
-
min_py = m_min.group(1)
|
|
229
|
+
data = tomllib.loads(Path('pyproject.toml').read_text(encoding='utf-8'))
|
|
230
|
+
project = data['project']['name']
|
|
231
|
+
version = data['project']['version']
|
|
232
|
+
requires = data['project']['requires-python']
|
|
233
|
+
|
|
234
|
+
min_match = re.search(r'([0-9]+\.[0-9]+)', requires)
|
|
235
|
+
if not min_match:
|
|
236
|
+
print('requires-python must declare a minimum like ">=3.X"'); sys.exit(1)
|
|
237
|
+
min_py = min_match.group(1)
|
|
195
238
|
min_digits = min_py.replace('.', '')
|
|
239
|
+
project_dash = project.replace('_', '-')
|
|
240
|
+
project_module = project.replace('-', '_')
|
|
196
241
|
|
|
197
242
|
# Conda
|
|
198
243
|
conda = Path('packaging/conda/recipe/meta.yaml').read_text(encoding='utf-8')
|
|
@@ -202,7 +247,10 @@ jobs:
|
|
|
202
247
|
print('conda/meta.yaml: python constraint not aligned (host/run)'); sys.exit(1)
|
|
203
248
|
|
|
204
249
|
# Brew
|
|
205
|
-
|
|
250
|
+
brew_path = Path(f'packaging/brew/Formula/{project_dash}.rb')
|
|
251
|
+
if not brew_path.exists():
|
|
252
|
+
print(f'brew formula missing: {brew_path}'); sys.exit(1)
|
|
253
|
+
brew = brew_path.read_text(encoding='utf-8')
|
|
206
254
|
if f"refs/tags/v{version}.tar.gz" not in brew:
|
|
207
255
|
print('brew formula: url tag mismatch'); sys.exit(1)
|
|
208
256
|
if f'"python@{min_py}"' not in brew:
|
|
@@ -210,7 +258,7 @@ jobs:
|
|
|
210
258
|
|
|
211
259
|
# Nix
|
|
212
260
|
nix = Path('packaging/nix/flake.nix').read_text(encoding='utf-8')
|
|
213
|
-
if not re.search(r'pname\s*=\s*"
|
|
261
|
+
if not re.search(r'pname\s*=\s*"' + re.escape(project_module) + r'";\s*[^}]*?version\s*=\s*"' + re.escape(version) + r'";', nix, re.S):
|
|
214
262
|
print('nix flake: version mismatch'); sys.exit(1)
|
|
215
263
|
if not re.search(r'pypkgs\s*=\s*pkgs\.python' + re.escape(min_digits) + r'Packages', nix):
|
|
216
264
|
print('nix flake: python package set not aligned'); sys.exit(1)
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## On session start
|
|
4
4
|
|
|
5
|
+
whenever You wait for user input or finished, execute "paplay /usr/share/sounds/codex/ready.wav"
|
|
6
|
+
whenever You have a question, execute "paplay /usr/share/sounds/codex/ready.wav"
|
|
7
|
+
whenever You have an error, execute "paplay /usr/share/sounds/codex/error.wav"
|
|
8
|
+
|
|
5
9
|
Review the system prompt files in `/media/srv-main/softdev/*/projects/softwarestack/systemprompts` and keep their guidance in working memory:
|
|
6
10
|
|
|
7
11
|
- core_programming_solid.md
|
|
@@ -16,6 +20,7 @@ Review the system prompt files in `/media/srv-main/softdev/*/projects/softwarest
|
|
|
16
20
|
- python_jupyter_notebooks.md
|
|
17
21
|
- python_testing.md
|
|
18
22
|
|
|
23
|
+
|
|
19
24
|
always apply those Rules :
|
|
20
25
|
|
|
21
26
|
- core_programming_solid.md
|
|
@@ -47,7 +52,7 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
47
52
|
|
|
48
53
|
- Single source of truth for the package version is `pyproject.toml` (`[project].version`).
|
|
49
54
|
- Runtime code reads metadata via `importlib.metadata`; do not duplicate the version in code files.
|
|
50
|
-
- On a version bump, update only `pyproject.toml` and the `CHANGELOG.md` entry;
|
|
55
|
+
- On a version bump, update only `pyproject.toml` and the `CHANGELOG.md` entry; runtime code should continue to read the version via `importlib.metadata` (no separate `__init__conf__` file).
|
|
51
56
|
- Tag releases `vX.Y.Z` and push tags; CI will build artifacts and publish when configured.
|
|
52
57
|
|
|
53
58
|
### Common Make Targets (Alphabetical)
|
|
@@ -73,6 +78,7 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
73
78
|
|
|
74
79
|
|
|
75
80
|
## Coding Style & Naming Conventions
|
|
81
|
+
- apply python_clean_code.md
|
|
76
82
|
|
|
77
83
|
## Commit & Pull Request Guidelines
|
|
78
84
|
|
|
@@ -88,23 +94,20 @@ when writing or refracturing Python scripts, apply those Rules :
|
|
|
88
94
|
## Translations (App UI Strings)
|
|
89
95
|
|
|
90
96
|
## Changes in WEB Documentation
|
|
91
|
-
|
|
92
97
|
- when asked to update documentation - only do that in the english docs under /website/docs because other languages will be translated automatically,
|
|
93
98
|
unless stated otherwise by the user. In doubt - ask the user
|
|
94
99
|
|
|
95
100
|
## Changes in APP Strings
|
|
96
|
-
|
|
97
101
|
- when i18 strings are changed, only to that in sources/\_locales/en because other languages will be translated automatically,
|
|
98
102
|
unless stated otherwise by the user. In doubt - ask the user
|
|
99
103
|
|
|
100
104
|
## commit/push/GitHub policy
|
|
101
|
-
|
|
102
105
|
- run "make test" before any push to avoid lint/test breakage.
|
|
103
106
|
- after push, monitor errors in the github actions and try to correct the errors
|
|
104
107
|
|
|
105
|
-
---
|
|
108
|
+
---
|
|
106
109
|
|
|
107
|
-
# ONLY ON USER REQEST !!!! :
|
|
110
|
+
# ONLY ON USER REQEST !!!! :
|
|
108
111
|
|
|
109
112
|
# 📘 Documentation Review & Enhancement Prompt
|
|
110
113
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## [1.6.0] - 2025-10-08
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- Property-based (Hypothesis) tests covering `SystemExit` payload handling and configurable broken-pipe exit codes.
|
|
10
|
+
- POSIX integration test that drives a subprocess through a SIGINT to assert real signal handling behaviour.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Local `make test` runs skip packaging-sync enforcement unless running in CI or with `ENFORCE_PACKAGING_SYNC=1`, reducing friction for contributors.
|
|
14
|
+
- CLI rich-click styling now preserves coloured tracebacks when stderr supports UTF/TTY output even if stdout is piped.
|
|
15
|
+
- Centralised public API exports so `lib_cli_exit_tools` and its facade share a single authoritative symbol list.
|
|
16
|
+
|
|
17
|
+
### Security
|
|
18
|
+
- Suppress pip-audit false positive for GHSA-4xh5-x5gv-qwph until an official fixed pip build is published.
|
|
19
|
+
|
|
20
|
+
## [1.5.0] - 2025-10-08
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Configuration helpers `config_overrides` and `reset_config` so embedders can
|
|
24
|
+
safely tweak and restore global CLI settings without bespoke fixtures.
|
|
25
|
+
- Expanded OS-aware test coverage (sysexits mappings, signal restoration, CLI
|
|
26
|
+
behaviours) and rewritten specs that no longer rely on private helpers.
|
|
27
|
+
- CI job that executes the Quickstart notebook on Python 3.13 and validations that ensure packaging metadata stays in sync at tag time.
|
|
28
|
+
- Automation that keeps Conda, Homebrew, and Nix specs aligned with `pyproject.toml`, including a dedicated `--sync-packaging` mode.
|
|
29
|
+
- Regression tests covering `SystemExit` variants, tolerant output rendering, English signal messages, and ValueError mappings on Windows.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Hardened `get_system_exit_code` handling for non-integer payloads and switched OS detection to `os.name`.
|
|
33
|
+
- Updated `_print_output` to decode both `bytes` and `str`, trimming assertions in favour of resilient diagnostics.
|
|
34
|
+
- Standardised signal messages (“Aborted (SIGINT).”, etc.) and cached metadata lookups in `__init__conf__`.
|
|
35
|
+
- Enforced an 85% coverage threshold (in line with `pyproject.toml` and Codecov settings) and removed spurious coverage pragmas to reflect the new test suite.
|
|
36
|
+
- Repartitioned the library into `core`, `adapters`, and `application` layers with `lib_cli_exit_tools` acting as the facade.
|
|
37
|
+
- `run_cli` now accepts injectable `exception_handler` and `signal_installer` hooks, and rich-click configuration is applied lazily from `main()`.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- Restored Pyright compatibility by typing metadata helpers against a minimal protocol.
|
|
41
|
+
- Removed a Ruff F401 false positive on the Quickstart notebook via per-file ignore.
|
|
42
|
+
|
|
43
|
+
### Documentation
|
|
44
|
+
- Expanded the README with packaging sync guidance and notebook usage notes.
|
|
45
|
+
- Clarified release steps in CONTRIBUTING and refreshed developer docs.
|
|
46
|
+
|
|
47
|
+
## [1.4.0] - 2025-09-26
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
- Refactored packaging automation and broadened the pytest suite to cover new CLI flows.
|
|
51
|
+
|
|
52
|
+
## [1.3.1] - 2025-09-26
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
- Adjusted coloured traceback behaviour to address regressions introduced in 1.3.0.
|
|
56
|
+
|
|
57
|
+
## [1.3.0] - 2025-09-25
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- Introduced Rich-powered traceback rendering for CLI failures.
|
|
61
|
+
|
|
62
|
+
## [1.2.0] - 2025-09-25
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- Switched the CLI stack to rich-click and delivered associated fixes.
|
|
66
|
+
|
|
67
|
+
## [1.1.1] - 2025-09-18
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- Documentation and doctest updates for newly exposed helpers.
|
|
71
|
+
|
|
72
|
+
## [1.1.0] - 2025-09-16
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
- `lib_cli_exit_tools.run_cli` helper to reduce Click boilerplate (see `cli.py`).
|
|
76
|
+
|
|
77
|
+
## [1.0.3] - 2025-09-16
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
- `make menu` target for the Textual-powered maintenance UI.
|
|
81
|
+
|
|
82
|
+
## [1.0.2] - 2025-09-15
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
- Miscellaneous internal improvements.
|
|
86
|
+
|
|
87
|
+
## [1.0.1] - 2025-09-15
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
- Miscellaneous internal improvements.
|
|
91
|
+
|
|
92
|
+
## [1.0.0] - 2025-09-15
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
- Initial public release.
|
|
96
|
+
|
|
97
|
+
## [0.1.1] - 2025-09-15
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
- Placeholder for early internal work.
|
|
101
|
+
|
|
102
|
+
## [0.1.0] - 2025-09-14
|
|
103
|
+
|
|
104
|
+
### Added
|
|
105
|
+
- Unified package naming, tightened public API exports, and added tests for exit-code mapping and CLI behaviour.
|
|
106
|
+
|
|
107
|
+
## [0.0.1] - 2025-09-13
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- Initial internal release.
|