Skip to content

Commit fb48105

Browse files
Image.py, tests, static analysis (#1)
* Added image.py and associated files * Add pre-commit-config.yaml * Pre-commit corrections - Removed unused variables ~ Modified line width to be 79 characters or less * Modified typing, location of isatty() check + Added Union typing to clarify argument types for output files ~ Moved isatty() check to the run() method to cover instances where the stdout changes over the course of usage * Bugfixes from prior commit * Exceptions & Command Availability Check + Added a CommandNotFoundOnImageError exception that is raised when an Image attempts to run a command that does not exist on the docker image. + Added a method to Image that performs checks on a docker image to see which commands from a given list are present on the image. + Added pytest tests to check the above + Corrected how interactive calls are made on Image.run() + Added a pytest test to check that interactive Image.run() calls proceed correctly + Added .gitignore * Image.tags str -> list ~ Image.tags modified to return a list of strings rather than a string representation of a list. ~ Modified associated pytests (tags and repr) to correctly reflect this change * File structure reorganization ~ Moved package files into docker_cls folder, test files into test folder + added __init__.py to docker_cls folder + added conftest.py to control the pytest working directory and clean up testing files ~ renamed some dockerfiles to be more indicative of their use and test that the system can use dockerfiles not named Dockerfile * PR Fixes + Added "Self" Type + Added return values to all methods ~ Modified some values to be keyword-only ~ Modified several argument types to be more idiomatic and expressive ~ Modified the value of the "network" command in build and run methods to be passed by argument instead of hardcoded ~ Changed parsing of the command argument from building and then splitting a string to constructing a list ~ Other small modifications * _run_process method added + Added the _run_process() method which governs how the Image class as a whole activates commands. This function can print, return, and write to files all of the outputs of a given command, and can also input an arbitrary string to stdin for that command. - Removed typing_extensions, changed to using typing.TypeVar + Added print_output arguments to run commands in order to allow them to print to the screen as they process. ~ Modified all command calling except for _inspect() to use _run_process() ~ Various small changes ~ Updated test_image run() tests to account for the fact that some stderr messages also output * Documentation update + Added to the docstring of run() to describe the CommandNotFoundOnImageError - Removed an extra testing file that was not intended for inclusion in the prior commit * Build overrides, Run redefined ~ build() redefined from build_from_dockerfile and build_from_string using overrides to allow users to define whether they want to build using a dockerfile string without having to call a separate function - this will allow for maintenance of only one method rather than two ~ run() modified to use subprocess.run() and flexibly handle the need for returning strings or writing to files ~ Tests modified and updated to fit new use cases * Update image.py Removed an accidental debug print statement from image.py * No-cache option added to image.build() methods + Added no-cache to image.build() methods to enable testing of image building in a more complete manner * PR updates + Added a ValueError check in get_image_id for name_or_id ~ Streamlined and/or clarified many docstrings in image.py and image_test.py ~ Renamed alpine_functional and alpine_broken to have ".dockerfile" extension ~ Modified methods with file outputs to accept stout and stderr arguments separately ~ Modified Image.build() to raise a ValueError if both dockerfile and dockerfile_string commands are given. ~ Modified image.build() to default to building a dockerfile in the context root folder if neither dockerfile_string nor dockerfile are given. ~ Moved the bash warning to the run command. ~ Updated pytest tests to fit new interfaces * Additional docstring changes ~ Added some further simplifications to the docstrings. ~ Modified Image.build such that `context` is optional and defaults to use "." * Update image.py ~ Listed optional arguments as optional in docstrings * Update image.py * Update image.py * Update image.py * Update docker_cli/image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update test/test_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update to use checkout from docker_build_tree ~ Moved exceptions.py and image.py to private files ~ Moved test_image_id fixture to conftest.py ~ Modified pytest_sessionstart to allow pytests from anywhere ~ Added a tox.ini file to handle additional changes ~ Added has_command to Image, adjusted check command to use it ~ Added drop-in to Image ~ Changes to documentation * Test upgrades - Removed pytest_sessionfinish from conftest.py ~ Changed test_image_id to image_id ~ Used yield to have image_id clean up after itself ~ Used try/finally blocks to have build tests clean up after themselves ~ Used temporary files instead of filenames ~ Improved some documentation in _image.py * More PR fixes ~ Changed "cat dockerfile" lines to use Path.read_text() ~ Changed Image.has_command to use try/except/else * Removed extra "Raises" commentary in docstrings * Fixed import issue * Update conftest.py Added comments to explain the purpose of the lines in pytest_sessionstart * Exception improvements ~ Changed CommandNotFoundError to subclass from Exception instead of CalledProcessError ~ Specified when ImageNotFoundError should be raised more clearly ~ Fixed some tests and documentation in test_image.py * Changed "test" image to "isce3_pytest_temp" ~ Changed other temporary images to "isce3_pytest_temp_2" ~ Removed some hanging commas in test parameters. * Proper capitalization of "Dockerfile" * Added image_tag fixture ~ Added an image_tag fixture to simplify modifying the test tags when needed. * Update docker_cli/_exceptions.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update test/test_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Update docker_cli/_image.py Co-authored-by: Geoffrey Gunter <[email protected]> * Exception overloads, dropin change, documentation ~ Exceptions modified to use method overloads for __init__ ~ Exceptions modified to call super.__init__ instead of defining __str__ ~ image.drop_in modified to just call image.run() ~ Some documentation changes and shuffling of arguments * Fixed DockerBuildError raises in Image.build * Added utils.py + added utils.py file ~ Moved image_tag, image_id fixtures to utils.py ~ Updated tests and pre-commit hooks for importing fixtures * More robust fixture usage, use of test classes and marks + Began using marks to enable later test segregation + Began using test classes for simpler marking + Simplified flake8 per-file-ignores in tox.ini ~ Renamed utils.py to fixtures.py (utils.py will later be used for helper functions) * Image fixture scope, parallelism + Added scope to fixtures in fixtures.py + Added test/utils.py, with a universal function for removing images to avoid syntax mistakes + Added docker_cli/utils.py, which has a codename generator to allow parallel tests to run without race conditions * Dynamic scope + Added a dynamic scope function for pytest-xdist rescoping * A docstring for determine_scope * PR Suggestions, pytest-cov compatibility * Dedent escape character corrected * minor * Added some documentation to determine_scope --------- Co-authored-by: Tyler Hudson <[email protected]> Co-authored-by: Geoffrey Gunter <[email protected]>
1 parent 50d54f9 commit fb48105

17 files changed

+1178
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.DS_Store
2+
*.vscode*
3+
*__pycache__*

.pre-commit-config.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
ci:
2+
autofix_prs: false
3+
4+
repos:
5+
- repo: https://github.com/pre-commit/pre-commit-hooks
6+
rev: "v4.4.0"
7+
hooks:
8+
- id: check-added-large-files
9+
- id: check-case-conflict
10+
- id: check-docstring-first
11+
- id: check-merge-conflict
12+
- id: check-toml
13+
- id: check-yaml
14+
- id: debug-statements
15+
- id: end-of-file-fixer
16+
- id: file-contents-sorter
17+
files: (\.gitignore|requirements.txt)$
18+
- id: mixed-line-ending
19+
- id: trailing-whitespace
20+
21+
- repo: https://github.com/pre-commit/mirrors-autopep8
22+
rev: "v2.0.1"
23+
hooks:
24+
- id: autopep8
25+
26+
- repo: https://github.com/PyCQA/flake8
27+
rev: "6.0.0"
28+
hooks:
29+
- id: flake8
30+
31+
- repo: https://github.com/PyCQA/isort
32+
rev: "5.12.0"
33+
hooks:
34+
- id: isort
35+
36+
- repo: https://github.com/pre-commit/mirrors-mypy
37+
rev: "v1.0.0"
38+
hooks:
39+
- id: mypy

docker_cli/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from ._exceptions import (CommandNotFoundError, DockerBuildError,
2+
ImageNotFoundError)
3+
from ._image import Image, get_image_id

docker_cli/_exceptions.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class CommandNotFoundError(Exception):
2+
"""Raised when a command is attempted but not found."""
3+
4+
def __init__(self, command_name: str):
5+
"""
6+
Raise this exception when a command is attempted but not found.
7+
8+
Parameters
9+
----------
10+
command_name : str
11+
The name of the command.
12+
"""
13+
self.command_name = command_name
14+
super().__init__(
15+
f"Command '{self.command_name}' was run, but is not "
16+
"present on the Docker image."
17+
)
18+
19+
20+
class DockerBuildError(Exception):
21+
"""Raised when a docker image fails to build"""
22+
pass
23+
24+
25+
class ImageNotFoundError(Exception):
26+
"""
27+
Raised when attempting to create an image using a tag or ID that does not
28+
exist.
29+
"""
30+
31+
def __init__(
32+
self,
33+
tag_or_id: str
34+
):
35+
"""
36+
Raise this exception when unable to find an image.
37+
38+
Parameters
39+
----------
40+
tag_or_id : str
41+
The tag or ID of the image.
42+
"""
43+
self.tag_or_id = tag_or_id
44+
super().__init__(
45+
f"Docker image \"{tag_or_id}\" not found."
46+
)

0 commit comments

Comments
 (0)