Skip to content

Commit 319c09c

Browse files
author
root
committed
Expose workflow catalog add metadata options
1 parent 73f77c2 commit 319c09c

3 files changed

Lines changed: 147 additions & 10 deletions

File tree

src/specify_cli/workflows/_commands.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,14 +1009,21 @@ def workflow_catalog_list():
10091009
def workflow_catalog_add(
10101010
url: str = typer.Argument(..., help="Catalog URL to add"),
10111011
name: str | None = typer.Option(None, "--name", help="Catalog name"),
1012+
priority: int | None = typer.Option(None, "--priority", help="Priority (lower = higher priority)"),
1013+
install_allowed: bool = typer.Option(
1014+
True,
1015+
"--install-allowed/--no-install-allowed",
1016+
help="Allow workflows from this catalog to be installed",
1017+
),
1018+
description: str = typer.Option("", "--description", help="Description of the catalog"),
10121019
):
10131020
"""Add a workflow catalog source."""
10141021
from .catalog import WorkflowCatalog, WorkflowValidationError
10151022

10161023
project_root = _require_specify_project()
10171024
catalog = WorkflowCatalog(project_root)
10181025
try:
1019-
catalog.add_catalog(url, name)
1026+
catalog.add_catalog(url, name, priority, install_allowed, description)
10201027
except WorkflowValidationError as exc:
10211028
console.print(f"[red]Error:[/red] {exc}")
10221029
raise typer.Exit(1)
@@ -1661,6 +1668,13 @@ def workflow_step_catalog_list():
16611668
def workflow_step_catalog_add(
16621669
url: str = typer.Argument(..., help="Catalog URL to add"),
16631670
name: str | None = typer.Option(None, "--name", help="Catalog name"),
1671+
priority: int | None = typer.Option(None, "--priority", help="Priority (lower = higher priority)"),
1672+
install_allowed: bool = typer.Option(
1673+
True,
1674+
"--install-allowed/--no-install-allowed",
1675+
help="Allow steps from this catalog to be installed",
1676+
),
1677+
description: str = typer.Option("", "--description", help="Description of the catalog"),
16641678
):
16651679
"""Add a step catalog source."""
16661680
from .catalog import StepCatalog, StepValidationError
@@ -1669,7 +1683,7 @@ def workflow_step_catalog_add(
16691683

16701684
catalog = StepCatalog(project_root)
16711685
try:
1672-
catalog.add_catalog(url, name)
1686+
catalog.add_catalog(url, name, priority, install_allowed, description)
16731687
except StepValidationError as exc:
16741688
console.print(f"[red]Error:[/red] {exc}")
16751689
raise typer.Exit(1)

src/specify_cli/workflows/catalog.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,14 @@ def get_catalog_configs(self) -> list[dict[str, Any]]:
476476
for e in entries
477477
]
478478

479-
def add_catalog(self, url: str, name: str | None = None) -> None:
479+
def add_catalog(
480+
self,
481+
url: str,
482+
name: str | None = None,
483+
priority: int | None = None,
484+
install_allowed: bool = True,
485+
description: str = "",
486+
) -> None:
480487
"""Add a catalog source to the project-level config."""
481488
self._validate_catalog_url(url)
482489
config_path = self.project_root / ".specify" / "workflow-catalogs.yml"
@@ -530,9 +537,9 @@ def _coerce_priority(value: Any) -> int:
530537
{
531538
"name": name or f"catalog-{len(catalogs) + 1}",
532539
"url": url,
533-
"priority": max_priority + 1,
534-
"install_allowed": True,
535-
"description": "",
540+
"priority": max_priority + 1 if priority is None else priority,
541+
"install_allowed": install_allowed,
542+
"description": description,
536543
}
537544
)
538545
data["catalogs"] = catalogs
@@ -1086,7 +1093,14 @@ def get_catalog_configs(self) -> list[dict[str, Any]]:
10861093
for e in entries
10871094
]
10881095

1089-
def add_catalog(self, url: str, name: str | None = None) -> None:
1096+
def add_catalog(
1097+
self,
1098+
url: str,
1099+
name: str | None = None,
1100+
priority: int | None = None,
1101+
install_allowed: bool = True,
1102+
description: str = "",
1103+
) -> None:
10901104
"""Add a catalog source to the project-level config."""
10911105
self._validate_catalog_url(url)
10921106
config_path = self.project_root / ".specify" / "step-catalogs.yml"
@@ -1136,9 +1150,9 @@ def _coerce_priority(value: Any) -> int:
11361150
{
11371151
"name": name or f"catalog-{len(catalogs) + 1}",
11381152
"url": url,
1139-
"priority": max_priority + 1,
1140-
"install_allowed": True,
1141-
"description": "",
1153+
"priority": max_priority + 1 if priority is None else priority,
1154+
"install_allowed": install_allowed,
1155+
"description": description,
11421156
}
11431157
)
11441158
data["catalogs"] = catalogs

