vortex-cli 4.17.2__tar.gz → 4.18.0__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 (44) hide show
  1. {vortex_cli-4.17.2/vortex_cli.egg-info → vortex_cli-4.18.0}/PKG-INFO +1 -1
  2. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/pyproject.toml +1 -1
  3. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/cli.py +119 -70
  4. vortex_cli-4.18.0/vortex/commands/clean.py +22 -0
  5. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/clone.py +4 -3
  6. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/export.py +2 -2
  7. vortex_cli-4.18.0/vortex/commands/import_.py +20 -0
  8. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/new.py +0 -18
  9. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/main.py +13 -7
  10. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/models.py +1 -1
  11. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/spinner.py +1 -3
  12. {vortex_cli-4.17.2 → vortex_cli-4.18.0/vortex_cli.egg-info}/PKG-INFO +1 -1
  13. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex_cli.egg-info/SOURCES.txt +1 -0
  14. vortex_cli-4.17.2/vortex/commands/clean.py +0 -20
  15. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/LICENSE +0 -0
  16. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/README.md +0 -0
  17. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/setup.cfg +0 -0
  18. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/__init__.py +0 -0
  19. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/__main__.py +0 -0
  20. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/colour.py +0 -0
  21. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/__init__.py +0 -0
  22. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/code.py +0 -0
  23. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/config.py +0 -0
  24. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/copy.py +0 -0
  25. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/db.py +0 -0
  26. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/delete.py +0 -0
  27. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/docs.py +0 -0
  28. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/execute.py +0 -0
  29. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/find.py +0 -0
  30. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/grep.py +0 -0
  31. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/list.py +0 -0
  32. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/log.py +0 -0
  33. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/commands/watch.py +0 -0
  34. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/constants.py +0 -0
  35. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/docs/Blackbook.pdf +0 -0
  36. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/lib/puakma-6.0.37.jar +0 -0
  37. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/logging.py +0 -0
  38. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/soap.py +0 -0
  39. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/util.py +0 -0
  40. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex/workspace.py +0 -0
  41. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex_cli.egg-info/dependency_links.txt +0 -0
  42. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex_cli.egg-info/entry_points.txt +0 -0
  43. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/vortex_cli.egg-info/requires.txt +0 -0
  44. {vortex_cli-4.17.2 → vortex_cli-4.18.0}/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.17.2
3
+ Version: 4.18.0
4
4
  Summary: Vortex CLI
5
5
  Author-email: Jordan Amos <jordan.amos@gmail.com>
6
6
  License: MIT License
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "vortex_cli"
8
- version = "4.17.2"
8
+ version = "4.18.0"
9
9
  description = "Vortex CLI"
10
10
  requires-python = ">=3.10"
11
11
  readme = { file = "README.md", content-type = "text/markdown" }
@@ -39,6 +39,19 @@ def _check_int_in_range(val: str, min_: int = 0, max_: int | None = 50) -> int:
39
39
  return new_val
40
40
 
41
41
 
42
+ def _pmx_type(val: str) -> Path:
43
+ path = Path(val).resolve()
44
+ if path.suffix != ".pmx" or not path.is_file():
45
+ raise ArgumentTypeError(f"Invalid '.pmx' file {path}")
46
+ return path
47
+
48
+
49
+ def _non_empty_string(val: str) -> str:
50
+ if not val.strip():
51
+ raise ArgumentTypeError("Value provided cannot be empty or just whitespace.")
52
+ return val
53
+
54
+
42
55
  def _add_server_option(parser: ArgumentParser) -> None:
