zrb 1.0.0b6__py3-none-any.whl → 1.0.0b7__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.
Files changed (26) hide show
  1. zrb/builtin/__init__.py +2 -0
  2. zrb/builtin/project/add/fastapp/fastapp_task.py +3 -3
  3. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_task.py +80 -1
  4. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +3 -3
  5. 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
  6. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +3 -3
  7. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +11 -13
  8. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +20 -18
  9. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +24 -14
  10. zrb/builtin/setup/tmux/tmux.py +1 -1
  11. zrb/builtin/setup/zsh/zsh.py +55 -0
  12. zrb/builtin/setup/zsh/zsh_config.sh +133 -0
  13. zrb/builtin/setup/zsh/zsh_helper.py +13 -0
  14. zrb/config.py +0 -1
  15. zrb/context/any_context.py +2 -0
  16. zrb/context/context.py +7 -5
  17. zrb/runner/web_route/static/resources/session/current-session.js +19 -12
  18. zrb/task/cmd_task.py +11 -1
  19. zrb/task/rsync_task.py +6 -4
  20. zrb/util/cmd/command.py +25 -3
  21. zrb/util/git.py +9 -9
  22. zrb/util/git_subtree.py +3 -3
  23. {zrb-1.0.0b6.dist-info → zrb-1.0.0b7.dist-info}/METADATA +1 -1
  24. {zrb-1.0.0b6.dist-info → zrb-1.0.0b7.dist-info}/RECORD +26 -23
  25. {zrb-1.0.0b6.dist-info → zrb-1.0.0b7.dist-info}/WHEEL +0 -0
  26. {zrb-1.0.0b6.dist-info → zrb-1.0.0b7.dist-info}/entry_points.txt +0 -0
zrb/builtin/__init__.py CHANGED
@@ -17,6 +17,7 @@ from zrb.builtin.setup.asdf.asdf import setup_asdf
17
17
  from zrb.builtin.setup.latex.ubuntu import setup_latex_on_ubuntu
18
18
  from zrb.builtin.setup.tmux.tmux import setup_tmux
19
19
  from zrb.builtin.setup.ubuntu import setup_ubuntu
20
+ from zrb.builtin.setup.zsh.zsh import setup_zsh
20
21
  from zrb.builtin.shell.autocomplete.bash import make_bash_autocomplete
21
22
  from zrb.builtin.shell.autocomplete.subcmd import get_shell_subcommands
22
23
  from zrb.builtin.shell.autocomplete.zsh import make_zsh_autocomplete
@@ -62,3 +63,4 @@ assert setup_ubuntu
62
63
  assert setup_latex_on_ubuntu
63
64
  assert setup_asdf
64
65
  assert setup_tmux
66
+ assert setup_zsh
@@ -20,11 +20,11 @@ from zrb.util.string.name import get_random_name
20
20
 
21
21
 
22
22
  @make_task(
23
- name="validate-create-fastapp",
23
+ name="validate-add-fastapp",
24
24
  input=[project_dir_input, app_name_input],
25
25
  retries=0,
26
26
  )
27
- async def validate_create_fastapp(ctx: AnyContext):
27
+ async def validate_add_fastapp(ctx: AnyContext):
28
28
  project_dir = ctx.input.project_dir
29
29
  if not os.path.isdir(project_dir):
30
30
  raise ValueError(f"Project directory not exists: {project_dir}")
@@ -39,7 +39,7 @@ scaffold_fastapp = Scaffolder(
39
39
  project_dir_input,
40
40
  app_name_input,
41
41
  ],
42
- upstream=validate_create_fastapp,
42
+ upstream=validate_add_fastapp,
43
43
  source_path=os.path.join(os.path.dirname(__file__), "fastapp_template"),
44
44
  render_source_path=False,
45
45
  destination_path="{ctx.input.project_dir}",
@@ -1,14 +1,93 @@
1
+ import os
2
+
3
+ from my_app_name._zrb.config import APP_DIR
1
4
  from my_app_name._zrb.format_task import format_my_app_name_code
2
5
  from my_app_name._zrb.group import app_create_group
6
+ from my_app_name._zrb.input import (
7
+ existing_entity_input,
8
+ new_column_input,
9
+ new_column_type_input,
10
+ )
11
+ from my_app_name._zrb.util import get_existing_schema_names
12
+
13
+ from zrb import AnyContext, Task, make_task
14
+ from zrb.util.codemod.prepend_property_to_class import prepend_property_to_class
15
+ from zrb.util.file import read_file, write_file
16
+ from zrb.util.string.conversion import to_pascal_case, to_snake_case
17
+
18
+
19
+ @make_task(
20
+ name="validate-add-my-app-name-column",
21
+ input=existing_entity_input,
22
+ retries=0,
23
+ )
24
+ async def validate_add_my_app_name_column(ctx: AnyContext):
25
+ schema_name = ctx.input.entity
26
+ if schema_name not in get_existing_schema_names():
27
+ raise ValueError(f"Schema not exist: {schema_name}")
28
+
29
+
30
+ @make_task(
31
+ name="update-my-app-name-schema",
32
+ input=[
33
+ existing_entity_input,
34
+ new_column_input,
35
+ new_column_type_input,
36
+ ],
37
+ retries=0,
38
+ upstream=validate_add_my_app_name_column,
39
+ )
40
+ def update_my_app_name_schema(ctx: AnyContext):
41
+ snake_entity_name = to_snake_case(ctx.input.entity)
42
+ pascal_entity_name = to_pascal_case(ctx.input.entity)
43
+ schema_file_path = os.path.join(APP_DIR, "schema", f"{snake_entity_name}.py")
44
+ existing_code = read_file(schema_file_path)
45
+ snake_column_name = to_snake_case(ctx.input.column)
46
+ column_type = ctx.input.type
47
+ # Base
48
+ new_code = prepend_property_to_class(
49
+ original_code=existing_code,
50
+ class_name=f"{pascal_entity_name}Base",
51
+ property_name=snake_column_name,
52
+ annotation=column_type,
53
+ default_value=_get_default_value(column_type),
54
+ )
55
+ # Update
56
+ new_code = prepend_property_to_class(
57
+ original_code=new_code,
58
+ class_name=f"{pascal_entity_name}Update",
59
+ property_name=snake_column_name,
60
+ annotation=f"{column_type} | None",
61
+ default_value="None",
62
+ )
63
+ # Table
64
+ new_code = prepend_property_to_class(
65
+ original_code=new_code,
66
+ class_name=f"{pascal_entity_name}",
67
+ property_name=snake_column_name,
68
+ annotation=f"{column_type} | None",
69
+ default_value="Field(index=False)",
70
+ )
71
+ write_file(schema_file_path, new_code)
3
72
 
