diff --git a/{{cookiecutter.project_name}}/Taskfile.yml b/{{cookiecutter.project_name}}/Taskfile.yml index 4e0f0c7..47eaa99 100644 --- a/{{cookiecutter.project_name}}/Taskfile.yml +++ b/{{cookiecutter.project_name}}/Taskfile.yml @@ -18,7 +18,7 @@ vars: VERSION: sh: "{{ '{{.RUN_SCRIPT}}' }} python -c \"import sys; sys.path.insert(0, 'src'); from {{ '{{.PROJECT_SLUG}}' }} import __version__; print(__version__)\"" LOCAL_PLATFORM: - sh: "bash {{ '{{.SCRIPTS_DIR}}' }}/get_platform.sh" + sh: "{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/get_platform.py" # Use PLATFORM if specified, otherwise use LOCAL_PLATFORM PLATFORM: '{{ '{{if .PLATFORM}}' }}{{ '{{.PLATFORM}}' }}{{ '{{else}}' }}{{ '{{.LOCAL_PLATFORM}}' }}{{ '{{end}}' }}' # Output redirect based on CI environment @@ -88,7 +88,7 @@ tasks: TIMESTAMP: sh: '{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/get_rfc3339_timestamp.py' EPOCH: - sh: 'bash {{ '{{.SCRIPTS_DIR}}' }}/get_epoch.sh' + sh: '{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/get_epoch.py' COMMIT_HASH: sh: git rev-parse HEAD BUILD_PLATFORM: '{{ '{{if eq .PLATFORM "all"}}' }}{{ '{{.SUPPORTED_PLATFORMS}}' }}{{ '{{else if .PLATFORM}}' }}{{ '{{.PLATFORM}}' }}{{ '{{else}}' }}{{ '{{.LOCAL_PLATFORM}}' }}{{ '{{end}}' }}' @@ -187,18 +187,7 @@ tasks: clean: desc: Clean up build artifacts, cache files/directories, temp files, etc. cmds: - - rm -rf .pytest_cache - - rm -rf htmlcov - - rm -rf .coverage - - rm -rf dist - - rm -rf build - - rm -rf *.egg-info - - rm -f sbom.*.json - - rm -f vulns.*.json - - rm -f license-check.*.json - - rm -f {{ cookiecutter.github_org }}_{{ cookiecutter.project_slug }}_*_*.tar - - find . -type d -name __pycache__ -exec rm -rf {} + || true - - find . -type f -name '*.pyc' -delete || true + - '{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/clean.py' release: desc: Cut a project release diff --git a/{{cookiecutter.project_name}}/scripts/clean.py b/{{cookiecutter.project_name}}/scripts/clean.py new file mode 100755 index 0000000..dbd5f41 --- /dev/null +++ b/{{cookiecutter.project_name}}/scripts/clean.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +"""Cross-platform cleanup of build artifacts, cache files, and temp files.""" + +import glob +import shutil +import sys +from pathlib import Path + + +def main() -> int: + """Remove build artifacts, cache directories, and temporary files.""" + root = Path(".") + + # Paths to remove (may be files or directories) + for name in [".pytest_cache", "htmlcov", ".coverage", "dist", "build"]: + path = root / name + if path.is_dir(): + shutil.rmtree(path) + elif path.is_file(): + path.unlink() + + # Glob patterns for directories + for path in glob.glob("*.egg-info"): + shutil.rmtree(path) + + # Glob patterns for files + for pattern in [ + "sbom.*.json", + "vulns.*.json", + "license-check.*.json", + "{{ cookiecutter.github_org }}_{{ cookiecutter.project_slug }}_*_*.tar", + ]: + for path in glob.glob(pattern): + Path(path).unlink() + + # Recursively remove __pycache__ directories + for path in root.rglob("__pycache__"): + if path.is_dir(): + shutil.rmtree(path) + + # Recursively remove .pyc files + for path in root.rglob("*.pyc"): + path.unlink() + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/{{cookiecutter.project_name}}/scripts/get_epoch.py b/{{cookiecutter.project_name}}/scripts/get_epoch.py new file mode 100755 index 0000000..9bd5159 --- /dev/null +++ b/{{cookiecutter.project_name}}/scripts/get_epoch.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +"""Get the current Unix epoch timestamp.""" + +import time + +print(int(time.time())) diff --git a/{{cookiecutter.project_name}}/scripts/get_epoch.sh b/{{cookiecutter.project_name}}/scripts/get_epoch.sh deleted file mode 100755 index 5bf579e..0000000 --- a/{{cookiecutter.project_name}}/scripts/get_epoch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -date +%s diff --git a/{{cookiecutter.project_name}}/scripts/get_platform.py b/{{cookiecutter.project_name}}/scripts/get_platform.py new file mode 100755 index 0000000..c1abfbd --- /dev/null +++ b/{{cookiecutter.project_name}}/scripts/get_platform.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +"""Get the Docker platform string for the current machine. + +Always uses 'linux' as the OS since container builds target Linux. +""" + +import platform +import sys + +# Always use linux for container builds +os_name = "linux" +machine = platform.machine().lower() + +# Inspired by https://github.com/containerd/containerd/blob/e0912c068b131b33798ae45fd447a1624a6faf0a/platforms/database.go#L76 +arch_map = { + # AMD64 + "x86_64": "amd64", + "amd64": "amd64", + # ARM64 + "aarch64": "arm64", + "arm64": "arm64", +} + +if machine not in arch_map: + print(f"Unsupported architecture: {machine}", file=sys.stderr) + sys.exit(1) + +print(f"{os_name}/{arch_map[machine]}") diff --git a/{{cookiecutter.project_name}}/scripts/get_platform.sh b/{{cookiecutter.project_name}}/scripts/get_platform.sh deleted file mode 100755 index 9010676..0000000 --- a/{{cookiecutter.project_name}}/scripts/get_platform.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Always use linux for container builds -os="linux" -arch="$(uname -m)" - -# Inspired by https://github.com/containerd/containerd/blob/e0912c068b131b33798ae45fd447a1624a6faf0a/platforms/database.go#L76 -case ${arch} in - # AMD64 - x86_64) echo "${os}/amd64" ;; - amd64) echo "${os}/amd64" ;; - - # ARM64 - aarch64) echo "${os}/arm64" ;; - arm64) echo "${os}/arm64" ;; - - *) echo "Unsupported architecture: $arch" && exit 1 ;; -esac