From b8ecafb8b780070ded9f6a2c4093b5842e1a35c2 Mon Sep 17 00:00:00 2001 From: naswierczek Date: Tue, 7 Nov 2023 15:50:09 -0500 Subject: [PATCH] RM-105: Adding Dockerfile - This will build a container and run all non-integration tests for records-mover - Added docker-compose to make life simpler - includes .dockerignore to exclude generated artifacts (copy-pasta of .gitgnore) - Updating .gitignore --- .dockerignore | 79 +++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 + Dockerfile.dev | 20 ++++++++++++ README.md | 75 ++++++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 20 ++++++++++++ 5 files changed, 195 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile.dev create mode 100644 docker-compose.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..059f6fab2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,79 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +venv/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage* +.cache +pytest.xml +coverage.xml +*,cover +/test-reports/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# pytesttest +/cover +/typecover +/.coverage +/coverage.xml +/pytest.xml +/test-reports + +.DS_Store + +# Build package cache +.mypy_cache +*.bak + +# PyCharm +.idea/ + +# VSCode +.vscode/settings.json diff --git a/.gitignore b/.gitignore index 433ed28c2..059f6fab2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ __pycache__/ # Distribution / packaging .Python env/ +venv/ build/ develop-eggs/ dist/ diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 000000000..5bcaeeec9 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,20 @@ +FROM cimg/python:3.9 +ARG VERSION=3.9.1 +ARG NAME=records-mover +ENV version_env=$VERSION +ENV name_env=$NAME + +USER root + +COPY . $HOME/records-mover/ +WORKDIR /records-mover + +RUN pyenv install $version_env +RUN pyenv virtualenv "$version_env" "$name_env"-"$version_env" +RUN pyenv local records-mover-$version_env +RUN python -m venv venv \ + && . venv/bin/activate \ + && pip install --upgrade pip \ + && pip install --progress-bar=off -r requirements.txt \ + && pip install --upgrade --progress-bar=off 'pandas>=1.5.3,<2' \ + && pip install -e '.[unittest,typecheck]' # diff --git a/README.md b/README.md index c5c09323a..461fff59c 100644 --- a/README.md +++ b/README.md @@ -151,3 +151,78 @@ In particular, note: * [targets factory methods](https://records-mover.readthedocs.io/en/latest/records_mover.records.targets.html) * [move() method](https://records-mover.readthedocs.io/en/latest/records_mover.records.html#records_mover.records.move) * [BaseRecordsFormat](https://records-mover.readthedocs.io/en/latest/records_mover.records.html#records_mover.records.base_records_format.BaseRecordsFormat) + +## Local Development + +The included Dockerfile can be used to build a docker image that is +suitable for local development. + +```bash +docker build Dockerfile.dev -t records-mover:latest . +``` + +Or, using docker compose, +```bash +docker compose build +``` + +The following commands assume the records-mover container has been +named `records-mover`. + +Mount the directory containing your local copy of the repository to +have it override what's in the container. + +```bash +docker run -it --mount src="$(pwd)/records_mover",target=/records-mover/records_mover,type=bind records-mover +``` +This will mount your local src overtop of the same directory in the +container. Mount any additional directories you are working on with +additional --mount entries + +Alternatively, you can launch the container using docker-compose. +This will start the container with pre-defined mounts. +``` +docker-compose up -d +``` +This will build the container image as necessary, launch it, and +mount the most relevant volumes for local dev. +The container is hosting a bash shell and will run until you +manually shut it down. + +Note, if you have to add a dependency to requirements.txt and want +to test it locally, add the line `COPY requirements.txt .` after +`RUN git clone ...` in the Dockerfile and rebuild the container. + +### Working within the container + +The container presumes you're still working with python +virtual environments when working with it. This could possibly +be considered a "hat on a hat" situation. +The practical consequence of this is that if you do open a shell +in the container, ensure you activate the `venv` virtual +environment. Otherwise, you will not have all the dependencies +you'll need. + +After you've started a shell with the `docker run...` command above, +you can activate the virtual environment with: +``` +source venv/bin/activate +``` + +### Running unit and type tests + +Unit and type tests can be run within the container by running: +``` +make citest +make cicoverage +make typecheck +make citypecoverage +``` + +The tests can be run from outside the container using docker-compose. +```bash +docker compose run test +``` +It's theoretically possible to build sufficient additional +containers to support running integration tests locally but +that has not been planned yet. diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..9ef6ad85b --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +version: '3.8' +services: + records-mover: + tty: true + build: + context: . + dockerfile: Dockerfile.dev + volumes: + - ./records_mover:/records-mover/records_mover + - ./setup.py:/records-mover/setup.py + test: + build: + context: . + dockerfile: Dockerfile.dev + command: > + bash -c "source venv/bin/activate && + make citest && + make cicoverage && + make typecheck && + make citypecoverage"