| 1 | from __future__ import annotations |
| 2 | |
| 3 | from pathlib import Path |
| 4 | import sys |
| 5 | |
| 6 | PROJECT_ROOT = Path(__file__).resolve().parents[4] |
| 7 | if str(PROJECT_ROOT) not in sys.path: |
| 8 | sys.path.insert(0, str(PROJECT_ROOT)) |
| 9 | |
| 10 | from helpers import plugins |
| 11 | from plugins._commands.extensions.python.startup_migration._20_migrate_legacy_commands import ( |
| 12 | migrate_legacy_commands, |
| 13 | ) |
| 14 | |
| 15 | |
| 16 | def test_migrate_legacy_commands_copies_user_data_and_disables_old_plugin(tmp_path: Path): |
| 17 | legacy_root = tmp_path / "usr" / "plugins" / "commands" |
| 18 | legacy_commands = legacy_root / "commands" |
| 19 | legacy_skills = legacy_root / "skills" / "custom-skill" |
| 20 | project_commands = ( |
| 21 | tmp_path |
| 22 | / "usr" |
| 23 | / "projects" |
| 24 | / "demo" |
| 25 | / ".a0proj" |
| 26 | / "plugins" |
| 27 | / "commands" |
| 28 | / "commands" |
| 29 | ) |
| 30 | new_commands = tmp_path / "usr" / "plugins" / "_commands" / "commands" |
| 31 | |
| 32 | legacy_commands.mkdir(parents=True) |
| 33 | legacy_skills.mkdir(parents=True) |
| 34 | project_commands.mkdir(parents=True) |
| 35 | new_commands.mkdir(parents=True) |
| 36 | |
| 37 | (legacy_root / "plugin.yaml").write_text("name: commands\n", encoding="utf-8") |
| 38 | (legacy_root / plugins.ENABLED_FILE_NAME).write_text("", encoding="utf-8") |
| 39 | (legacy_commands / "demo.command.yaml").write_text( |
| 40 | "name: demo\ndescription: Demo\ntype: text\ntemplate_path: demo.txt\n", |
| 41 | encoding="utf-8", |
| 42 | ) |
| 43 | (legacy_commands / "demo.txt").write_text("legacy demo\n", encoding="utf-8") |
| 44 | (legacy_commands / "keep.command.yaml").write_text( |
| 45 | "name: keep\ndescription: Keep\ntype: text\ntemplate_path: keep.txt\n", |
| 46 | encoding="utf-8", |
| 47 | ) |
| 48 | (new_commands / "keep.command.yaml").write_text("existing\n", encoding="utf-8") |
| 49 | (project_commands / "project.command.yaml").write_text( |
| 50 | "name: project\ndescription: Project\ntype: text\ntemplate_path: project.txt\n", |
| 51 | encoding="utf-8", |
| 52 | ) |
| 53 | (legacy_skills / "SKILL.md").write_text("---\nname: custom-skill\n---\n", encoding="utf-8") |
| 54 | |
| 55 | result = migrate_legacy_commands(tmp_path) |
| 56 | |
| 57 | assert result["copied_commands"] == 3 |
| 58 | assert result["copied_skills"] == 1 |
| 59 | assert result["disabled_roots"] == 2 |
| 60 | |
| 61 | assert (new_commands / "demo.command.yaml").read_text(encoding="utf-8").startswith( |
| 62 | "name: demo" |
| 63 | ) |
| 64 | assert (new_commands / "demo.txt").read_text(encoding="utf-8") == "legacy demo\n" |
| 65 | assert (new_commands / "keep.command.yaml").read_text(encoding="utf-8") == "existing\n" |
| 66 | assert ( |
| 67 | tmp_path |
| 68 | / "usr" |
| 69 | / "projects" |
| 70 | / "demo" |
| 71 | / ".a0proj" |
| 72 | / "plugins" |
| 73 | / "_commands" |
| 74 | / "commands" |
| 75 | / "project.command.yaml" |
| 76 | ).exists() |
| 77 | assert ( |
| 78 | tmp_path |
| 79 | / "usr" |
| 80 | / "plugins" |
| 81 | / "_commands" |
| 82 | / "skills" |
| 83 | / "custom-skill" |
| 84 | / "SKILL.md" |
| 85 | ).exists() |
| 86 | assert not (legacy_root / plugins.ENABLED_FILE_NAME).exists() |
| 87 | assert (legacy_root / plugins.DISABLED_FILE_NAME).exists() |
| 88 | assert ( |
| 89 | tmp_path |
| 90 | / "usr" |
| 91 | / "projects" |
| 92 | / "demo" |
| 93 | / ".a0proj" |
| 94 | / "plugins" |
| 95 | / "commands" |
| 96 | / plugins.DISABLED_FILE_NAME |
| 97 | ).exists() |