4
- from zrb import Task
5
73
 
6
74
  add_my_app_name_column = app_create_group.add_task(
7
75
  Task(
8
76
  name="add-my-app-name-column",
9
77
  description="📊 Create new column on an entity",
78
+ upstream=update_my_app_name_schema,
10
79
  successor=format_my_app_name_code,
11
80
  retries=0,
12
81
  ),
13
82
  alias="column",
14
83
  )
84
+
85
+
86
+ def _get_default_value(data_type: str) -> str:
87
+ if data_type == "str":
88
+ return '""'
89
+ if data_type in ("int", "float"):
90
+ return "0"
91
+ if data_type == "bool":
92
+ return "True"
93
+ return "None"
@@ -48,7 +48,7 @@ from zrb.util.string.conversion import to_snake_case
48
48
 
49
49
 
50
50
  @make_task(
51
- name="validate-create-my-app-name-entity",
51
+ name="validate-add-my-app-name-entity",
52
52
  input=[
53
53
  existing_module_input,
54
54
  new_entity_input,
@@ -57,7 +57,7 @@ from zrb.util.string.conversion import to_snake_case
57
57
  ],
58
58
  retries=0,
59
59
  )
60
- async def validate_create_my_app_name_entity(ctx: AnyContext):
60
+ async def validate_add_my_app_name_entity(ctx: AnyContext):
61
61
  module_name = to_snake_case(ctx.input.module)
62
62
  if module_name not in get_existing_module_names():
63
63
  raise ValueError(f"Module not exist: {module_name}")
@@ -147,7 +147,7 @@ scaffold_my_app_name_entity = Scaffolder(
147
147
  ),
148
148
  ],
149
149
  retries=0,
150
- upstream=validate_create_my_app_name_entity,
150
+ upstream=validate_add_my_app_name_entity,
151
151
  )
152
152
 
