diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile deleted file mode 100644 index b51f081b..00000000 --- a/.devcontainer/Containerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/python:1-3.11-bookworm - -# Install development dependencies -RUN apt update && apt install -y iperf3 libusb-dev \ No newline at end of file diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..5372760f --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,39 @@ +FROM debian:bookworm-slim AS builder + +WORKDIR /opt + +# The installer requires curl (and certificates) to download the release archive +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl + +SHELL [ "/bin/bash", "-o", "pipefail", "-c" ] + +# Download the latest installer +ADD https://astral.sh/uv/install.sh uv-installer.sh + +# Run the installer then remove it +RUN sh uv-installer.sh + + +FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm + +ENV CARGO_HOME="/opt/.cargo/bin" +ENV PATH="$CARGO_HOME/:$PATH" + +ENV PYTHONUNBUFFERED=True +ENV UV_LINK_MODE=copy + +WORKDIR /opt + +COPY --from=builder /root/.cargo/bin/uv $CARGO_HOME/uv +COPY --from=builder /root/.cargo/bin/uvx $CARGO_HOME/uvx +COPY ./.python-version ./ + +RUN uv python pin "$(cat .python-version)" + +RUN chown -R vscode $CARGO_HOME + +# Install required tools for development +RUN apt-get update && apt-get install -y iperf3 libusb-dev diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1769f2cc..069c5840 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,10 +1,12 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/python { - "name": "Python 3", - "dockerFile": "Containerfile", - // Install poetry and packages - "postCreateCommand": "pip3 install -U uv && uv sync --all-extras", + "name": "uv", + "build": { + "context": "..", + "dockerfile": "Dockerfile" + }, + "postCreateCommand": "make sync", + "postStartCommand": "uv run pre-commit install", + "remoteUser": "vscode", // Mount USB devices to devcontainer for tests "mounts": [ "type=bind,source=/dev/bus/usb,target=/dev/bus/usb" @@ -13,25 +15,45 @@ "vscode": { "extensions": [ "tamasfe.even-better-toml", - "ms-python.vscode-pylance", - "ms-python.debugpy", - "charliermarsh.ruff", "tekumara.typos-vscode", + "charliermarsh.ruff", + "codezombiech.gitignore", "littlefoxteam.vscode-python-test-adapter", "hbenl.vscode-test-explorer", "ryanluker.vscode-coverage-gutters", "lextudio.restructuredtext", "trond-snekvik.simple-rst", "swyddfa.esbonio", - "ExecutableBookProject.myst-highlight" + "ExecutableBookProject.myst-highlight", + "eamodio.gitlens", + "kevinrose.vsc-python-indent", + "mosapride.zenkaku", + "ms-azuretools.vscode-docker", + "ms-python.python", + "njpwerner.autodocstring", + "pkief.material-icon-theme", + "shardulm94.trailing-spaces", + "usernamehw.errorlens", + "yzhang.markdown-all-in-one", + "ms-vscode.makefile-tools" ], "settings": { - "extensions.ignoreRecommendations": true, "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python", "[python]": { - "editor.formatOnType": true, - "editor.formatOnSave": true, - "editor.defaultFormatter": "charliermarsh.ruff" + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.codeActionsOnSave": { + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" + }, + "editor.formatOnSave": true + }, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } }, "[markdown]": { "editor.rulers": [ @@ -46,4 +68,4 @@ } } } -} \ No newline at end of file +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..9758601e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +default_stages: [commit] +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 + hooks: + - id: ruff + name: Ruff check + description: "Run 'ruff check' for extremely fast Python linting" + args: [ --fix ] + + - id: ruff-format + name: Ruff format + description: "Run 'ruff format' for extremely fast Python formatting" \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..4c8b864a --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12.3 \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 70b251a9..1c43e86b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,19 +1,29 @@ { "recommendations": [ "tamasfe.even-better-toml", - "ms-python.vscode-pylance", - "ms-python.debugpy", - "charliermarsh.ruff", "tekumara.typos-vscode", + "charliermarsh.ruff", + "codezombiech.gitignore", "littlefoxteam.vscode-python-test-adapter", "hbenl.vscode-test-explorer", "ryanluker.vscode-coverage-gutters", "lextudio.restructuredtext", "trond-snekvik.simple-rst", "swyddfa.esbonio", - "executablebookproject.myst-highlight" + "ExecutableBookProject.myst-highlight", + "eamodio.gitlens", + "kevinrose.vsc-python-indent", + "mosapride.zenkaku", + "ms-azuretools.vscode-docker", + "ms-python.python", + "njpwerner.autodocstring", + "pkief.material-icon-theme", + "shardulm94.trailing-spaces", + "usernamehw.errorlens", + "yzhang.markdown-all-in-one", + "ms-vscode.makefile-tools" ], "unwantedRecommendations": [ "ms-python.autopep8" ] -} \ No newline at end of file +} diff --git a/Makefile b/Makefile index 0dd674c9..f9d8f194 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,14 @@ CONTRIB_TARGETS = $(subst contrib/,contrib-,$(wildcard contrib/*)) +default: build + docs: cd docs && make html -docs-watch: +watch-docs: sphinx-autobuild docs/source docs/build/html -clean: +clean-docs: rm -rf ./docs/build sync-jumpstarter: @@ -33,10 +35,24 @@ test-contrib: $(addprefix test-,$(CONTRIB_TARGETS)) build-contrib: $(addprefix build-,$(CONTRIB_TARGETS)) +clean-venv: + -rm -rf ./.venv + -find . -type d -name __pycache__ -exec rm -r {} \+ + +clean-build: + -rm -rf dist + +clean-test: + -rm .coverage + -rm coverage.xml + -rm -rf htmlcov + sync: sync-jumpstarter sync-contrib test: test-jumpstarter test-contrib -build: build-jumpstarter build-contrib +build: sync build-jumpstarter build-contrib + +clean: clean-docs clean-venv clean-build clean-test -.PHONY: docs test test-jumpstarter test-contrib build build-jumpstarter build-contrib +.PHONY: sync docs test test-jumpstarter test-contrib build build-jumpstarter build-contrib clean-test clean-docs clean-venv clean-build diff --git a/pyproject.toml b/pyproject.toml index c6255e99..1b2c32d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ name = "jumpstarter" version = "0.1.0" description = "" authors = [ - { name = "Miguel Angel Ajo Pelayo", email = "majopela@redhat.com" }, - { name = "Nick Cao", email = "ncao@redhat.com" }, - { name = "Kirk Brauer", email = "kbrauer@hatci.com" }, + { name = "Miguel Angel Ajo Pelayo", email = "majopela@redhat.com" }, + { name = "Nick Cao", email = "ncao@redhat.com" }, + { name = "Kirk Brauer", email = "kbrauer@hatci.com" }, ] readme = "README.md" requires-python = ">=3.11" @@ -50,6 +50,7 @@ dev-dependencies = [ "pytest-cov>=5.0.0", "ruff>=0.6.1", "typos>=1.23.6", + "pre-commit>=3.8.0", ] [tool.uv.workspace] diff --git a/uv.lock b/uv.lock index 5f01308a..6758ab34 100644 --- a/uv.lock +++ b/uv.lock @@ -262,6 +262,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/94/19/cf5baa07ee0f0e55eab7382459fbddaba0fdb0ba45973dd92556ae0d02db/cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7", size = 181504 }, ] +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -437,6 +446,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/8d/778b7d51b981a96554f29136cd59ca7880bf58094338085bcf2a979a0e6a/Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", size = 9561 }, ] +[[package]] +name = "distlib" +version = "0.3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/91/e2df406fb4efacdf46871c25cde65d3c6ee5e173b7e5a4547a47bae91920/distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64", size = 609931 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/41/9307e4f5f9976bc8b7fea0b66367734e8faf3ec84bc0d412d8cfabbb66cd/distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", size = 468850 }, +] + [[package]] name = "docutils" version = "0.21.2" @@ -476,6 +494,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d6/1f/e99e23ee01847147fa194e8d41cfcf2535a2dbfcb51414c541cadb15c5d7/fabric-3.2.2-py3-none-any.whl", hash = "sha256:91c47c0be68b14936c88b34da8a1f55e5710fd28397dac5d4ff2e21558113a6f", size = 59417 }, ] +[[package]] +name = "filelock" +version = "3.15.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/08/dd/49e06f09b6645156550fb9aee9cc1e59aba7efbc972d665a1bd6ae0435d4/filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb", size = 18007 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/f0/48285f0262fe47103a4a45972ed2f9b93e4c80b8fd609fa98da78b2a5706/filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7", size = 16159 }, +] + [[package]] name = "frozenlist" version = "1.4.1" @@ -606,6 +633,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, ] +[[package]] +name = "identify" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/32/f4/8e8f7db397a7ce20fbdeac5f25adaf567fc362472432938d25556008e03a/identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf", size = 99116 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/6c/a4f39abe7f19600b74528d0c717b52fff0b300bb0161081510d39c53cb00/identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0", size = 98962 }, +] + [[package]] name = "idna" version = "3.8" @@ -687,6 +723,7 @@ docs = [ [package.dev-dependencies] dev = [ + { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-anyio" }, { name = "pytest-cov" }, @@ -720,6 +757,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pre-commit", specifier = ">=3.8.0" }, { name = "pytest", specifier = ">=8.3.2" }, { name = "pytest-anyio", specifier = ">=0.0.0" }, { name = "pytest-cov", specifier = ">=5.0.0" }, @@ -953,6 +991,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + [[package]] name = "opendal" version = "0.45.9" @@ -1019,6 +1066,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] +[[package]] +name = "pre-commit" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643 }, +] + [[package]] name = "protobuf" version = "5.28.0" @@ -1571,6 +1634,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5", size = 62835 }, ] +[[package]] +name = "virtualenv" +version = "20.26.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/68/60/db9f95e6ad456f1872486769c55628c7901fb4de5a72c2f7bdd912abf0c1/virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a", size = 9057588 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/4d/410156100224c5e2f0011d435e477b57aed9576fc7fe137abcf14ec16e11/virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589", size = 5684792 }, +] + [[package]] name = "watchfiles" version = "0.24.0"