tests/test_workflows.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4513,6 +4513,60 @@ def test_add_catalog(self, project_dir):
45134513
data = yaml.safe_load(config_path.read_text())
45144514
assert len(data["catalogs"]) == 1
45154515
assert data["catalogs"][0]["url"] == "https://example.com/new-catalog.json"
4516+
assert data["catalogs"][0]["priority"] == 1
4517+
assert data["catalogs"][0]["install_allowed"] is True
4518+
assert data["catalogs"][0]["description"] == ""
4519+
4520+
def test_add_catalog_accepts_metadata_overrides(self, project_dir):
4521+
from specify_cli.workflows.catalog import WorkflowCatalog
4522+
4523+
catalog = WorkflowCatalog(project_dir)
4524+
catalog.add_catalog(
4525+
"https://example.com/new-catalog.json",
4526+
"my-catalog",
4527+
priority=7,
4528+
install_allowed=False,
4529+
description="Workflow source",
4530+
)
4531+
4532+
config_path = project_dir / ".specify" / "workflow-catalogs.yml"
4533+
data = yaml.safe_load(config_path.read_text())
4534+
assert data["catalogs"][0] == {
4535+
"name": "my-catalog",
4536+
"url": "https://example.com/new-catalog.json",
4537+
"priority": 7,
4538+
"install_allowed": False,
4539+
"description": "Workflow source",
4540+
}
4541+
4542+
def test_catalog_add_cli_accepts_metadata_options(self, project_dir, monkeypatch):
4543+
from typer.testing import CliRunner
4544+
from specify_cli import app
4545+
4546+
monkeypatch.chdir(project_dir)
4547+
result = CliRunner().invoke(
4548+
app,
4549+
[
4550+
"workflow",
4551+
"catalog",
4552+
"add",
4553+
"https://example.com/new-catalog.json",
4554+
"--name",
4555+
"my-catalog",
4556+
"--priority",
4557+
"7",
4558+
"--no-install-allowed",
4559+
"--description",
4560+
"Workflow source",
4561+
],
4562+
)
4563+
4564+
assert result.exit_code == 0, result.output
4565+
config_path = project_dir / ".specify" / "workflow-catalogs.yml"
4566+
data = yaml.safe_load(config_path.read_text())
4567+
assert data["catalogs"][0]["priority"] == 7
4568+
assert data["catalogs"][0]["install_allowed"] is False
4569+
assert data["catalogs"][0]["description"] == "Workflow source"
45164570

45174571
def test_add_catalog_duplicate_rejected(self, project_dir):
45184572
from specify_cli.workflows.catalog import WorkflowCatalog, WorkflowValidationError
@@ -4959,6 +5013,61 @@ def test_add_catalog(self, project_dir):
49595013
data = yaml.safe_load(config_path.read_text())
49605014
assert len(data["catalogs"]) == 1
49615015
assert data["catalogs"][0]["url"] == "https://example.com/new-steps.json"
5016+
assert data["catalogs"][0]["priority"] == 1
5017+
assert data["catalogs"][0]["install_allowed"] is True
5018+
assert data["catalogs"][0]["description"] == ""
5019+
5020+
def test_add_catalog_accepts_metadata_overrides(self, project_dir):
5021+
from specify_cli.workflows.catalog import StepCatalog
5022+
5023+
catalog = StepCatalog(project_dir)
5024+
catalog.add_catalog(
5025+
"https://example.com/new-steps.json",
5026+
"my-steps",
5027+
priority=7,
5028+
install_allowed=False,
5029+
description="Step source",
5030+
)
5031+
5032+
config_path = project_dir / ".specify" / "step-catalogs.yml"
5033+
data = yaml.safe_load(config_path.read_text())
5034+
assert data["catalogs"][0] == {
5035+
"name": "my-steps",
5036+
"url": "https://example.com/new-steps.json",
5037+
"priority": 7,
5038+
"install_allowed": False,
5039+
"description": "Step source",
5040+
}
5041+
5042+
def test_catalog_add_cli_accepts_metadata_options(self, project_dir, monkeypatch):
5043+
from typer.testing import CliRunner
5044+
from specify_cli import app
5045+
5046+
monkeypatch.chdir(project_dir)
5047+
result = CliRunner().invoke(
5048+
app,
5049+
[
5050+
"workflow",
5051+
"step",
5052+
"catalog",
5053+
"add",
5054+
"https://example.com/new-steps.json",
5055+
"--name",
5056+
"my-steps",
5057+
"--priority",
5058+
"7",
5059+
"--no-install-allowed",
5060+
"--description",
5061+
"Step source",
5062+
],
5063+
)
5064+
5065+
assert result.exit_code == 0, result.output
5066+
config_path = project_dir / ".specify" / "step-catalogs.yml"
5067+
data = yaml.safe_load(config_path.read_text())
5068+
assert data["catalogs"][0]["priority"] == 7
5069+
assert data["catalogs"][0]["install_allowed"] is False
5070+
assert data["catalogs"][0]["description"] == "Step source"
49625071

49635072
def test_add_catalog_empty_yaml_file(self, project_dir):
49645073
"""An empty YAML config file should be treated as empty, not corrupted."""

0 commit comments

Comments
 (0)