Skip to content

Commit 07272ea

Browse files
authored
feature/pre commit updates (#102)
* fix pre-commit config and typings * tests: move registry infos to fixtures Signed-off-by: Tiziano Müller <tiziano.mueller@hpe.com>
1 parent 0bc0db2 commit 07272ea

File tree

11 files changed

+104
-102
lines changed

11 files changed

+104
-102
lines changed

.pre-commit-config.yaml

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,29 @@
11
exclude: ".all-contributorsrc|.tributors"
22
repos:
33
- repo: https://github.com/pre-commit/pre-commit-hooks
4-
rev: v4.3.0
4+
rev: v4.4.0
55
hooks:
66
- id: check-added-large-files
77
- id: check-case-conflict
88
- id: check-docstring-first
99
- id: end-of-file-fixer
1010
- id: trailing-whitespace
1111
- id: mixed-line-ending
12-
13-
- repo: local
12+
- repo: https://github.com/pycqa/isort
13+
rev: 5.12.0
1414
hooks:
15-
- id: black
16-
name: black
17-
language: python
18-
types: [python]
19-
entry: black
20-
2115
- id: isort
22-
name: isort
23-
args: [--filter-files]
24-
language: python
25-
types: [python]
26-
entry: isort
27-
28-
- id: mypy
29-
name: mypy
30-
language: python
31-
types: [python]
32-
entry: mypy
33-
16+
- repo: https://github.com/psf/black
17+
rev: 23.9.1
18+
hooks:
19+
- id: black
20+
language_version: python3.11
21+
- repo: https://github.com/pycqa/flake8
22+
rev: 6.1.0
23+
hooks:
3424
- id: flake8
35-
name: flake8
36-
language: python
37-
types: [python]
38-
entry: flake8
25+
- repo: https://github.com/pre-commit/mirrors-mypy
26+
rev: v1.5.1
27+
hooks:
28+
- id: mypy
29+
additional_dependencies: ["types-requests"]

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
1414
The versions coincide with releases on pip. Only major versions will be released as tags on Github.
1515

1616
## [0.0.x](https://github.com/oras-project/oras-py/tree/main) (0.0.x)
17+
- refactor tests using fixtures and rework pre-commit configuration (0.1.25)
1718
- eliminate the additional subdirectory creation while pulling an image to a custom output directory (0.1.24)
1819
- updating the exclude string in the pyproject.toml file to match the [data type black expects](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-format)
1920
- patch fix for pulling artifacts by digest (0.1.23)

oras/logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def exit(self, msg: str, return_code: int = 1):
213213
self.handler({"level": "error", "msg": msg})
214214
sys.exit(return_code)
215215

216-
def progress(self, done: int = None, total: int = None):
216+
def progress(self, done: int, total: int):
217217
"""
218218
Show piece of a progress bar
219219

oras/oci.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def NewLayer(
116116

117117

118118
def ManifestConfig(
119-
path: str = None, media_type: str = None
119+
path: Optional[str] = None, media_type: Optional[str] = None
120120
) -> Tuple[Dict[str, object], str]:
121121
"""
122122
Write an empty config, if one is not provided

oras/provider.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ def pull(self, *args, **kwargs) -> List[str]:
816816

817817
@decorator.ensure_container
818818
def get_manifest(
819-
self, container: container_type, allowed_media_type: list = None
819+
self, container: container_type, allowed_media_type: Optional[list] = None
820820
) -> dict:
821821
"""
822822
Retrieve a manifest for a package.
@@ -842,9 +842,9 @@ def do_request(
842842
self,
843843
url: str,
844844
method: str = "GET",
845-
data: Union[dict, bytes] = None,
846-
headers: dict = None,
847-
json: dict = None,
845+
data: Optional[Union[dict, bytes]] = None,
846+
headers: Optional[dict] = None,
847+
json: Optional[dict] = None,
848848
stream: bool = False,
849849
):
850850
"""

oras/tests/conftest.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import os
2+
from dataclasses import dataclass
3+
4+
import pytest
5+
6+
7+
@dataclass
8+
class TestCredentials:
9+
with_auth: bool
10+
user: str
11+
password: str
12+
13+
14+
@pytest.fixture
15+
def registry():
16+
host = os.environ.get("ORAS_HOST")
17+
port = os.environ.get("ORAS_PORT")
18+
19+
if not host or not port:
20+
pytest.skip(
21+
"You must export ORAS_HOST and ORAS_PORT"
22+
" for a running registry before running tests."
23+
)
24+
25+
return f"{host}:{port}"
26+
27+
28+
@pytest.fixture
29+
def credentials(request):
30+
with_auth = os.environ.get("ORAS_AUTH") == "true"
31+
user = os.environ.get("ORAS_USER", "myuser")
32+
pwd = os.environ.get("ORAS_PASS", "mypass")
33+
34+
if with_auth and not user or not pwd:
35+
pytest.skip("To test auth you need to export ORAS_USER and ORAS_PASS")
36+
37+
marks = [m.name for m in request.node.iter_markers()]
38+
if request.node.parent:
39+
marks += [m.name for m in request.node.parent.iter_markers()]
40+
41+
if request.node.get_closest_marker("with_auth"):
42+
if request.node.get_closest_marker("with_auth").args[0] != with_auth:
43+
if with_auth:
44+
pytest.skip("test requires un-authenticated access to registry")
45+
else:
46+
pytest.skip("test requires authenticated access to registry")
47+
48+
return TestCredentials(with_auth, user, pwd)
49+
50+
51+
@pytest.fixture
52+
def target(registry):
53+
return f"{registry}/dinosaur/artifact:v1"
54+
55+
56+
@pytest.fixture
57+
def target_dir(registry):
58+
return f"{registry}/dinosaur/directory:v1"

oras/tests/test_oras.py

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,40 @@
44

55
import os
66
import shutil
7-
import sys
87

98
import pytest
109

1110
import oras.client
1211

1312
here = os.path.abspath(os.path.dirname(__file__))
1413

15-
registry_host = os.environ.get("ORAS_HOST")
16-
registry_port = os.environ.get("ORAS_PORT")
17-
with_auth = os.environ.get("ORAS_AUTH") == "true"
18-
oras_user = os.environ.get("ORAS_USER", "myuser")
19-
oras_pass = os.environ.get("ORAS_PASS", "mypass")
2014

21-
22-
def setup_module(module):
23-
"""
24-
Ensure the registry port and host is in the environment.
25-
"""
26-
if not registry_host or not registry_port:
27-
sys.exit(
28-
"You must export ORAS_HOST and ORAS_PORT for a running registry before running tests."
29-
)
30-
if with_auth and not oras_user or not oras_pass:
31-
sys.exit("To test auth you need to export ORAS_USER and ORAS_PASS")
32-
33-
34-
registry = f"{registry_host}:{registry_port}"
35-
target = f"{registry}/dinosaur/artifact:v1"
36-
target_dir = f"{registry}/dinosaur/directory:v1"
37-
38-
39-
def test_basic_oras():
15+
def test_basic_oras(registry):
4016
"""
4117
Basic tests for oras (without authentication)
4218
"""
4319
client = oras.client.OrasClient(hostname=registry, insecure=True)
4420
assert "Python version" in client.version()
4521

4622

47-
@pytest.mark.skipif(not with_auth, reason="basic auth is needed for login/logout")
48-
def test_login_logout():
23+
@pytest.mark.with_auth(True)
24+
def test_login_logout(registry, credentials):
4925
"""
5026
Login and logout are all we can test with basic auth!
5127
"""
5228
client = oras.client.OrasClient(hostname=registry, insecure=True)
5329
res = client.login(
54-
hostname=registry, username=oras_user, password=oras_pass, insecure=True
30+
hostname=registry,
31+
username=credentials.user,
32+
password=credentials.password,
33+
insecure=True,
5534
)
5635
assert res["Status"] == "Login Succeeded"
5736
client.logout(registry)
5837

5938

60-
@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
61-
def test_basic_push_pull(tmp_path):
39+
@pytest.mark.with_auth(False)
40+
def test_basic_push_pull(tmp_path, registry, credentials, target):
6241
"""
6342
Basic tests for oras (without authentication)
6443
"""
@@ -88,8 +67,8 @@ def test_basic_push_pull(tmp_path):
8867
assert res.status_code == 201
8968

9069

91-
@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
92-
def test_get_delete_tags(tmp_path):
70+
@pytest.mark.with_auth(False)
71+
def test_get_delete_tags(tmp_path, registry, credentials, target):
9372
"""
9473
Test creationg, getting, and deleting tags.
9574
"""
@@ -139,8 +118,8 @@ def test_get_many_tags():
139118
assert len(tags) == 10
140119

141120

142-
@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
143-
def test_directory_push_pull(tmp_path):
121+
@pytest.mark.with_auth(False)
122+
def test_directory_push_pull(tmp_path, registry, credentials, target_dir):
144123
"""
145124
Test push and pull for directory
146125
"""

oras/tests/test_provider.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
__license__ = "Apache-2.0"
44

55
import os
6-
import sys
76
from pathlib import Path
87

98
import pytest
@@ -15,35 +14,13 @@
1514

1615
here = os.path.abspath(os.path.dirname(__file__))
1716

18-
registry_host = os.environ.get("ORAS_HOST")
19-
registry_port = os.environ.get("ORAS_PORT")
20-
with_auth = os.environ.get("ORAS_AUTH") == "true"
21-
oras_user = os.environ.get("ORAS_USER", "myuser")
22-
oras_pass = os.environ.get("ORAS_PASS", "mypass")
2317

24-
25-
def setup_module(module):
26-
"""
27-
Ensure the registry port and host is in the environment.
28-
"""
29-
if not registry_host or not registry_port:
30-
sys.exit(
31-
"You must export ORAS_HOST and ORAS_PORT for a running registry before running tests."
32-
)
33-
if with_auth and not oras_user or not oras_pass:
34-
sys.exit("To test auth you need to export ORAS_USER and ORAS_PASS")
35-
36-
37-
registry = f"{registry_host}:{registry_port}"
38-
target = f"{registry}/dinosaur/artifact:v1"
39-
target_dir = f"{registry}/dinosaur/directory:v1"
40-
41-
42-
@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
43-
def test_annotated_registry_push(tmp_path):
18+
@pytest.mark.with_auth(False)
19+
def test_annotated_registry_push(tmp_path, registry, credentials, target):
4420
"""
4521
Basic tests for oras push with annotations
4622
"""
23+
4724
# Direct access to registry functions
4825
remote = oras.provider.Registry(hostname=registry, insecure=True)
4926
client = oras.client.OrasClient(hostname=registry, insecure=True)
@@ -84,7 +61,7 @@ def test_annotated_registry_push(tmp_path):
8461
)
8562

