vortex-cli 4.16.0__tar.gz → 4.16.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/PKG-INFO +1 -1
  2. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/setup.cfg +1 -1
  3. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/cli.py +49 -15
  4. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/clone.py +2 -1
  5. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/find.py +16 -11
  6. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/new.py +64 -40
  7. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/main.py +7 -1
  8. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/models.py +2 -0
  9. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/util.py +8 -4
  10. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/workspace.py +7 -1
  11. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/PKG-INFO +1 -1
  12. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/LICENSE +0 -0
  13. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/README.md +0 -0
  14. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/setup.py +0 -0
  15. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/__init__.py +0 -0
  16. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/__main__.py +0 -0
  17. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/colour.py +0 -0
  18. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/__init__.py +0 -0
  19. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/clean.py +0 -0
  20. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/code.py +0 -0
  21. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/config.py +0 -0
  22. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/copy.py +0 -0
  23. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/db.py +0 -0
  24. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/delete.py +0 -0
  25. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/docs.py +0 -0
  26. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/execute.py +0 -0
  27. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/grep.py +0 -0
  28. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/list.py +0 -0
  29. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/log.py +0 -0
  30. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/commands/watch.py +0 -0
  31. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/constants.py +0 -0
  32. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/docs/Blackbook.pdf +0 -0
  33. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/lib/puakma-6.0.37.jar +0 -0
  34. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/logging.py +0 -0
  35. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/soap.py +0 -0
  36. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex/spinner.py +0 -0
  37. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/SOURCES.txt +0 -0
  38. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/dependency_links.txt +0 -0
  39. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/entry_points.txt +0 -0
  40. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/requires.txt +0 -0
  41. {vortex_cli-4.16.0 → vortex_cli-4.16.2}/vortex_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vortex_cli
3
- Version: 4.16.0
3
+ Version: 4.16.2
4
4
  Home-page: https://github.com/jordanamos/vortex-cli
5
5
  Author: Jordan Amos
6
6
  Author-email: jordan.amos@gmail.com
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = vortex_cli
3
- version = 4.16.0
3
+ version = 4.16.2
4
4
  long_description = file: README.md
5
5
  long_description_content_type = text/markdown
6
6
  url = https://github.com/jordanamos/vortex-cli
@@ -52,6 +52,7 @@ def _add_design_type_option(
52
52
  parser: ArgumentParser | _MutuallyExclusiveGroup | _ArgumentGroup,
53
53
  nargs: str | None = "*",
54
54
  required: bool = False,
55
+ help_suffix: str | None = None,
55
56
  ) -> None:
