Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase to Python 3.8 #47

Merged
merged 10 commits into from
Jul 19, 2024
7 changes: 3 additions & 4 deletions .github/workflows/bump_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.7
- run: pip3 install --upgrade pip wheel
- run: |
sudo apt-get install python3-venv make
pip3 install --upgrade pip wheel
- run: echo bldr_version=$(make bump-version) | tee --append $GITHUB_ENV
- uses: peter-evans/create-pull-request@v5
with:
Expand Down
21 changes: 12 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.7
- run: pip3 install --upgrade pip
- run: |
sudo apt-get install python3-venv make
pip3 install --upgrade pip
cemiarni marked this conversation as resolved.
Show resolved Hide resolved
- run: make dev
- run: make cs lint

Expand All @@ -26,12 +25,16 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
docker-image: ['ubuntu:xenial', 'ubuntu:bionic', 'ubuntu:focal', 'debian:bullseye']
docker-image:
- ubuntu:focal
- ubuntu:jammy
- ubuntu:noble
- debian:bullseye
- debian:bookworm

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.7
- run: pip3 install --upgrade pip
- run: |
sudo apt-get install python3-venv make
wferi marked this conversation as resolved.
Show resolved Hide resolved
pip3 install --upgrade pip
- run: make DOCKER_IMAGE=${{ matrix.docker-image }} check-docker-image
7 changes: 3 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.7
- run: pip3 install --upgrade pip wheel twine
- run: |
sudo apt-get install python3-venv make
pip3 install --upgrade pip wheel twine
- run: make release
- run: make release-test
- name: Publish a Python distribution to PyPI
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ check-docker-image: dev
# Run tests on one selected docker image
.PHONY: quick-check
quick-check:
. $(VIRTUALENV)/bin/activate && pytest --docker-image=ubuntu:bionic
. $(VIRTUALENV)/bin/activate && pytest --docker-image=ubuntu:focal

# Update requirements files for setup.py
.PHONY: update-requirements
Expand All @@ -68,7 +68,7 @@ release:

.PHONY: release-test
release-test: release
. $(RELEASE_TEST_VENV)/bin/activate && pytest --docker-image=ubuntu:bionic
. $(RELEASE_TEST_VENV)/bin/activate && pytest --docker-image=ubuntu:focal

# Install development dependencies (for testing) in virtualenv
.PHONY: dev
Expand Down
10 changes: 7 additions & 3 deletions bldr/bldr.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import importlib_resources
import logging
import os
import pwd
Expand All @@ -10,7 +11,7 @@
from tempfile import TemporaryDirectory

from .docker_utils import create_docker_client, DockerImageBuilder, DockerImage, DockerContainer, DEFAULT_DOCKER_TIMEOUT
from .utils import BLDRError, BLDRSetupFailed, escape_docker_image_tag, get_resource
from .utils import BLDRError, BLDRSetupFailed, escape_docker_image_tag


PRE_BUILD_HOOK = "/hooks/pre-build"
Expand Down Expand Up @@ -106,7 +107,10 @@ def _build_image(self, tag: str, control_file: Optional[Path] = None) -> DockerI

with TemporaryDirectory(prefix="bldr_docker_dir_") as tmp_dir:
docker_files_dir = Path(tmp_dir).joinpath('docker_files')
shutil.copytree(str(get_resource('.')), str(docker_files_dir))
with importlib_resources.as_file(
importlib_resources.files().joinpath('data')
) as resource_dir:
shutil.copytree(resource_dir, docker_files_dir)
if control_file is None:
docker_files_dir.joinpath('control').write_text('')
else:
Expand Down Expand Up @@ -201,7 +205,7 @@ def build(self, package_dir: Path) -> DockerImage:
@classmethod
def selftest(cls) -> None:
client = create_docker_client()
for ubuntu_release in ['xenial', 'bionic', 'focal']:
for ubuntu_release in ['focal', 'jammy']:
image = DockerImage(client=client, image='ubuntu:{}'.format(ubuntu_release))
assert image is not None, "DockerImage should be initialized without Exception"

Expand Down
2 changes: 1 addition & 1 deletion bldr/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def _add_common_arguments(cls, parser: argparse.ArgumentParser) -> None:

parser.add_argument(
"docker_from",
help="Specify the value which will be used for the FROM keyword when building the docker image. Example: 'ubuntu:bionic'",
help="Specify the value which will be used for the FROM keyword when building the docker image. Example: 'ubuntu:jammy'",
)
parser.add_argument(
'-s', '--snapshot',
Expand Down
2 changes: 1 addition & 1 deletion bldr/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, *args: Any, **kwargs: Any):

super().__init__(*args, **kwargs)

