zrb 1.0.0a14__py3-none-any.whl → 1.0.0a15__py3-none-any.whl

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.
zrb/builtin/git.py CHANGED
@@ -55,9 +55,11 @@ from zrb.util.git import (
55
55
  group=git_group,
56
56
  alias="diff",
57
57
  )
58
- def get_git_diff(ctx: AnyContext):
59
- repo_dir = get_repo_dir()
60
- diff = get_diff(repo_dir, ctx.input.source, ctx.input.current)
58
+ async def get_git_diff(ctx: AnyContext):
59
+ repo_dir = await get_repo_dir(log_method=ctx.print)
60
+ diff = await get_diff(
61
+ repo_dir, ctx.input.source, ctx.input.current, log_method=ctx.print
62
+ )
61
63
  result = []
62
64
  decorated = []
63
65
  if ctx.input.created and diff.created:
@@ -83,16 +85,16 @@ def get_git_diff(ctx: AnyContext):
83
85
  group=git_branch_group,
84
86
  alias="prune",
85
87
  )
86
- def prune_local_branches(ctx: AnyContext):
87
- repo_dir = get_repo_dir()
88
- branches = get_branches(repo_dir)
89
- current_branch = get_current_branch(repo_dir)
88
+ async def prune_local_branches(ctx: AnyContext):
89
+ repo_dir = await get_repo_dir(log_method=ctx.print)
90
+ branches = await get_branches(repo_dir, log_method=ctx.print)
91
+ current_branch = await get_current_branch(repo_dir, log_method=ctx.print)
90
92
  for branch in branches:
91
93
  if branch == current_branch or branch == "main" or branch == "master":
92
94
  continue
93
95
  ctx.print(stylize_yellow(f"Removing local branch: {branch}"))
94
96
  try:
95
- delete_branch(repo_dir, branch)
97
+ await delete_branch(repo_dir, branch, log_method=ctx.print)
96
98
  except Exception as e:
97
99
  ctx.log_error(e)
98
100
 
@@ -109,12 +111,12 @@ def prune_local_branches(ctx: AnyContext):
109
111
  group=git_group,
110
112
  alias="commit",
111
113
  )
112
- def git_commit(ctx: AnyContext):
113
- repo_dir = get_repo_dir()
114
+ async def git_commit(ctx: AnyContext):
115
+ repo_dir = await get_repo_dir(log_method=ctx.print)
114
116
  ctx.print("Add changes to staging")
115
- add(repo_dir)
117
+ await add(repo_dir, log_method=ctx.print)
116
118
  ctx.print("Commit changes")
117
- commit(repo_dir, ctx.input.message)
119
+ await commit(repo_dir, ctx.input.message, log_method=ctx.print)
118
120
 
119
121
 
120
122
  @make_task(
@@ -130,12 +132,12 @@ def git_commit(ctx: AnyContext):
130
132
  group=git_group,
131
133
  alias="pull",
132
134
  )
133
- def git_pull(ctx: AnyContext):
134
- repo_dir = get_repo_dir()
135
+ async def git_pull(ctx: AnyContext):
136
+ repo_dir = await get_repo_dir(log_method=ctx.print)
135
137
  remote = ctx.input.remote
136
- current_branch = get_current_branch(repo_dir)
138
+ current_branch = await get_current_branch(repo_dir, log_method=ctx.print)
137
139
  ctx.print(f"Pulling from {remote}/{current_branch}")
138
- pull(repo_dir, remote, current_branch)
140
+ await pull(repo_dir, remote, current_branch, log_method=ctx.print)
139
141
 
140
142
 
141
143
  @make_task(
@@ -151,9 +153,9 @@ def git_pull(ctx: AnyContext):
151
153
  group=git_group,
152
154
  alias="push",
153
155
  )
154
- def git_push(ctx: AnyContext):
155
- repo_dir = get_repo_dir()
156
+ async def git_push(ctx: AnyContext):
157
+ repo_dir = await get_repo_dir(log_method=ctx.print)
156
158
  remote = ctx.input.remote
157
- current_branch = get_current_branch(repo_dir)
159
+ current_branch = await get_current_branch(repo_dir, log_method=ctx.print)
158
160
  ctx.print(f"Pushing to {remote}/{current_branch}")
159
- push(repo_dir, remote, current_branch)
161
+ await push(repo_dir, remote, current_branch, log_method=ctx.print)
@@ -32,14 +32,15 @@ from zrb.util.git_subtree import add_subtree, load_config, pull_subtree, push_su
32
32
  group=git_subtree_group,
33
33
  alias="add",
34
34
  )
