zrb 1.0.0b6__py3-none-any.whl → 1.0.0b8__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/__init__.py +2 -0
- zrb/builtin/git.py +15 -15
- zrb/builtin/git_subtree.py +6 -6
- zrb/builtin/project/add/fastapp/fastapp_task.py +3 -3
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_task.py +80 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +3 -3
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service.py +11 -13
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +3 -3
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +11 -13
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +20 -18
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +24 -14
- zrb/builtin/setup/tmux/tmux.py +1 -1
- zrb/builtin/setup/zsh/zsh.py +55 -0
- zrb/builtin/setup/zsh/zsh_config.sh +133 -0
- zrb/builtin/setup/zsh/zsh_helper.py +13 -0
- zrb/config.py +0 -1
- zrb/context/any_context.py +2 -0
- zrb/context/context.py +7 -5
- zrb/runner/web_route/static/resources/session/current-session.js +19 -12
- zrb/task/cmd_task.py +11 -1
- zrb/task/rsync_task.py +6 -4
- zrb/util/cmd/command.py +27 -5
- zrb/util/git.py +18 -18
- zrb/util/git_subtree.py +6 -6
- {zrb-1.0.0b6.dist-info → zrb-1.0.0b8.dist-info}/METADATA +1 -1
- {zrb-1.0.0b6.dist-info → zrb-1.0.0b8.dist-info}/RECORD +28 -25
- {zrb-1.0.0b6.dist-info → zrb-1.0.0b8.dist-info}/WHEEL +0 -0
- {zrb-1.0.0b6.dist-info → zrb-1.0.0b8.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
# If you come from bash you might have to change your $PATH.
|
2
|
+
# export PATH=$HOME/bin:/usr/local/bin:$PATH
|
3
|
+
|
4
|
+
# Path to your oh-my-zsh installation.
|
5
|
+
export ZSH="$HOME/.oh-my-zsh"
|
6
|
+
|
7
|
+
# Set name of the theme to load --- if set to "random", it will
|
8
|
+
# load a random theme each time oh-my-zsh is loaded, in which case,
|
9
|
+
# to know which specific one was loaded, run: echo $RANDOM_THEME
|
10
|
+
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
|
11
|
+
ZSH_THEME="candy"
|
12
|
+
|
13
|
+
# Set list of themes to pick from when loading at random
|
14
|
+
# Setting this variable when ZSH_THEME=random will cause zsh to load
|
15
|
+
# a theme from this variable instead of looking in $ZSH/themes/
|
16
|
+
# If set to an empty array, this variable will have no effect.
|
17
|
+
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
|
18
|
+
|
19
|
+
# Uncomment the following line to use case-sensitive completion.
|
20
|
+
# CASE_SENSITIVE="true"
|
21
|
+
|
22
|
+
# Uncomment the following line to use hyphen-insensitive completion.
|
23
|
+
# Case-sensitive completion must be off. _ and - will be interchangeable.
|
24
|
+
# HYPHEN_INSENSITIVE="true"
|
25
|
+
|
26
|
+
# Uncomment one of the following lines to change the auto-update behavior
|
27
|
+
# zstyle ':omz:update' mode disabled # disable automatic updates
|
28
|
+
# zstyle ':omz:update' mode auto # update automatically without asking
|
29
|
+
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
|
30
|
+
|
31
|
+
# Uncomment the following line to change how often to auto-update (in days).
|
32
|
+
# zstyle ':omz:update' frequency 13
|
33
|
+
|
34
|
+
# Uncomment the following line if pasting URLs and other text is messed up.
|
35
|
+
# DISABLE_MAGIC_FUNCTIONS="true"
|
36
|
+
|
37
|
+
# Uncomment the following line to disable colors in ls.
|
38
|
+
# DISABLE_LS_COLORS="true"
|
39
|
+
|
40
|
+
# Uncomment the following line to disable auto-setting terminal title.
|
41
|
+
# DISABLE_AUTO_TITLE="true"
|
42
|
+
|
43
|
+
# Uncomment the following line to enable command auto-correction.
|
44
|
+
# ENABLE_CORRECTION="true"
|
45
|
+
|
46
|
+
# Uncomment the following line to display red dots whilst waiting for completion.
|
47
|
+
# You can also set it to another string to have that shown instead of the default red dots.
|
48
|
+
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
|
49
|
+
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
|
50
|
+
# COMPLETION_WAITING_DOTS="true"
|
51
|
+
|
52
|
+
# Uncomment the following line if you want to disable marking untracked files
|
53
|
+
# under VCS as dirty. This makes repository status check for large repositories
|
54
|
+
# much, much faster.
|
55
|
+
# DISABLE_UNTRACKED_FILES_DIRTY="true"
|
56
|
+
|
57
|
+
# Uncomment the following line if you want to change the command execution time
|
58
|
+
# stamp shown in the history command output.
|
59
|
+
# You can set one of the optional three formats:
|
60
|
+
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
|
61
|
+
# or set a custom format using the strftime function format specifications,
|
62
|
+
# see 'man strftime' for details.
|
63
|
+
# HIST_STAMPS="mm/dd/yyyy"
|
64
|
+
|
65
|
+
# Would you like to use another custom folder than $ZSH/custom?
|
66
|
+
# ZSH_CUSTOM=/path/to/new-custom-folder
|
67
|
+
|
68
|
+
# Which plugins would you like to load?
|
69
|
+
# Standard plugins can be found in $ZSH/plugins/
|
70
|
+
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
|
71
|
+
# Example format: plugins=(rails git textmate ruby lighthouse)
|
72
|
+
# Add wisely, as too many plugins slow down shell startup.
|
73
|
+
plugins=(
|
74
|
+
git
|
75
|
+
kubectl
|
76
|
+
)
|
77
|
+
|
78
|
+
source $ZSH/oh-my-zsh.sh
|
79
|
+
|
80
|
+
# User configuration
|
81
|
+
|
82
|
+
# export MANPATH="/usr/local/man:$MANPATH"
|
83
|
+
|
84
|
+
# You may need to manually set your language environment
|
85
|
+
# export LANG=en_US.UTF-8
|
86
|
+
|
87
|
+
# Preferred editor for local and remote sessions
|
88
|
+
# if [[ -n $SSH_CONNECTION ]]; then
|
89
|
+
# export EDITOR='vim'
|
90
|
+
# else
|
91
|
+
# export EDITOR='mvim'
|
92
|
+
# fi
|
93
|
+
|
94
|
+
# Compilation flags
|
95
|
+
# export ARCHFLAGS="-arch x86_64"
|
96
|
+
|
97
|
+
# Set personal aliases, overriding those provided by oh-my-zsh libs,
|
98
|
+
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
|
99
|
+
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
|
100
|
+
# For a full list of active aliases, run `alias`.
|
101
|
+
#
|
102
|
+
# Example aliases
|
103
|
+
# alias zshconfig="mate ~/.zshrc"
|
104
|
+
# alias ohmyzsh="mate ~/.oh-my-zsh"
|
105
|
+
|
106
|
+
source "$HOME/.local/share/zinit/zinit.git/zinit.zsh"
|
107
|
+
autoload -Uz _zinit
|
108
|
+
(( ${+_comps} )) && _comps[zinit]=_zinit
|
109
|
+
|
110
|
+
# Load a few important annexes, without Turbo
|
111
|
+
# (this is currently required for annexes)
|
112
|
+
zinit light-mode for \
|
113
|
+
zdharma-continuum/zinit-annex-as-monitor \
|
114
|
+
zdharma-continuum/zinit-annex-bin-gem-node \
|
115
|
+
zdharma-continuum/zinit-annex-patch-dl \
|
116
|
+
zdharma-continuum/zinit-annex-rust
|
117
|
+
### End of Zinit's installer chunk
|
118
|
+
|
119
|
+
# Plugin history-search-multi-word loaded with investigating.
|
120
|
+
zinit load zdharma-continuum/history-search-multi-word
|
121
|
+
|
122
|
+
# Two regular plugins loaded without investigating.
|
123
|
+
zinit light zsh-users/zsh-autosuggestions
|
124
|
+
zinit light zdharma-continuum/fast-syntax-highlighting
|
125
|
+
|
126
|
+
zinit light jonmosco/kube-ps1
|
127
|
+
KUBE_PS1_SYMBOL_ENABLE=false
|
128
|
+
KUBE_PS1_PREFIX=''
|
129
|
+
KUBE_PS1_SUFFIX=' '
|
130
|
+
KUBE_PS1_CTX_COLOR=cyan
|
131
|
+
PROMPT='$(kube_ps1)'$PROMPT
|
132
|
+
|
133
|
+
export COLORTERM=truecolor
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from zrb.context.any_context import AnyContext
|
2
|
+
|
3
|
+
|
4
|
+
def get_install_zsh_cmd(ctx: AnyContext) -> str:
|
5
|
+
package_manager: str = ctx.input["package-manager"]
|
6
|
+
if package_manager == "pacman":
|
7
|
+
cmd = f"{package_manager} -S zsh"
|
8
|
+
else:
|
9
|
+
cmd = f"{package_manager} install zsh"
|
10
|
+
use_sudo: bool = ctx.input["use-sudo"]
|
11
|
+
if use_sudo:
|
12
|
+
return f"sudo {cmd}"
|
13
|
+
return cmd
|
zrb/config.py
CHANGED
@@ -47,7 +47,6 @@ INIT_SCRIPTS = (
|
|
47
47
|
)
|
48
48
|
LOGGING_LEVEL = _get_log_level(os.getenv("ZRB_LOGGING_LEVEL", "WARNING"))
|
49
49
|
LOAD_BUILTIN = to_boolean(os.getenv("ZRB_LOAD_BUILTIN", "1"))
|
50
|
-
SHOW_TIME = to_boolean(os.getenv("ZRB_SHOW_TIME", "1"))
|
51
50
|
WARN_UNRECOMMENDED_COMMAND = to_boolean(
|
52
51
|
os.getenv("ZRB_WARN_UNRECOMMENDED_COMMAND", "1")
|
53
52
|
)
|
zrb/context/any_context.py
CHANGED
@@ -43,6 +43,7 @@ class AnyContext(AnySharedContext):
|
|
43
43
|
end: str | None = "\n",
|
44
44
|
file: TextIO | None = sys.stderr,
|
45
45
|
flush: bool = True,
|
46
|
+
plain: bool = False,
|
46
47
|
):
|
47
48
|
"""Prints values to the specified output stream.
|
48
49
|
|
@@ -52,6 +53,7 @@ class AnyContext(AnySharedContext):
|
|
52
53
|
end (str, optional): String appended after the last value. Defaults to a newline.
|
53
54
|
file (TextIO, optional): The output stream to print to. Defaults to sys.stderr.
|
54
55
|
flush (bool, optional): Whether to flush the output stream. Defaults to True.
|
56
|
+
plain (bool, optional): Whether to use plain text. Defaults to False.
|
55
57
|
"""
|
56
58
|
pass
|
57
59
|
|
zrb/context/context.py
CHANGED
@@ -3,7 +3,6 @@ import logging
|
|
3
3
|
import sys
|
4
4
|
from typing import Any, TextIO
|
5
5
|
|
6
|
-
from zrb.config import SHOW_TIME
|
7
6
|
from zrb.context.any_context import AnyContext
|
8
7
|
from zrb.context.any_shared_context import AnySharedContext
|
9
8
|
from zrb.dot_dict.dot_dict import DotDict
|
@@ -101,7 +100,13 @@ class Context(AnyContext):
|
|
101
100
|
end: str | None = "\n",
|
102
101
|
file: TextIO | None = sys.stderr,
|
103
102
|
flush: bool = True,
|
103
|
+
plain: bool = False,
|
104
104
|
):
|
105
|
+
message = sep.join([f"{value}" for value in values])
|
106
|
+
if plain:
|
107
|
+
self.append_to_shared_log(remove_style(message))
|
108
|
+
print(message, sep=sep, end=end, file=file, flush=flush)
|
109
|
+
return
|
105
110
|
color = self._color
|
106
111
|
icon = self._icon
|
107
112
|
max_name_length = max(len(name) + len(icon) for name in self.session.task_names)
|
@@ -112,11 +117,8 @@ class Context(AnyContext):
|
|
112
117
|
else:
|
113
118
|
attempt_status = f"{self._attempt}/{self._max_attempt}".ljust(5)
|
114
119
|
now = datetime.datetime.now()
|
115
|
-
formatted_time = (
|
116
|
-
now.strftime("%y%m%d %H:%M:%S.%f")[:19] + " " if SHOW_TIME else ""
|
117
|
-
)
|
120
|
+
formatted_time = now.strftime("%y%m%d %H:%M:%S.%f")[:19] + " "
|
118
121
|
prefix = f"{formatted_time}{attempt_status} {padded_styled_task_name} ⬤ "
|
119
|
-
message = sep.join([f"{value}" for value in values])
|
120
122
|
self.append_to_shared_log(remove_style(f"{prefix} {message}"))
|
121
123
|
stylized_prefix = stylize(prefix, color=color)
|
122
124
|
print(f"{stylized_prefix} {message}", sep=sep, end=end, file=file, flush=flush)
|
@@ -65,14 +65,18 @@ const CURRENT_SESSION = {
|
|
65
65
|
showCurrentSession(allTaskStatus, finished) {
|
66
66
|
const taskNames = Object.keys(allTaskStatus);
|
67
67
|
const now = Date.now();
|
68
|
+
const barHeight = 30;
|
69
|
+
const gap = 40;
|
68
70
|
|
69
71
|
// Set up canvas context
|
70
72
|
const canvas = document.getElementById("history-canvas");
|
71
|
-
canvas.height = taskNames.length *
|
73
|
+
canvas.height = taskNames.length * (barHeight + gap) + 10;
|
72
74
|
const ctx = canvas.getContext("2d");
|
73
75
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
74
76
|
ctx.fillStyle = "#EEE";
|
75
77
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
78
|
+
ctx.textBaseline = "top";
|
79
|
+
ctx.imageSmoothingEnabled = true;
|
76
80
|
|
77
81
|
// Calculate start and end times
|
78
82
|
let minDateTime = null;
|
@@ -102,8 +106,6 @@ const CURRENT_SESSION = {
|
|
102
106
|
}
|
103
107
|
// Canvas settings
|
104
108
|
const chartWidth = canvas.width;
|
105
|
-
const barHeight = 20;
|
106
|
-
const gap = 10;
|
107
109
|
const timeScale = (chartWidth - 200) / (maxDateTime - minDateTime);
|
108
110
|
|
109
111
|
// Draw labels and bars
|
@@ -118,13 +120,13 @@ const CURRENT_SESSION = {
|
|
118
120
|
const endDateTime = this.getTaskEndDateTime(allTaskStatus[taskName], now);
|
119
121
|
const startX = 100 + (startDateTime - minDateTime) * timeScale;
|
120
122
|
const barWidth = (endDateTime - startDateTime) * timeScale;
|
121
|
-
const startY = index * (barHeight + gap
|
123
|
+
const startY = index * (barHeight + gap) + 5;
|
122
124
|
|
123
125
|
// Draw task label
|
124
126
|
ctx.fillStyle = "#000";
|
125
|
-
ctx.font = "
|
127
|
+
ctx.font = "10px Arial";
|
126
128
|
ctx.textAlign = "right";
|
127
|
-
ctx.fillText(taskName, 90, startY + barHeight
|
129
|
+
ctx.fillText(taskName, 90, startY + barHeight - 0.5 * barHeight);
|
128
130
|
|
129
131
|
// Draw task bar
|
130
132
|
ctx.fillStyle = UTIL.getFinalColor(finalStatus);
|
@@ -145,14 +147,19 @@ const CURRENT_SESSION = {
|
|
145
147
|
}
|
146
148
|
}
|
147
149
|
// Draw start and end time below the bar
|
148
|
-
|
150
|
+
let sortedStartX = Object.keys(labels).sort((a, b) => a - b);
|
151
|
+
let offsetY = 0;
|
152
|
+
for (let statusStartX of sortedStartX) {
|
149
153
|
const {dateTime, caption} = labels[statusStartX];
|
150
|
-
const
|
154
|
+
const timeStr = dateTime.toISOString().split("T")[1].split(".")[0];
|
151
155
|
ctx.font = "10px Arial";
|
152
|
-
ctx.fillText(caption, statusStartX, startY +
|
153
|
-
ctx.font = "
|
154
|
-
ctx.fillText(
|
155
|
-
|
156
|
+
ctx.fillText(caption, statusStartX, startY + offsetY);
|
157
|
+
ctx.font = "10px Arial";
|
158
|
+
ctx.fillText(timeStr, statusStartX, startY + barHeight + offsetY);
|
159
|
+
offsetY += 10
|
160
|
+
if (offsetY >= barHeight) {
|
161
|
+
offsetY = 0;
|
162
|
+
}
|
156
163
|
}
|
157
164
|
});
|
158
165
|
},
|
zrb/task/cmd_task.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
from functools import partial
|
2
3
|
|
3
4
|
from zrb.attr.type import BoolAttr, IntAttr, StrAttr
|
4
5
|
from zrb.cmd.cmd_result import CmdResult
|
@@ -12,6 +13,7 @@ from zrb.task.base_task import BaseTask
|
|
12
13
|
from zrb.util.attr import get_int_attr, get_str_attr
|
13
14
|
from zrb.util.cmd.command import check_unrecommended_commands, run_command
|
14
15
|
from zrb.util.cmd.remote import get_remote_cmd_script
|
16
|
+
from zrb.xcom.xcom import Xcom
|
15
17
|
|
16
18
|
|
17
19
|
class CmdTask(BaseTask):
|
@@ -42,6 +44,7 @@ class CmdTask(BaseTask):
|
|
42
44
|
render_cmd: bool = True,
|
43
45
|
cwd: str | None = None,
|
44
46
|
render_cwd: bool = True,
|
47
|
+
plain_print: bool = False,
|
45
48
|
warn_unrecommended_command: bool | None = None,
|
46
49
|
max_output_line: int = 1000,
|
47
50
|
max_error_line: int = 1000,
|
@@ -99,6 +102,7 @@ class CmdTask(BaseTask):
|
|
99
102
|
self._render_cwd = render_cwd
|
100
103
|
self._max_output_line = max_output_line
|
101
104
|
self._max_error_line = max_error_line
|
105
|
+
self._should_plain_print = plain_print
|
102
106
|
self._should_warn_unrecommended_command = warn_unrecommended_command
|
103
107
|
|
104
108
|
async def _exec_action(self, ctx: AnyContext) -> CmdResult:
|
@@ -122,11 +126,17 @@ class CmdTask(BaseTask):
|
|
122
126
|
if self._get_should_warn_unrecommended_commands():
|
123
127
|
self._check_unrecommended_commands(ctx, shell, cmd_script)
|
124
128
|
ctx.log_info("Running script")
|
129
|
+
print_method = (
|
130
|
+
partial(ctx.print, plain=True) if self._should_plain_print else ctx.print
|
131
|
+
)
|
132
|
+
xcom_pid_key = f"{self.name}-pid"
|
133
|
+
ctx.xcom[xcom_pid_key] = Xcom([])
|
125
134
|
cmd_result, return_code = await run_command(
|
126
135
|
cmd=[shell, shell_flag, cmd_script],
|
127
136
|
cwd=cwd,
|
128
137
|
env_map=env_map,
|
129
|
-
|
138
|
+
print_method=print_method,
|
139
|
+
register_pid_method=lambda pid: ctx.xcom.get(xcom_pid_key).push(pid),
|
130
140
|
max_output_line=self._max_output_line,
|
131
141
|
max_error_line=self._max_error_line,
|
132
142
|
)
|
zrb/task/rsync_task.py
CHANGED
@@ -22,7 +22,7 @@ class RsyncTask(CmdTask):
|
|
22
22
|
shell: StrAttr | None = None,
|
23
23
|
auto_render_shell: bool = True,
|
24
24
|
remote_host: StrAttr | None = None,
|
25
|
-
|
25
|
+
render_remote_host: bool = True,
|
26
26
|
remote_port: IntAttr | None = None,
|
27
27
|
render_remote_port: bool = True,
|
28
28
|
remote_user: StrAttr | None = None,
|
@@ -40,7 +40,8 @@ class RsyncTask(CmdTask):
|
|
40
40
|
local_destination_path: StrAttr | None = None,
|
41
41
|
render_local_destination_path: bool = True,
|
42
42
|
cwd: str | None = None,
|
43
|
-
|
43
|
+
render_cwd: bool = True,
|
44
|
+
plain_print: bool = False,
|
44
45
|
max_output_line: int = 1000,
|
45
46
|
max_error_line: int = 1000,
|
46
47
|
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
@@ -62,7 +63,7 @@ class RsyncTask(CmdTask):
|
|
62
63
|
shell=shell,
|
63
64
|
render_shell=auto_render_shell,
|
64
65
|
remote_host=remote_host,
|
65
|
-
render_remote_host=
|
66
|
+
render_remote_host=render_remote_host,
|
66
67
|
remote_port=remote_port,
|
67
68
|
auto_render_remote_port=render_remote_port,
|
68
69
|
remote_user=remote_user,
|
@@ -72,7 +73,8 @@ class RsyncTask(CmdTask):
|
|
72
73
|
remote_ssh_key=remote_ssh_key,
|
73
74
|
render_remote_ssh_key=render_remote_ssh_key,
|
74
75
|
cwd=cwd,
|
75
|
-
render_cwd=
|
76
|
+
render_cwd=render_cwd,
|
77
|
+
plain_print=plain_print,
|
76
78
|
max_output_line=max_output_line,
|
77
79
|
max_error_line=max_error_line,
|
78
80
|
execute_condition=execute_condition,
|
zrb/util/cmd/command.py
CHANGED
@@ -1,11 +1,27 @@
|
|
1
1
|
import asyncio
|
2
2
|
import os
|
3
3
|
import re
|
4
|
+
import signal
|
4
5
|
import sys
|
5
6
|
from collections.abc import Callable
|
6
7
|
|
7
8
|
from zrb.cmd.cmd_result import CmdResult
|
8
9
|
|
10
|
+
_RUNNING_PROCESSES = []
|
11
|
+
|
12
|
+
|
13
|
+
def _cleanup_processes():
|
14
|
+
"""Terminate all running subprocesses on exit."""
|
15
|
+
for process in _RUNNING_PROCESSES:
|
16
|
+
if process.returncode is None:
|
17
|
+
process.terminate()
|
18
|
+
process.kill()
|
19
|
+
|
20
|
+
|
21
|
+
# Register a single cleanup function once
|
22
|
+
signal.signal(signal.SIGINT, lambda sig, frame: _cleanup_processes())
|
23
|
+
signal.signal(signal.SIGTERM, lambda sig, frame: _cleanup_processes())
|
24
|
+
|
9
25
|
|
10
26
|
def check_unrecommended_commands(cmd_script: str) -> dict[str, str]:
|
11
27
|
banned_commands = {
|
@@ -43,12 +59,13 @@ async def run_command(
|
|
43
59
|
cmd: list[str],
|
44
60
|
cwd: str | None = None,
|
45
61
|
env_map: dict[str, str] | None = None,
|
46
|
-
|
62
|
+
print_method: Callable[..., None] | None = None,
|
63
|
+
register_pid_method: Callable[[int], None] | None = None,
|
47
64
|
max_output_line: int = 1000,
|
48
65
|
max_error_line: int = 1000,
|
49
66
|
) -> tuple[CmdResult, int]:
|
50
67
|
async def __read_stream(
|
51
|
-
stream,
|
68
|
+
stream, print_method: Callable[..., None], max_lines: int
|
52
69
|
) -> str:
|
53
70
|
lines = []
|
54
71
|
while True:
|
@@ -59,9 +76,10 @@ async def run_command(
|
|
59
76
|
lines.append(line)
|
60
77
|
if len(lines) > max_lines:
|
61
78
|
lines.pop(0) # Keep only the last max_lines
|
62
|
-
|
79
|
+
print_method(line)
|
63
80
|
return "\n".join(lines)
|
64
81
|
|
82
|
+
actual_print_method = print_method if print_method is not None else print
|
65
83
|
cmd_process = None
|
66
84
|
try:
|
67
85
|
if cwd is None:
|
@@ -77,11 +95,13 @@ async def run_command(
|
|
77
95
|
env=env_map,
|
78
96
|
bufsize=0,
|
79
97
|
)
|
98
|
+
if register_pid_method is not None:
|
99
|
+
register_pid_method(cmd_process.pid)
|
80
100
|
stdout_task = asyncio.create_task(
|
81
|
-
__read_stream(cmd_process.stdout,
|
101
|
+
__read_stream(cmd_process.stdout, actual_print_method, max_output_line)
|
82
102
|
)
|
83
103
|
stderr_task = asyncio.create_task(
|
84
|
-
__read_stream(cmd_process.stderr,
|
104
|
+
__read_stream(cmd_process.stderr, actual_print_method, max_error_line)
|
85
105
|
)
|
86
106
|
# Wait for process to complete and gather stdout/stderr
|
87
107
|
return_code = await cmd_process.wait()
|
@@ -89,5 +109,7 @@ async def run_command(
|
|
89
109
|
stderr = await stderr_task
|
90
110
|
return CmdResult(stdout, stderr), return_code
|
91
111
|
finally:
|
112
|
+
if cmd_process in _RUNNING_PROCESSES:
|
113
|
+
_RUNNING_PROCESSES.remove(cmd_process)
|
92
114
|
if cmd_process is not None and cmd_process.returncode is None:
|
93
115
|
cmd_process.terminate()
|
zrb/util/git.py
CHANGED
@@ -17,12 +17,12 @@ async def get_diff(
|
|
17
17
|
repo_dir: str,
|
18
18
|
source_commit: str,
|
19
19
|
current_commit: str,
|
20
|
-
|
20
|
+
print_method: Callable[..., Any] = print,
|
21
21
|
) -> DiffResult:
|
22
22
|
cmd_result, exit_code = await run_command(
|
23
23
|
cmd=["git", "diff", source_commit, current_commit],
|
24
24
|
cwd=repo_dir,
|
25
|
-
|
25
|
+
print_method=print_method,
|
26
26
|
)
|
27
27
|
if exit_code != 0:
|
28
28
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -54,10 +54,10 @@ async def get_diff(
|
|
54
54
|
)
|
55
55
|
|
56
56
|
|
57
|
-
async def get_repo_dir(
|
57
|
+
async def get_repo_dir(print_method: Callable[..., Any] = print) -> str:
|
58
58
|
cmd_result, exit_code = await run_command(
|
59
59
|
cmd=["git", "rev-parse", "--show-toplevel"],
|
60
|
-
|
60
|
+
print_method=print_method,
|
61
61
|
)
|
62
62
|
if exit_code != 0:
|
63
63
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -65,12 +65,12 @@ async def get_repo_dir(log_method: Callable[..., Any] = print) -> str:
|
|
65
65
|
|
66
66
|
|
67
67
|
async def get_current_branch(
|
68
|
-
repo_dir: str,
|
68
|
+
repo_dir: str, print_method: Callable[..., Any] = print
|
69
69
|
) -> str:
|
70
70
|
cmd_result, exit_code = await run_command(
|
71
71
|
cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
72
72
|
cwd=repo_dir,
|
73
|
-
|
73
|
+
print_method=print_method,
|
74
74
|
)
|
75
75
|
if exit_code != 0:
|
76
76
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -78,12 +78,12 @@ async def get_current_branch(
|
|
78
78
|
|
79
79
|
|
80
80
|
async def get_branches(
|
81
|
-
repo_dir: str,
|
81
|
+
repo_dir: str, print_method: Callable[..., Any] = print
|
82
82
|
) -> list[str]:
|
83
83
|
cmd_result, exit_code = await run_command(
|
84
84
|
cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
85
85
|
cwd=repo_dir,
|
86
|
-
|
86
|
+
print_method=print_method,
|
87
87
|
)
|
88
88
|
if exit_code != 0:
|
89
89
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -93,35 +93,35 @@ async def get_branches(
|
|
93
93
|
|
94
94
|
|
95
95
|
async def delete_branch(
|
96
|
-
repo_dir: str, branch_name: str,
|
96
|
+
repo_dir: str, branch_name: str, print_method: Callable[..., Any] = print
|
97
97
|
) -> str:
|
98
98
|
cmd_result, exit_code = await run_command(
|
99
99
|
cmd=["git", "branch", "-D", branch_name],
|
100
100
|
cwd=repo_dir,
|
101
|
-
|
101
|
+
print_method=print_method,
|
102
102
|
)
|
103
103
|
if exit_code != 0:
|
104
104
|
raise Exception(f"Non zero exit code: {exit_code}")
|
105
105
|
return cmd_result.output.strip()
|
106
106
|
|
107
107
|
|
108
|
-
async def add(repo_dir: str,
|
108
|
+
async def add(repo_dir: str, print_method: Callable[..., Any] = print):
|
109
109
|
_, exit_code = await run_command(
|
110
110
|
cmd=["git", "add", ".", "-A"],
|
111
111
|
cwd=repo_dir,
|
112
|
-
|
112
|
+
print_method=print_method,
|
113
113
|
)
|
114
114
|
if exit_code != 0:
|
115
115
|
raise Exception(f"Non zero exit code: {exit_code}")
|
116
116
|
|
117
117
|
|
118
118
|
async def commit(
|
119
|
-
repo_dir: str, message: str,
|
119
|
+
repo_dir: str, message: str, print_method: Callable[..., Any] = print
|
120
120
|
) -> str:
|
121
121
|
cmd_result, exit_code = await run_command(
|
122
122
|
cmd=["git", "commit", "-m", message],
|
123
123
|
cwd=repo_dir,
|
124
|
-
|
124
|
+
print_method=print_method,
|
125
125
|
)
|
126
126
|
if exit_code != 0:
|
127
127
|
ignored_error_message = "nothing to commit, working tree clean"
|
@@ -133,24 +133,24 @@ async def commit(
|
|
133
133
|
|
134
134
|
|
135
135
|
async def pull(
|
136
|
-
repo_dir: str, remote: str, branch: str,
|
136
|
+
repo_dir: str, remote: str, branch: str, print_method: Callable[..., Any] = print
|
137
137
|
) -> str:
|
138
138
|
_, exit_code = await run_command(
|
139
139
|
cmd=["git", "pull", remote, branch],
|
140
140
|
cwd=repo_dir,
|
141
|
-
|
141
|
+
print_method=print_method,
|
142
142
|
)
|
143
143
|
if exit_code != 0:
|
144
144
|
raise Exception(f"Non zero exit code: {exit_code}")
|
145
145
|
|
146
146
|
|
147
147
|
async def push(
|
148
|
-
repo_dir: str, remote: str, branch: str,
|
148
|
+
repo_dir: str, remote: str, branch: str, print_method: Callable[..., Any] = print
|
149
149
|
) -> str:
|
150
150
|
_, exit_code = await run_command(
|
151
151
|
cmd=["git", "push", "-u", remote, branch],
|
152
152
|
cwd=repo_dir,
|
153
|
-
|
153
|
+
print_method=print_method,
|
154
154
|
)
|
155
155
|
if exit_code != 0:
|
156
156
|
raise Exception(f"Non zero exit code: {exit_code}")
|
zrb/util/git_subtree.py
CHANGED
@@ -36,7 +36,7 @@ async def add_subtree(
|
|
36
36
|
repo_url: str,
|
37
37
|
branch: str,
|
38
38
|
prefix: str,
|
39
|
-
|
39
|
+
print_method: Callable[..., Any] = print,
|
40
40
|
):
|
41
41
|
config = load_config()
|
42
42
|
if os.path.isdir(prefix):
|
@@ -54,7 +54,7 @@ async def add_subtree(
|
|
54
54
|
branch,
|
55
55
|
],
|
56
56
|
cwd=repo_dir,
|
57
|
-
|
57
|
+
print_method=print_method,
|
58
58
|
)
|
59
59
|
if exit_code != 0:
|
60
60
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -69,7 +69,7 @@ async def pull_subtree(
|
|
69
69
|
prefix: str,
|
70
70
|
repo_url: str,
|
71
71
|
branch: str,
|
72
|
-
|
72
|
+
print_method: Callable[..., Any] = print,
|
73
73
|
):
|
74
74
|
_, exit_code = await run_command(
|
75
75
|
cmd=[
|
@@ -82,7 +82,7 @@ async def pull_subtree(
|
|
82
82
|
branch,
|
83
83
|
],
|
84
84
|
cwd=repo_dir,
|
85
|
-
|
85
|
+
print_method=print_method,
|
86
86
|
)
|
87
87
|
if exit_code != 0:
|
88
88
|
raise Exception(f"Non zero exit code: {exit_code}")
|
@@ -93,7 +93,7 @@ async def push_subtree(
|
|
93
93
|
prefix: str,
|
94
94
|
repo_url: str,
|
95
95
|
branch: str,
|
96
|
-
|
96
|
+
print_method: Callable[..., Any] = print,
|
97
97
|
):
|
98
98
|
_, exit_code = await run_command(
|
99
99
|
cmd=[
|
@@ -106,7 +106,7 @@ async def push_subtree(
|
|
106
106
|
branch,
|
107
107
|
],
|
108
108
|
cwd=repo_dir,
|
109
|
-
|
109
|
+
print_method=print_method,
|
110
110
|
)
|
111
111
|
if exit_code != 0:
|
112
112
|
raise Exception(f"Non zero exit code: {exit_code}")
|