def parse_known_args(self, args: Optional[Sequence[str]] = None, namespace: Optional[argparse.Namespace] = None) -> Tuple[argparse.Namespace, List[str]]:
def parse_known_args(self, args: Optional[Sequence[str]] = None, namespace=None):
cemiarni marked this conversation as resolved.
Show resolved Hide resolved
if self.config_loader:
self.set_defaults_from_config(args)
return super().parse_known_args(args, namespace=None)
Expand Down
5 changes: 0 additions & 5 deletions bldr/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os
import pwd
from pathlib import Path
from pkg_resources import resource_filename


class BLDRError(Exception):
Expand All @@ -19,10 +18,6 @@ def __init__(self, msg: str, exitcode: int = 1) -> None:
super().__init__(msg, exitcode)


def get_resource(path: str) -> Path:
return Path(resource_filename('bldr', str(Path('data', path))))


def escape_docker_image_tag(tag: str) -> str:
return tag.replace(":", "-").replace("/", "-")

Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
autopep8
flake8>=5 # for type annotation support and Python 3.8 compatibility in pyflakes 2.1.0+
flake8
mypy
pycodestyle
pytest
Expand Down
54 changes: 22 additions & 32 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,70 +1,60 @@
#
# This file is autogenerated by pip-compile with Python 3.7
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --no-emit-index-url --no-emit-trusted-host --output-file=requirements-dev.txt --resolver=backtracking requirements-dev.in
# pip-compile --no-emit-index-url --no-emit-trusted-host --output-file=requirements-dev.txt requirements-dev.in
#
autopep8==2.0.0
autopep8==2.3.1
# via -r requirements-dev.in
coverage[toml]==7.2.7
# via
# coverage
# pytest-cov
coverage[toml]==7.6.0
# via pytest-cov
exceptiongroup==1.2.2
# via pytest
flake8==5.0.4
flake8==7.1.0
# via -r requirements-dev.in
importlib-metadata==4.2.0
# via
# flake8
# pluggy
# pytest
# pytest-console-scripts
importlib-metadata==8.0.0
# via pytest-console-scripts
iniconfig==2.0.0
# via pytest
mccabe==0.7.0
# via flake8
mypy==1.4.1
mypy==1.10.1
# via -r requirements-dev.in
mypy-extensions==1.0.0
# via mypy
packaging==24.0
packaging==24.1
# via pytest
pluggy==1.2.0
pluggy==1.5.0
# via pytest
pycodestyle==2.9.1
pycodestyle==2.12.0
# via
# -r requirements-dev.in
# autopep8
# flake8
pyflakes==2.5.0
pyflakes==3.2.0
# via flake8
pytest==7.4.4
pytest==8.2.2
# via
# -r requirements-dev.in
# pytest-console-scripts
# pytest-cov
pytest-console-scripts==1.4.0
pytest-console-scripts==1.4.1
# via -r requirements-dev.in
pytest-cov==4.1.0
pytest-cov==5.0.0
# via -r requirements-dev.in
tomli==2.0.1
# via
# autopep8
# coverage
# mypy
# pytest
typed-ast==1.5.5
# via mypy
types-requests==2.31.0.20231231
types-requests==2.32.0.20240712
# via -r requirements-dev.in
types-setuptools==69.0.0.0
types-setuptools==70.3.0.20240710
# via -r requirements-dev.in
typing-extensions==4.7.1
# via
# importlib-metadata
# mypy
urllib3==2.0.7
typing-extensions==4.12.2
# via mypy
urllib3==2.2.2
# via types-requests
zipp==3.15.0
zipp==3.19.2
# via importlib-metadata
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
docker
dockerpty
importlib_resources
18 changes: 9 additions & 9 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.7
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --no-emit-index-url --no-emit-trusted-host --output-file=requirements.txt --resolver=backtracking requirements.in
# pip-compile --no-emit-index-url --no-emit-trusted-host --output-file=requirements.txt requirements.in
#
certifi==2024.7.4
# via requests
charset-normalizer==3.3.2
# via requests
docker==6.1.3
docker==7.1.0
# via -r requirements.in
dockerpty==0.4.1
# via -r requirements.in
idna==3.7
# via requests
packaging==24.0
# via docker
requests==2.31.0
importlib-resources==6.4.0
# via -r requirements.in
requests==2.32.3
# via docker
six==1.16.0
# via dockerpty
urllib3==2.0.7
urllib3==2.2.2
# via
# docker
# requests
websocket-client==1.6.1
# via docker
zipp==3.19.2
# via importlib-resources
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_package_data():
extras_require={
'dev': Path('requirements-dev.txt').read_text(),
},
python_requires=">=3.7",
python_requires=">=3.8",
package_data={'bldr': [
'VERSION',
] + get_package_data()},
Expand All @@ -50,10 +50,11 @@ def get_package_data():
"Operating System :: POSIX :: Linux",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: System :: Systems Administration",
"Topic :: Utilities",
],
Expand Down
2 changes: 1 addition & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import shutil
from pathlib import Path