43
56
  parser.add_argument(
44
57
  "--server",
@@ -75,39 +88,43 @@ def validate_args(
75
88
  clone_parser: ArgumentParser,
76
89
  db_parser: ArgumentParser,
77
90
  ) -> None:
78
- if args.command == "new" and args.subcommand == "object":
79
- missing_required_fields = not args.update_ids and not (
80
- args.name and args.app_id and args.design_type
81
- )
82
- missing_content_type = (
83
- args.design_type in (DesignType.RESOURCE, DesignType.DOCUMENTATION)
84
- and not args.content_type
85
- )
86
- update_arg_contains_app_id = args.update_ids and args.app_id
87
- update_is_missing_args = args.update_ids and not (
88
- args.name
89
- or args.app_id
90
- or args.design_type
91
- or args.comment
92
- or args.inherit_from
93
- or args.open_action
94
- or args.save_action
95
- or args.parent_page
96
- or args.content_type
97
- )
91
+ if args.command == "new":
98
92
  msg = None
99
- if missing_required_fields:
100
- msg = "--name, --app-id, and --type are required unless using --update"
101
- elif missing_content_type:
102
- msg = (
103
- f"--type argument value '{args.design_type.name}' "
104
- "requires --content-type"
93
+ is_update_mode = bool(args.update_ids)
94
+ if args.subcommand == "object":
95
+ missing_required_fields = not is_update_mode and not (
96
+ args.name and args.app_id and args.design_type
105
97
  )
106
- elif update_arg_contains_app_id:
107
- msg = "Can't use --app-id with --update"
108
- elif update_is_missing_args:
109
- msg = "Please specify an option to update"
110
-
98
+ missing_content_type = (
99
+ args.design_type in (DesignType.RESOURCE, DesignType.DOCUMENTATION)
100
+ and not args.content_type
101
+ )
102
+ update_arg_contains_app_id = is_update_mode and args.app_id
103
+ update_is_missing_args = is_update_mode and not (
104
+ args.name
105
+ or args.app_id
106
+ or args.design_type
107
+ or args.comment
108
+ or args.inherit_from
109
+ or args.open_action
110
+ or args.save_action
111
+ or args.parent_page
112
+ or args.content_type
113
+ )
114
+ if missing_required_fields:
115
+ msg = "--name, --app-id, and --type are required unless using --update"
116
+ elif missing_content_type:
117
+ msg = (
118
+ f"--type argument value '{args.design_type.name}' "
119
+ "requires --content-type"
120
+ )
121
+ elif update_arg_contains_app_id:
122
+ msg = "Can't use --app-id with --update"
123
+ elif update_is_missing_args:
124
+ msg = "Please specify an option to update"
125
+ elif args.subcommand == "app":
126
+ if not is_update_mode and not (args.name and args.group):
127
+ msg = "--name and --group are required when creating new applications."
111
128
  if msg:
112
129
  new_parser.error(msg)
113
130
 
@@ -303,10 +320,17 @@ def add_watch_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
303
320
 
304
321
 
305
322
  def add_clean_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
306
- command_parser.add_parser(
323
+ clean_parser = command_parser.add_parser(
307
324
  "clean",
308
325
  help="Delete the cloned Puakma Application directories in the workspace",
309
326
  )
327
+ clean_parser.add_argument(
328
+ "--all",
329
+ "-a",
330
+ help="Set this flag to clean all servers",
331
+ action="store_true",
332
+ )
333
+ _add_server_option(clean_parser)
310
334
 
311
335
 
312
336
  def add_config_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
@@ -456,23 +480,6 @@ def add_grep_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
456
480
  def add_new_parser(
457
481
  command_parser: _SubParsersAction[ArgumentParser],
458
482
  ) -> ArgumentParser:
459
- def _pmx_type(val: str) -> Path:
460
- path = Path(val).resolve()
461
- if path.suffix != ".pmx" or not path.is_file():
462
- raise ArgumentTypeError(f"Invalid '.pmx' file {path}")
463
- return path
464
-
465
- def _add_update_option(parser: ArgumentParser) -> None:
466
- parser.add_argument(
467
- "--update",
468
- "-u",
469
- type=int,
470
- nargs="*",
471
- metavar="ID",
472
- dest="update_ids",
473
- help="Update a Design Object with the given ID instead",
474
- )
475
-
476
483
  new_parser = command_parser.add_parser(
477
484
  "new",
478
485
  help="Create new Design Objects, Applications or Keywords",
@@ -484,14 +491,16 @@ def add_new_parser(
484
491
  nargs="*",
485
492
  metavar="ID",
486
493
  dest="update_ids",
487
- help="Update a Design Object with the given ID instead",
494
+ help="Update mode. Entities with the given ID(s) are updated instead",
488
495
  )
489
496
  _add_server_option(new_parser)
490
497
 
491
498
  sub_parser = new_parser.add_subparsers(dest="subcommand")
492
499
 
493
500
  # Object parser
494
- object_parser = sub_parser.add_parser("object", help="Create a new Design Object")
501
+ object_parser = sub_parser.add_parser(
502
+ "object", aliases=("obj",), help="Create/Update Design Objects"
503
+ )
495
504
  obj_optional_group = object_parser.add_argument_group("Design Object Options")
496
505
  _add_design_type_option(
497
506
  obj_optional_group,
@@ -522,33 +531,42 @@ def add_new_parser(
522
531
  )
523
532
 
524
533
  # App Parser
525
- app_parser = sub_parser.add_parser("app", help="Create a new Puakama Application")
526
- app_parser.add_argument("--name", "-n", help="The application name", required=True)
534
+ app_parser = sub_parser.add_parser("app", help="Create/Update Applications")
527
535
  app_parser.add_argument(
528
- "--group", "-g", help="The application group", required=True
529
- )
530
- app_optional_group = app_parser.add_argument_group("Optional Arguments")
531
- app_optional_group.add_argument("--description")
532
- app_optional_group.add_argument("--inherit-from")
533
- app_optional_group.add_argument("--template")
534
- app_optional_group.add_argument(
535
- "--import",
536
- metavar="PMX_PATH",
537
- type=_pmx_type,
538
- dest="import_path",
539
- help="Create the application from the given .pmx path",
536
+ "--name",
537
+ "-n",
538
+ help="The name of the application. Required if not updating.",
539
+ type=_non_empty_string,
540
+ )
541
+ app_parser.add_argument(
542
+ "--group",
543
+ "-g",
544
+ help="The application group",
545
+ default="",
546
+ type=lambda v: v.strip(),
547
+ )
548
+
549
+ optional_group = app_parser.add_argument_group(
550
+ "Optional Arguments (Not applicable when importing)"
551
+ )
552
+ optional_group.add_argument(
553
+ "--description", help="Brief description of the application"
554
+ )
555
+ optional_group.add_argument(
556
+ "--inherit-from", help="Parent application to inherit from"
557
+ )
558
+ optional_group.add_argument(
559
+ "--template", help="Template to base the application on"
540
560
  )
541
561
 
542
562
  # Keyword Parser
543
- keyword_parser = sub_parser.add_parser("keyword", help="Create a new Keyword")
563
+ keyword_parser = sub_parser.add_parser(
564
+ "keyword", aliases=("kw",), help="Create/Update Keywords"
565
+ )
544
566
  keyword_parser.add_argument("--app-id", type=int, required=True)
545
567
  keyword_parser.add_argument("--name", "-n", help="The keyword name", required=True)
546
568
  keyword_parser.add_argument("--values", nargs="*", required=True)
547
569
 
548
- _add_update_option(object_parser)
549
- _add_update_option(app_parser)
550
- _add_update_option(keyword_parser)
551
-
552
570
  return new_parser
553
571
 
554
572
 
@@ -682,3 +700,34 @@ def add_execute_parser(command_parser: _SubParsersAction[ArgumentParser]) -> Non
682
700
  help="View the agenda schedule. Alias for 'tell agenda schedule'",
683
701
  )
684
702
  _add_server_option(execute_parser)
703
+
704
+
705
+ def add_import_parser(
706
+ command_parser: _SubParsersAction[ArgumentParser],
707
+ ) -> ArgumentParser:
708
+ import_parser = command_parser.add_parser(
709
+ "import",
710
+ help="Import a .pmx file to create an application.",
711
+ )
712
+ import_parser.add_argument(
713
+ "pmx_path",
714
+ metavar="PATH",
715
+ help="Path to a .pmx file to create an application from.",
716
+ type=_pmx_type,
717
+ )
718
+ import_parser.add_argument(
719
+ "--name",
720
+ "-n",
721
+ help="The application name.",
722
+ required=True,
723
+ type=_non_empty_string,
724
+ )
725
+ import_parser.add_argument(
726
+ "--group",
727
+ "-g",
728
+ help="The application group.",
729
+ default="",
730
+ type=lambda v: v.strip(),
731
+ )
732
+ _add_server_option(import_parser)
733
+ return import_parser
@@ -0,0 +1,22 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import shutil
5
+
6
+ from vortex.models import PuakmaServer
7
+ from vortex.workspace import Workspace
8
+
9
+ logger = logging.getLogger("vortex")
10
+
11
+
12
+ def clean(workspace: Workspace, server: PuakmaServer, include_all: bool = False) -> int:
13
+ cloned_apps = workspace.listapps(None if include_all else server)
14
+ if cloned_apps:
15
+ host_dirs = set(workspace.path / app.host for app in cloned_apps)
16
+ with workspace.exclusive_lock():
17
+ for host_dir in host_dirs:
18
+ shutil.rmtree(host_dir)
19
+ logger.debug(f"Deleted directory '{host_dir}'")
20
+ workspace.update_vscode_settings()
21
+ logger.info("Workspace cleaned")
22
+ return 0
@@ -188,7 +188,7 @@ async def _aclone_app(
188
188
  async def _aclone_apps(
189
189
  workspace: Workspace,
190
190
  server: PuakmaServer,
191
- app_ids: list[int],
191
+ app_ids: set[int],
192
192
  get_resources: bool,
193
193
  open_urls: bool,
194
194
  ) -> int:
@@ -233,10 +233,11 @@ def clone(
233
233
  if reclone:
234
234
  app_ids.extend(app.id for app in workspace.listapps(server))
235
235
 
236
+ unique_app_ids = set(app_ids)
236
237
  with (
237
238
  workspace.exclusive_lock(),
238
- Spinner(f"Cloning {len(app_ids)} application(s)..."),
239
+ Spinner(f"Cloning {len(unique_app_ids)} application(s)..."),
239
240
  ):
240
241
  return asyncio.run(
241
- _aclone_apps(workspace, server, app_ids, get_resources, open_urls)
242
+ _aclone_apps(workspace, server, unique_app_ids, get_resources, open_urls)
242
243
  )
@@ -21,7 +21,7 @@ def _save_bytes(data: bytes, output_path: Path) -> None:
21
21
 
22
22
  async def _aexport(
23
23
  server: PuakmaServer,
24
- app_ids: list[int],
24
+ app_ids: set[int],
25
25
  output_dir: Path,
26
26
  timeout: int,
27
27
  include_source: bool,
@@ -86,7 +86,7 @@ async def _aexport_app_pmx(
86
86
  def export(
87
87
  workspace: Workspace,
88
88
  server: PuakmaServer,
89
- app_ids: list[int],
89
+ app_ids: set[int],
90
90
  *,
91
91
  timeout: int,
92
92
  include_source: bool,
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ from vortex.models import PuakmaServer
7
+ from vortex.spinner import Spinner
8
+
9
+ logger = logging.getLogger("vortex")
10
+
11
+
12
+ def import_(server: PuakmaServer, pmx_path: Path, name: str, group: str) -> int:
13
+ with Spinner("Importing..."):
14
+ with open(pmx_path, "rb") as f:
15
+ pmx_bytes = f.read()
16
+
17
+ with server as s:
18
+ app_id = s.download_designer.upload_pmx(group, name, pmx_bytes)
19
+ logger.info(f"Created Application {group}/{name} [{app_id}] from {pmx_path.name}")
20
+ return 0
@@ -6,7 +6,6 @@ import base64
6
6
  import logging
7
7
  import mimetypes
8
8
  from collections.abc import Iterable
9
- from pathlib import Path
10
9
  from typing import Any
11
10
 
12
11
  import tabulate
@@ -20,7 +19,6 @@ from vortex.models import DesignType
20
19
  from vortex.models import PuakmaApplication
21
20
  from vortex.models import PuakmaServer
22
21
  from vortex.soap import AppDesigner
23
- from vortex.spinner import Spinner
24
22
  from vortex.util import render_apps
25
23
  from vortex.util import render_objects
26
24
  from vortex.workspace import Workspace
@@ -303,17 +301,6 @@ def _new_object(
303
301
  return 0
304
302
 
305
303
 
306
- def _import_pmx(server: PuakmaServer, group: str, name: str, pmx_path: Path) -> int:
307
- with Spinner("Importing..."):
308
- with open(pmx_path, "rb") as f:
309
- pmx_bytes = f.read()
310
-
311
- with server as s:
312
- app_id = s.download_designer.upload_pmx(group, name, pmx_bytes)
313
- logger.info(f"Created Application {group}/{name} [{app_id}] from {pmx_path.name}")
314
- return 0
315
-
316
-
317
304
  def _new_app(
318
305
  server: PuakmaServer,
319
306
  group: str,
@@ -321,11 +308,7 @@ def _new_app(
321
308
  inherit_from: str | None,
322
309
  template_name: str | None,
323
310
  description: str | None,
324
- import_path: Path | None,
325
311
  ) -> int:
326
- if import_path:
327
- return _import_pmx(server, group, name, import_path)
328
-
329
312
  app = PuakmaApplication(-1, name, group, inherit_from, template_name, server.host)
330
313
  print("The following Application will be created:\n")
331
314
  render_apps([app], show_inherited=True)
@@ -398,7 +381,6 @@ def new(workspace: Workspace, server: PuakmaServer, args: argparse.Namespace) ->
398
381
  args.inherit_from,
399
382
  args.template,
400
383
  args.description,
401
- args.import_path,
402
384
  )
403
385
  elif args.subcommand == "keyword":
404
386
  return _new_keyword(
@@ -24,6 +24,7 @@ from vortex.commands.execute import execute
24
24
  from vortex.commands.export import export
25
25
  from vortex.commands.find import find
26
26
  from vortex.commands.grep import grep
27
+ from vortex.commands.import_ import import_
27
28
  from vortex.commands.list import list_
28
29
  from vortex.commands.log import log
29
30
  from vortex.commands.new import new
@@ -95,6 +96,8 @@ def main(argv: Sequence[str] | None = None) -> int:
95
96
  cli.add_docs_parser(command_parser)
96
97
  cli.add_execute_parser(command_parser)
97
98
  cli.add_export_parser(command_parser)
99
+ cli.add_import_parser(command_parser)
100
+
98
101
  clone_parser = cli.add_clone_parser(command_parser)
99
102
  code_parser = cli.add_code_parser(command_parser)
100
103
  db_parser = cli.add_db_parser(command_parser)
@@ -124,9 +127,7 @@ def main(argv: Sequence[str] | None = None) -> int:
124
127
  return 0
125
128
 
126
129
  # Non server commands
127
- if args.command == "clean":
128
- return clean(workspace)
129
- elif args.command == "code":
130
+ if args.command == "code":
130
131
  if args.help:
131
132
  code_parser.print_help()
132
133
  util.print_row_break()
@@ -136,8 +137,11 @@ def main(argv: Sequence[str] | None = None) -> int:
136
137
  return docs()
137
138
 
138
139
  server = workspace.read_server_from_config(server_name)
140
+ logger.debug(f"Using server {server}")
139
141
 
140
- if args.command == "log":
142
+ if args.command == "clean":
143
+ return clean(workspace, server, args.all)
144
+ elif args.command == "log":
141
145
  return log(
142
146
  server,
143
147
  args.limit,
@@ -193,11 +197,13 @@ def main(argv: Sequence[str] | None = None) -> int:
193
197
  return export(
194
198
  workspace,
195
199
  server,
196
- args.app_ids,
200
+ set(args.app_ids),
197
201
  timeout=args.timeout,
198
202
  export_dir=args.export_dir,
199
203
  include_source=args.include_source,
200
204
  )
205
+ elif args.command == "import":
206
+ return import_(server, args.pmx_path, args.name, args.group)
201
207
  elif args.command == "watch":
202
208
  return watch(workspace, server)
203
209
  elif args.command == "find":
@@ -225,9 +231,9 @@ def main(argv: Sequence[str] | None = None) -> int:
225
231
  include_resources=args.include_resources,
226
232
  )
227
233
  elif args.command == "new":
228
- if args.subcommand not in ["object", "app", "keyword"]:
234
+ if args.subcommand not in ["object", "obj", "app", "keyword", "kw"]:
229
235
  new_parser.error(
230
- "'new' command requires a sub command 'object', 'app' or 'keyword'"
236
+ "'new' command requires a sub command 'object', 'obj', 'app' or 'keyword' or 'kw'"
231
237
  )
232
238
  return new(workspace, server, args)
233
239
  elif args.command == "delete":
@@ -368,7 +368,7 @@ class PuakmaApplication:
368
368
  @classmethod
369
369
  def from_dir(cls, path: Path) -> PuakmaApplication:
370
370
  """
371
- Returns an instance of this class from the .PuakmaApplication.pickle file
371
+ Returns an instance of this class from the .pma file
372
372
  within the given directory.
373
373
  Raises ValueError if unsuccessful
374
374
  """
@@ -5,7 +5,6 @@ import sys
5
5
  import threading
6
6
  import time
7
7
  from types import TracebackType
8
- from typing import Literal
9
8
 
10
9
 
11
10
  class Spinner:
@@ -53,6 +52,5 @@ class Spinner:
53
52
  exc_type: type[BaseException] | None,
54
53
  exc_val: BaseException | None,
55
54
  exc_tb: TracebackType | None = None,
56
- ) -> Literal[False]:
55
+ ) -> None:
57
56
  self.stop()
58
- return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vortex_cli
3
- Version: 4.17.2
3
+ Version: 4.18.0
4
4
  Summary: Vortex CLI
5
5
  Author-email: Jordan Amos <jordan.amos@gmail.com>
6
6
  License: MIT License
@@ -26,6 +26,7 @@ vortex/commands/execute.py
26
26
  vortex/commands/export.py
27
27
  vortex/commands/find.py
28
28
  vortex/commands/grep.py
29
+ vortex/commands/import_.py
29
30
  vortex/commands/list.py
30
31
  vortex/commands/log.py
31
32
  vortex/commands/new.py
@@ -1,20 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- import shutil
5
-
6
- from vortex.workspace import Workspace
7
-
8
- logger = logging.getLogger("vortex")
9
-
10
-
11
- def clean(workspace: Workspace) -> int:
12
- app_dirs = workspace.listdir(strict=False)
13
- if app_dirs:
14
- with workspace.exclusive_lock():
15
- for app_dir in app_dirs:
16
- shutil.rmtree(app_dir)
17
- logger.debug(f"Deleted directory '{app_dir}'")
18
- workspace.update_vscode_settings()
19
- logger.info("Workspace cleaned")
20
- return 0
File without changes
File without changes
File without changes
File without changes
File without changes