diff --git a/.gitignore b/.gitignore index 61bfcf5..0bdc11d 100644 --- a/.gitignore +++ b/.gitignore @@ -71,4 +71,7 @@ target/ .idea/ # Gemini -.gemini +.gemini/ + +# Claude Code +.claude/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7b60a6a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +ARG PYTHON_VERSION + +FROM python:${PYTHON_VERSION} + +RUN pip install hatch==1.14.0 + +# Add only the minimal files required to be able to pre-create the hatch environments. +# If any of these files changes, a new Docker build is necessary. This is why we need +# to only include the minimal set of files. +ADD pyproject.toml /working/pyproject.toml +ADD LICENSE.txt /working/LICENSE.txt +ADD README.md /working/README.md +ADD src/kaggle/__init__.py /working/src/kaggle/__init__.py +WORKDIR /working + +# Pre-create the hatch environments. +# This drastically cut the time to run commands with the `docker-hatch` wrapper +# since the creation of the environments (including syncing dependencies) is +# only done once when building this image and is skipped later. +RUN hatch env create default +RUN hatch env create lint + +ENTRYPOINT ["hatch"] diff --git a/README.md b/README.md index 57e01e3..b29fd01 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,17 @@ After setting up your credentials, you can run the integration tests as follows: hatch run test:integration ``` +### Running `hatch` commands inside Docker + +This is useful to run in a consistent environment and easily switch between Python versions. + +The following shows how to run `hatch run lint:all` but this also works for any other hatch commands: + +``` +# Use default Python version +./docker-hatch run lint:all +``` + ## Changelog See [CHANGELOG](CHANGELOG.md). diff --git a/docker-hatch b/docker-hatch new file mode 100755 index 0000000..e6b6627 --- /dev/null +++ b/docker-hatch @@ -0,0 +1,72 @@ +#!/bin/bash +set -e + +PYTHON_VERSION='3.11.6' # Default Python version to use. +CACHE_FLAG='' + +usage() { +cat << EOF +Usage: $0 [OPTIONS] HATCH-OPTIONS-COMMAND-ARGS +Run the given HATCH-OPTIONS-COMMAND-ARGS in a container. + +Options: + -h, --help Show documentation on how to use $0 + -v, --python-version PYTHON-VERSION Run in a container using this specfic Python version. + Valid versions are tags of the \`python\` Docker image: https://hub.docker.com/_/python + -f, --force-rebuild-docker-image Force re-build the Docker image. +EOF +} + +while :; do + case "$1" in + -h|--help) + usage + exit + ;; + -v|--python-version) + if [[ -z $2 ]]; then + usage + printf 'ERROR: No PYTHON-VERSION specified after the %s flag.\n' "$1" >&2 + exit + fi + PYTHON_VERSION=$2 + shift # skip the flag value + ;; + -f|--force-rebuild-docker-image) + CACHE_FLAG='--no-cache' + ;; + # Use this marker to indicate that the rest of the command is for hatch + --) + shift # skip this one to pass the rest to hatch + break + ;; + -?*) + usage + printf 'ERROR: Unknown option: %s\n' "$1" >&2 + exit + ;; + *) + break + esac + + shift +done + +DOCKER_IMAGE="kaggle-cli-docker-hatch:${PYTHON_VERSION}" + +readonly PYTHON_VERSION +readonly DOCKER_IMAGE +readonly CACHE_FLAG + +echo "Running 'hatch $@' inside a Docker container using Python ${PYTHON_VERSION}" + +docker build -f Dockerfile \ + -t ${DOCKER_IMAGE} \ + ${CACHE_FLAG} \ + --cache-from ${DOCKER_IMAGE} \ + --build-arg PYTHON_VERSION=${PYTHON_VERSION} \ + --quiet \ + . + +set -x +docker run -it --rm -v $PWD:/working -v ~/.kaggle:/root/.kaggle -w /working ${DOCKER_IMAGE} "$@"