153
153
  create_my_app_name_entity_migration = CmdTask(
@@ -72,10 +72,8 @@ class MyEntityService(BaseService):
72
72
  async def update_my_entity_bulk(
73
73
  self, my_entity_ids: list[str], data: MyEntityUpdateWithAudit
74
74
  ) -> MyEntityResponse:
75
- my_entities = await self.my_entity_repository.update_bulk(my_entity_ids, data)
76
- return await self.my_entity_repository.get_by_ids(
77
- [my_entity.id for my_entity in my_entities]
78
- )
75
+ await self.my_entity_repository.update_bulk(my_entity_ids, data)
76
+ return await self.my_entity_repository.get_by_ids(my_entity_ids)
79
77
 
80
78
  @BaseService.route(
81
79
  "/api/v1/my-entities/{my_entity_id}",
@@ -85,21 +83,20 @@ class MyEntityService(BaseService):
85
83
  async def update_my_entity(
86
84
  self, my_entity_id: str, data: MyEntityUpdateWithAudit
87
85
  ) -> MyEntityResponse:
88
- my_entity = await self.my_entity_repository.update(my_entity_id, data)
89
- return await self.my_entity_repository.get_by_id(my_entity.id)
86
+ await self.my_entity_repository.update(my_entity_id, data)
87
+ return await self.my_entity_repository.get_by_id(my_entity_id)
90
88
 
91
89
  @BaseService.route(
92
- "/api/v1/my-entities/{my_entity_id}",
90
+ "/api/v1/my-entities/bulk",
93
91
  methods=["delete"],
94
92
  response_model=MyEntityResponse,
95
93
  )
96
94
  async def delete_my_entity_bulk(
97
95
  self, my_entity_ids: list[str], deleted_by: str
98
96
  ) -> MyEntityResponse:
99
- my_entities = await self.my_entity_repository.delete_bulk(my_entity_ids)
100
- return await self.my_entity_repository.get_by_ids(
101
- [my_entity.id for my_entity in my_entities]
102
- )
97
+ my_entities = await self.my_entity_repository.get_by_ids(my_entity_ids)
98
+ await self.my_entity_repository.delete_bulk(my_entity_ids)
99
+ return my_entities
103
100
 
104
101
  @BaseService.route(
105
102
  "/api/v1/my-entities/{my_entity_id}",
@@ -109,5 +106,6 @@ class MyEntityService(BaseService):
109
106
  async def delete_my_entity(
110
107
  self, my_entity_id: str, deleted_by: str
111
108
  ) -> MyEntityResponse:
112
- my_entity = await self.my_entity_repository.delete(my_entity_id)
113
- return await self.my_entity_repository.get_by_id(my_entity.id)
109
+ my_entity = await self.my_entity_repository.get_by_id(my_entity.id)
110
+ await self.my_entity_repository.delete(my_entity_id)
111
+ return my_entity
@@ -24,11 +24,11 @@ from zrb import AnyContext, ContentTransformer, Scaffolder, Task, make_task
24
24
 
25
25
 
26
26
  @make_task(
27
- name="validate-create-my-app-name-module",
27
+ name="validate-add-my-app-name-module",
28
28
  input=new_module_input,
29
29
  retries=0,
30
30
  )
31
- async def validate_create_my_app_name_module(ctx: AnyContext):
31
+ async def validate_add_my_app_name_module(ctx: AnyContext):
32
32
  if ctx.input.module in get_existing_module_names():
33
33
  raise ValueError(f"Module already exists: {ctx.input.module}")
34
34
 
@@ -93,7 +93,7 @@ scaffold_my_app_name_module = Scaffolder(
93
93
  ),
94
94
  ],
95
95
  retries=0,
96
- upstream=validate_create_my_app_name_module,
96
+ upstream=validate_add_my_app_name_module,
97
97
  )
98
98
 
99
99
  add_my_app_name_module = app_create_group.add_task(
@@ -76,10 +76,8 @@ class PermissionService(BaseService):
76
76
  async def update_permission_bulk(
77
77
  self, permission_ids: list[str], data: PermissionUpdateWithAudit
78
78
  ) -> PermissionResponse:
79
- permissions = await self.permission_repository.update_bulk(permission_ids, data)
80
- return await self.permission_repository.get_by_ids(
81
- [permission.id for permission in permissions]
82
- )
79
+ await self.permission_repository.update_bulk(permission_ids, data)
80
+ return await self.permission_repository.get_by_ids(permission_ids)
83
81
 
84
82
  @BaseService.route(
85
83
  "/api/v1/permissions/{permission_id}",
@@ -89,21 +87,20 @@ class PermissionService(BaseService):
89
87
  async def update_permission(
90
88
  self, permission_id: str, data: PermissionUpdateWithAudit
91
89
  ) -> PermissionResponse:
92
- permission = await self.permission_repository.update(permission_id, data)
93
- return await self.permission_repository.get_by_id(permission.id)
90
+ await self.permission_repository.update(permission_id, data)
91
+ return await self.permission_repository.get_by_id(permission_id)
94
92
 
95
93
  @BaseService.route(
96
- "/api/v1/permissions/{permission_id}",
94
+ "/api/v1/permissions/bulk",
97
95
  methods=["delete"],
98
96
  response_model=PermissionResponse,
99
97
  )
100
98
  async def delete_permission_bulk(
101
99
  self, permission_ids: list[str], deleted_by: str
102
100
  ) -> PermissionResponse:
103
- permissions = await self.permission_repository.delete_bulk(permission_ids)
104
- return await self.permission_repository.get_by_ids(
105
- [permission.id for permission in permissions]
106
- )
101
+ permissions = await self.permission_repository.get_by_ids(permission_ids)
102
+ await self.permission_repository.delete_bulk(permission_ids)
103
+ return permissions
107
104
 
108
105
  @BaseService.route(
109
106
  "/api/v1/permissions/{permission_id}",
@@ -113,5 +110,6 @@ class PermissionService(BaseService):
113
110
  async def delete_permission(
114
111
  self, permission_id: str, deleted_by: str
115
112
  ) -> PermissionResponse:
116
- permission = await self.permission_repository.delete(permission_id)
117
- return await self.permission_repository.get_by_id(permission.id)
113
+ permission = await self.permission_repository.get_by_id(permission_id)
114
+ await self.permission_repository.delete(permission_id)
115
+ return permission
@@ -87,17 +87,15 @@ class RoleService(BaseService):
87
87
  ) -> RoleResponse:
88
88
  permission_ids = [row.get_permission_ids() for row in data]
89
89
  data = [row.get_role_update_with_audit() for row in data]
90
- roles = await self.role_repository.update_bulk(role_ids, data)
91
- if len(roles) > 0:
92
- updated_by = roles[0].updated_by
93
- await self.role_repository.remove_all_permissions(
94
- [role.id for role in roles]
95
- )
90
+ await self.role_repository.update_bulk(role_ids, data)
91
+ if len(role_ids) > 0:
92
+ updated_by = data[0].updated_by
93
+ await self.role_repository.remove_all_permissions(role_ids)
96
94
  await self.role_repository.add_permissions(
97
- data={role.id: permission_ids[i] for i, role in enumerate(roles)},
95
+ data={role_id: permission_ids[i] for i, role_id in enumerate(role_ids)},
98
96
  created_by=updated_by,
99
97
  )
100
- return await self.role_repository.get_by_ids([role.id for role in roles])
98
+ return await self.role_repository.get_by_ids(role_ids)
101
99
 
102
100
  @BaseService.route(
103
101
  "/api/v1/roles/{role_id}",
@@ -108,24 +106,26 @@ class RoleService(BaseService):
108
106
  self, role_id: str, data: RoleUpdateWithPermissionsAndAudit
109
107
  ) -> RoleResponse:
110
108
  permission_ids = data.get_permission_ids()
111
- data = data.get_role_update_with_audit()
112
- role = await self.role_repository.update(role_id, data)
113
- await self.role_repository.remove_all_permissions([role.id])
109
+ role_data = data.get_role_update_with_audit()
110
+ await self.role_repository.update(role_id, role_data)
111
+ await self.role_repository.remove_all_permissions([role_id])
114
112
  await self.role_repository.add_permissions(
115
- data={role.id: permission_ids}, created_by=role.updated_by
113
+ data={role_id: permission_ids}, created_by=role_data.updated_by
116
114
  )
117
- return await self.role_repository.get_by_id(role.id)
115
+ return await self.role_repository.get_by_id(role_id)
118
116
 
119
117
  @BaseService.route(
120
- "/api/v1/roles/{role_id}",
118
+ "/api/v1/roles/bulk",
121
119
  methods=["delete"],
122
120
  response_model=RoleResponse,
123
121
  )
124
122
  async def delete_role_bulk(
125
123
  self, role_ids: list[str], deleted_by: str
126
124
  ) -> RoleResponse:
127
- roles = await self.role_repository.delete_bulk(role_ids)
128
- return await self.role_repository.get_by_ids([role.id for role in roles])
125
+ roles = await self.role_repository.get_by_ids(role_ids)
126
+ await self.role_repository.delete_bulk(role_ids)
127
+ await self.role_repository.remove_all_permissions(role_ids)
128
+ return roles
129
129
 
130
130
  @BaseService.route(
131
131
  "/api/v1/roles/{role_id}",
@@ -133,5 +133,7 @@ class RoleService(BaseService):
133
133
  response_model=RoleResponse,
134
134
  )
135
135
  async def delete_role(self, role_id: str, deleted_by: str) -> RoleResponse:
136
- role = await self.role_repository.delete(role_id)
137
- return await self.role_repository.get_by_id(role.id)
136
+ role = await self.role_repository.get_by_id(role_id)
137
+ await self.role_repository.delete(role_id)
138
+ await self.role_repository.remove_all_permissions([role_id])
139
+ return role
@@ -84,16 +84,16 @@ class UserService(BaseService):
84
84
  self, user_ids: list[str], data: UserUpdateWithRolesAndAudit
85
85
  ) -> UserResponse:
86
86
  role_ids = [row.get_role_ids() for row in data]
87
- data = [row.get_user_create_with_audit() for row in data]
88
- users = await self.user_repository.update_bulk(user_ids, data)
89
- if len(users) > 0:
90
- updated_by = users[0].updated_by
91
- await self.user_repository.remove_all_roles([user.id for user in users])
87
+ user_data = [row.get_user_create_with_audit() for row in data]
88
+ await self.user_repository.update_bulk(user_ids, user_data)
89
+ if len(user_ids) > 0:
90
+ updated_by = user_data[0].updated_by
91
+ await self.user_repository.remove_all_roles(user_ids)
92
92
  await self.user_repository.add_roles(
93
- data={user.id: role_ids[i] for i, user in enumerate(data)},
93
+ data={user_id: role_ids[i] for i, user_id in enumerate(user_ids)},
94
94
  updated_by=updated_by,
95
95
  )
96
- return await self.user_repository.get_by_ids([user.id for user in users])
96
+ return await self.user_repository.get_by_ids(user_ids)
97
97
 
98
98
  @BaseService.route(
99
99
  "/api/v1/users/{user_id}",
@@ -103,19 +103,27 @@ class UserService(BaseService):
103
103
  async def update_user(
104
104
  self, user_id: str, data: UserUpdateWithRolesAndAudit
105
105
  ) -> UserResponse:
106
- user = await self.user_repository.update(user_id, data)
107
- return await self.user_repository.get_by_id(user.id)
106
+ role_ids = data.get_role_ids()
107
+ user_data = data.get_user_update_with_audit()
108
+ await self.user_repository.update(user_id, user_data)
109
+ await self.user_repository.remove_all_roles([user_id])
110
+ await self.user_repository.add_roles(
111
+ data={user_id: role_ids}, created_by=user_data.updated_by
112
+ )
113
+ return await self.user_repository.get_by_id(user_id)
108
114
 
109
115
  @BaseService.route(
110
- "/api/v1/users/{user_id}",
116
+ "/api/v1/users/bulk",
111
117
  methods=["delete"],
112
118
  response_model=UserResponse,
113
119
  )
114
120
  async def delete_user_bulk(
115
121
  self, user_ids: list[str], deleted_by: str
116
122
  ) -> UserResponse:
117
- users = await self.user_repository.delete_bulk(user_ids)
118
- return await self.user_repository.get_by_ids([user.id for user in users])
123
+ roles = await self.user_repository.get_by_ids(user_ids)
124
+ await self.user_repository.delete_bulk(user_ids)
125
+ await self.user_repository.remove_all_roles(user_ids)
126
+ return roles
119
127
 
120
128
  @BaseService.route(
121
129
  "/api/v1/users/{user_id}",
@@ -123,5 +131,7 @@ class UserService(BaseService):
123
131
  response_model=UserResponse,
124
132
  )
125
133
  async def delete_user(self, user_id: str, deleted_by: str) -> UserResponse:
126
- user = await self.user_repository.delete(user_id)
127
- return await self.user_repository.get_by_id(user.id)
134
+ user = await self.user_repository.get_by_id(user_id)
135
+ await self.user_repository.delete(user_id)
136
+ await self.user_repository.remove_all_roles([user_id])
137
+ return user
@@ -24,7 +24,7 @@ install_tmux = CmdTask(
24
24
  prompt="Tmux config file",
25
25
  default_str="~/.tmux.conf",
26
26
  ),
27
- description="🖥️ Setup `tmux`.",
27
+ description="📺 Setup `tmux`.",
28
28
  group=setup_group,
29
29
  alias="tmux",
30
30
  )
@@ -0,0 +1,55 @@
1
+ import os
2
+
3
+ from zrb.builtin.group import setup_group
4
+ from zrb.builtin.setup.common_input import package_manager_input, use_sudo_input
5
+ from zrb.builtin.setup.zsh.zsh_helper import get_install_zsh_cmd
6
+ from zrb.context.any_context import AnyContext
7
+ from zrb.input.str_input import StrInput
8
+ from zrb.task.cmd_task import CmdTask
9
+ from zrb.task.make_task import make_task
10
+ from zrb.util.file import read_file, write_file
11
+
12
+ install_zsh = CmdTask(
13
+ name="install-zsh",
14
+ input=[package_manager_input, use_sudo_input],
15
+ cmd=get_install_zsh_cmd,
16
+ )
17
+
18
+ install_omz = CmdTask(
19
+ name="install-omz",
20
+ cmd='sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"', # noqa
21
+ upstream=install_zsh,
22
+ )
23
+
24
+ install_zinit = CmdTask(
25
+ name="install-zinit",
26
+ cmd='bash -c "$(curl --fail --show-error --silent --location https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"', # noqa
27
+ upstream=install_zsh,
28
+ )
29
+
30
+
31
+ @make_task(
32
+ name="setup-zsh",
33
+ input=StrInput(
34
+ name="zsh-config",
35
+ description="zsh config file",
36
+ prompt="zsh config file",
37
+ default_str="~/.zshrc",
38
+ ),
39
+ upstream=[install_omz, install_zinit],
40
+ description="💻 Setup `zsh`.",
41
+ group=setup_group,
42
+ alias="zsh",
43
+ )
44
+ def setup_zsh(ctx: AnyContext):
45
+ zsh_config = read_file(os.path.join(os.path.dirname(__file__), "zsh_config.sh"))
46
+ zsh_config_file = os.path.expanduser(ctx.input["zsh-config"])
47
+ # Make sure config file exists
48
+ if not os.path.isfile(zsh_config_file):
49
+ write_file(zsh_config_file, "")
50
+ content = read_file(zsh_config_file)
51
+ if zsh_config in content:
52
+ return
53
+ # Write config
54
+ write_file(zsh_config_file, [content, zsh_config, ""])
55
+ ctx.print("Setup complete, restart your terminal to continue")
@@ -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
  )
@@ -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 * 50 + 10;
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 + 20) + 5;
123
+ const startY = index * (barHeight + gap) + 5;
122
124
 
