datatrail-cli 1.1.0__tar.gz → 1.2.0__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.
- datatrail_cli-1.2.0/.release-please-manifest.json +3 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/CHANGELOG.md +8 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/PKG-INFO +1 -1
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/workflow.md +3 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/pull.py +2 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/workflow.py +11 -1
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/pyproject.toml +1 -1
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_pull_reliability.py +20 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_workflow.py +26 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/uv.lock +1 -1
- datatrail_cli-1.1.0/.release-please-manifest.json +0 -3
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/dependabot.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/workflows/codeql.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/workflows/continuous-deployment.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/workflows/continuous-integration.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/workflows/docs.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.github/workflows/stale.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.gitignore +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/.pre-commit-config.yaml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/LICENSE +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/README.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/clear.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/cli.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/commands.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/discovery.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/doctor.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/images/Datatrail-logo.png +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/index.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/initialising.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/install.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/inventory.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/list.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/ps.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/pull-manifest.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/pull.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/scout.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/unregistered.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/user_guide.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/docs/verify.md +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/__init__.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/clear.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/cli.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/config.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/config.yaml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/doctor.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/inventory.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/locking.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/ls.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/ps.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/pull_manifest.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/scout.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/src/functions.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/unregistered.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/utilities/cadcclient.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/utilities/results.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/utilities/utilities.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/dtcli/verify.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/mkdocs-site.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/mkdocs.yml +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/release-please-config.json +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/conftest.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_cadc_summary.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_canfar_permissions.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_cli.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_config.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_doctor.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_functions.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_inventory.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_locking.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_pull_manifest.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_pull_size.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_scout.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_utils.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tests/test_verify.py +0 -0
- {datatrail_cli-1.1.0 → datatrail_cli-1.2.0}/tox.ini +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0](https://github.com/CHIMEFRB/datatrail-cli/compare/datatrail-cli-v1.1.0...datatrail-cli-v1.2.0) (2026-11-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **workflow:** pull_dataset can pull to a given directory ([7f2da01](https://github.com/CHIMEFRB/datatrail-cli/commit/7f2da01a257668fd3b8efbd916c82d0d4d441340))
|
|
9
|
+
* **workflow:** pull_dataset can pull to a given directory ([ae3bb39](https://github.com/CHIMEFRB/datatrail-cli/commit/ae3bb397ecea15c850fce33b38af6b38f76e44ee))
|
|
10
|
+
|
|
3
11
|
## [1.1.0](https://github.com/CHIMEFRB/datatrail-cli/compare/datatrail-cli-v1.0.2...datatrail-cli-v1.1.0) (2026-11-01)
|
|
4
12
|
|
|
5
13
|
|
|
@@ -27,6 +27,9 @@ work:
|
|
|
27
27
|
for this site (as `datatrail config init --site <site>`); if there is one for
|
|
28
28
|
another site, the step fails.
|
|
29
29
|
- `verbose`: 1 for INFO (default), 2 for DEBUG.
|
|
30
|
+
- `directory`: where to pull to, created if it isn't there (default: the site's
|
|
31
|
+
root mount). The files go under it at their Datatrail paths, e.g.
|
|
32
|
+
`/scratch/data/chime/baseband/raw/...` for `directory: /scratch`.
|
|
30
33
|
|
|
31
34
|
Results: `scope`, `dataset`, `files` (how many are here) and `directory`.
|
|
32
35
|
|
|
@@ -98,6 +98,8 @@ def pull( # noqa: C901
|
|
|
98
98
|
if directory is None:
|
|
99
99
|
directory = config["root_mounts"][site]
|
|
100
100
|
logger.info(f"No directory, setting to: {directory}.")
|
|
101
|
+
# The file paths are added to it as they are, and click drops the slash
|
|
102
|
+
directory = path.join(directory, "")
|
|
101
103
|
except Exception:
|
|
102
104
|
logger.exception(
|
|
103
105
|
"Configuration Missing!! Run `datatrail config init`.",
|
|
@@ -76,6 +76,7 @@ def pull_dataset(
|
|
|
76
76
|
cores: int = 1,
|
|
77
77
|
site: Optional[str] = None,
|
|
78
78
|
verbose: int = 1,
|
|
79
|
+
directory: Optional[str] = None,
|
|
79
80
|
) -> Outcome:
|
|
80
81
|
"""Download a dataset, then check that all its files are here.
|
|
81
82
|
|
|
@@ -86,6 +87,9 @@ def pull_dataset(
|
|
|
86
87
|
site (Optional[str]): Site this runs at; the configuration is created for it
|
|
87
88
|
if there's none. Defaults to the configured site.
|
|
88
89
|
verbose (int): Verbosity: 1=INFO, 2=DEBUG. Defaults to 1.
|
|
90
|
+
directory (Optional[str]): Directory to pull to, created if it isn't there;
|
|
91
|
+
the files go under it at their Datatrail paths. Defaults to the site's
|
|
92
|
+
root mount.
|
|
89
93
|
|
|
90
94
|
Returns:
|
|
91
95
|
Outcome: Results (scope, dataset, number of files and where they are), no
|
|
@@ -96,9 +100,15 @@ def pull_dataset(
|
|
|
96
100
|
after the pull.
|
|
97
101
|
"""
|
|
98
102
|
config = _configure(site)
|
|
99
|
-
directory = config["root_mounts"][config["site"]]
|
|
100
103
|
dataset = str(dataset)
|
|
101
104
|
args = [scope, dataset, "--force", "--cores", str(cores)] + ["-v"] * verbose
|
|
105
|
+
if directory:
|
|
106
|
+
os.makedirs(directory, exist_ok=True)
|
|
107
|
+
args += ["--directory", directory]
|
|
108
|
+
# the file paths are added to it as they are
|
|
109
|
+
directory = os.path.join(directory, "")
|
|
110
|
+
else:
|
|
111
|
+
directory = config["root_mounts"][config["site"]]
|
|
102
112
|
_run(pull, args)
|
|
103
113
|
|
|
104
114
|
files = find_missing_dataset_files(scope, dataset, directory, verbose)
|
|
@@ -274,6 +274,26 @@ def test_pull_exits_nonzero_when_file_is_still_missing(monkeypatch, tmp_path):
|
|
|
274
274
|
assert "File not downloaded" in result.output
|
|
275
275
|
|
|
276
276
|
|
|
277
|
+
def test_pull_checks_a_given_directory_for_existing_files(monkeypatch, tmp_path):
|
|
278
|
+
"""Files already under --directory are found, though click drops its slash."""
|
|
279
|
+
configure_pull(monkeypatch, tmp_path, lambda *args, **kwargs: [])
|
|
280
|
+
roots = []
|
|
281
|
+
monkeypatch.setattr(
|
|
282
|
+
pull_module,
|
|
283
|
+
"find_missing_dataset_files",
|
|
284
|
+
lambda scope, dataset, root, verbose: roots.append(root)
|
|
285
|
+
or {"missing": [], "existing": ["data/file.dat"]},
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
result = CliRunner().invoke(
|
|
289
|
+
pull_module.pull,
|
|
290
|
+
["scope", "dataset", "--directory", str(tmp_path), "--force"],
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
assert result.exit_code == 0
|
|
294
|
+
assert roots == [str(tmp_path) + "/"]
|
|
295
|
+
|
|
296
|
+
|
|
277
297
|
def test_pull_interruption_exits_nonzero(monkeypatch, tmp_path):
|
|
278
298
|
"""An interrupted pull is not reported as successful."""
|
|
279
299
|
|
|
@@ -70,6 +70,32 @@ def test_pull_dataset_returns_workflow_outcome(config, monkeypatch):
|
|
|
70
70
|
assert products == [] and plots == []
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
def test_pull_dataset_pulls_to_a_given_directory(config, tmp_path, monkeypatch):
|
|
74
|
+
config.write()
|
|
75
|
+
pull = FakeCommand("pull")
|
|
76
|
+
monkeypatch.setattr(workflow, "pull", pull)
|
|
77
|
+
checked = []
|
|
78
|
+
monkeypatch.setattr(
|
|
79
|
+
workflow,
|
|
80
|
+
"find_missing_dataset_files",
|
|
81
|
+
lambda scope, dataset, root, verbose: checked.append(root)
|
|
82
|
+
or {"missing": [], "existing": ["a"]},
|
|
83
|
+
)
|
|
84
|
+
scratch = tmp_path / "scratch"
|
|
85
|
+
|
|
86
|
+
results, _, _ = workflow.pull_dataset(
|
|
87
|
+
"scope", "1", site="canfar", directory=str(scratch)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
assert scratch.is_dir()
|
|
91
|
+
assert pull.calls == [
|
|
92
|
+
["scope", "1", "--force", "--cores", "1", "-v", "--directory", str(scratch)]
|
|
93
|
+
]
|
|
94
|
+
# the files' paths are added to it, so it ends with a slash
|
|
95
|
+
assert checked == [str(scratch) + "/"]
|
|
96
|
+
assert results["directory"] == str(scratch) + "/"
|
|
97
|
+
|
|
98
|
+
|
|
73
99
|
def test_pull_dataset_creates_the_configuration(config, monkeypatch):
|
|
74
100
|
monkeypatch.setattr(workflow, "pull", FakeCommand("pull"))
|
|
75
101
|
monkeypatch.setattr(
|
|
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
|
|
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
|
|
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
|
|
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
|