mirror of
https://github.com/github/spec-kit.git
synced 2026-08-03 06:26:30 +08:00
fix(workflows): escape rich markup in list output and catalog install errors, isolate update failures
workflow list now escapes id/name/version/description before printing, matching how extensions render user-editable fields. The catalog install helper computes safe_wf_id once and uses it for every early error path plus the final failure message. workflow update wraps _safe_workflow_id_dir and the backup read inside the try/except typer.Exit block so an unsafe id in a corrupted registry fails that one workflow and the rest continue. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -7541,6 +7541,73 @@ steps:
|
||||
assert "corrupted" in result.output
|
||||
assert "OK Workflow" in result.output
|
||||
|
||||
def test_list_escapes_rich_markup_in_registry_fields(self, project_dir, monkeypatch):
|
||||
"""User-editable name/description/id fields must not be parsed as Rich markup."""
|
||||
import json
|
||||
from typer.testing import CliRunner
|
||||
from specify_cli import app
|
||||
from specify_cli.workflows.catalog import WorkflowRegistry
|
||||
|
||||
monkeypatch.chdir(project_dir)
|
||||
registry_path = WorkflowRegistry(project_dir).registry_path
|
||||
registry_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
registry_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"workflows": {
|
||||
"ok": {
|
||||
"name": "Bracket [Test]",
|
||||
"version": "1.0.0",
|
||||
"description": "desc [with] brackets",
|
||||
},
|
||||
},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["workflow", "list"])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "Bracket [Test]" in result.output
|
||||
assert "desc [with] brackets" in result.output
|
||||
|
||||
def test_update_reports_unsafe_registry_id_per_workflow(self, project_dir, monkeypatch):
|
||||
"""An unsafe workflow id in the registry must fail that one entry, not abort the whole update."""
|
||||
import json
|
||||
from typer.testing import CliRunner
|
||||
from specify_cli import app
|
||||
from specify_cli.workflows.catalog import WorkflowRegistry, WorkflowCatalog
|
||||
|
||||
monkeypatch.chdir(project_dir)
|
||||
registry_path = WorkflowRegistry(project_dir).registry_path
|
||||
registry_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
registry_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"workflows": {
|
||||
"../evil": {
|
||||
"name": "Bad",
|
||||
"version": "0.0.1",
|
||||
"source": "catalog",
|
||||
"url": "https://example.com/evil.yml",
|
||||
},
|
||||
},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
WorkflowCatalog,
|
||||
"get_workflow_info",
|
||||
lambda self, wid: {"version": "9.9.9", "url": "https://example.com/evil.yml", "_install_allowed": True},
|
||||
)
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["workflow", "update"], input="y\n")
|
||||
assert result.exit_code != 0
|
||||
assert "Failed to update" in result.output
|
||||
|
||||
def test_enable_disable_corrupted_registry_entry_errors(self, project_dir, monkeypatch):
|
||||
import json
|
||||
from typer.testing import CliRunner
|
||||
|
||||
Reference in New Issue
Block a user