123
125
  // Draw task label
124
126
  ctx.fillStyle = "#000";
125
- ctx.font = "12px Arial";
127
+ ctx.font = "10px Arial";
126
128
  ctx.textAlign = "right";
127
- ctx.fillText(taskName, 90, startY + barHeight / 1.5);
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
- for (let statusStartX in labels) {
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 [dateStr, timeStr] = dateTime.toISOString().split("T");
154
+ const timeStr = dateTime.toISOString().split("T")[1].split(".")[0];
151
155
  ctx.font = "10px Arial";
152
- ctx.fillText(caption, statusStartX, startY + 10);
153
- ctx.font = "8px Arial";
154
- ctx.fillText(dateStr, statusStartX, startY + barHeight + 10);
155
- ctx.fillText(timeStr, statusStartX, startY + barHeight + 20);
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
+ log_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
- log_method=ctx.print,
138
+ print_method=log_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
- auto_render_remote_host: bool = True,
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
- auto_render_cwd: bool = True,
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=auto_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=auto_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,7 +59,8 @@ 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
- log_method: Callable[..., None] = print,
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]:
@@ -62,6 +79,7 @@ async def run_command(
62
79
  log_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, log_method, max_output_line)
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, log_method, max_error_line)
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
@@ -22,7 +22,7 @@ async def get_diff(
22
22
  cmd_result, exit_code = await run_command(
23
23
  cmd=["git", "diff", source_commit, current_commit],
24
24
  cwd=repo_dir,
25
- log_method=log_method,
25
+ print_method=log_method,
26
26
  )
27
27
  if exit_code != 0:
28
28
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -57,7 +57,7 @@ async def get_diff(
57
57
  async def get_repo_dir(log_method: Callable[..., Any] = print) -> str:
58
58
  cmd_result, exit_code = await run_command(
59
59
  cmd=["git", "rev-parse", "--show-toplevel"],
60
- log_method=log_method,
60
+ print_method=log_method,
61
61
  )
62
62
  if exit_code != 0:
63
63
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -70,7 +70,7 @@ async def get_current_branch(
70
70
  cmd_result, exit_code = await run_command(
71
71
  cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
72
72
  cwd=repo_dir,
73
- log_method=log_method,
73
+ print_method=log_method,
74
74
  )
75
75
  if exit_code != 0:
76
76
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -83,7 +83,7 @@ async def get_branches(
83
83
  cmd_result, exit_code = await run_command(
84
84
  cmd=["git", "rev-parse", "--abbrev-ref", "HEAD"],
85
85
  cwd=repo_dir,
86
- log_method=log_method,
86
+ print_method=log_method,
87
87
  )
88
88
  if exit_code != 0:
89
89
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -98,7 +98,7 @@ async def delete_branch(
98
98
  cmd_result, exit_code = await run_command(
99
99
  cmd=["git", "branch", "-D", branch_name],
100
100
  cwd=repo_dir,
101
- log_method=log_method,
101
+ print_method=log_method,
102
102
  )
103
103
  if exit_code != 0:
104
104
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -109,7 +109,7 @@ async def add(repo_dir: str, log_method: Callable[..., Any] = print):
109
109
  _, exit_code = await run_command(
110
110
  cmd=["git", "add", ".", "-A"],
111
111
  cwd=repo_dir,
112
- log_method=log_method,
112
+ print_method=log_method,
113
113
  )
114
114
  if exit_code != 0:
115
115
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -121,7 +121,7 @@ async def commit(
121
121
  cmd_result, exit_code = await run_command(
122
122
  cmd=["git", "commit", "-m", message],
123
123
  cwd=repo_dir,
124
- log_method=log_method,
124
+ print_method=log_method,
125
125
  )
126
126
  if exit_code != 0:
127
127
  ignored_error_message = "nothing to commit, working tree clean"
@@ -138,7 +138,7 @@ async def pull(
138
138
  _, exit_code = await run_command(
139
139
  cmd=["git", "pull", remote, branch],
140
140
  cwd=repo_dir,
141
- log_method=log_method,
141
+ print_method=log_method,
142
142
  )
143
143
  if exit_code != 0:
144
144
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -150,7 +150,7 @@ async def push(
150
150
  _, exit_code = await run_command(
151
151
  cmd=["git", "push", "-u", remote, branch],
152
152
  cwd=repo_dir,
153
- log_method=log_method,
153
+ print_method=log_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
@@ -54,7 +54,7 @@ async def add_subtree(
54
54
  branch,
55
55
  ],
56
56
  cwd=repo_dir,
57
- log_method=log_method,
57
+ print_method=log_method,
58
58
  )
59
59
  if exit_code != 0:
60
60
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -82,7 +82,7 @@ async def pull_subtree(
82
82
  branch,
83
83
  ],
84
84
  cwd=repo_dir,
85
- log_method=log_method,
85
+ print_method=log_method,
86
86
  )
87
87
  if exit_code != 0:
88
88
  raise Exception(f"Non zero exit code: {exit_code}")
@@ -106,7 +106,7 @@ async def push_subtree(
106
106
  branch,
107
107
  ],
108
108
  cwd=repo_dir,
109
- log_method=log_method,
109
+ print_method=log_method,
110
110
  )
111
111
  if exit_code != 0:
112
112
  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.0b6
3
+ Version: 1.0.0b7
4
4
  Summary: Your Automation Powerhouse
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -2,7 +2,7 @@ zrb/__init__.py,sha256=JYLyBeSv-FP2iVKgsXJH8Ae-Cmjp5nmmIiwqayhCOEE,2964
2
2
  zrb/__main__.py,sha256=TnWp9Z3uuNb_6uf5FT1fcwh6BLZwGCAJB4R9NxnFLNs,748
3
3
  zrb/attr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  zrb/attr/type.py,sha256=4TV5gPYMMrKh5V-yB6iRYKCbsXAH_AvGXMsjxKLHcUs,568
5
- zrb/builtin/__init__.py,sha256=m8Cw6v8v5ANEoIlQXaeMKAHqg_J1LyhzovANRd9UbD8,1861
5
+ zrb/builtin/__init__.py,sha256=oXG4Zm_rIp3G81Y7hiSe38jeS2sGZAnADoP_yxxhYEc,1926
6
6
  zrb/builtin/base64.py,sha256=1YnSwASp7OEAvQcsnHZGpJEvYoI1Z2zTIJ1bCDHfcPQ,921
7
7
  zrb/builtin/git.py,sha256=xHzg0srhp1uOSXWvwA--Fo8idkt0G9010iJ8uIndzg4,5463
8
8
  zrb/builtin/git_subtree.py,sha256=GwI8befmvXEoX1xyZ4jkeG8nsyCkuRG1lzPiGss3yqw,3493
@@ -16,16 +16,16 @@ zrb/builtin/llm/tool/web.py,sha256=N2HYuXbKPUpjVAq_UnQMbUrTIE8u0Ut3TeQadZ7_NJc,2
16
16
  zrb/builtin/md5.py,sha256=0pNlrfZA0wlZlHvFHLgyqN0JZJWGKQIF5oXxO44_OJk,949
17
17
  zrb/builtin/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  zrb/builtin/project/add/fastapp/fastapp_input.py,sha256=fYD6n8-PlrTyz1Kq5GYAt0PQsyUp2qsPKRJ68hINSXE,314
19
- zrb/builtin/project/add/fastapp/fastapp_task.py,sha256=XuyQVuaaNRPQftisSpWMFmKFXpEi4HngKW62aRgz3KQ,2644
19
+ zrb/builtin/project/add/fastapp/fastapp_task.py,sha256=m48ENwROECcAVzmianijcI2Ct4t9BhPyPjfxTbS3Zy0,2635
20
20
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.flake8,sha256=fgvHmuskgYiCvHZHaFtiyOWW0zasVrs0P-sFHOq3W5U,56
21
21
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.gitignore,sha256=1BMFpr_M5OyTs-weCZZlVlf85sWikzdbvmKu86YD7G0,28
22
22
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/README.md,sha256=MAo7ZFbg7LLiAfQbXcippMgjJ2-VXMKtiTDEZ3I4AAg,221
23
23
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_task.py,sha256=0sPR_pe_oYUevWu0FvMvxTu6lwefsw4YH01vkCBBZsg,391
24
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/add_column_task.py,sha256=x7igeeJl8M0vKw9v0VG6zIFk7qAZD2NIH3_uG-VJimY,2868
25
25
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py,sha256=rllXYH4LRyt-vXAoMLENx1T-01nxjN6CpWf76b_-ppw,580
26
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py,sha256=483e-dMm6URApCm62d-PD6Z-3NONBRT9X6uRsrNLFDo,6265
26
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py,sha256=l7RAPWZZBHY3Uv6TmbPDuEvF0IwJ_lx3vHz6Cq4tgus,6256
27
27
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py,sha256=gtWMWdc0QC4vbMtzUJi_ZDlY5dZJCTWdJBCPGn0vkso,11962
28
- 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,sha256=04H7NWh-xQ6yIBNmoVSNboaE5DGQrDfVX9SMiLJwQus,3996
28
+ 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,sha256=Z8yzVRx_Eew2cnyB82nQMpJfFdvd2LlKv-KZ53a0R1E,3894
29
29
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service_factory.py,sha256=lnhhpc_AflWnCQbLkYORrshiqIA5wy4SdxDuUxmn7Ts,372
30
30
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_db_repository.py,sha256=GrMxMb98-XD7Rue1v14jBu6HRb8Gy5DywBSKnMhN0iY,770
31
31
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_repository.py,sha256=QJmQmeXvkuhpnAFWkATJk7zvr-GY1RSyb5U9bSslFn4,1644
@@ -36,7 +36,7 @@ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/templat
36
36
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py,sha256=8YykCthDgjXT8MFvTrPSWYUXsfhafmoSMG9LH2ZiaD0,431
37
37
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/group.py,sha256=S0sKnnABSGy3YzaExH40xJjm4UsEX6AyDE1u94ewk6A,648
38
38
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py,sha256=PYbPwO5odaQDzRIgKkLmLEKOOYs9gQw3q7L-Fakw90Q,1349
39
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py,sha256=Ow_l3hDtR8WZLy4cC8NUi9Cdu6zqpfsap81ux_QtD2g,3699
39
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py,sha256=mGD3iHocO3TcmFgrBRHEoOgci3qXmwaSmEpVe7jGjvE,3690
40
40
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py,sha256=2totrFEzt0sEA4U0HHMy5GAsNM-X6uLv9eq8rsrA9XU,7145
41
41
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py,sha256=Ks-TtmuhzFy1H5BGQt7FU09ZHBTWwsSVhHFzOXpnSQg,120
42
42
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/alembic.ini,sha256=mgQyBAIwdkZZJWLu_FQWPx1FkyaARCNp6-rLqSVvMbA,3723
@@ -85,7 +85,7 @@ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migrati
85
85
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py,sha256=oLKVOCRvupnGmguEO10b7ZE5pXbhTBV8OSZmp_nOkfc,1255
86
86
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
87
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py,sha256=Mn9i-h74F30V3MmYkBWXaO2BXuVJYEBYSsfP7xle6Ok,4137
88
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py,sha256=ro3LOvHNh9VnZwoeOg4T2n1mvXWoiAmOsk15vxvH_2o,4032
89
89
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py,sha256=PhAhpLtk9Qz96DsHTMTeHeWilv_L7SVOU-Wfpmg741Y,380
90
90
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py,sha256=dldy05Jx6hJzWJz6YHIXUVUX7LrPrZLSpQQjZ8C_fTQ,728
91
91
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py,sha256=qpzSQg_opkq0U2bGjShxS8cGX26zncqNPoZsqqHnRfk,1699
@@ -94,13 +94,13 @@ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service
94
94
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py,sha256=CLjMEGE4sJyT4VpURYfqO6nh_lRWmYupfE86pbVDMBE,3152
95
95
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py,sha256=LWPNu6kURF3xU2n8mVn4Kfq12rFsZq2vxnh-mgT9SDY,1791
96
96
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py,sha256=iTEoSP3kKnhpGEFW3veA3lnGb3CfmQJslnneUJ8ktJs,463
97
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py,sha256=rOUP9gSYt39a8-jeeyv9uEzh1bheTxu54fRBDJoKTIk,4977
97
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py,sha256=gCoWt-N10Sg_sSnSx5AS4m_eDboFlKc8beys28hUkWE,5057
98
98
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py,sha256=TqQfx0jXGZmBDR1UYPyys8-I6tDKhqr1yjWpp-ezkDA,305
99
99
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
100
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py,sha256=pcR9gFa2_deordx6jvSWNnz4hih3cyMJrJ-gWRTW6UU,8444
101
101
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py,sha256=_mP1VN0TW0TFvzHN6k7uBZt5GST5ueK4G5T6EwXiEsI,2563
102
102
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py,sha256=Ea9ykNhzYiWu_IEhfpWsg1OIWeQ9pOTCzbZF9rrsZqU,463
103
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py,sha256=FL-_fz3smPZUKbWYELFfPCjrVv4Xpqi8V4baZJ3zAas,4515
103
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py,sha256=KgfHIBHvEVY5V7CNm0Y8BnNQ6sd5UJB_wFq6WMnrBvg,4901
104
104
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py,sha256=vyJv-gK4Myo1GH3ZwJm4b2lws35gW04VFW5K8Nw-iCw,305
105
105
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/alembic.ini,sha256=mgQyBAIwdkZZJWLu_FQWPx1FkyaARCNp6-rLqSVvMbA,3723
106
106
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
@@ -155,10 +155,13 @@ zrb/builtin/setup/asdf/asdf.py,sha256=n_dWoyYa7vZ9tBCy8hgxmSWZ-XHltC1R70mIVZQhnX
155
155
  zrb/builtin/setup/asdf/asdf_helper.py,sha256=6jARtyIAE1H82HKVQ84D25RrMAsAip_gD28X9ZlaTCk,1205
156
156
  zrb/builtin/setup/common_input.py,sha256=M8q9Unt7dCfBHTHqV3__Mxk9YC2Pl3DDtxat2BanZCQ,870
157
157
  zrb/builtin/setup/latex/ubuntu.py,sha256=er9wJAT4CpmghIaiIPFb3FvgqAn1aqU5UgX7GHL3FjA,577
158
- zrb/builtin/setup/tmux/tmux.py,sha256=4CswI40w3W6vsNckO7oEYnI7ySAeGhA80FsYzoq6HWQ,1410
158
+ zrb/builtin/setup/tmux/tmux.py,sha256=r7XdEx-AcHiF63uhOqgDuhSq0DR1IK52fHj3ZMtUrZg,1407
159
159
  zrb/builtin/setup/tmux/tmux_config.sh,sha256=wQCb4Q-mNkxIPOcvpN84X9RUWkGY16u3Vd-pOhVidgg,416
160
160
  zrb/builtin/setup/tmux/tmux_helper.py,sha256=M03l0wfL25TzGGp6lnVfX40ayT_x7N2lz-nz2chO7PU,396
161
161
  zrb/builtin/setup/ubuntu.py,sha256=oOSN7Eq7arEpY2i0vWHPR2owio6dqqOvceteYrgmbYw,1019
162
+ zrb/builtin/setup/zsh/zsh.py,sha256=quz3OegZBNNBm_K8IH2DUt9G0Q6XZ6cKsDs_WzHGqjg,1824
163
+ zrb/builtin/setup/zsh/zsh_config.sh,sha256=SRkcXvVT3tdfS1UDT0-dSj2PKXPLohhyakY6tUEQPjc,4764
164
+ zrb/builtin/setup/zsh/zsh_helper.py,sha256=1zF1FH0oEPVAVhMA20tsdk1H0RPMCkLusYX8twsTbGI,393
162
165
  zrb/builtin/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
163
166
  zrb/builtin/shell/autocomplete/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
167
  zrb/builtin/shell/autocomplete/bash.py,sha256=-7YDVV7txgJH9mAYSYN0jmvUEeDIzWFvVNY-cY0myF8,1181
@@ -171,14 +174,14 @@ zrb/callback/callback.py,sha256=hKefB_Jd1XGjPSLQdMKDsGLHPzEGO2dqrIArLl_EmD0,848
171
174
  zrb/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
175
  zrb/cmd/cmd_result.py,sha256=L8bQJzWCpcYexIxHBNsXj2pT3BtLmWex0iJSMkvimOA,597
173
176
  zrb/cmd/cmd_val.py,sha256=7Doowyg6BK3ISSGBLt-PmlhzaEkBjWWm51cED6fAUOQ,1014
174
- zrb/config.py,sha256=RB0ikM82RnCDZaarJOEBfD7GeYPfcq6jLb6F359il1s,4677
177
+ zrb/config.py,sha256=Kb-GOsUS4poSCds4Wqg9LkscpS7BHXSy3dQmqvsFm2Q,4621
175
178
  zrb/content_transformer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
179
  zrb/content_transformer/any_content_transformer.py,sha256=v8ZUbcix1GGeDQwB6OKX_1TjpY__ksxWVeqibwa_iZA,850
177
180
  zrb/content_transformer/content_transformer.py,sha256=YU6Xr3G_IaCWKQGsf9z9YlCclbiwcJ7ytQv3wKpPIiI,2125
178
181
  zrb/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
- zrb/context/any_context.py,sha256=itd_lCyaPbZvcB_8XDEbvde9yQ7YPRHlOQCxE4hniB4,6251
182
+ zrb/context/any_context.py,sha256=2hgVKbbDwmwrEl1h1L1FaTUjuUYaDd_b7YRGkaorW6Q,6362
180
183
  zrb/context/any_shared_context.py,sha256=p1i9af_CUDz5Mf1h1kBZMAa2AEhf17I3O5IgAcjRLoY,1768
181
- zrb/context/context.py,sha256=RWjluPpNBAZ_qjfza5fP-ScnEsZk2pD5rroYWQSfjAE,6201
184
+ zrb/context/context.py,sha256=qVMqt2tkLEFSI81mLYb_OSD615KH5jP685aUmHEm3XQ,6319
182
185
  zrb/context/shared_context.py,sha256=47Tnnor1ttpwpe_N07rMNM1jgIYPY9abMe1Q5igkMtE,2735
183
186
  zrb/dot_dict/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
187
  zrb/dot_dict/dot_dict.py,sha256=ubw_x8I7AOJ59xxtFVJ00VGmq_IYdZP3mUhNlO4nEK0,556
@@ -234,7 +237,7 @@ zrb/runner/web_route/static/resources/login/event.js,sha256=1-NxaUwU-X7Tu2RAwVkz
234
237
  zrb/runner/web_route/static/resources/logout/event.js,sha256=MfZxrTa2yL49Lbh7cCZDdqsIcf9e1q3W8-WjmZXV5pA,692
235
238
  zrb/runner/web_route/static/resources/pico.min.css,sha256=_Esfkjs_U_igYn-tXBUaK3AEKb7d4l9DlmaOiw9bXfI,82214
236
239
  zrb/runner/web_route/static/resources/session/common-util.js,sha256=t7_s5DXgMyZlT8L8LYZTkzOT6vWVeZvmCKjt-bflQY0,2117
237
- zrb/runner/web_route/static/resources/session/current-session.js,sha256=GlRBLwItCwITqVR_hUQFr6W1myD9WRl8R_TTbrzCovw,6739
240
+ zrb/runner/web_route/static/resources/session/current-session.js,sha256=kAYHoSVjtQ4XA5yfXocKFVjOmYihQoIHTW0pHx22sPg,7010
238
241
  zrb/runner/web_route/static/resources/session/event.js,sha256=X5OlSHefK0SDB9VkFCRyBKE_Pb7mqM319mW9jRGoDOk,4716
239
242
  zrb/runner/web_route/static/resources/session/past-session.js,sha256=RwGJYKSp75K8NZ-iZP58XppWgdzkiKFaiC5wgcMLxDo,5470
240
243
  zrb/runner/web_route/static/static_route.py,sha256=7x069VfACZLkLykY0vLL5t13jIQPgkeEJtkpbfNQfLg,1540
@@ -260,11 +263,11 @@ zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
263
  zrb/task/any_task.py,sha256=9rCdKe-Sayr34Han9AsbhRxFpkbk6Rteg1DOyETulwQ,4917
261
264
  zrb/task/base_task.py,sha256=ImA0ReyB6neVUfY4nKLnL0h2EMGIJ9wvvNvIAN92-RE,21194
262
265
  zrb/task/base_trigger.py,sha256=jC722rDvodaBLeNaFghkTyv1u0QXrK6BLZUUqcmBJ7Q,4581
263
- zrb/task/cmd_task.py,sha256=JpClYoEmJTqKSxhuCErXd2kHLS3Hk2zXeYnl7entNeU,10378
266
+ zrb/task/cmd_task.py,sha256=lg9Dkb0wwjo-F1F6gsH-RqNdndfQAwLkd7SOW5DdpGc,10809
264
267
  zrb/task/http_check.py,sha256=Gf5rOB2Se2EdizuN9rp65HpGmfZkGc-clIAlHmPVehs,2565
265
268
  zrb/task/llm_task.py,sha256=ptXC3x9Dwn7-4JrGQyEtzOXZ4dNQATDgCeowkvwAu9U,7723
266
269
  zrb/task/make_task.py,sha256=PD3b_aYazthS8LHeJsLAhwKDEgdurQZpymJDKeN60u0,2265
267
- zrb/task/rsync_task.py,sha256=pVVslZ46qgcpU_EKhyTQEQie8kUOMuTsVQdbQG2L-yk,6318
270
+ zrb/task/rsync_task.py,sha256=GSL9144bmp6F0EckT6m-2a1xG25AzrrWYzH4k3SVUKM,6370
268
271
  zrb/task/scaffolder.py,sha256=rME18w1HJUHXgi9eTYXx_T2G4JdqDYzBoNOkdOOo5-o,6806
269
272
  zrb/task/scheduler.py,sha256=aSDF_WtDbmwrYXaVo3BesCG8w21UNV8XLtn-5x9GWzY,3137
270
273
  zrb/task/task.py,sha256=KCrCaWYOQQvv1RJsYtHDeo9RBFmlXQ28oKyEFU4Q7pA,73
@@ -277,7 +280,7 @@ zrb/util/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
277
280
  zrb/util/cli/style.py,sha256=wxdtE18d4Q3GV7aojinD-XN9iWvazfvLs9MTJPlCNQU,3805
278
281
  zrb/util/cli/subcommand.py,sha256=gYr-CzVeKFQhY43s_FDstPwn8r-ypUz1Q2Rv_l2r-ck,1027
279
282
  zrb/util/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
- zrb/util/cmd/command.py,sha256=hllMoHh2gUSNip3kgEJwKz1JxFC--bCoFyyT1quJgnE,3455
283
+ zrb/util/cmd/command.py,sha256=g6MNfBFSfeabwbevCeXn2puVsOxo8N3pi8k_Olv2zxQ,4254
281
284
  zrb/util/cmd/remote.py,sha256=VklVORobTmE7FqdtYsVLq9xkSYTR2W5r2Zou0-soidw,710
282
285
  zrb/util/codemod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
286
  zrb/util/codemod/append_code_to_class.py,sha256=5PiGzFqB-q8XQnGnDqWBn4OA4ydSmQWpKQzSr3l6wws,1361
@@ -290,8 +293,8 @@ zrb/util/codemod/prepend_parent_to_class.py,sha256=xOcDHv1cXXV_VqLHVifr6jvDoWk_i
290
293
  zrb/util/codemod/prepend_property_to_class.py,sha256=9L11WaYIUF53Kn_ZMT51ylhm7xTxttNjPp83Mnm9iUQ,2079
291
294
  zrb/util/cron.py,sha256=9fTGatUMYCRgmDFGg-z6_XerT4U5Vq72nD05NnEVUm4,2852
292
295
  zrb/util/file.py,sha256=cBPkIonfcWytoqtG3ScJd6FFK7HVYeCIuLmfAFO1HIQ,791
293
- zrb/util/git.py,sha256=o_kLF1fySv5uQdLlhY-ztc-z0zLOdcDf0IpuPAl2ciA,4733
294
- zrb/util/git_subtree.py,sha256=US8oCHUOKgt14Ie6SaEelwTs__jLGLPsDQZvI-1P4KY,2640
296
+ zrb/util/git.py,sha256=qTc6rHJd_HyJktiOC_kZGKc75qLx_6X899TG0DrXC04,4751
297
+ zrb/util/git_subtree.py,sha256=8oLaMBy2giMQcZnLZ31Tu0W5xicSEKrm5xiHfd1worA,2646
295
298
  zrb/util/group.py,sha256=Bg7HrSycoK110U5s_Tca6-uUQuZ5CMgb8wxZSrvDQ98,2790
296
299
  zrb/util/llm/tool.py,sha256=NkENrUlGxcqqU7jzHAH7DBXNcm_ndEo2dFnJ5nhvWmk,2991
297
300
  zrb/util/load.py,sha256=i8_83ApWJXlZlbFMNfEptrOzfXdvtaIhAErsd6tU9y8,1649
@@ -303,7 +306,7 @@ zrb/util/string/name.py,sha256=8picJfUBXNpdh64GNaHv3om23QHhUZux7DguFLrXHp8,1163
303
306
  zrb/util/todo.py,sha256=1nDdwPc22oFoK_1ZTXyf3638Bg6sqE2yp_U4_-frHoc,16015
304
307
  zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
305
308
  zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
306
- zrb-1.0.0b6.dist-info/METADATA,sha256=ZGOBMXjA82fN6lsJ3yNmJTGqwoZWJcNEKCxXtTouk68,4270
307
- zrb-1.0.0b6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
308
- zrb-1.0.0b6.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
309
- zrb-1.0.0b6.dist-info/RECORD,,
309
+ zrb-1.0.0b7.dist-info/METADATA,sha256=nw9wiAEB0ViBOiqQGH0SQXPz-3YulrupirW9Rw3EZFY,4270
310
+ zrb-1.0.0b7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
311
+ zrb-1.0.0b7.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
312
+ zrb-1.0.0b7.dist-info/RECORD,,
File without changes