8663

87-
def test_parse_manifest():
64+
def test_parse_manifest(registry):
8865
"""
8966
Test parse manifest function.
9067

oras/utils/fileio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def get_tmpdir(
189189
return tmpdir
190190

191191

192-
def recursive_find(base: str, pattern: str = None) -> Generator:
192+
def recursive_find(base: str, pattern: Optional[str] = None) -> Generator:
193193
"""
194194
Find filenames that match a particular pattern, and yield them.
195195

oras/version.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__copyright__ = "Copyright The ORAS Authors."
33
__license__ = "Apache-2.0"
44

5-
__version__ = "0.1.24"
5+
__version__ = "0.1.25"
66
AUTHOR = "Vanessa Sochat"
77
EMAIL = "vsoch@users.noreply.github.com"
88
NAME = "oras"
@@ -19,14 +19,7 @@
1919
("requests", {"min_version": None}),
2020
)
2121

22-
TESTS_REQUIRES = (
23-
("pytest", {"min_version": "4.6.2"}),
24-
("mypy", {"min_version": None}),
25-
("pyflakes", {"min_version": None}),
26-
("black", {"min_version": None}),
27-
("types-requests", {"min_version": None}),
28-
("isort", {"min_version": None}),
29-
)
22+
TESTS_REQUIRES = (("pytest", {"min_version": "4.6.2"}),)
3023

3124
DOCKER_REQUIRES = (("docker", {"exact_version": "5.0.1"}),)
3225

0 commit comments

Comments
 (0)