snk-cli 0.5.1__tar.gz → 0.5.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.
Files changed (70) hide show
  1. {snk_cli-0.5.1 → snk_cli-0.5.2}/PKG-INFO +1 -1
  2. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/__about__.py +1 -1
  3. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/config/config.py +11 -0
  4. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/dynamic_typer.py +1 -1
  5. snk_cli-0.5.2/tests/test_SnkConfig.py +125 -0
  6. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_validate.py +6 -0
  7. {snk_cli-0.5.1 → snk_cli-0.5.2}/.github/workflows/publish.yml +0 -0
  8. {snk_cli-0.5.1 → snk_cli-0.5.2}/.github/workflows/tests.yml +0 -0
  9. {snk_cli-0.5.1 → snk_cli-0.5.2}/.gitignore +0 -0
  10. {snk_cli-0.5.1 → snk_cli-0.5.2}/LICENSE.txt +0 -0
  11. {snk_cli-0.5.1 → snk_cli-0.5.2}/README.md +0 -0
  12. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/index.md +0 -0
  13. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/cli.md +0 -0
  14. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/config.md +0 -0
  15. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/dynamic_typer.md +0 -0
  16. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/options.md +0 -0
  17. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/subcommands.md +0 -0
  18. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/testing.md +0 -0
  19. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/utils.md +0 -0
  20. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/validate.md +0 -0
  21. {snk_cli-0.5.1 → snk_cli-0.5.2}/docs/reference/workflow.md +0 -0
  22. {snk_cli-0.5.1 → snk_cli-0.5.2}/mkdocs.yml +0 -0
  23. {snk_cli-0.5.1 → snk_cli-0.5.2}/pyproject.toml +0 -0
  24. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/__init__.py +0 -0
  25. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/cli.py +0 -0
  26. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/conda.py +0 -0
  27. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/config/__init__.py +0 -0
  28. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/config/utils.py +0 -0
  29. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/options/__init__.py +0 -0
  30. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/options/option.py +0 -0
  31. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/options/utils.py +0 -0
  32. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/__init__.py +0 -0
  33. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/config.py +0 -0
  34. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/env.py +0 -0
  35. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/profile.py +0 -0
  36. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/run.py +0 -0
  37. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/subcommands/script.py +0 -0
  38. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/testing.py +0 -0
  39. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/utils.py +0 -0
  40. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/validate.py +0 -0
  41. {snk_cli-0.5.1 → snk_cli-0.5.2}/src/snk_cli/workflow.py +0 -0
  42. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/__init__.py +0 -0
  43. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/conftest.py +0 -0
  44. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/artic_v4.1.bed +0 -0
  45. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/config.yaml +0 -0
  46. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/cov.fasta +0 -0
  47. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/print_config/Snakefile +0 -0
  48. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/print_config/cli.py +0 -0
  49. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/print_config/config.yaml +0 -0
  50. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/print_config/snk.yaml +0 -0
  51. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/cli.py +0 -0
  52. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/config.yaml +0 -0
  53. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/resources/data.txt +0 -0
  54. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/snk.yaml +0 -0
  55. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/things/__about__.py +0 -0
  56. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/workflow/Snakefile +0 -0
  57. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/workflow/envs/wget.yml +0 -0
  58. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/workflow/profiles/base/config.yaml +0 -0
  59. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/workflow/profiles/slurm/config.yaml +0 -0
  60. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/data/workflow/workflow/scripts/hello.py +0 -0
  61. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/__init__.py +0 -0
  62. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_dynamic_options.py +0 -0
  63. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_profile.py +0 -0
  64. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_run.py +0 -0
  65. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_snk_config.py +0 -0
  66. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_subcommands.py +0 -0
  67. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_cli/test_workflow_cli.py +0 -0
  68. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_conda_env.py +0 -0
  69. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/test_dynamic_typer.py +0 -0
  70. {snk_cli-0.5.1 → snk_cli-0.5.2}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: snk-cli
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Project-URL: Documentation, https://github.com/wytamma/snk-cli#readme
5
5
  Project-URL: Issues, https://github.com/wytamma/snk-cli/issues
