grz-cli 1.7.0__tar.gz → 1.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {grz_cli-1.7.0 → grz_cli-1.7.2}/CHANGELOG.md +14 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/PKG-INFO +1 -1
- grz_cli-1.7.2/src/grz_cli/__init__.py +1 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/submit.py +7 -6
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/validate.py +1 -1
- grz_cli-1.7.2/tests/conftest.py +32 -0
- grz_cli-1.7.2/tests/test_submit.py +71 -0
- grz_cli-1.7.0/src/grz_cli/__init__.py +0 -1
- {grz_cli-1.7.0 → grz_cli-1.7.2}/.gitignore +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/LICENSE +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/MANIFEST.in +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/README.md +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/docs/version-compatibility-check.md +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/pyproject.toml +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/__init__.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/cli.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/__init__.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/encrypt.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/get_id.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/commands/upload.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/models/__init__.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/models/config.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/py.typed +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/src/grz_cli/utils/version_check.py +0 -0
- {grz_cli-1.7.0 → grz_cli-1.7.2}/tests/test_smoke.py +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.7.2](https://github.com/BfArM-MVH/grz-tools/compare/grz-cli-v1.7.1...grz-cli-v1.7.2) (2026-06-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **grzctl,grz-cli:** use correct argument name "mmap" in validate callback function ([#590](https://github.com/BfArM-MVH/grz-tools/issues/590)) ([9f5cc42](https://github.com/BfArM-MVH/grz-tools/commit/9f5cc425bd1626f65dfb197d21c27eccb02f16b1))
|
|
9
|
+
|
|
10
|
+
## [1.7.1](https://github.com/BfArM-MVH/grz-tools/compare/grz-cli-v1.7.0...grz-cli-v1.7.1) (2026-05-29)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **grz-cli:** handle tuple from multi-config in submit ([#588](https://github.com/BfArM-MVH/grz-tools/issues/588)) ([553f4e9](https://github.com/BfArM-MVH/grz-tools/commit/553f4e99ce7146d839d4502c8a9ee07778e50f04))
|
|
16
|
+
|
|
3
17
|
## [1.7.0](https://github.com/BfArM-MVH/grz-tools/compare/grz-cli-v1.6.1...grz-cli-v1.7.0) (2026-05-19)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: grz-cli
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: Tool for validation, encryption and upload of MV submissions to GDCs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/BfArM-MVH/grz-tools
|
|
6
6
|
Project-URL: Repository, https://github.com/BfArM-MVH/grz-tools
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.7.2"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Command for submitting (validating, encrypting, and uploading) a submission."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
import click
|
|
6
7
|
from grz_cli.utils.version_check import check_version_and_exit_if_needed
|
|
@@ -18,11 +19,11 @@ from ..models.config import UploadConfig
|
|
|
18
19
|
|
|
19
20
|
@click.command("submit")
|
|
20
21
|
@grzcli.submission_dir
|
|
21
|
-
@grzcli.
|
|
22
|
+
@grzcli.configuration
|
|
22
23
|
@grzcli.threads
|
|
23
24
|
@grzcli.force
|
|
24
25
|
@click.pass_context
|
|
25
|
-
def submit(ctx,
|
|
26
|
+
def submit(ctx, configuration: dict[str, Any], submission_dir, threads, force, **kwargs):
|
|
26
27
|
"""
|
|
27
28
|
Validate, encrypt, and then upload.
|
|
28
29
|
|
|
@@ -31,11 +32,11 @@ def submit(ctx, submission_dir, config_file, threads, force):
|
|
|
31
32
|
2. Encrypt the submission
|
|
32
33
|
3. Upload the encrypted submission
|
|
33
34
|
"""
|
|
34
|
-
config = UploadConfig.
|
|
35
|
+
config = UploadConfig.model_validate(configuration)
|
|
35
36
|
check_version_and_exit_if_needed(config.s3)
|
|
36
37
|
|
|
37
38
|
click.echo("Starting submission process...")
|
|
38
|
-
ctx.invoke(validate, submission_dir=submission_dir,
|
|
39
|
-
ctx.invoke(encrypt, submission_dir=submission_dir,
|
|
40
|
-
ctx.invoke(upload, submission_dir=submission_dir,
|
|
39
|
+
ctx.invoke(validate, submission_dir=submission_dir, force=force)
|
|
40
|
+
ctx.invoke(encrypt, submission_dir=submission_dir, force=force, check_validation_logs=True)
|
|
41
|
+
ctx.invoke(upload, submission_dir=submission_dir, threads=threads)
|
|
41
42
|
click.echo("Submission finished!")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Shared fixtures for grz-cli tests."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import yaml
|
|
7
|
+
|
|
8
|
+
MINIMAL_S3_CONFIG: dict[str, dict[str, str]] = {
|
|
9
|
+
"s3": {
|
|
10
|
+
"endpoint_url": "https://example.invalid",
|
|
11
|
+
"bucket": "test-bucket",
|
|
12
|
+
"access_key": "test-key",
|
|
13
|
+
"secret": "test-secret",
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def s3_config_path(tmp_path: Path) -> Path:
|
|
20
|
+
"""Write a minimal S3 config file and return its path."""
|
|
21
|
+
config_path = tmp_path / "config.yaml"
|
|
22
|
+
config_path.write_text(yaml.dump(MINIMAL_S3_CONFIG))
|
|
23
|
+
return config_path
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def submission_dir(tmp_path: Path) -> Path:
|
|
28
|
+
"""Empty submission directory with the four standard subdirectories."""
|
|
29
|
+
submission_dir = tmp_path / "submission"
|
|
30
|
+
for sub in ("metadata", "files", "encrypted_files", "logs"):
|
|
31
|
+
(submission_dir / sub).mkdir(parents=True)
|
|
32
|
+
return submission_dir
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Integration tests for the ``grz-cli submit`` command."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import click.testing
|
|
6
|
+
import pytest
|
|
7
|
+
import yaml
|
|
8
|
+
from grz_cli.cli import build_cli
|
|
9
|
+
from pytest_mock import MockerFixture
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def stub_subcommands(mocker: MockerFixture) -> dict[str, object]:
|
|
14
|
+
"""Replace the subcommands ``submit`` invokes with no-op mocks.
|
|
15
|
+
|
|
16
|
+
``ctx.invoke`` accepts any callable when the target is not a click
|
|
17
|
+
``Command``, so swapping the module-level imports lets the real submit
|
|
18
|
+
callback run end-to-end without executing real validation, encryption,
|
|
19
|
+
or upload.
|
|
20
|
+
"""
|
|
21
|
+
mocker.patch("grz_cli.commands.submit.check_version_and_exit_if_needed")
|
|
22
|
+
return {
|
|
23
|
+
"validate": mocker.patch("grz_cli.commands.submit.validate"),
|
|
24
|
+
"encrypt": mocker.patch("grz_cli.commands.submit.encrypt"),
|
|
25
|
+
"upload": mocker.patch("grz_cli.commands.submit.upload"),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _invoke_submit(*extra_args: str) -> click.testing.Result:
|
|
30
|
+
runner = click.testing.CliRunner()
|
|
31
|
+
return runner.invoke(build_cli(), ["submit", *extra_args], catch_exceptions=False)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_submit_runs_subcommands_in_order(
|
|
35
|
+
s3_config_path: Path,
|
|
36
|
+
submission_dir: Path,
|
|
37
|
+
stub_subcommands: dict[str, object],
|
|
38
|
+
) -> None:
|
|
39
|
+
result = _invoke_submit(
|
|
40
|
+
"--submission-dir",
|
|
41
|
+
str(submission_dir),
|
|
42
|
+
"--config-file",
|
|
43
|
+
str(s3_config_path),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
assert result.exit_code == 0, result.output
|
|
47
|
+
stub_subcommands["validate"].assert_called_once()
|
|
48
|
+
stub_subcommands["encrypt"].assert_called_once()
|
|
49
|
+
stub_subcommands["upload"].assert_called_once()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_submit_accepts_multiple_config_files(
|
|
53
|
+
tmp_path: Path,
|
|
54
|
+
s3_config_path: Path,
|
|
55
|
+
submission_dir: Path,
|
|
56
|
+
stub_subcommands: dict[str, object],
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Regression: repeated ``--config-file`` once produced a tuple that crashed config parsing."""
|
|
59
|
+
override_path = tmp_path / "override.yaml"
|
|
60
|
+
override_path.write_text(yaml.dump({"s3": {"access_key": "override-key"}}))
|
|
61
|
+
|
|
62
|
+
result = _invoke_submit(
|
|
63
|
+
"--submission-dir",
|
|
64
|
+
str(submission_dir),
|
|
65
|
+
"--config-file",
|
|
66
|
+
str(s3_config_path),
|
|
67
|
+
"--config-file",
|
|
68
|
+
str(override_path),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
assert result.exit_code == 0, result.output
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.7.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|