35
- def git_add_subtree(ctx: AnyContext):
36
- repo_dir = get_repo_dir()
37
- add_subtree(
35
+ async def git_add_subtree(ctx: AnyContext):
36
+ repo_dir = await get_repo_dir(log_method=ctx.print)
37
+ await add_subtree(
38
38
  repo_dir=repo_dir,
39
39
  name=ctx.input.name,
40
40
  repo_url=ctx.input["repo-url"],
41
41
  branch=ctx.input["repo-branch"],
42
42
  prefix=ctx.input["repo-prefix"],
43
+ log_method=ctx.print,
43
44
  )
44
45
 
45
46
 
@@ -50,8 +51,8 @@ def git_add_subtree(ctx: AnyContext):
50
51
  group=git_subtree_group,
51
52
  alias="pull",
52
53
  )
53
- def git_pull_subtree(ctx: AnyContext):
54
- repo_dir = get_repo_dir()
54
+ async def git_pull_subtree(ctx: AnyContext):
55
+ repo_dir = await get_repo_dir(log_method=ctx.print)
55
56
  config = load_config(repo_dir)
56
57
  if not config.data:
57
58
  raise ValueError("No subtree config found")
@@ -59,11 +60,12 @@ def git_pull_subtree(ctx: AnyContext):
59
60
  for name, detail in config.data.items():
60
61
  try:
61
62
  ctx.print(f"Pull from subtree {name}")
62
- pull_subtree(
63
+ await pull_subtree(
63
64
  repo_dir=repo_dir,
64
65
  prefix=detail.prefix,
65
66
  repo_url=detail.repo_url,
66
67
  branch=detail.branch,
68
+ log_method=ctx.print,
67
69
  )
68
70
  except Exception as e:
69
71
  if first_err is None:
@@ -80,8 +82,8 @@ def git_pull_subtree(ctx: AnyContext):
80
82
  group=git_subtree_group,
81
83
  alias="push",
82
84
  )
83
- def git_push_subtree(ctx: AnyContext):
84
- repo_dir = get_repo_dir()
85
+ async def git_push_subtree(ctx: AnyContext):
86
+ repo_dir = await get_repo_dir(log_method=ctx.print)
85
87
  config = load_config(repo_dir)
86
88
  if not config.data:
87
89
  raise ValueError("No subtree config found")
@@ -89,11 +91,12 @@ def git_push_subtree(ctx: AnyContext):
89
91
  for name, detail in config.data.items():
90
92
  try:
91
93
  ctx.print(f"Push to subtree {name}")