6
6
  Project-URL: Source, https://github.com/wytamma/snk-cli
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Wytamma Wirth <wytamma.wirth@me.com>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.5.1"
4
+ __version__ = "0.5.2"
@@ -205,6 +205,17 @@ class SnkConfig:
205
205
  >>> snk_config.to_yaml(Path("snk.yaml"))
206
206
  """
207
207
  config_dict = {k: v for k, v in vars(self).items() if not k.startswith("_")}
208
+ def convert_paths(data):
209
+ if isinstance(data, dict):
210
+ return {key: convert_paths(value) for key, value in data.items()}
211
+ elif isinstance(data, list):
212
+ return [convert_paths(item) for item in data]
213
+ elif isinstance(data, Path):
214
+ return str(data)
215
+ return data
216
+
217
+ config_dict = convert_paths(config_dict)
218
+
208
219
  with open(path, "w") as f:
209
220
  yaml.dump(config_dict, f)
210
221
 
@@ -152,7 +152,7 @@ class DynamicTyper:
152
152
  if option.type is Enum or option.choices:
153
153
  if not option.choices:
154
154
  raise ValueError(f"Enum type {option.name} requires choices to be defined.")
155
- annotation_type = Enum(f'{option.name}Enum', {e: e for e in option.choices})
155
+ annotation_type = Enum(f'{option.name}', {str(e): str(e) for e in option.choices})
156
156
  if default:
157
157
  try:
158
158
  default = annotation_type(default)
@@ -0,0 +1,125 @@
1
+ import pytest
2
+ from snk_cli.config.config import SnkConfig
3
+
4
+
5
+ def test_snk_config_creation():
6
+ snk_config = SnkConfig()
7
+ assert snk_config.tagline == "A Snakemake workflow CLI generated with Snk"
8
+ assert snk_config.font == "small"
9
+ assert snk_config.resources == []
10
+ assert snk_config.cli == {}
11
+ assert snk_config.symlink_resources is False
12
+ assert snk_config.version is None
13
+ assert snk_config.skip_missing is False
14
+
15
+
16
+ def test_validate_resources_with_existing_files(tmp_path):
17
+ resources = [tmp_path / "file1", tmp_path / "file2"]
18
+ for resource in resources:
19
+ resource.touch()
20
+ snk_config = SnkConfig()
21
+ # Should not raise an exception
22
+ snk_config.validate_resources(resources)
23
+
24
+
25
+ def test_validate_resources_with_missing_files(tmp_path):
26
+ resources = [tmp_path / "file1", tmp_path / "missing_file"]
27
+ resources[0].touch()
28
+ snk_config = SnkConfig()
29
+ with pytest.raises(FileNotFoundError):
30
+ snk_config.validate_resources(resources)
31
+
32
+
33
+ def test_add_resources(tmp_path):
34
+ resources = [tmp_path / "file1", tmp_path / "file2"]
35
+ for resource in resources:
36
+ resource.touch()
37
+ snk_config = SnkConfig()
38
+ snk_config.add_resources(resources)
39
+ assert len(snk_config.resources) == 2
40
+
41
+
42
+ def test_from_path_with_existing_file(tmp_path):
43
+ config_file = tmp_path / "snk.yaml"
44
+ config_file.touch()
45
+ config_file.write_text("logo: test_logo")
46
+ snk_config = SnkConfig.from_path(config_file)
47
+ assert snk_config._snk_config_path == config_file
48
+
49
+ def test_missing_file(tmp_path):
50
+ config_file = tmp_path / "snk.yaml"
51
+ with pytest.raises(FileNotFoundError):
52
+ SnkConfig.from_path(config_file)
53
+
54
+ def test_empty_file(tmp_path):
55
+ config_file = tmp_path / "snk.yaml"
56
+ config_file.touch()
57
+ with pytest.raises(ValueError):
58
+ SnkConfig.from_path(config_file)
59
+
60
+ def test_invalid_yaml(tmp_path):
61
+ config_file = tmp_path / "snk.yaml"
62
+ config_file.touch()
63
+ config_file.write_text("logo: test_logo\ninvalid_yaml")
64
+ with pytest.raises(Exception):
65
+ SnkConfig.from_path(config_file)
66
+
67
+ def test_from_dir_with_existing_file(tmp_path):
68
+ config_file = tmp_path / ".snk"
69
+ config_file.touch()
70
+ config_file.write_text("logo: test_logo")
71
+ # catch warning
72
+ with pytest.warns(DeprecationWarning):
73
+ snk_config = SnkConfig.from_workflow_dir(tmp_path)
74
+ assert snk_config._snk_config_path == config_file
75
+
76
+
77
+ def test_from_path_with_missing_file(tmp_path):
78
+ config_file = tmp_path / "missing_file.yaml"
79
+ # assert it raises FileNotFoundError
80
+ with pytest.raises(FileNotFoundError):
81
+ SnkConfig.from_path(config_file)
82
+
83
+
84
+ def test_to_yaml(tmp_path):
85
+ snk_config = SnkConfig(art="test_art", logo="test_logo")
86
+ yaml_file = tmp_path / "snk.yaml"
87
+ snk_config.to_yaml(yaml_file)
88
+ assert yaml_file.exists()
89
+
90
+
91
+ def test_save(tmp_path):
92
+ config_file = tmp_path / "snk.yaml"
93
+ snk_config = SnkConfig(_snk_config_path=config_file)
94
+ snk_config.art = "new_art"
95
+ snk_config.save()
96
+ saved_snk_config = SnkConfig.from_path(config_file)
97
+ assert saved_snk_config.art == "new_art"
98
+
99
+
100
+ def test_version_from_about_file(tmp_path):
101
+ config_file = tmp_path / "snk.yaml"
102
+ about_file = tmp_path / "__about__.py"
103
+ about_file.touch()
104
+ about_file.write_text("__version__ = '0.0.1'")
105
+ config_file.write_text("version: __about__.py")
106
+ snk_config = SnkConfig.from_path(config_file)
107
+ assert snk_config.version == "0.0.1"
108
+
109
+ def test_version_from_about_file_with_missing_file(tmp_path):
110
+ config_file = tmp_path / "snk.yaml"
111
+ about_file = tmp_path / "__about__.py"
112
+ config_file.write_text("version: __about__.py")
113
+ with pytest.raises(FileNotFoundError):
114
+ SnkConfig.from_path(config_file)
115
+
116
+ def test_paths_are_written_as_strings(tmp_path):
117
+ config_file = tmp_path / "snk.yaml"
118
+ snk_config = SnkConfig(snakefile=tmp_path / "snakefile", resources=[tmp_path / "file1", tmp_path / "file2"])
119
+ snk_config.to_yaml(config_file)
120
+ with open(config_file) as f:
121
+ config = f.read()
122
+ print(config)
123
+ assert f"snakefile: {tmp_path / 'snakefile'}" in config
124
+ assert f"- {tmp_path / 'file1'}" in config
125
+ assert f"- {tmp_path / 'file2'}" in config
@@ -24,6 +24,12 @@ import pytest
24
24
  {"example": {"type": "bool"}},
25
25
  {"example": True}
26
26
  ),
27
+ # timestamp
28
+ (
29
+ {"example": "2021-01-01T00:00:00"},
30
+ {"example": {"type": "str"}},
31
+ {"example": "2021-01-01T00:00:00"}
32
+ ),
27
33
  # None
28
34
  (
29
35
  {"example": None},
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