arctx-cli 0.2.0b2__tar.gz → 0.2.0b3__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.
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/PKG-INFO +8 -5
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/pyproject.toml +8 -5
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/__init__.py +3 -0
- arctx_cli-0.2.0b3/src/arctx_cli/commands/export.py +66 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/git.py +11 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/use.py +30 -4
- arctx_cli-0.2.0b3/src/arctx_cli/ext/git/repo.py +231 -0
- arctx_cli-0.2.0b3/tests/cli/test_git_repo.py +118 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_init_stag_id.py +52 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/.gitignore +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/README.md +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/alias.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/append_batch.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/alias_cmd.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/anchor.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/current.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/cut.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/dump.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/ext.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/graph.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/guide.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/init.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/list.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/migrate.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/node.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/outcomes.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/payload.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/reachable.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/show.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/sync.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/trace.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/transition.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/view.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/commands/work_session.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/context.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/command/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/branch.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/cherry_pick.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/commit.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/hook.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/merge.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/reset.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/revert.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/verify.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext/git/worktree.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/ext_registry.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/main.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/paths.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/payload_builder.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/src/arctx_cli/workspace.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_alias_cli.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_alias_resolve.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_basic.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_branch.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_cherry_pick.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_command_extension.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_commit.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_commit_guard.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_ext_cli.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_git_namespace_cli.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_git_worktree.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_hook_install.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_hook_post_merge.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_hook_post_rewrite.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_init_extension.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_init_hooks.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_merge.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_paths.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_reset.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_revert.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_show_history.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_verify.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/cli/test_work_session.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/fixtures/__init__.py +0 -0
- {arctx_cli-0.2.0b2 → arctx_cli-0.2.0b3}/tests/fixtures/dummy_ext.py +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arctx-cli
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: ARCTX
|
|
5
|
-
Project-URL: Homepage, https://github.com/takumiecd/
|
|
6
|
-
Project-URL: Repository, https://github.com/takumiecd/
|
|
3
|
+
Version: 0.2.0b3
|
|
4
|
+
Summary: CLI for ARCTX — append-only DAG for reasoning history and parallel agent work
|
|
5
|
+
Project-URL: Homepage, https://github.com/takumiecd/arctx
|
|
6
|
+
Project-URL: Repository, https://github.com/takumiecd/arctx
|
|
7
7
|
Author: Takumi Ishida
|
|
8
8
|
License: MIT
|
|
9
|
+
Keywords: agents,arctx,cli,dag,developer-tools,workflow
|
|
9
10
|
Classifier: Development Status :: 4 - Beta
|
|
10
11
|
Classifier: Intended Audience :: Developers
|
|
11
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -13,8 +14,10 @@ Classifier: Programming Language :: Python :: 3
|
|
|
13
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
16
19
|
Requires-Python: >=3.10
|
|
17
|
-
Requires-Dist: arctx>=0.2.
|
|
20
|
+
Requires-Dist: arctx>=0.2.0b3
|
|
18
21
|
Provides-Extra: dev
|
|
19
22
|
Requires-Dist: black>=23.0; extra == 'dev'
|
|
20
23
|
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
@@ -4,14 +4,15 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "arctx-cli"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "ARCTX
|
|
7
|
+
version = "0.2.0b3"
|
|
8
|
+
description = "CLI for ARCTX — append-only DAG for reasoning history and parallel agent work"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = {text = "MIT"}
|
|
12
12
|
authors = [
|
|
13
13
|
{name = "Takumi Ishida"},
|
|
14
14
|
]
|
|
15
|
+
keywords = ["cli", "arctx", "dag", "agents", "developer-tools", "workflow"]
|
|
15
16
|
classifiers = [
|
|
16
17
|
"Development Status :: 4 - Beta",
|
|
17
18
|
"Intended Audience :: Developers",
|
|
@@ -20,9 +21,11 @@ classifiers = [
|
|
|
20
21
|
"Programming Language :: Python :: 3.10",
|
|
21
22
|
"Programming Language :: Python :: 3.11",
|
|
22
23
|
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
"Topic :: Utilities",
|
|
23
26
|
]
|
|
24
27
|
dependencies = [
|
|
25
|
-
"arctx>=0.2.
|
|
28
|
+
"arctx>=0.2.0b3",
|
|
26
29
|
]
|
|
27
30
|
|
|
28
31
|
[project.optional-dependencies]
|
|
@@ -38,8 +41,8 @@ dev = [
|
|
|
38
41
|
arctx = "arctx_cli.main:main"
|
|
39
42
|
|
|
40
43
|
[project.urls]
|
|
41
|
-
Homepage = "https://github.com/takumiecd/
|
|
42
|
-
Repository = "https://github.com/takumiecd/
|
|
44
|
+
Homepage = "https://github.com/takumiecd/arctx"
|
|
45
|
+
Repository = "https://github.com/takumiecd/arctx"
|
|
43
46
|
|
|
44
47
|
[tool.hatch.build.targets.wheel]
|
|
45
48
|
packages = ["src/arctx_cli"]
|
|
@@ -17,6 +17,8 @@ def core_cli_commands() -> list[CliCommand]:
|
|
|
17
17
|
from arctx_cli.commands.cut import cli_cut
|
|
18
18
|
from arctx_cli.commands.dump import add_parser as add_dump_parser
|
|
19
19
|
from arctx_cli.commands.dump import cli_dump
|
|
20
|
+
from arctx_cli.commands.export import add_parser as add_export_parser
|
|
21
|
+
from arctx_cli.commands.export import cli_export
|
|
20
22
|
from arctx_cli.commands.ext import add_parser as add_ext_parser
|
|
21
23
|
from arctx_cli.commands.ext import cli_ext
|
|
22
24
|
from arctx_cli.commands.graph import add_parser as add_graph_parser
|
|
@@ -58,6 +60,7 @@ def core_cli_commands() -> list[CliCommand]:
|
|
|
58
60
|
CliCommand("current", add_current_parser, cli_current),
|
|
59
61
|
CliCommand("ext", add_ext_parser, cli_ext),
|
|
60
62
|
CliCommand("dump", add_dump_parser, cli_dump),
|
|
63
|
+
CliCommand("export", add_export_parser, cli_export),
|
|
61
64
|
CliCommand("graph", add_graph_parser, cli_graph),
|
|
62
65
|
CliCommand("guide", add_guide_parser, cli_guide),
|
|
63
66
|
CliCommand("init", add_init_parser, cli_init),
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""arctx CLI export command: render a run as markdown, LaTeX, or HTML.
|
|
2
|
+
|
|
3
|
+
Unlike ``dump`` (inspection / LLM), ``export`` produces a standalone document
|
|
4
|
+
to share. By default it strips machine-local data (repo ``local_path``); pass
|
|
5
|
+
``--include-local`` to keep it. ``--exclude-cut`` drops cut history.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
|
|
12
|
+
from arctx.core.run.export import ExportOptions, export
|
|
13
|
+
from arctx_cli.context import resolve_run_id_from_args, resolve_store
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def add_parser(subparsers) -> argparse.ArgumentParser:
|
|
17
|
+
parser = subparsers.add_parser(
|
|
18
|
+
"export",
|
|
19
|
+
help="Export the run as a shareable document (md / tex / html)",
|
|
20
|
+
)
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"--format",
|
|
23
|
+
dest="fmt",
|
|
24
|
+
choices=["md", "tex", "html"],
|
|
25
|
+
default="md",
|
|
26
|
+
help="Output format (default: md)",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument("--node", dest="node_id", default=None,
|
|
29
|
+
help="Export only the subtree rooted at this node")
|
|
30
|
+
parser.add_argument("--depth", type=int, default=None,
|
|
31
|
+
help="Limit traversal depth")
|
|
32
|
+
parser.add_argument("--full-payloads", action="store_true",
|
|
33
|
+
help="Include full payload content")
|
|
34
|
+
parser.add_argument("--exclude-cut", action="store_true",
|
|
35
|
+
help="Drop cut (inactive) nodes and transitions")
|
|
36
|
+
parser.add_argument("--include-local", action="store_true",
|
|
37
|
+
help="Keep repo local_path in the output (off by default)")
|
|
38
|
+
parser.add_argument("--output", "-o", default=None,
|
|
39
|
+
help="Write to this file instead of stdout")
|
|
40
|
+
parser.add_argument("--run", default=None)
|
|
41
|
+
parser.add_argument("--store-dir", default=None)
|
|
42
|
+
return parser
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def cli_export(args) -> int:
|
|
46
|
+
store = resolve_store(args.store_dir)
|
|
47
|
+
run_id = resolve_run_id_from_args(args)
|
|
48
|
+
if not store.run_path(run_id).exists():
|
|
49
|
+
raise KeyError(f"unknown run_id: {run_id}")
|
|
50
|
+
handle = store.load_run(run_id)
|
|
51
|
+
|
|
52
|
+
opts = ExportOptions(
|
|
53
|
+
node_id=args.node_id,
|
|
54
|
+
depth=args.depth,
|
|
55
|
+
full_payloads=args.full_payloads,
|
|
56
|
+
exclude_cut=args.exclude_cut,
|
|
57
|
+
include_local=args.include_local,
|
|
58
|
+
)
|
|
59
|
+
text = export(handle, args.fmt, opts)
|
|
60
|
+
if args.output:
|
|
61
|
+
with open(args.output, "w", encoding="utf-8") as f:
|
|
62
|
+
f.write(text)
|
|
63
|
+
print(f"wrote {args.output}")
|
|
64
|
+
else:
|
|
65
|
+
print(text)
|
|
66
|
+
return 0
|
|
@@ -31,6 +31,7 @@ def add_parser(subparsers) -> argparse.ArgumentParser:
|
|
|
31
31
|
from arctx_cli.ext.git.hook import add_parser as add_hook_parser
|
|
32
32
|
from arctx_cli.ext.git.merge import add_parser as add_merge_parser
|
|
33
33
|
from arctx_cli.ext.git.reset import add_parser as add_reset_parser
|
|
34
|
+
from arctx_cli.ext.git.repo import add_init_parser, add_repo_parser
|
|
34
35
|
from arctx_cli.ext.git.revert import add_parser as add_revert_parser
|
|
35
36
|
from arctx_cli.ext.git.verify import add_parser as add_verify_parser
|
|
36
37
|
from arctx_cli.ext.git.worktree import add_parser as add_worktree_parser
|
|
@@ -39,7 +40,9 @@ def add_parser(subparsers) -> argparse.ArgumentParser:
|
|
|
39
40
|
add_cherry_pick_parser(git_sub)
|
|
40
41
|
add_commit_parser(git_sub)
|
|
41
42
|
add_hook_parser(git_sub)
|
|
43
|
+
add_init_parser(git_sub)
|
|
42
44
|
add_merge_parser(git_sub)
|
|
45
|
+
add_repo_parser(git_sub)
|
|
43
46
|
add_reset_parser(git_sub)
|
|
44
47
|
add_revert_parser(git_sub)
|
|
45
48
|
add_verify_parser(git_sub)
|
|
@@ -100,10 +103,18 @@ def cli_git(args) -> int:
|
|
|
100
103
|
return cli_commit(args)
|
|
101
104
|
if args.git_command == "hook":
|
|
102
105
|
return cli_hook(args)
|
|
106
|
+
if args.git_command == "init":
|
|
107
|
+
from arctx_cli.ext.git.repo import cli_git_init # noqa: PLC0415
|
|
108
|
+
|
|
109
|
+
return cli_git_init(args)
|
|
103
110
|
if args.git_command == "list":
|
|
104
111
|
return _cli_git_list(args)
|
|
105
112
|
if args.git_command == "merge":
|
|
106
113
|
return cli_merge(args)
|
|
114
|
+
if args.git_command == "repo":
|
|
115
|
+
from arctx_cli.ext.git.repo import cli_repo # noqa: PLC0415
|
|
116
|
+
|
|
117
|
+
return cli_repo(args)
|
|
107
118
|
if args.git_command == "reset":
|
|
108
119
|
return cli_reset(args)
|
|
109
120
|
if args.git_command == "revert":
|
|
@@ -19,6 +19,15 @@ def add_parser(subparsers) -> argparse.ArgumentParser:
|
|
|
19
19
|
default=None,
|
|
20
20
|
help="Directory where runs are stored (default: <ARCTX_HOME>/runs)",
|
|
21
21
|
)
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"--shell",
|
|
24
|
+
action="store_true",
|
|
25
|
+
help=(
|
|
26
|
+
"Print 'export ARCTX_RUN_ID=<run>' for this terminal instead of "
|
|
27
|
+
"writing the repo's persistent pointer. Use as: "
|
|
28
|
+
'eval "$(arctx use <run> --shell)"'
|
|
29
|
+
),
|
|
30
|
+
)
|
|
22
31
|
return parser
|
|
23
32
|
|
|
24
33
|
|
|
@@ -26,8 +35,15 @@ def run_use_command(
|
|
|
26
35
|
*,
|
|
27
36
|
run_id: str,
|
|
28
37
|
store_dir: str | None,
|
|
38
|
+
shell: bool = False,
|
|
29
39
|
) -> dict:
|
|
30
|
-
"""Set the current run
|
|
40
|
+
"""Set the current run.
|
|
41
|
+
|
|
42
|
+
By default this writes the run id to ``<gitdir>/arctx-id`` — a persistent,
|
|
43
|
+
repo-scoped default that every terminal in that checkout sees. With
|
|
44
|
+
*shell* set, nothing is written; the caller is expected to ``eval`` the
|
|
45
|
+
emitted ``export ARCTX_RUN_ID=<run>`` line to pin the run for the current
|
|
46
|
+
terminal only (env beats the repo pointer in the resolution chain).
|
|
31
47
|
|
|
32
48
|
Parameters
|
|
33
49
|
----------
|
|
@@ -35,23 +51,29 @@ def run_use_command(
|
|
|
35
51
|
Identifier of the run.
|
|
36
52
|
store_dir:
|
|
37
53
|
Directory where runs are stored.
|
|
54
|
+
shell:
|
|
55
|
+
Emit a shell ``export`` line (terminal-scoped) instead of writing the
|
|
56
|
+
repo pointer.
|
|
38
57
|
|
|
39
58
|
Returns
|
|
40
59
|
-------
|
|
41
|
-
dict with ``run_id``
|
|
60
|
+
dict with ``run_id``; ``arctx_id_path`` (repo mode) or ``export`` (shell
|
|
61
|
+
mode).
|
|
42
62
|
|
|
43
63
|
Raises
|
|
44
64
|
------
|
|
45
65
|
KeyError
|
|
46
66
|
If the run_id does not exist in the store.
|
|
47
67
|
RuntimeError
|
|
48
|
-
If not inside a git repository.
|
|
68
|
+
If not inside a git repository (repo mode only).
|
|
49
69
|
"""
|
|
50
70
|
resolved_store_dir = store_dir if store_dir is not None else resolve_store_dir()
|
|
51
71
|
store = resolve_store(resolved_store_dir)
|
|
52
72
|
run_path = store.run_path(run_id)
|
|
53
73
|
if not run_path.exists():
|
|
54
74
|
raise KeyError(f"unknown run_id: {run_id}")
|
|
75
|
+
if shell:
|
|
76
|
+
return {"run_id": run_id, "export": f"export ARCTX_RUN_ID={run_id}"}
|
|
55
77
|
repo_root = find_repo_root()
|
|
56
78
|
write_arctx_id(repo_root, run_id)
|
|
57
79
|
return {"run_id": run_id, "arctx_id_path": str(arctx_id_path(repo_root))}
|
|
@@ -62,6 +84,10 @@ def cli_use(args) -> int:
|
|
|
62
84
|
result = run_use_command(
|
|
63
85
|
run_id=args.run_id,
|
|
64
86
|
store_dir=args.store_dir,
|
|
87
|
+
shell=getattr(args, "shell", False),
|
|
65
88
|
)
|
|
66
|
-
|
|
89
|
+
if "export" in result:
|
|
90
|
+
print(result["export"])
|
|
91
|
+
else:
|
|
92
|
+
print(result["run_id"])
|
|
67
93
|
return 0
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""arctx git repo — manage the run's git repo registry (the repo 対応表).
|
|
2
|
+
|
|
3
|
+
One run can span several git repos. ``repo add`` is the "途中で入れる" verb:
|
|
4
|
+
it registers a repo into an already-running run (RepoPayload + ``.arctx-id``
|
|
5
|
+
pointer + ``.arctx-repo`` marker, and optionally installs hooks). ``arctx git
|
|
6
|
+
init`` is a thin wrapper that always installs hooks.
|
|
7
|
+
|
|
8
|
+
``repo list`` / ``repo show`` inspect the registry. These are local-inspection
|
|
9
|
+
commands (like ``dump``), so they show ``local_path`` by default — export is
|
|
10
|
+
the outlet that strips it for sharing.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import json
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from arctx_cli.context import (
|
|
21
|
+
resolve_run_id_from_args,
|
|
22
|
+
resolve_store,
|
|
23
|
+
resolve_user_id_from_args,
|
|
24
|
+
resolve_work_session_id_from_args,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Parser registration
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def add_repo_parser(git_sub) -> argparse.ArgumentParser:
|
|
34
|
+
p = git_sub.add_parser("repo", help="Manage the run's git repo registry (対応表)")
|
|
35
|
+
sub = p.add_subparsers(dest="repo_command", required=True)
|
|
36
|
+
|
|
37
|
+
add = sub.add_parser(
|
|
38
|
+
"add", help="Register a git repo into the current run (途中で入れる)"
|
|
39
|
+
)
|
|
40
|
+
_add_common(add)
|
|
41
|
+
add.add_argument("--repo-path", default=None, help="Repo working tree (default: cwd)")
|
|
42
|
+
add.add_argument("--slug", default=None, help="Override display slug (USER/REPO)")
|
|
43
|
+
add.add_argument("--no-hooks", action="store_true", help="Skip installing git hooks")
|
|
44
|
+
add.add_argument("--user", default=None)
|
|
45
|
+
add.add_argument("--work-session", default=None)
|
|
46
|
+
|
|
47
|
+
lst = sub.add_parser("list", help="List repos registered in the run")
|
|
48
|
+
_add_common(lst)
|
|
49
|
+
|
|
50
|
+
show = sub.add_parser("show", help="Show one repo registry entry as JSON")
|
|
51
|
+
_add_common(show)
|
|
52
|
+
show.add_argument("--repo-id", default=None, help="Repo id (default: resolve cwd)")
|
|
53
|
+
show.add_argument("--repo-path", default=None, help="Resolve by working tree instead")
|
|
54
|
+
|
|
55
|
+
return p
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def add_init_parser(git_sub) -> argparse.ArgumentParser:
|
|
59
|
+
p = git_sub.add_parser(
|
|
60
|
+
"init",
|
|
61
|
+
help="Set up git integration for the current run on this repo "
|
|
62
|
+
"(registers the repo and installs hooks)",
|
|
63
|
+
)
|
|
64
|
+
_add_common(p)
|
|
65
|
+
p.add_argument("--repo-path", default=None, help="Repo working tree (default: cwd)")
|
|
66
|
+
p.add_argument("--slug", default=None, help="Override display slug (USER/REPO)")
|
|
67
|
+
p.add_argument("--no-hooks", action="store_true", help="Skip installing git hooks")
|
|
68
|
+
p.add_argument("--user", default=None)
|
|
69
|
+
p.add_argument("--work-session", default=None)
|
|
70
|
+
return p
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _add_common(p: argparse.ArgumentParser) -> None:
|
|
74
|
+
p.add_argument("--run", default=None)
|
|
75
|
+
p.add_argument("--store-dir", default=None)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# ---------------------------------------------------------------------------
|
|
79
|
+
# add (the primitive; git init wraps it)
|
|
80
|
+
# ---------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def run_repo_add(
|
|
84
|
+
*,
|
|
85
|
+
repo_path: str | None,
|
|
86
|
+
slug: str | None,
|
|
87
|
+
run_id: str | None,
|
|
88
|
+
store_dir: str | None,
|
|
89
|
+
user_id: str | None,
|
|
90
|
+
work_session_id: str | None,
|
|
91
|
+
install_hooks: bool,
|
|
92
|
+
) -> dict:
|
|
93
|
+
from arctx.ext.git.helpers.repo import resolve_worktree_path
|
|
94
|
+
from arctx.ext.git.registry import list_repos, repo_by_id, resolve_repo_id
|
|
95
|
+
from arctx.paths import find_repo_root, write_arctx_id
|
|
96
|
+
|
|
97
|
+
store = resolve_store(store_dir)
|
|
98
|
+
handle = store.load_run(run_id)
|
|
99
|
+
|
|
100
|
+
resolved_path = resolve_worktree_path(repo_path)
|
|
101
|
+
existing_ids = {r.repo_id for r in list_repos(handle.run_graph)}
|
|
102
|
+
repo_id = resolve_repo_id(handle, resolved_path, slug=slug)
|
|
103
|
+
entry = repo_by_id(handle.run_graph, repo_id)
|
|
104
|
+
|
|
105
|
+
if repo_id not in existing_ids and entry is not None:
|
|
106
|
+
handle.record_work_event(
|
|
107
|
+
user_id=user_id,
|
|
108
|
+
work_session_id=work_session_id,
|
|
109
|
+
event_type="repo_added",
|
|
110
|
+
target_kind="node",
|
|
111
|
+
target_id=handle.root_node_id,
|
|
112
|
+
created_records=(entry.payload_id,),
|
|
113
|
+
summary=f"repo {entry.slug or repo_id} added",
|
|
114
|
+
data={"repo_id": repo_id, "slug": entry.slug, "canonical": entry.canonical},
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
store.save_run(handle)
|
|
118
|
+
|
|
119
|
+
# Point this repo's checkout at the run so future commands resolve it.
|
|
120
|
+
try:
|
|
121
|
+
repo_root = find_repo_root(resolved_path)
|
|
122
|
+
write_arctx_id(repo_root, handle.run_id)
|
|
123
|
+
except RuntimeError:
|
|
124
|
+
repo_root = Path(resolved_path)
|
|
125
|
+
|
|
126
|
+
hooks: dict | None = None
|
|
127
|
+
if install_hooks:
|
|
128
|
+
from arctx_cli.ext.git.hook import run_hook_install
|
|
129
|
+
|
|
130
|
+
hooks = run_hook_install(repo_path=repo_root)
|
|
131
|
+
|
|
132
|
+
result: dict = {
|
|
133
|
+
"run_id": handle.run_id,
|
|
134
|
+
"repo_id": repo_id,
|
|
135
|
+
"slug": entry.slug if entry else None,
|
|
136
|
+
"canonical": entry.canonical if entry else None,
|
|
137
|
+
"local_path": entry.local_path if entry else None,
|
|
138
|
+
}
|
|
139
|
+
if hooks is not None:
|
|
140
|
+
result["hooks"] = hooks.get("status")
|
|
141
|
+
return result
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# ---------------------------------------------------------------------------
|
|
145
|
+
# Dispatch
|
|
146
|
+
# ---------------------------------------------------------------------------
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def cli_repo(args) -> int:
|
|
150
|
+
if args.repo_command == "add":
|
|
151
|
+
return _cli_repo_add(args)
|
|
152
|
+
if args.repo_command == "list":
|
|
153
|
+
return _cli_repo_list(args)
|
|
154
|
+
if args.repo_command == "show":
|
|
155
|
+
return _cli_repo_show(args)
|
|
156
|
+
print(f"unknown repo subcommand: {args.repo_command}", file=sys.stderr)
|
|
157
|
+
return 1
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def cli_git_init(args) -> int:
|
|
161
|
+
try:
|
|
162
|
+
result = run_repo_add(
|
|
163
|
+
repo_path=args.repo_path,
|
|
164
|
+
slug=args.slug,
|
|
165
|
+
run_id=resolve_run_id_from_args(args),
|
|
166
|
+
store_dir=args.store_dir,
|
|
167
|
+
user_id=resolve_user_id_from_args(args),
|
|
168
|
+
work_session_id=resolve_work_session_id_from_args(args),
|
|
169
|
+
install_hooks=not args.no_hooks,
|
|
170
|
+
)
|
|
171
|
+
except Exception as exc: # noqa: BLE001
|
|
172
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
173
|
+
return 1
|
|
174
|
+
print(json.dumps(result, indent=2))
|
|
175
|
+
return 0
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _cli_repo_add(args) -> int:
|
|
179
|
+
try:
|
|
180
|
+
result = run_repo_add(
|
|
181
|
+
repo_path=args.repo_path,
|
|
182
|
+
slug=args.slug,
|
|
183
|
+
run_id=resolve_run_id_from_args(args),
|
|
184
|
+
store_dir=args.store_dir,
|
|
185
|
+
user_id=resolve_user_id_from_args(args),
|
|
186
|
+
work_session_id=resolve_work_session_id_from_args(args),
|
|
187
|
+
install_hooks=not args.no_hooks,
|
|
188
|
+
)
|
|
189
|
+
except Exception as exc: # noqa: BLE001
|
|
190
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
191
|
+
return 1
|
|
192
|
+
print(json.dumps(result, indent=2))
|
|
193
|
+
return 0
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _cli_repo_list(args) -> int:
|
|
197
|
+
from arctx.ext.git.registry import list_repos
|
|
198
|
+
|
|
199
|
+
store = resolve_store(args.store_dir)
|
|
200
|
+
run_id = resolve_run_id_from_args(args)
|
|
201
|
+
handle = store.load_run(run_id)
|
|
202
|
+
entries = [r.to_dict() for r in list_repos(handle.run_graph)]
|
|
203
|
+
print(json.dumps(entries, indent=2))
|
|
204
|
+
return 0
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _cli_repo_show(args) -> int:
|
|
208
|
+
from arctx.ext.git.helpers.repo import resolve_worktree_path
|
|
209
|
+
from arctx.ext.git.registry import read_repo_marker, repo_by_id
|
|
210
|
+
|
|
211
|
+
store = resolve_store(args.store_dir)
|
|
212
|
+
run_id = resolve_run_id_from_args(args)
|
|
213
|
+
handle = store.load_run(run_id)
|
|
214
|
+
|
|
215
|
+
repo_id = args.repo_id
|
|
216
|
+
if repo_id is None:
|
|
217
|
+
marker = read_repo_marker(resolve_worktree_path(args.repo_path))
|
|
218
|
+
if marker is None:
|
|
219
|
+
print(
|
|
220
|
+
"error: no --repo-id given and no .arctx-repo marker found in cwd",
|
|
221
|
+
file=sys.stderr,
|
|
222
|
+
)
|
|
223
|
+
return 1
|
|
224
|
+
repo_id = marker
|
|
225
|
+
|
|
226
|
+
entry = repo_by_id(handle.run_graph, repo_id)
|
|
227
|
+
if entry is None:
|
|
228
|
+
print(f"error: repo not found in run: {repo_id}", file=sys.stderr)
|
|
229
|
+
return 1
|
|
230
|
+
print(json.dumps(entry.to_dict(), indent=2))
|
|
231
|
+
return 0
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Integration tests for `arctx git repo` / `arctx git init` with real repos."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from arctx_cli.commands.init import run_init_command
|
|
9
|
+
from arctx_cli.context import resolve_store
|
|
10
|
+
from arctx_cli.ext.git.repo import run_repo_add
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _init_git_repo(path: Path, *, remote: str | None = None) -> Path:
|
|
14
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
15
|
+
subprocess.run(["git", "init"], cwd=str(path), capture_output=True, check=True)
|
|
16
|
+
subprocess.run(["git", "config", "user.email", "t@e.com"], cwd=str(path),
|
|
17
|
+
capture_output=True, check=True)
|
|
18
|
+
subprocess.run(["git", "config", "user.name", "t"], cwd=str(path),
|
|
19
|
+
capture_output=True, check=True)
|
|
20
|
+
subprocess.run(["git", "checkout", "-b", "main"], cwd=str(path),
|
|
21
|
+
capture_output=True, check=True)
|
|
22
|
+
(path / "README.md").write_text("hello\n")
|
|
23
|
+
subprocess.run(["git", "add", "."], cwd=str(path), capture_output=True, check=True)
|
|
24
|
+
subprocess.run(["git", "commit", "-m", "init"], cwd=str(path),
|
|
25
|
+
capture_output=True, check=True)
|
|
26
|
+
if remote is not None:
|
|
27
|
+
subprocess.run(["git", "remote", "add", "origin", remote], cwd=str(path),
|
|
28
|
+
capture_output=True, check=True)
|
|
29
|
+
return path
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _store_dir(tmp_path: Path) -> str:
|
|
33
|
+
return str(tmp_path / "arctx_home" / "runs")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _init_run(tmp_path: Path, run_id: str) -> None:
|
|
37
|
+
run_init_command(
|
|
38
|
+
requirement_id="req1",
|
|
39
|
+
target_type="task",
|
|
40
|
+
target_id="t",
|
|
41
|
+
run_id=run_id,
|
|
42
|
+
store_dir=_store_dir(tmp_path),
|
|
43
|
+
extensions=["git"],
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TestRepoAdd:
|
|
48
|
+
def test_add_registers_repo_and_persists(self, tmp_path, monkeypatch):
|
|
49
|
+
repo = _init_git_repo(tmp_path / "repo", remote="git@github.com:me/proj.git")
|
|
50
|
+
monkeypatch.setenv("ARCTX_HOME", str(tmp_path / "arctx_home"))
|
|
51
|
+
monkeypatch.chdir(repo)
|
|
52
|
+
_init_run(tmp_path, "run_a")
|
|
53
|
+
|
|
54
|
+
result = run_repo_add(
|
|
55
|
+
repo_path=str(repo),
|
|
56
|
+
slug=None,
|
|
57
|
+
run_id="run_a",
|
|
58
|
+
store_dir=_store_dir(tmp_path),
|
|
59
|
+
user_id="alice",
|
|
60
|
+
work_session_id="ws",
|
|
61
|
+
install_hooks=False,
|
|
62
|
+
)
|
|
63
|
+
assert result["repo_id"].startswith("repo_")
|
|
64
|
+
assert result["slug"] == "me/proj"
|
|
65
|
+
assert result["canonical"] == "github.com/me/proj"
|
|
66
|
+
|
|
67
|
+
# Reload from store: registry survived persistence.
|
|
68
|
+
store = resolve_store(_store_dir(tmp_path))
|
|
69
|
+
handle = store.load_run("run_a")
|
|
70
|
+
from arctx.ext.git.registry import list_repos
|
|
71
|
+
|
|
72
|
+
repos = list_repos(handle.run_graph)
|
|
73
|
+
assert [r.repo_id for r in repos] == [result["repo_id"]]
|
|
74
|
+
# .arctx-id pointer written for this repo.
|
|
75
|
+
from arctx.paths import read_arctx_id
|
|
76
|
+
|
|
77
|
+
assert read_arctx_id(repo) == "run_a"
|
|
78
|
+
|
|
79
|
+
def test_slug_override(self, tmp_path, monkeypatch):
|
|
80
|
+
repo = _init_git_repo(tmp_path / "repo", remote="git@github.com:me/proj.git")
|
|
81
|
+
monkeypatch.setenv("ARCTX_HOME", str(tmp_path / "arctx_home"))
|
|
82
|
+
monkeypatch.chdir(repo)
|
|
83
|
+
_init_run(tmp_path, "run_b")
|
|
84
|
+
|
|
85
|
+
result = run_repo_add(
|
|
86
|
+
repo_path=str(repo),
|
|
87
|
+
slug="custom/name",
|
|
88
|
+
run_id="run_b",
|
|
89
|
+
store_dir=_store_dir(tmp_path),
|
|
90
|
+
user_id="alice",
|
|
91
|
+
work_session_id="ws",
|
|
92
|
+
install_hooks=False,
|
|
93
|
+
)
|
|
94
|
+
assert result["slug"] == "custom/name"
|
|
95
|
+
|
|
96
|
+
def test_idempotent_re_add(self, tmp_path, monkeypatch):
|
|
97
|
+
repo = _init_git_repo(tmp_path / "repo", remote="git@github.com:me/proj.git")
|
|
98
|
+
monkeypatch.setenv("ARCTX_HOME", str(tmp_path / "arctx_home"))
|
|
99
|
+
monkeypatch.chdir(repo)
|
|
100
|
+
_init_run(tmp_path, "run_c")
|
|
101
|
+
|
|
102
|
+
first = run_repo_add(
|
|
103
|
+
repo_path=str(repo), slug=None, run_id="run_c",
|
|
104
|
+
store_dir=_store_dir(tmp_path), user_id="alice",
|
|
105
|
+
work_session_id="ws", install_hooks=False,
|
|
106
|
+
)
|
|
107
|
+
second = run_repo_add(
|
|
108
|
+
repo_path=str(repo), slug=None, run_id="run_c",
|
|
109
|
+
store_dir=_store_dir(tmp_path), user_id="alice",
|
|
110
|
+
work_session_id="ws", install_hooks=False,
|
|
111
|
+
)
|
|
112
|
+
assert first["repo_id"] == second["repo_id"]
|
|
113
|
+
|
|
114
|
+
store = resolve_store(_store_dir(tmp_path))
|
|
115
|
+
handle = store.load_run("run_c")
|
|
116
|
+
from arctx.ext.git.registry import list_repos
|
|
117
|
+
|
|
118
|
+
assert len(list_repos(handle.run_graph)) == 1
|
|
@@ -182,6 +182,58 @@ def test_use_raises_for_unknown_run(tmp_path, monkeypatch):
|
|
|
182
182
|
run_use_command(run_id="no_such_run", store_dir=_store_dir(tmp_path))
|
|
183
183
|
|
|
184
184
|
|
|
185
|
+
def test_use_shell_emits_export_without_writing_pointer(tmp_path, monkeypatch):
|
|
186
|
+
repo = _fake_git_repo(tmp_path)
|
|
187
|
+
monkeypatch.setenv("ARCTX_HOME", str(_arctx_home(tmp_path)))
|
|
188
|
+
monkeypatch.chdir(repo)
|
|
189
|
+
run_init_command(
|
|
190
|
+
requirement_id="req1", target_type="task", target_id="t",
|
|
191
|
+
run_id="run_a", store_dir=_store_dir(tmp_path),
|
|
192
|
+
)
|
|
193
|
+
run_init_command(
|
|
194
|
+
requirement_id="req2", target_type="task", target_id="t",
|
|
195
|
+
run_id="run_b", store_dir=_store_dir(tmp_path),
|
|
196
|
+
)
|
|
197
|
+
# After the two inits the repo pointer is run_b.
|
|
198
|
+
assert read_arctx_id(repo) == "run_b"
|
|
199
|
+
|
|
200
|
+
result = run_use_command(
|
|
201
|
+
run_id="run_a", store_dir=_store_dir(tmp_path), shell=True
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Shell mode emits an export line for eval and leaves the repo pointer
|
|
205
|
+
# untouched (terminal-scoped, not repo-scoped).
|
|
206
|
+
assert result["export"] == "export ARCTX_RUN_ID=run_a"
|
|
207
|
+
assert read_arctx_id(repo) == "run_b"
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def test_use_shell_validates_run_exists(tmp_path, monkeypatch):
|
|
211
|
+
repo = _fake_git_repo(tmp_path)
|
|
212
|
+
monkeypatch.setenv("ARCTX_HOME", str(_arctx_home(tmp_path)))
|
|
213
|
+
monkeypatch.chdir(repo)
|
|
214
|
+
|
|
215
|
+
with pytest.raises(KeyError, match="unknown run_id"):
|
|
216
|
+
run_use_command(run_id="nope", store_dir=_store_dir(tmp_path), shell=True)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def test_use_shell_works_outside_git_repo(tmp_path, monkeypatch):
|
|
220
|
+
# No .git here: shell mode must not require a repo (it writes no pointer).
|
|
221
|
+
monkeypatch.setenv("ARCTX_HOME", str(_arctx_home(tmp_path)))
|
|
222
|
+
monkeypatch.chdir(tmp_path)
|
|
223
|
+
run_init_command(
|
|
224
|
+
requirement_id="req1",
|
|
225
|
+
target_type="task",
|
|
226
|
+
target_id="t",
|
|
227
|
+
run_id="run_a",
|
|
228
|
+
store_dir=_store_dir(tmp_path),
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
result = run_use_command(
|
|
232
|
+
run_id="run_a", store_dir=_store_dir(tmp_path), shell=True
|
|
233
|
+
)
|
|
234
|
+
assert result["export"] == "export ARCTX_RUN_ID=run_a"
|
|
235
|
+
|
|
236
|
+
|
|
185
237
|
# ---------------------------------------------------------------------------
|
|
186
238
|
# ARCTX_HOME env overrides run storage location end-to-end
|
|
187
239
|
# ---------------------------------------------------------------------------
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|