92
- push_subtree(
94
+ await push_subtree(
93
95
  repo_dir=repo_dir,
94
96
  prefix=detail.prefix,
95
97
  repo_url=detail.repo_url,
96
98
  branch=detail.branch,
99
+ log_method=ctx.print,
97
100
  )
98
101
  except Exception as e:
99
102
  if first_err is None:
zrb/task/cmd_task.py CHANGED
@@ -1,6 +1,4 @@
1
- import asyncio
2
1
  import os
3
- import sys
4
2
 
5
3
  from zrb.attr.type import BoolAttr, IntAttr, StrAttr
6
4
  from zrb.cmd.cmd_result import CmdResult
@@ -12,7 +10,7 @@ from zrb.input.any_input import AnyInput
12
10
  from zrb.task.any_task import AnyTask
13
11
  from zrb.task.base_task import BaseTask
14
12
  from zrb.util.attr import get_int_attr, get_str_attr
15
- from zrb.util.cmd.command import check_unrecommended_commands
13
+ from zrb.util.cmd.command import check_unrecommended_commands, run_command
16
14
  from zrb.util.cmd.remote import get_remote_cmd_script
17
15
 
18
16
 
@@ -119,43 +117,25 @@ class CmdTask(BaseTask):
119
117
  ctx.log_debug(f"Working directory: {cwd}")
120
118
  env_map = self.__get_env_map(ctx)
121
119
  ctx.log_debug(f"Environment map: {env_map}")
122
- cmd_process = None
123
120
  if self._get_should_warn_unrecommended_commands():
124
121
  self._check_unrecommended_commands(ctx, shell, cmd_script)
125
- try:
126
- ctx.log_info("Running script")
127
- cmd_process = await asyncio.create_subprocess_exec(
128
- shell,
129
- shell_flag,
130
- cmd_script,
131
- cwd=cwd,
132
- stdin=sys.stdin if sys.stdin.isatty() else None,
133
- stdout=asyncio.subprocess.PIPE,
134
- stderr=asyncio.subprocess.PIPE,
135
- env=env_map,
136
- bufsize=0,
137
- )
138
- stdout_task = asyncio.create_task(
139
- self.__read_stream(cmd_process.stdout, ctx.print, self._max_output_line)
140
- )
141
- stderr_task = asyncio.create_task(
142
- self.__read_stream(cmd_process.stderr, ctx.print, self._max_error_line)
122
+ ctx.log_info("Running script")
123
+ cmd_result, return_code = await run_command(
124
+ cmd=[shell, shell_flag, cmd_script],
125
+ cwd=cwd,
126
+ env_map=env_map,
127
+ log_method=ctx.print,
128
+ max_output_line=self._max_output_line,
129
+ max_error_line=self._max_error_line,
130
+ )
131
+ # Check for errors
132
+ if return_code != 0:
133
+ ctx.log_error(f"Exit status: {return_code}")
134
+ raise Exception(
135
+ f"Process {self._name} exited ({return_code}): {cmd_result.stderr}"
143
136
  )
144
- # Wait for process to complete and gather stdout/stderr
145
- return_code = await cmd_process.wait()
146
- stdout = await stdout_task
147
- stderr = await stderr_task
148
- # Check for errors
149
- if return_code != 0:
150
- ctx.log_error(f"Exit status: {return_code}")
151
- raise Exception(
152
- f"Process {self._name} exited ({return_code}): {stderr}"
153
- )
154
- ctx.log_info(f"Exit status: {return_code}")
155
- return CmdResult(stdout, stderr)
156
- finally:
157
- if cmd_process is not None and cmd_process.returncode is None:
158
- cmd_process.terminate()
137
+ ctx.log_info(f"Exit status: {return_code}")
138
+ return cmd_result
159
139
 
160
140
  def _get_should_warn_unrecommended_commands(self):
161
141
  if self._should_warn_unrecommended_command is None:
@@ -178,19 +158,6 @@ class CmdTask(BaseTask):
178
158
  envs["PYTHONBUFFERED"] = "1"
179
159
  return envs
180
160
 
181
- async def __read_stream(self, stream, log_method, max_lines):
182
- lines = []
183
- while True:
184
- line = await stream.readline()
185
- if not line:
186
- break
187
- line = line.decode("utf-8").rstrip()
188
- lines.append(line)
189
- if len(lines) > max_lines:
190
- lines.pop(0) # Keep only the last max_lines
191
- log_method(line)
192
- return "\n".join(lines)
193
-
194
161
  def _get_shell(self, ctx: AnyContext) -> str:
195
162
  return get_str_attr(
196
163
  ctx, self._shell, DEFAULT_SHELL, auto_render=self._render_shell
zrb/util/cmd/command.py CHANGED
@@ -1,4 +1,10 @@
1
+ import asyncio
2
+ import os
1
3
  import re
4
+ import sys
5
+ from collections.abc import Callable
6
+
7
+ from zrb.cmd.cmd_result import CmdResult
2
8
 
3
9
 
4
10
  def check_unrecommended_commands(cmd_script: str) -> dict[str, str]:
@@ -31,3 +37,57 @@ def check_unrecommended_commands(cmd_script: str) -> dict[str, str]:
31
37
  if re.search(pattern, cmd_script):
32
38
  violations[pattern] = reason
33
39
  return violations
40
+
41
+
42
+ async def run_command(
43
+ cmd: list[str],
44
+ cwd: str | None = None,
45
+ env_map: dict[str, str] | None = None,
46
+ log_method: Callable[..., None] = print,
47
+ max_output_line: int = 1000,
48
+ max_error_line: int = 1000,
49
+ ) -> tuple[CmdResult, int]:
50
+
51
+ async def __read_stream(
52
+ stream, log_method: Callable[..., None], max_lines: int
53
+ ) -> str:
54
+ lines = []
55
+ while True:
56
+ line = await stream.readline()
57
+ if not line:
58
+ break
59
+ line = line.decode("utf-8").rstrip()
60
+ lines.append(line)
61
+ if len(lines) > max_lines:
62
+ lines.pop(0) # Keep only the last max_lines
63
+ log_method(line)
64
+ return "\n".join(lines)
65
+
66
+ try:
67
+ if cwd is None:
68
+ cwd = os.getcwd()
69
+ if env_map is None:
70
+ env_map = os.environ
71
+ cmd_process = await asyncio.create_subprocess_exec(
72
+ *cmd,
73
+ cwd=cwd,
74
+ stdin=sys.stdin if sys.stdin.isatty() else None,
75
+ stdout=asyncio.subprocess.PIPE,
76
+ stderr=asyncio.subprocess.PIPE,
77
+ env=env_map,
78
+ bufsize=0,
79
+ )
80
+ stdout_task = asyncio.create_task(
81
+ __read_stream(cmd_process.stdout, log_method, max_output_line)
82
+ )
83
+ stderr_task = asyncio.create_task(
84
+ __read_stream(cmd_process.stderr, log_method, max_error_line)
85
+ )
86
+ # Wait for process to complete and gather stdout/stderr
87
+ return_code = await cmd_process.wait()
88
+ stdout = await stdout_task
89
+ stderr = await stderr_task
90
+ return CmdResult(stdout, stderr), return_code
91
+ finally:
92
+ if cmd_process is not None and cmd_process.returncode is None:
93
+ cmd_process.terminate()
zrb/util/git.py CHANGED
@@ -1,8 +1,11 @@
1
1
  import os
2
- import subprocess
2
+ from collections.abc import Callable
3
+ from typing import Any
3
4
 
4
5
  from pydantic import BaseModel
5
6
 
7
+ from zrb.util.cmd.command import run_command
8
+
6
9
 
7
10
  class DiffResult(BaseModel):
8
11
  created: list[str]
@@ -10,19 +13,20 @@ class DiffResult(BaseModel):
10
13
  updated: list[str]
11
14
 
12
15
 
13
- def get_diff(repo_dir: str, source_commit: str, current_commit: str) -> DiffResult:
14
- try:
15
- result = subprocess.run(
16
- ["git", "diff", source_commit, current_commit],
17
- stdout=subprocess.PIPE,
18
- stderr=subprocess.PIPE,
19
- cwd=repo_dir,
20
- text=True,
21
- check=True,
22
- )
23
- except subprocess.CalledProcessError as e:
24
- raise Exception(e.stderr or e.stdout)
25
- lines = result.stdout.strip().split("\n")
16
+ async def get_diff(
17
+ repo_dir: str,
18
+ source_commit: str,
19
+ current_commit: str,
20
+ log_method: Callable[..., Any] = print,
21
+ ) -> DiffResult:
22
+ cmd_result, exit_code = await run_command(
23
+ cmd=["git", "diff", source_commit, current_commit],
24
+ cwd=repo_dir,
25
+ log_method=log_method,
26
+ )
27
+ if exit_code != 0:
28
+ raise Exception(f"Non zero exit code: {exit_code}")
29
+ lines = cmd_result.output.strip().split("\n")
26
30
  diff: dict[str, dict[str, bool]] = {}
27
31
  for line in lines:
28
32
  if not line.startswith("---") and not line.startswith("+++"):
@@ -50,125 +54,103 @@ def get_diff(repo_dir: str, source_commit: str, current_commit: str) -> DiffResu
50
54
  )
51
55
 
52
56
 
53
- def get_repo_dir() -> str:
54
- try:
55
- # Run the Git command to get the repository's top-level directory
56
- result = subprocess.run(
57
- ["git", "rev-parse", "--show-toplevel"],
58
- stdout=subprocess.PIPE,
59
- stderr=subprocess.PIPE,
60
- text=True,
61
- check=True,
62
- )
63
- # Return the directory path
64
- return os.path.abspath(result.stdout.strip())
65
- except subprocess.CalledProcessError as e:
66
- raise Exception(e.stderr or e.stdout)
67
-
68
-
69
- def get_current_branch(repo_dir: str) -> str:
70
- try:
71
- result = subprocess.run(
72
- ["git", "rev-parse", "--abbrev-ref", "HEAD"],
73
- stdout=subprocess.PIPE,
74
- stderr=subprocess.PIPE,
75
- cwd=repo_dir,
76
- text=True,
77
- check=True,
78
- )
79
- return result.stdout.strip()
80
- except subprocess.CalledProcessError as e:
81
- raise Exception(e.stderr or e.stdout)
82
-
83
-
84
- def get_branches(repo_dir: str) -> list[str]:
85
- try:
86
- result = subprocess.run(
87
- ["git", "branch"],
88
- stdout=subprocess.PIPE,
89
- stderr=subprocess.PIPE,
90
- cwd=repo_dir,
91
- text=True,
92
- check=True,
93
- )
94
- return [
95
- branch.lstrip("*").strip() for branch in result.stdout.strip().split("\n")
96
- ]
97
- except subprocess.CalledProcessError as e:
98
- raise Exception(e.stderr or e.stdout)
99
-
100
-
101
- def delete_branch(repo_dir: str, branch_name: str) -> str:
102
- try:
103
- result = subprocess.run(
104
- ["git", "branch", "-D", branch_name],
105
- stdout=subprocess.PIPE,
106
- stderr=subprocess.PIPE,
107
- cwd=repo_dir,
108
- text=True,
109
- check=True,
110
- )
111
- return result.stdout.strip()
112
- except subprocess.CalledProcessError as e:
113
- raise Exception(e.stderr or e.stdout)
114
-
115
-
116
- def add(repo_dir: str) -> str:
117
- try:
118
- subprocess.run(
119
- ["git", "add", ".", "-A"],
120
- stdout=subprocess.PIPE,
121
- stderr=subprocess.PIPE,
122
- cwd=repo_dir,
123
- text=True,
124
- check=True,
125
- )
126
- except subprocess.CalledProcessError as e:
127
- raise Exception(e.stderr or e.stdout)
128
-
129
-
130
- def commit(repo_dir: str, message: str) -> str:
131
- try:
132
- subprocess.run(
133
- ["git", "commit", "-m", message],
134
- stdout=subprocess.PIPE,
135
- stderr=subprocess.PIPE,
136
- cwd=repo_dir,
137
- text=True,
138
- check=True,
139
- )
140
- except subprocess.CalledProcessError as e:
57
+ async def get_repo_dir(log_method: Callable[..., Any] = print) -> str:
58
+ cmd_result, exit_code = await run_command(
59
+ cmd=["git", "rev-parse", "--show-toplevel"],
60
+ log_method=log_method,
61
+ )
62
+ if exit_code != 0:
63
+ raise Exception(f"Non zero exit code: {exit_code}")
64
+ return os.path.abspath(cmd_result.output.strip())
65
+
66
+
67
+ async def get_current_branch(
68
+ repo_dir: str, log_method: Callable[..., Any] = print
69
+ ) -> str:
70
+ cmd_result, exit_code = await run_command(
71
+ cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
72
+ cwd=repo_dir,
73
+ log_method=log_method,
74
+ )
75
+ if exit_code != 0:
76
+ raise Exception(f"Non zero exit code: {exit_code}")
77
+ return cmd_result.output.strip()
78
+
79
+
80
+ async def get_branches(
81
+ repo_dir: str, log_method: Callable[..., Any] = print
82
+ ) -> list[str]:
83
+ cmd_result, exit_code = await run_command(
84
+ cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
85
+ cwd=repo_dir,
86
+ log_method=log_method,
87
+ )
88
+ if exit_code != 0:
89
+ raise Exception(f"Non zero exit code: {exit_code}")
90
+ return [
91
+ branch.lstrip("*").strip() for branch in cmd_result.output.strip().split("\n")
92
+ ]
93
+
94
+
95
+ async def delete_branch(
96
+ repo_dir: str, branch_name: str, log_method: Callable[..., Any] = print
97
+ ) -> str:
98
+ cmd_result, exit_code = await run_command(
99
+ cmd=["git", "branch", "-D", branch_name],
100
+ cwd=repo_dir,
101
+ log_method=log_method,
102
+ )
103
+ if exit_code != 0:
104
+ raise Exception(f"Non zero exit code: {exit_code}")
105
+ return cmd_result.output.strip()
106
+
107
+
108
+ async def add(repo_dir: str, log_method: Callable[..., Any] = print):
109
+ _, exit_code = await run_command(
110
+ cmd=["git", "add", ".", "-A"],
111
+ cwd=repo_dir,
112
+ log_method=log_method,
113
+ )
114
+ if exit_code != 0:
115
+ raise Exception(f"Non zero exit code: {exit_code}")
116
+
117
+
118
+ async def commit(
119
+ repo_dir: str, message: str, log_method: Callable[..., Any] = print
120
+ ) -> str:
121
+ cmd_result, exit_code = await run_command(
122
+ cmd=["git", "commit", "-m", message],
123
+ cwd=repo_dir,
124
+ log_method=log_method,
125
+ )
126
+ if exit_code != 0:
141
127
  ignored_error_message = "nothing to commit, working tree clean"
142
128
  if (
143
- ignored_error_message not in e.stderr
144
- and ignored_error_message not in e.stdout
129
+ ignored_error_message not in cmd_result.error
130
+ and ignored_error_message not in cmd_result.output
145
131
  ):
146
- raise Exception(e.stderr or e.stdout)
147
-
148
-
149
- def pull(repo_dir: str, remote: str, branch: str) -> str:
150
- try:
151
- subprocess.run(
152
- ["git", "pull", remote, branch],
153
- stdout=subprocess.PIPE,
154
- stderr=subprocess.PIPE,
155
- cwd=repo_dir,
156
- text=True,
157
- check=True,
158
- )
159
- except subprocess.CalledProcessError as e:
160
- raise Exception(e.stderr or e.stdout)
161
-
162
-
163
- def push(repo_dir: str, remote: str, branch: str) -> str:
164
- try:
165
- subprocess.run(
166
- ["git", "push", "-u", remote, branch],
167
- stdout=subprocess.PIPE,
168
- stderr=subprocess.PIPE,
169
- cwd=repo_dir,
170
- text=True,
171
- check=True,
172
- )
173
- except subprocess.CalledProcessError as e:
174
- raise Exception(e.stderr or e.stdout)
132
+ raise Exception(f"Non zero exit code: {exit_code}")
133
+
134
+
135
+ async def pull(
136
+ repo_dir: str, remote: str, branch: str, log_method: Callable[..., Any] = print
137
+ ) -> str:
138
+ _, exit_code = await run_command(
139
+ cmd=["git", "pull", remote, branch],
140
+ cwd=repo_dir,
141
+ log_method=log_method,
142
+ )
143
+ if exit_code != 0:
144
+ raise Exception(f"Non zero exit code: {exit_code}")
145
+
146
+
147
+ async def push(
148
+ repo_dir: str, remote: str, branch: str, log_method: Callable[..., Any] = print
149
+ ) -> str:
150
+ _, exit_code = await run_command(
151
+ cmd=["git", "push", "-u", remote, branch],
152
+ cwd=repo_dir,
153
+ log_method=log_method,
154
+ )
155
+ if exit_code != 0:
156
+ raise Exception(f"Non zero exit code: {exit_code}")
zrb/util/git_subtree.py CHANGED
@@ -1,8 +1,11 @@
1
1
  import os
2
- import subprocess
2
+ from collections.abc import Callable
3
+ from typing import Any
3
4
 
4
5
  from pydantic import BaseModel
5
6
 
7
+ from zrb.util.cmd.command import run_command
8
+
6
9
 
7
10
  class SingleSubTreeConfig(BaseModel):
8
11
  repo_url: str
@@ -28,68 +31,83 @@ def save_config(repo_dir: str, config: SubTreeConfig):
28
31
  f.write(config.model_dump_json(indent=2))
29
32
 
30
33
 
31
- def add_subtree(repo_dir: str, name: str, repo_url: str, branch: str, prefix: str):
34
+ async def add_subtree(
35
+ repo_dir: str,
36
+ name: str,
37
+ repo_url: str,
38
+ branch: str,
39
+ prefix: str,
40
+ log_method: Callable[..., Any] = print,
41
+ ):
32
42
  config = load_config()
33
43
  if os.path.isdir(prefix):
34
44
  raise ValueError(f"Directory exists: {prefix}")
35
45
  if name in config.data:
36
46
  raise ValueError(f"Subtree config already exists: {name}")
37
- try:
38
- subprocess.run(
39
- ["git", "subtree", "add", "--prefix", prefix, repo_url, branch],
40
- stdout=subprocess.PIPE,
41
- stderr=subprocess.PIPE,
42
- cwd=repo_dir,
43
- text=True,
44
- check=True,
45
- )
46
- except subprocess.CalledProcessError as e:
47
- raise Exception(e.stderr or e.stdout)
47
+ _, exit_code = await run_command(
48
+ cmd=[
49
+ "git",
50
+ "subtree",
51
+ "add",
52
+ "--prefix",
53
+ prefix,
54
+ repo_url,
55
+ branch,
56
+ ],
57
+ cwd=repo_dir,
58
+ log_method=log_method,
59
+ )
60
+ if exit_code != 0:
61
+ raise Exception(f"Non zero exit code: {exit_code}")
48
62
  config.data[name] = SingleSubTreeConfig(
49
63
  repo_url=repo_url, branch=branch, prefix=prefix
50
64
  )
51
65
  save_config(repo_dir, config)
52
66
 
53
67
 
54
- def pull_subtree(repo_dir: str, prefix: str, repo_url: str, branch: str):
55
- try:
56
- subprocess.run(
57
- [
58
- "git",
59
- "subtree",
60
- "pull",
61
- "--prefix",
62
- prefix,
63
- repo_url,
64
- branch,
65
- ],
66
- stdout=subprocess.PIPE,
67
- stderr=subprocess.PIPE,
68
- cwd=repo_dir,
69
- text=True,
70
- check=True,
71
- )
72
- except subprocess.CalledProcessError as e:
73
- raise Exception(e.stderr or e.stdout)
74
-
75
-
76
- def push_subtree(repo_dir: str, prefix: str, repo_url: str, branch: str):
77
- try:
78
- subprocess.run(
79
- [
80
- "git",
81
- "subtree",
82
- "push",
83
- "--prefix",
84
- prefix,
85
- repo_url,
86
- branch,
87
- ],
88
- stdout=subprocess.PIPE,
89
- stderr=subprocess.PIPE,
90
- cwd=repo_dir,
91
- text=True,
92
- check=True,
93
- )
94
- except subprocess.CalledProcessError as e:
95
- raise Exception(e.stderr or e.stdout)
68
+ async def pull_subtree(
69
+ repo_dir: str,
70
+ prefix: str,
71
+ repo_url: str,
72
+ branch: str,
73
+ log_method: Callable[..., Any] = print,
74
+ ):
75
+ _, exit_code = await run_command(
76
+ cmd=[
77
+ "git",
78
+ "subtree",
79
+ "pull",
80
+ "--prefix",
81
+ prefix,
82
+ repo_url,
83
+ branch,
84
+ ],
85
+ cwd=repo_dir,
86
+ log_method=log_method,
87
+ )
88
+ if exit_code != 0:
89
+ raise Exception(f"Non zero exit code: {exit_code}")
90
+
91
+
92
+ async def push_subtree(
93
+ repo_dir: str,
94
+ prefix: str,
95
+ repo_url: str,
96
+ branch: str,
97
+ log_method: Callable[..., Any] = print,
98
+ ):
99
+ _, exit_code = await run_command(
100
+ cmd=[
101
+ "git",
102
+ "subtree",
103
+ "push",
104
+ "--prefix",
105
+ prefix,
106
+ repo_url,
107
+ branch,
108
+ ],
109
+ cwd=repo_dir,
110
+ log_method=log_method,
111
+ )
112
+ if exit_code != 0:
113
+ raise Exception(f"Non zero exit code: {exit_code}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 1.0.0a14
3
+ Version: 1.0.0a15
4
4
  Summary: Your Automation Powerhouse
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -4,8 +4,8 @@ zrb/attr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  zrb/attr/type.py,sha256=4TV5gPYMMrKh5V-yB6iRYKCbsXAH_AvGXMsjxKLHcUs,568
5
5
  zrb/builtin/__init__.py,sha256=seqFeTQk4k9I31oTdVrCDoud4_AzCrdVEZx1VxVUtZk,1744
6
6
  zrb/builtin/base64.py,sha256=1YnSwASp7OEAvQcsnHZGpJEvYoI1Z2zTIJ1bCDHfcPQ,921
7
- zrb/builtin/git.py,sha256=ypxGT4JyokYbXMvxdWFG684sEa6x7wht1b4PxpddTMA,4544
8
- zrb/builtin/git_subtree.py,sha256=M5Fr8NB4LaC3ra997tzZMLeD4H5o84MvvwefrLcWEIk,3016
7
+ zrb/builtin/git.py,sha256=u6tfB6ktZLtT5OqTPXgFCyaKUDTeaoDjfn6Gdo4nQOY,4998
8
+ zrb/builtin/git_subtree.py,sha256=BieE7ScL7yI1YBr7fHc70CxpE4xXvht4r-nyqfxOU7c,3236
9
9
  zrb/builtin/group.py,sha256=3xfEx9aEDcq6rDprGKYGqOXN2i0ts4W_RQVErL51o1o,1594
10
10
  zrb/builtin/llm/llm_chat.py,sha256=ATENrihXUMkQ8IoarhacohUe-I_43yb7c0Tl5f69mAI,1397
11
11
  zrb/builtin/llm/tool/cli.py,sha256=n8THj513k1vrXUoZrTcxESmdZzhBOP1-L3Dmup5ZW54,225
@@ -183,7 +183,7 @@ zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
183
  zrb/task/any_task.py,sha256=9rCdKe-Sayr34Han9AsbhRxFpkbk6Rteg1DOyETulwQ,4917
184
184
  zrb/task/base_task.py,sha256=Vn_MTR5aa3jIEWmh5LXpzezh-JwaEXPbjGKptx-Q-U8,19161
185
185
  zrb/task/base_trigger.py,sha256=milE5BNeIeq8jGCP38qTfstSvrc0CkSnO2sV-vlhzsM,4491
186
- zrb/task/cmd_task.py,sha256=sF4fT-inYhbR831Oht0LDMMuPCjY5TnIx9-rgPghnsI,11446
186
+ zrb/task/cmd_task.py,sha256=C_MxuBp51cx9rYR5OLMLNfI_FIAtJL176uaFZszjT1E,10185
187
187
  zrb/task/http_check.py,sha256=TwQCql3589a4-H2c7hgS1HayyU-NdBAdJ4qQNTvjXHM,2474
188
188
  zrb/task/llm_task.py,sha256=-OpLLXl39H1diHlPq1S8uiIwfQk_TY7nN8GHKqL4_m4,8643
189
189
  zrb/task/make_task.py,sha256=ldXRfe3rA8utJrEPjWrie-_tg6NM2G8sFnZ0UNqzT08,2179
@@ -200,7 +200,7 @@ zrb/util/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
200
  zrb/util/cli/style.py,sha256=wxdtE18d4Q3GV7aojinD-XN9iWvazfvLs9MTJPlCNQU,3805
201
201
  zrb/util/cli/subcommand.py,sha256=gYr-CzVeKFQhY43s_FDstPwn8r-ypUz1Q2Rv_l2r-ck,1027
202
202
  zrb/util/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
- zrb/util/cmd/command.py,sha256=dGihcEASO_5hkQbtpnLhd0FMZMNtdXk6W8X7ZP_2bQY,1545
203
+ zrb/util/cmd/command.py,sha256=B5cwzDKo63G-5lEeTStsBf24B4PoWRWgC63hUnJLAO0,3433
204
204
  zrb/util/cmd/remote.py,sha256=VklVORobTmE7FqdtYsVLq9xkSYTR2W5r2Zou0-soidw,710
205
205
  zrb/util/codemod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
206
206
  zrb/util/codemod/add_code_to_class.py,sha256=jg-ISD3sHCecOJ1CCJGR9quizRgvzddKH9GZ33-IQ1A,1358
@@ -212,8 +212,8 @@ zrb/util/codemod/add_param_to_function_call.py,sha256=cNC16uYbkjl33QEZ7i3pYvifGJ
212
212
  zrb/util/codemod/add_parent_to_class.py,sha256=xHLKAYDUShiaShocZTrIUUFbEw0obKRVB7WX5ktQ0kc,1416
213
213
  zrb/util/codemod/add_property_to_class.py,sha256=43ll7b7SUWHPDpIoMp8Zp_I71wG1eAvnW_acp-HVF_4,2075
214
214
  zrb/util/cron.py,sha256=9fTGatUMYCRgmDFGg-z6_XerT4U5Vq72nD05NnEVUm4,2852
215
- zrb/util/git.py,sha256=QNGvJJ9kY1Hy6WNO4d22D_GXyC1l3yGtTOMJ9nXqqpc,5151
216
- zrb/util/git_subtree.py,sha256=DidHZdKcpylomlJLiUyQJSpPSXaY399e-97H0WbOcvs,2619
215
+ zrb/util/git.py,sha256=o_kLF1fySv5uQdLlhY-ztc-z0zLOdcDf0IpuPAl2ciA,4733
216
+ zrb/util/git_subtree.py,sha256=Y-R02FPSY51M2XYqlDjEfXLkaE-c-yNPv8fKLHJRfT8,2646
217
217
  zrb/util/group.py,sha256=Bg7HrSycoK110U5s_Tca6-uUQuZ5CMgb8wxZSrvDQ98,2790
218
218
  zrb/util/llm/tool.py,sha256=9ezbPEAyMKLWABgeqAimJ82KBFl7ciWNFVGhtllXg6s,2106
219
219
  zrb/util/load.py,sha256=i8_83ApWJXlZlbFMNfEptrOzfXdvtaIhAErsd6tU9y8,1649
@@ -225,7 +225,7 @@ zrb/util/string/name.py,sha256=8picJfUBXNpdh64GNaHv3om23QHhUZux7DguFLrXHp8,1163
225
225
  zrb/util/todo.py,sha256=LharTudwr1gTNmt8iDUkQ6u21bGaCqVJh54Txe0bMOk,13529
226
226
  zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
227
  zrb/xcom/xcom.py,sha256=P4aYHdE3FRsTsNrXGyW8N44IWZjw-vG_qys1Ymn3aBg,1572
228
- zrb-1.0.0a14.dist-info/METADATA,sha256=89dXpMy37pyWDmENYtj1Juv6RQrnEKVxc2Jdtu7WPao,4106
229
- zrb-1.0.0a14.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
230
- zrb-1.0.0a14.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
231
- zrb-1.0.0a14.dist-info/RECORD,,
228
+ zrb-1.0.0a15.dist-info/METADATA,sha256=anjZuGKZzK7q-wklDNp31lVXsWfpS3BI93kgGtsNrbk,4106
229
+ zrb-1.0.0a15.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
230
+ zrb-1.0.0a15.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
231
+ zrb-1.0.0a15.dist-info/RECORD,,
File without changes