56
57
  parser.add_argument(
57
58
  "--type",
@@ -63,6 +64,7 @@ def _add_design_type_option(
63
64
  metavar="DESIGN_TYPE",
64
65
  help=(
65
66
  f"Choices: {[t.name.lower() for t in DesignType if t != DesignType.ERROR]}"
67
+ f"{help_suffix or ''}"
66
68
  ),
67
69
  )
68
70
 
@@ -74,15 +76,15 @@ def validate_args(
74
76
  db_parser: ArgumentParser,
75
77
  ) -> None:
76
78
  if args.command == "new" and args.subcommand == "object":
77
- missing_required_fields = not args.update_id and not (
79
+ missing_required_fields = not args.update_ids and not (
78
80
  args.name and args.app_id and args.design_type
79
81
  )
80
82
  missing_content_type = (
81
83
  args.design_type in (DesignType.RESOURCE, DesignType.DOCUMENTATION)
82
84
  and not args.content_type
83
85
  )
84
- update_arg_contains_app_id = args.update_id and args.app_id
85
- update_is_missing_args = args.update_id and not (
86
+ update_arg_contains_app_id = args.update_ids and args.app_id
87
+ update_is_missing_args = args.update_ids and not (
86
88
  args.name
87
89
  or args.app_id
88
90
  or args.design_type
@@ -376,12 +378,21 @@ def add_log_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
376
378
  def add_find_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
377
379
  find_parser = command_parser.add_parser(
378
380
  "find",
379
- help="Find Design Objects of cloned applications by name",
380
- usage="%(prog)s [options] name",
381
+ help="Search Design Objects of cloned applications",
382
+ usage="%(prog)s [options] query",
383
+ )
384
+ find_parser.add_argument(
385
+ "query", help="The query to search Design Objects. Default is search by name."
381
386
  )
382
- find_parser.add_argument("name", help="The name of Design Objects to find")
383
387
  find_parser.add_argument("--app-id", type=int, nargs="*", dest="app_ids")
384
388
  find_parser.add_argument("--strict", "-z", action="store_true")
389
+ query_mutex = find_parser.add_mutually_exclusive_group()
390
+ query_mutex.add_argument(
391
+ "--inherits-from", action="store_true", help="Search by inherits from instead"
392
+ )
393
+ query_mutex.add_argument(
394
+ "--parent-page", action="store_true", help="Search by parent page instead"
395
+ )
385
396
  find_parser.add_argument(
386
397
  "--ids-only",
387
398
  "-x",
@@ -433,6 +444,17 @@ def add_new_parser(
433
444
  raise ArgumentTypeError(f"Invalid '.pmx' file {path}")
434
445
  return path
435
446
 
447
+ def _add_update_option(parser: ArgumentParser) -> None:
448
+ parser.add_argument(
449
+ "--update",
450
+ "-u",
451
+ type=int,
452
+ nargs="*",
453
+ metavar="ID",
454
+ dest="update_ids",
455
+ help="Update a Design Object with the given ID instead",
456
+ )
457
+
436
458
  new_parser = command_parser.add_parser(
437
459
  "new",
438
460
  help="Create new Design Objects, Applications or Keywords",
@@ -441,8 +463,9 @@ def add_new_parser(
441
463
  "--update",
442
464
  "-u",
443
465
  type=int,
466
+ nargs="*",
444
467
  metavar="ID",
445
- dest="update_id",
468
+ dest="update_ids",
446
469
  help="Update a Design Object with the given ID instead",
447
470
  )
448
471
  _add_server_option(new_parser)
@@ -451,15 +474,22 @@ def add_new_parser(
451
474
 
452
475
  # Object parser
453
476
  object_parser = sub_parser.add_parser("object", help="Create a new Design Object")
454
- obj_required_no_update_group = object_parser.add_argument_group(
455
- "Required When Creating (no --update)"
477
+ obj_optional_group = object_parser.add_argument_group("Design Object Options")
478
+ _add_design_type_option(
479
+ obj_optional_group,
480
+ nargs=None,
481
+ help_suffix=". Required when creating a new object.",
482
+ )
483
+ obj_optional_group.add_argument(
484
+ "--app-id",
485
+ type=int,
486
+ help="Required when creating a new object.",
487
+ )
488
+ obj_optional_group.add_argument(
489
+ "--name",
490
+ "-n",
491
+ help="Required when creating a new object.",
456
492
  )
457
-
458
- obj_required_no_update_group.add_argument("--app-id", type=int)
459
- obj_required_no_update_group.add_argument("--name", "-n")
460
- _add_design_type_option(obj_required_no_update_group, nargs=None)
461
-
462
- obj_optional_group = object_parser.add_argument_group("Optional Arguments")
463
493
  obj_optional_group.add_argument("--comment")
464
494
  obj_optional_group.add_argument("--inherit-from")
465
495
  obj_optional_group.add_argument("--open-action")
@@ -497,6 +527,10 @@ def add_new_parser(
497
527
  keyword_parser.add_argument("--name", "-n", help="The keyword name", required=True)
498
528
  keyword_parser.add_argument("--values", nargs="*", required=True)
499
529
 
530
+ _add_update_option(object_parser)
531
+ _add_update_option(app_parser)
532
+ _add_update_option(keyword_parser)
533
+
500
534
  return new_parser
501
535
 
502
536
 
@@ -107,6 +107,8 @@ def _aparse_design_objs(
107
107
  obj["ctype"],
108
108
  obj["data"],
109
109
  obj["src"],
110
+ inherit_from=obj["inherit"],
111
+ comment=obj["comment"],
110
112
  )
111
113
  )
112
114
  return ret
@@ -130,7 +132,6 @@ def _parse_app_xml(
130
132
  db_ele.attrib["userName"],
131
133
  db_ele.attrib["pwd"],
132
134
  )
133
- # print(db_ele.attrib)
134
135
  db_connections.append(db_conn)
135
136
 
136
137
  java_version_ele = app_xml.find('.//sysProp[@name="java.class.version"]')
@@ -9,29 +9,34 @@ from vortex.workspace import Workspace
9
9
  def find(
10
10
  workspace: Workspace,
11
11
  server: PuakmaServer,
12
- name: str,
12
+ query: str,
13
13
  *,
14
14
  app_ids: list[int] | None = None,
15
15
  design_types: list[DesignType] | None = None,
16
16
  show_params: bool = False,
17
17
  show_ids_only: bool = False,
18
18
  strict_search: bool = False,
19
+ search_parent_page: bool = False,
20
+ search_inherits_from: bool = False,
19
21
  ) -> int:
20
22
  if app_ids:
21
23
  apps = [workspace.lookup_app(server, id) for id in app_ids]
22
24
  else:
23
25
  apps = workspace.listapps(server)
24
26
 
25
- matches = [
26
- obj
27
- for app in apps
28
- for obj in app.design_objects
29
- if (
30
- (not strict_search and (name.lower() in obj.name.lower()))
31
- or (name == obj.name)
32
- )
33
- and (not design_types or obj.design_type in design_types)
34
- ]
27
+ matches = []
28
+ for app in apps:
29
+ for obj in app.design_objects:
30
+ value_to_search = obj.name
31
+ if search_inherits_from:
32
+ value_to_search = obj.inherit_from or ""
33
+ elif search_parent_page:
34
+ value_to_search = obj.parent_page or ""
35
+ if (
36
+ (not strict_search and (query.lower() in value_to_search.lower()))
37
+ or (query == value_to_search)
38
+ ) and (not design_types or obj.design_type in design_types):
39
+ matches.append(obj)
35
40
 
36
41
  if show_ids_only:
37
42
  for obj in matches:
@@ -5,6 +5,7 @@ import asyncio
5
5
  import base64
6
6
  import logging
7
7
  import mimetypes
8
+ from collections.abc import Iterable
8
9
  from pathlib import Path
9
10
  from typing import Any
10
11
 
@@ -152,7 +153,7 @@ async def _acreate_or_update_obj(
152
153
  async def _acreate_or_update_objects(
153
154
  workspace: Workspace,
154
155
  server: PuakmaServer,
155
- objs: list[DesignObject],
156
+ objs: Iterable[DesignObject],
156
157
  recreate_params: bool,
157
158
  ) -> int:
158
159
  async with server as s:
@@ -174,56 +175,79 @@ async def _acreate_or_update_objects(
174
175
  return ret
175
176
 
176
177
 
177
- def _update_object(
178
+ def _validate_update_objs(
178
179
  workspace: Workspace,
179
180
  server: PuakmaServer,
180
- design_obj_id: int,
181
+ design_obj_ids: list[int],
181
182
  **kwargs: Any,
182
- ) -> int:
183
- try:
184
- _, obj = workspace.lookup_design_obj(server, design_obj_id)
185
- except (DesignObjectNotFound, DesignObjectAmbiguousError) as e:
186
- logger.error(e)
187
- return 1
183
+ ) -> tuple[tuple[DesignObject, ...], bool]:
188
184
 
189
185
  _universal_keys = ("name", "design_type", "comment", "inherit_from")
190
- non_universal_kwargs = dict(kwargs)
191
- for k in _universal_keys:
192
- non_universal_kwargs.pop(k)
193
- if not _validate_args_for_type(obj.design_type, **non_universal_kwargs):
194
- return 1
195
-
196
- row_headers = ["ID", "Application", "Name"]
197
- row = [str(obj.id), str(obj.app), obj.name]
198
- param_name_map = {
199
- "open_action": "OpenAction",
200
- "save_action": "SaveAction",
201
- "parent_page": "ParentPage",
202
- }
203
- recreate_params = False
204
-
205
- for key, value in kwargs.items():
206
- if hasattr(obj, key) and value is not None:
207
- row_headers.append(Colour.colour(f"new_{key}", Colour.YELLOW))
208
- row.append(f"{getattr(obj, key)} -> {value}")
209
- if key in param_name_map:
210
- param = DesignObjectParam(param_name_map[key], value)
211
- obj.update_or_append_param(param)
212
- recreate_params = True
213
- else:
214
- setattr(obj, key, value)
186
+ objs = []
187
+ rows = []
188
+ for obj_id in design_obj_ids:
189
+ _, obj = workspace.lookup_design_obj(server, obj_id)
190
+ non_universal_kwargs = dict(kwargs)
191
+ for k in _universal_keys:
192
+ non_universal_kwargs.pop(k)
193
+ if not _validate_args_for_type(obj.design_type, **non_universal_kwargs):
194
+ exit(1)
195
+ row_headers = ["ID", "Application", "Name"]
196
+ row = [str(obj.id), str(obj.app), obj.name]
197
+ param_name_map = {
198
+ "open_action": "OpenAction",
199
+ "save_action": "SaveAction",
200
+ "parent_page": "ParentPage",
201
+ }
202
+ recreate_params = False
203
+ for key, value in kwargs.items():
204
+ if hasattr(obj, key) and value is not None:
205
+ row_headers.append(Colour.colour(f"new_{key}", Colour.YELLOW))
206
+ row.append(f"{getattr(obj, key)} -> {value}")
207
+ if key in param_name_map:
208
+ param = DesignObjectParam(param_name_map[key], value)
209
+ obj.update_or_append_param(param)
210
+ recreate_params = True
211
+ else:
212
+ setattr(obj, key, value)
213
+ rows.append(row)
214
+ objs.append(obj)
215
215
 
216
216
  _updated = Colour.colour("UPDATED", Colour.GREEN)
217
217
  print(f"The following Design Object(s) will be {_updated}:\n")
218
- print(tabulate.tabulate([row], headers=row_headers))
218
+ print(tabulate.tabulate(rows, headers=row_headers))
219
219
  if input("\n[Y/y] to continue:") not in ["Y", "y"]:
220
+ exit(1)
221
+
222
+ return tuple(objs), recreate_params
223
+
224
+
225
+ def _update_objects(
226
+ workspace: Workspace,
227
+ server: PuakmaServer,
228
+ design_obj_ids: list[int],
229
+ **kwargs: Any,
230
+ ) -> int:
231
+
232
+ try:
233
+ updated_objs, recreate_params = _validate_update_objs(
234
+ workspace, server, design_obj_ids, **kwargs
235
+ )
236
+ except (DesignObjectNotFound, DesignObjectAmbiguousError) as e:
237
+ logger.error(e)
220
238
  return 1
221
239
 
222
240
  with workspace.exclusive_lock():
223
241
  ret = asyncio.run(
224
- _acreate_or_update_objects(workspace, server, [obj], recreate_params)
242
+ _acreate_or_update_objects(workspace, server, updated_objs, recreate_params)
225
243
  )
226
- workspace.mkdir(obj.app)
244
+ apps = {obj.app for obj in updated_objs}
245
+ for app in apps:
246
+ new_app_objs = [obj for obj in updated_objs if obj.app == app]
247
+ for new_obj in new_app_objs:
248
+ idx, _ = app.lookup_design_obj(new_obj.name)
249
+ app.design_objects[idx] = new_obj
250
+ workspace.mkdir(app)
227
251
  return ret
228
252
 
229
253
 
@@ -340,11 +364,11 @@ def _new_keyword(
340
364
 
341
365
  def new(workspace: Workspace, server: PuakmaServer, args: argparse.Namespace) -> int:
342
366
  if args.subcommand == "object":
343
- if args.update_id:
344
- return _update_object(
367
+ if args.update_ids:
368
+ return _update_objects(
345
369
  workspace,
346
370
  server,
347
- args.update_id,
371
+ args.update_ids,
348
372
  name=args.name,
349
373
  design_type=args.design_type,
350
374
  content_type=args.content_type,
@@ -196,12 +196,14 @@ def main(argv: Sequence[str] | None = None) -> int:
196
196
  return find(
197
197
  workspace,
198
198
  server,
199
- args.name,
199
+ args.query,
200
200
  app_ids=args.app_ids,
201
201
  design_types=args.design_type,
202
202
  show_params=args.show_params,
203
203
  show_ids_only=args.show_ids_only,
204
204
  strict_search=args.strict,
205
+ search_parent_page=args.parent_page,
206
+ search_inherits_from=args.inherits_from,
205
207
  )
206
208
  elif args.command == "grep":
207
209
  return grep(
@@ -215,6 +217,10 @@ def main(argv: Sequence[str] | None = None) -> int:
215
217
  include_resources=args.include_resources,
216
218
  )
217
219
  elif args.command == "new":
220
+ if args.subcommand not in ["object", "app", "keyword"]:
221
+ new_parser.error(
222
+ "'new' command requires a sub command 'object', 'app' or 'keyword'"
223
+ )
218
224
  return new(workspace, server, args)
219
225
  elif args.command == "delete":
220
226
  return delete(workspace, server, args.obj_ids)
@@ -51,6 +51,8 @@ SELECT designbucketid AS id
51
51
  , contenttype AS ctype
52
52
  , designdata AS data
53
53
  , designsource AS src
54
+ , inheritfrom AS inherit
55
+ , comment
54
56
  FROM designbucket
55
57
  WHERE appid = %d
56
58
  """
@@ -139,24 +139,28 @@ def render_objects(
139
139
  *,
140
140
  show_params: bool = False,
141
141
  ) -> None:
142
- row_headers = ["ID", "Name", "Type", "Application"]
142
+ row_headers = ["ID", "Name", "Type", "Application", "Inherit"]
143
143
  row_data = []
144
144
  if show_params:
145
145
  row_headers.append("Content Type")
146
146
  row_headers.append("Open Action")
147
147
  row_headers.append("Save Action")
148
148
  row_headers.append("Parent Page")
149
- row_headers.append("Inherit From")
150
149
  row_headers.append("Comment")
151
150
 
152
151
  for obj in sorted(objs, key=lambda obj: obj.name.casefold()):
153
- row = [obj.id, obj.name, obj.design_type.name, str(obj.app)]
152
+ row = [
153
+ obj.id,
154
+ obj.name,
155
+ obj.design_type.name,
156
+ str(obj.app),
157
+ obj.inherit_from or "",
158
+ ]
154
159
  if show_params:
155
160
  row.append(obj.content_type or "")
156
161
  row.append(obj.open_action or "")
157
162
  row.append(obj.save_action or "")
158
163
  row.append(obj.parent_page or "")
159
- row.append(obj.inherit_from or "")
160
164
  row.append(obj.comment or "")
161
165
  row_data.append(row)
162
166
 
@@ -314,8 +314,14 @@ class Workspace:
314
314
 
315
315
  # Java project settings
316
316
  settings: dict[str, Any] = workspace_settings.get("settings", {})
317
- puakma_path = os.path.join(os.path.dirname(__file__), "lib", "puakma.jar")
317
+ # Get the packaged puakma-*.jar file
318
+ # Assumes only 1 file in the /lib directory
319
+ lib_dir = os.path.join(os.path.dirname(__file__), "lib")
320
+ puakma_jar = os.listdir(lib_dir)[0]
321
+ puakma_path = os.path.join(lib_dir, puakma_jar)
322
+
318
323
  referenced_libs = [puakma_path, os.path.join("zlib", "**", "*.jar")]
324
+ # Java runtimes
319
325
  java_runtimes: list[dict[str, Any]] = [{}]
320
326
  if server is not None:
321
327
  config = configparser.ConfigParser()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vortex_cli
3
- Version: 4.16.0
3
+ Version: 4.16.2
4
4
  Home-page: https://github.com/jordanamos/vortex-cli
5
5
  Author: Jordan Amos
6
6
  Author-email: jordan.amos@gmail.com
File without changes
File without changes
File without changes
File without changes