DEFAULT_DOCKER_IMAGES = ["ubuntu:xenial", "ubuntu:bionic", "ubuntu:focal", "debian:bullseye"]
DEFAULT_DOCKER_IMAGES = ["ubuntu:focal", "ubuntu:jammy"]


def pytest_addoption(parser):
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_command_help(script_runner: ScriptRunner):
def test_config_with_a_non_existent_file(script_runner: ScriptRunner, tmp_path: Path):
config = tmp_path.joinpath('non-existent-config.json')
ret = script_runner.run([
'bldr', '--config', str(config), 'build', 'ubuntu:bionic'
'bldr', '--config', str(config), 'build', 'ubuntu:focal'
])
assert not ret.success
assert "Unable to open configuration file: '{}'".format(config) in ret.stderr
Expand All @@ -98,7 +98,7 @@ def test_config_with_a_unreadable_file(script_runner: ScriptRunner, tmp_path: Pa
config.touch()
config.chmod(0)
ret = script_runner.run([
'bldr', '--config', str(config), 'build', 'ubuntu:bionic'
'bldr', '--config', str(config), 'build', 'ubuntu:focal'
])
assert not ret.success
assert "Unable to open configuration file: '{}'".format(config) in ret.stderr
Expand All @@ -109,7 +109,7 @@ def test_config_with_a_non_json_file(script_runner: ScriptRunner, tmp_path: Path
config.write_text('{"foo": ')

ret = script_runner.run([
'bldr', '--config', str(config), 'build', 'ubuntu:bionic'
'bldr', '--config', str(config), 'build', 'ubuntu:focal'
])
assert not ret.success
assert "Unable to parse configuration file: 'Expecting value: line 1 column 9 (char 8)'" in ret.stderr
10 changes: 5 additions & 5 deletions test/integration/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ def test_config_with_an_existent_file(tmp_path: Path):
config = tmp_path.joinpath('config.json')
with config.open('w') as config_file:
json.dump({'container_env': ['foo=bar', 'bar=baz']}, config_file)
bldr = CLI(['bldr', '--config', str(config), 'build', 'ubuntu:bionic'])
bldr = CLI(['bldr', '--config', str(config), 'build', 'ubuntu:focal'])
assert bldr.args.container_env == [('foo', 'bar'), ('bar', 'baz')]


def test_config_and_cmdline_arg_has_a_same_value_and_a_proper_type(tmp_path: Path):
config = tmp_path.joinpath('config.json')
with config.open('w') as config_file:
json.dump({'hooks_dir': '/foo/hooks'}, config_file)
bldr = CLI(['bldr', '--config', str(config), 'build', 'ubuntu:bionic'])
bldr = CLI(['bldr', '--config', str(config), 'build', 'ubuntu:focal'])
hooks_dir1 = bldr.args.hooks_dir
bldr = CLI(['bldr', 'build', 'ubuntu:bionic', '--hooks-dir', '/foo/hooks'])
bldr = CLI(['bldr', 'build', 'ubuntu:focal', '--hooks-dir', '/foo/hooks'])
hooks_dir2 = bldr.args.hooks_dir

assert hooks_dir1 == Path('/foo/hooks')
Expand All @@ -37,7 +37,7 @@ def test_config_override_with_cmdline_arg(tmp_path):
with config.open('w') as config_file:
json.dump({'hooks_dir': '/foo/hooks'}, config_file)
bldr = CLI(
['bldr', 'build', 'ubuntu:bionic', '--hooks-dir', '/override/hooks']
['bldr', 'build', 'ubuntu:focal', '--hooks-dir', '/override/hooks']
)

assert bldr.args.hooks_dir == Path('/override/hooks')
Expand Down Expand Up @@ -80,7 +80,7 @@ def test_container_env(tmp_path: Path, config_data, arguments, expected):
with config.open('w') as config_file:
json.dump(config_data, config_file)
base_arguments = [
'bldr', '--config', str(config), 'build', 'ubuntu:bionic',
'bldr', '--config', str(config), 'build', 'ubuntu:focal',
]
bldr = CLI(base_arguments + arguments)

Expand Down
2 changes: 1 addition & 1 deletion test/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ def test_argparse_inheritance(tmp_path: Path):
def test_argparse_api_definitions():
parser = argparse.ArgumentParser()
assert hasattr(parser, "_actions"), "parser object should have '_actions' attribute"
assert type(parser._actions) == list, "parser's '_actions' attribute must be a list"
assert isinstance(parser._actions, list), "parser's '_actions' attribute must be a list"
assert hasattr(argparse, "_StoreAction"), "argparse must have a '_StoreAction' class defined"
Loading
Loading