gibson-cli 0.1.0__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 (102) hide show
  1. api/BaseApi.py +45 -0
  2. api/Cli.py +248 -0
  3. bin/gibson.py +16 -0
  4. command/Api.py +31 -0
  5. command/Base.py +28 -0
  6. command/BaseCommand.py +26 -0
  7. command/Build.py +69 -0
  8. command/Code.py +198 -0
  9. command/Conf.py +74 -0
  10. command/Count.py +35 -0
  11. command/Dev.py +121 -0
  12. command/Forget.py +34 -0
  13. command/Import.py +109 -0
  14. command/List.py +61 -0
  15. command/Merge.py +35 -0
  16. command/Model.py +42 -0
  17. command/Models.py +31 -0
  18. command/Modify.py +43 -0
  19. command/Module.py +42 -0
  20. command/New.py +38 -0
  21. command/OpenApi.py +141 -0
  22. command/Question.py +105 -0
  23. command/Remove.py +80 -0
  24. command/Rename.py +71 -0
  25. command/Rewrite.py +107 -0
  26. command/Schema.py +42 -0
  27. command/Schemas.py +31 -0
  28. command/Show.py +37 -0
  29. command/Test.py +42 -0
  30. command/Tests.py +31 -0
  31. command/Tree.py +92 -0
  32. command/WarGames.py +35 -0
  33. command/auth/Auth.py +25 -0
  34. command/auth/Login.py +17 -0
  35. command/auth/Logout.py +7 -0
  36. command/tests/test_command_BaseCommand.py +10 -0
  37. command/tests/test_command_Conf.py +19 -0
  38. conf/Api.py +3 -0
  39. conf/Code.py +9 -0
  40. conf/Custom.py +4 -0
  41. conf/Datastore.py +4 -0
  42. conf/Dependencies.py +24 -0
  43. conf/Dev.py +15 -0
  44. conf/Frameworks.py +7 -0
  45. conf/Modeler.py +3 -0
  46. conf/Paths.py +10 -0
  47. conf/Platform.py +16 -0
  48. conf/Project.py +18 -0
  49. conf/Version.py +2 -0
  50. conf/dev/Api.py +5 -0
  51. conf/dev/Base.py +3 -0
  52. conf/dev/Model.py +3 -0
  53. conf/dev/Schema.py +3 -0
  54. conf/tests/test_conf_Dependencies.py +5 -0
  55. conf/tests/test_conf_Platform.py +7 -0
  56. core/CommandRouter.py +249 -0
  57. core/Configuration.py +418 -0
  58. core/Conversation.py +270 -0
  59. core/Env.py +12 -0
  60. core/Memory.py +148 -0
  61. core/TimeKeeper.py +12 -0
  62. core/utils.py +19 -0
  63. data/default-ref-table.tmpl +4 -0
  64. data/default-table.tmpl +6 -0
  65. db/TableExceptions.py +6 -0
  66. db/tests/test_db_TableExceptions.py +9 -0
  67. dev/Dev.py +92 -0
  68. display/Header.py +6 -0
  69. display/WorkspaceFooter.py +10 -0
  70. display/WorkspaceHeader.py +8 -0
  71. display/tests/test_display_Header.py +9 -0
  72. display/tests/test_display_WorkspaceFooter.py +9 -0
  73. display/tests/test_display_WorkspaceHeader.py +8 -0
  74. gibson_cli-0.1.0.dist-info/METADATA +306 -0
  75. gibson_cli-0.1.0.dist-info/RECORD +102 -0
  76. gibson_cli-0.1.0.dist-info/WHEEL +5 -0
  77. gibson_cli-0.1.0.dist-info/entry_points.txt +2 -0
  78. gibson_cli-0.1.0.dist-info/top_level.txt +12 -0
  79. lang/Python.py +57 -0
  80. lang/tests/test_lang_Python.py +70 -0
  81. services/auth/Server.py +75 -0
  82. services/code/context/schema/DataDictionary.py +12 -0
  83. services/code/context/schema/EntityKeys.py +49 -0
  84. services/code/context/schema/Manager.py +28 -0
  85. services/code/context/schema/tests/test_code_context_schema_DataDictionary.py +8 -0
  86. services/code/context/schema/tests/test_code_context_schema_EntityKeys.py +52 -0
  87. services/code/context/schema/tests/test_code_context_schema_Manager.py +34 -0
  88. services/code/customization/Authenticator.py +51 -0
  89. services/code/customization/BaseCustomization.py +12 -0
  90. services/code/customization/CustomizationManager.py +20 -0
  91. services/code/customization/tests/test_code_customization_Authenticator.py +53 -0
  92. services/code/customization/tests/test_code_customization_BaseCustomization.py +14 -0
  93. structure/Entity.py +115 -0
  94. structure/constraints/ReferenceConstraint.py +36 -0
  95. structure/keys/ForeignKey.py +41 -0
  96. structure/keys/Index.py +64 -0
  97. structure/keys/IndexAttribute.py +14 -0
  98. structure/keys/tests/test_ForeignKey.py +80 -0
  99. structure/keys/tests/test_Index.py +98 -0
  100. structure/keys/tests/test_IndexAttribute.py +17 -0
  101. structure/testing.py +194 -0
  102. structure/tests/test_Entity.py +107 -0
command/OpenApi.py ADDED
@@ -0,0 +1,141 @@
1
+ import json
2
+ import re
3
+ import sys
4
+
5
+ from api.Cli import Cli
6
+
7
+ from .BaseCommand import BaseCommand
8
+
9
+
10
+ class OpenApi(BaseCommand):
11
+ def bad_json(self):
12
+ self.conversation.display_project(self.configuration.project.name)
13
+ self.conversation.type(
14
+ "I need valid JSON. That file does not appear to be that. Try again?\n"
15
+ )
16
+ self.conversation.newline()
17
+ exit(1)
18
+
19
+ def execute(self):
20
+ if len(sys.argv) != 3:
21
+ self.usage()
22
+
23
+ try:
24
+ with open(sys.argv[2], "r") as f:
25
+ contents = json.loads(f.read())
26
+ except FileNotFoundError:
27
+ self.file_not_found()
28
+ except json.decoder.JSONDecodeError:
29
+ self.bad_json()
30
+
31
+ if "paths" not in contents:
32
+ self.unrecognized_format()
33
+
34
+ self.conversation.display_project(self.configuration.project.name)
35
+
36
+ if contents.get("info", None) is not None:
37
+ if contents["info"].get("title", None) is not None:
38
+ self.conversation.type(contents["info"]["title"])
39
+ self.conversation.newline()
40
+
41
+ path_list = []
42
+ for path, description in contents["paths"].items():
43
+ path_list.append(path)
44
+
45
+ path_list.sort()
46
+
47
+ i = 0
48
+ for path in path_list:
49
+ self.conversation.type(f" {i}: ".rjust(10) + path + "\n", delay=0.0009)
50
+ i += 1
51
+
52
+ self.conversation.newline()
53
+
54
+ self.conversation.type(
55
+ "Now tell me which ones you want me to build for you. You can provide a "
56
+ + 'single\nnumber, a comma separated list of numbers or "all" to build '
57
+ + "everything.\n"
58
+ )
59
+ self.conversation.newline()
60
+
61
+ selection = ""
62
+ while len(selection) == 0:
63
+ selection = input("What should I build? ")
64
+
65
+ selection_list = re.sub(" ", "", selection.lower()).split(",")
66
+
67
+ choices = []
68
+ if "all" in selection_list:
69
+ choices = path_list
70
+ else:
71
+ for choice in selection_list:
72
+ try:
73
+ choices.append(path_list[int(choice)])
74
+ except (IndexError, ValueError):
75
+ pass
76
+
77
+ self.conversation.newline()
78
+
79
+ if len(choices) == 0:
80
+ exit(1)
81
+
82
+ cli = Cli(self.configuration)
83
+ self.conversation.type("Building schema...\n")
84
+
85
+ entities = []
86
+ for choice in choices:
87
+ self.conversation.type(" " + choice + "\n")
88
+
89
+ response = cli.modeler_openapi(
90
+ self.configuration.project.modeler.version,
91
+ json.dumps(contents["paths"][choice]),
92
+ )
93
+
94
+ for entity in response["entities"]:
95
+ entities.append(entity)
96
+ self.conversation.type(" " * 8 + entity["name"])
97
+ self.conversation.newline()
98
+
99
+ self.conversation.type("Reconciling schema...\n")
100
+ response = cli.modeler_reconcile(
101
+ self.configuration.project.modeler.version, entities
102
+ )
103
+
104
+ self.memory.remember_last(response)
105
+
106
+ word_entities = "entities"
107
+ if len(response["entities"]) == 1:
108
+ word_entities = "entity"
109
+
110
+ self.conversation.type("\nSummary\n")
111
+ self.conversation.type(
112
+ f" {len(response['entities'])} {word_entities} imported\n"
113
+ )
114
+ self.conversation.newline()
115
+
116
+ return True
117
+
118
+ def file_not_found(self):
119
+ self.conversation.display_project(self.configuration.project.name)
120
+ self.conversation.type(
121
+ f'Well that embarrassing. There is no file "{sys.argv[2]}".\n'
122
+ )
123
+ self.conversation.newline()
124
+ exit(1)
125
+
126
+ def unrecognized_format(self):
127
+ self.conversation.display_project(self.configuration.project.name)
128
+ self.conversation.type(
129
+ "Well that sucks. I do not recognize this JSON format.\n"
130
+ )
131
+ self.conversation.newline()
132
+ exit(1)
133
+
134
+ def usage(self):
135
+ self.conversation.display_project(self.configuration.project.name)
136
+ self.conversation.type(
137
+ f"usage: {self.configuration.command} openapi [file path]"
138
+ + "\n where [file path] is the full path to an OpenAPI spec\n"
139
+ )
140
+ self.conversation.newline()
141
+ exit(1)
command/Question.py ADDED
@@ -0,0 +1,105 @@
1
+ import os
2
+ import sys
3
+
4
+ from api.Cli import Cli
5
+
6
+ from .BaseCommand import BaseCommand
7
+
8
+
9
+ class Question(BaseCommand):
10
+ TOKEN_FILE = "file://"
11
+ TOKEN_PYTHON = "py://"
12
+ TOKEN_SQL = "sql://"
13
+
14
+ def execute(self):
15
+ if len(sys.argv) < 3:
16
+ self.usage()
17
+
18
+ instructions = ""
19
+ has_file = False
20
+ has_python = False
21
+ has_sql = False
22
+ for term in sys.argv[2:]:
23
+ if self.TOKEN_FILE in term:
24
+ token, path = term.split(self.TOKEN_FILE)
25
+
26
+ try:
27
+ with open(path, "r") as f:
28
+ contents = f.read()
29
+ except FileNotFoundError:
30
+ self.__file_not_found(path)
31
+
32
+ has_file = True
33
+ instructions += f"\n\n{contents}\n\n"
34
+ elif self.TOKEN_PYTHON in term:
35
+ token, import_ = term.split(self.TOKEN_PYTHON)
36
+ import_ = import_.replace(".", "/")
37
+
38
+ contents = None
39
+ for path in os.environ["PYTHONPATH"].split(":"):
40
+ try:
41
+ with open(f"{path}/{import_}.py", "r") as f:
42
+ contents = f.read()
43
+ except FileNotFoundError:
44
+ pass
45
+
46
+ if contents is None:
47
+ self.__python_import_not_found(import_.replace("/", "."))
48
+
49
+ has_python = True
50
+ instructions += f"\n\n{contents}\n\n"
51
+ elif self.TOKEN_SQL in term:
52
+ token, name = term.split(self.TOKEN_SQL)
53
+
54
+ entity = self.memory.recall_entity(name)
55
+ if entity is None:
56
+ self.conversation.not_sure_no_entity(
57
+ self.configuration.project.name, name
58
+ )
59
+ exit(1)
60
+
61
+ has_sql = True
62
+ instructions += f"\n\n{entity['definition']}\n\n"
63
+ else:
64
+ instructions += f"{term} "
65
+
66
+ if instructions != "":
67
+ cli = Cli(self.configuration)
68
+ response = cli.llm_query(instructions, has_file, has_python, has_sql)
69
+
70
+ if response["entities"] is not None and len(response["entities"]) > 0:
71
+ self.memory.remember_last({"entities": response["entities"]})
72
+
73
+ self.conversation.raw_llm_response()
74
+ print(response["commentary"].rstrip())
75
+
76
+ if response["entities"] is not None and len(response["entities"]) > 0:
77
+ self.conversation.newline()
78
+ self.conversation.entities_hijacked()
79
+ self.conversation.newline()
80
+
81
+ self.conversation.newline()
82
+
83
+ def __file_not_found(self, path):
84
+ self.conversation.display_project(self.configuration.project.name)
85
+ self.conversation.type(f'404, My Friend. Cannot find file "{path}".\n')
86
+ self.conversation.newline()
87
+ exit(1)
88
+
89
+ def __python_import_not_found(self, import_):
90
+ self.conversation.display_project(self.configuration.project.name)
91
+ self.conversation.type(f'That\'s a misfire, "{import_}" does not exist.\n')
92
+ self.conversation.newline()
93
+ exit(1)
94
+
95
+ def usage(self):
96
+ self.conversation.display_project(self.configuration.project.name)
97
+ self.conversation.type(
98
+ f"usage: {self.configuration.command} ? [instructions]\n"
99
+ + " where [instructions] is natural language\n"
100
+ + f" use {self.TOKEN_FILE}[path] to import a file from the filesystem\n"
101
+ + f" use {self.TOKEN_PYTHON}[import] to import a file from PYTHONPATH\n"
102
+ + f" use {self.TOKEN_SQL}[entity name] to import the SQL\n"
103
+ )
104
+ self.conversation.newline()
105
+ exit(1)
command/Remove.py ADDED
@@ -0,0 +1,80 @@
1
+ import sys
2
+
3
+ from api.Cli import Cli
4
+
5
+ from .BaseCommand import BaseCommand
6
+ from .Rewrite import Rewrite
7
+
8
+
9
+ class Remove(BaseCommand):
10
+ def execute(self):
11
+ if len(sys.argv) != 3:
12
+ self.usage()
13
+
14
+ self.conversation.display_project(self.configuration.project.name)
15
+
16
+ found = False
17
+
18
+ last = self.memory.recall_last()
19
+ if last is not None:
20
+ entities = []
21
+ for entity in last["entities"]:
22
+ if entity["name"] == sys.argv[2]:
23
+ found = True
24
+ else:
25
+ entities.append(entity)
26
+
27
+ if found:
28
+ if len(entities) == 0:
29
+ self.memory.forget_last()
30
+ else:
31
+ self.memory.remember_last({"entities": entities})
32
+
33
+ self.conversation.type(f"[Removed] {sys.argv[2]}\n")
34
+ self.conversation.newline()
35
+
36
+ return self
37
+
38
+ cli = Cli(self.configuration)
39
+ entities = []
40
+
41
+ stored = self.memory.recall_entities()
42
+ if stored is not None and len(stored) > 0:
43
+ for entity in stored:
44
+ entities.append(entity)
45
+ if entity["name"] == sys.argv[2]:
46
+ found = True
47
+
48
+ if not found:
49
+ self.conversation.type(
50
+ f'Nothing removed, did not find entity named "{sys.argv[2]}".\n'
51
+ )
52
+ self.conversation.newline()
53
+ return self
54
+
55
+ response = cli.modeler_entity_remove(
56
+ self.configuration.project.modeler.version, entities, sys.argv[2]
57
+ )
58
+
59
+ if len(response["entities"]) == 0:
60
+ self.memory.forget_stored()
61
+ else:
62
+ self.memory.remember_entities(response["entities"])
63
+
64
+ self.conversation.type(f"[Removed] {sys.argv[2]}\n")
65
+ self.conversation.newline()
66
+
67
+ Rewrite(self.configuration, header="Refactoring").execute()
68
+
69
+ self.conversation.newline()
70
+
71
+ return self
72
+
73
+ def usage(self):
74
+ self.conversation.display_project(self.configuration.project.name)
75
+ self.conversation.type(
76
+ f"usage: {self.configuration.command} remove [entity name]\n"
77
+ + " where [entity name] is one of the entities that exists in this project\n"
78
+ )
79
+ self.conversation.newline()
80
+ exit(1)
command/Rename.py ADDED
@@ -0,0 +1,71 @@
1
+ import sys
2
+
3
+ from api.Cli import Cli
4
+
5
+ from .BaseCommand import BaseCommand
6
+ from .Rewrite import Rewrite
7
+
8
+
9
+ class Rename(BaseCommand):
10
+ def execute(self):
11
+ if len(sys.argv) != 4:
12
+ self.usage()
13
+
14
+ self.conversation.display_project(self.configuration.project.name)
15
+
16
+ if self.memory.recall_entity(sys.argv[2]) is None:
17
+ self.conversation.type(
18
+ f'Nothing renamed, did not find entity named "{sys.argv[2]}".\n'
19
+ )
20
+ self.conversation.newline()
21
+ return self
22
+
23
+ if self.memory.recall_entity(sys.argv[3]) is not None:
24
+ self.conversation.type(
25
+ f'Cannot rename to "{sys.argv[3]}" because that entity already exists.\n'
26
+ )
27
+ self.conversation.newline()
28
+ return self
29
+
30
+ cli = Cli(self.configuration)
31
+
32
+ last = self.memory.recall_last()
33
+ if last is not None:
34
+ response = cli.modeler_entity_rename(
35
+ self.configuration.project.modeler.version,
36
+ last["entities"],
37
+ sys.argv[2],
38
+ sys.argv[3],
39
+ )
40
+
41
+ self.memory.remember_last({"entities": response["entities"]})
42
+
43
+ stored = self.memory.recall_entities()
44
+ if stored is not None:
45
+ response = cli.modeler_entity_rename(
46
+ self.configuration.project.modeler.version,
47
+ stored,
48
+ sys.argv[2],
49
+ sys.argv[3],
50
+ )
51
+
52
+ self.memory.remember_entities(response["entities"])
53
+
54
+ self.conversation.type(f"[Renamed] {sys.argv[2]} -> {sys.argv[3]}\n")
55
+ self.conversation.newline()
56
+
57
+ Rewrite(self.configuration, header="Refactoring").execute()
58
+
59
+ self.conversation.newline()
60
+
61
+ return self
62
+
63
+ def usage(self):
64
+ self.conversation.display_project(self.configuration.project.name)
65
+ self.conversation.type(
66
+ f"usage: {self.configuration.command} rename [current] [new]\n"
67
+ + " where [current] is the name of an entity and [new] is what "
68
+ + "you want to call it\n"
69
+ )
70
+ self.conversation.newline()
71
+ exit(1)
command/Rewrite.py ADDED
@@ -0,0 +1,107 @@
1
+ import os
2
+ import shutil
3
+
4
+ from core.Configuration import Configuration
5
+ from services.code.customization.CustomizationManager import CustomizationManager
6
+ from core.TimeKeeper import TimeKeeper
7
+
8
+ from .Api import Api
9
+ from .Base import Base
10
+ from .BaseCommand import BaseCommand
11
+ from .Models import Models
12
+ from .Schemas import Schemas
13
+ from .Tests import Tests
14
+
15
+
16
+ class Rewrite(BaseCommand):
17
+ def __init__(
18
+ self,
19
+ configuration: Configuration,
20
+ header="Writing Code",
21
+ wipe=True,
22
+ with_header=False,
23
+ ):
24
+ super().__init__(configuration)
25
+ self.wipe = wipe
26
+ self.with_header = with_header
27
+
28
+ def execute(self):
29
+ if self.with_header is True:
30
+ self.conversation.display_project(self.configuration.project.name)
31
+
32
+ customization_manager = CustomizationManager(self.configuration).preserve()
33
+
34
+ try:
35
+ if self.wipe is True:
36
+ for root, dirs, files in os.walk(
37
+ os.path.expandvars(self.configuration.project.dev.base.path)
38
+ ):
39
+ for file in files:
40
+ os.unlink(os.path.join(root, file))
41
+
42
+ for dir_ in dirs:
43
+ shutil.rmtree(os.path.join(root, dir_))
44
+
45
+ self.conversation.type("Writing Code\n")
46
+
47
+ time_keeper = TimeKeeper()
48
+
49
+ self.conversation.type(" API ")
50
+
51
+ self.conversation.mute()
52
+ Api(self.configuration).disable_customization_management().execute()
53
+ self.conversation.unmute()
54
+
55
+ self.conversation.type(time_keeper.get_display())
56
+ self.conversation.newline()
57
+
58
+ time_keeper = TimeKeeper()
59
+
60
+ self.conversation.type(" Base ")
61
+
62
+ self.conversation.mute()
63
+ Base(self.configuration).execute()
64
+ self.conversation.unmute()
65
+
66
+ self.conversation.type(time_keeper.get_display())
67
+ self.conversation.newline()
68
+
69
+ time_keeper = TimeKeeper()
70
+
71
+ self.conversation.type(" Models ")
72
+
73
+ self.conversation.mute()
74
+ Models(self.configuration).execute()
75
+ self.conversation.unmute()
76
+
77
+ self.conversation.type(time_keeper.get_display())
78
+ self.conversation.newline()
79
+
80
+ time_keeper = TimeKeeper()
81
+
82
+ self.conversation.type(" Schemas ")
83
+
84
+ self.conversation.mute()
85
+ Schemas(self.configuration).execute()
86
+ self.conversation.unmute()
87
+
88
+ self.conversation.type(time_keeper.get_display())
89
+ self.conversation.newline()
90
+
91
+ time_keeper = TimeKeeper()
92
+
93
+ self.conversation.type(" Tests ")
94
+
95
+ self.conversation.mute()
96
+ Tests(self.configuration).execute()
97
+ self.conversation.unmute()
98
+
99
+ self.conversation.type(time_keeper.get_display())
100
+ self.conversation.newline()
101
+ finally:
102
+ customization_manager.restore()
103
+
104
+ if self.with_header is True:
105
+ self.conversation.newline()
106
+
107
+ return self
command/Schema.py ADDED
@@ -0,0 +1,42 @@
1
+ import sys
2
+
3
+ from api.Cli import Cli
4
+ from dev.Dev import Dev
5
+ from core.TimeKeeper import TimeKeeper
6
+
7
+ from .BaseCommand import BaseCommand
8
+
9
+
10
+ class Schema(BaseCommand):
11
+ def execute(self):
12
+ if len(sys.argv) != 3:
13
+ self.usage()
14
+
15
+ entity = self.memory.recall_stored_entity(sys.argv[2])
16
+ if entity is None:
17
+ self.conversation.not_sure_no_entity(
18
+ self.configuration.project.name, sys.argv[2]
19
+ )
20
+ exit(1)
21
+
22
+ time_keeper = TimeKeeper()
23
+
24
+ cli = Cli(self.configuration)
25
+ response = cli.code_schemas([entity["name"]])
26
+
27
+ Dev(self.configuration).schema(
28
+ response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
+ )
30
+
31
+ print(response["code"][0]["definition"])
32
+ time_keeper.display()
33
+
34
+ def usage(self):
35
+ self.conversation.display_project(self.configuration.project.name)
36
+ self.conversation.type(
37
+ f"usage: {self.configuration.command} schema [entity name]\n"
38
+ + " where [entity name] is one of the entities that exists in "
39
+ + "this project\n"
40
+ )
41
+ self.conversation.newline()
42
+ exit(1)
command/Schemas.py ADDED
@@ -0,0 +1,31 @@
1
+ from api.Cli import Cli
2
+ from dev.Dev import Dev
3
+ from core.TimeKeeper import TimeKeeper
4
+
5
+ from .BaseCommand import BaseCommand
6
+
7
+
8
+ class Schemas(BaseCommand):
9
+ def execute(self):
10
+ entities = []
11
+ if self.memory.entities is not None:
12
+ for entity in self.memory.entities:
13
+ entities.append(entity["name"])
14
+
15
+ if len(entities) == 0:
16
+ self.conversation.cant_no_entities(self.configuration.project.name)
17
+ exit(1)
18
+
19
+ time_keeper = TimeKeeper()
20
+
21
+ cli = Cli(self.configuration)
22
+ response = cli.code_schemas(entities)
23
+
24
+ for entry in response["code"]:
25
+ Dev(self.configuration).schema(entry["entity"]["name"], entry["definition"])
26
+
27
+ if self.conversation.muted() is False:
28
+ print(entry["definition"])
29
+
30
+ if self.conversation.muted() is False:
31
+ time_keeper.display()
command/Show.py ADDED
@@ -0,0 +1,37 @@
1
+ import sys
2
+
3
+ from .BaseCommand import BaseCommand
4
+
5
+
6
+ class Show(BaseCommand):
7
+ def execute(self):
8
+ if len(sys.argv) == 2:
9
+ entities = self.memory.recall_merged()
10
+ if entities is None:
11
+ self.conversation.cant_no_entities(self.configuration.project.name)
12
+ exit(1)
13
+ elif len(sys.argv) == 3:
14
+ entity = self.memory.recall_entity(sys.argv[2])
15
+ if entity is None:
16
+ self.conversation.not_sure_no_entity(
17
+ self.configuration.project.name, sys.argv[2]
18
+ )
19
+ exit(1)
20
+
21
+ entities = [entity]
22
+ else:
23
+ self.usage()
24
+
25
+ for entity in entities:
26
+ print(entity["definition"])
27
+
28
+ def usage(self):
29
+ self.conversation.display_project(self.configuration.project.name)
30
+ self.conversation.type(
31
+ f"usage: {self.configuration.command} show {{entity name}}\n"
32
+ + " where {entity name} is one of the entities that exists in "
33
+ + "this project\n"
34
+ + " omitting {entity name} displays all entities\n"
35
+ )
36
+ self.conversation.newline()
37
+ exit(1)
command/Test.py ADDED
@@ -0,0 +1,42 @@
1
+ import sys
2
+
3
+ from api.Cli import Cli
4
+ from dev.Dev import Dev
5
+ from core.TimeKeeper import TimeKeeper
6
+
7
+ from .BaseCommand import BaseCommand
8
+
9
+
10
+ class Test(BaseCommand):
11
+ def execute(self):
12
+ if len(sys.argv) != 3:
13
+ self.usage()
14
+
15
+ entity = self.memory.recall_stored_entity(sys.argv[2])
16
+ if entity is None:
17
+ self.conversation.not_sure_no_entity(
18
+ self.configuration.project.name, sys.argv[2]
19
+ )
20
+ exit(1)
21
+
22
+ time_keeper = TimeKeeper()
23
+
24
+ cli = Cli(self.configuration)
25
+ response = cli.code_testing([entity["name"]])
26
+
27
+ Dev(self.configuration).tests(
28
+ response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
+ )
30
+
31
+ print(response["code"][0]["definition"])
32
+ time_keeper.display()
33
+
34
+ def usage(self):
35
+ self.conversation.display_project(self.configuration.project.name)
36
+ self.conversation.type(
37
+ f"usage: {self.configuration.command} test [entity name]\n"
38
+ + " where [entity name] is one of the entities that exists "
39
+ + "in this project\n"
40
+ )
41
+ self.conversation.newline()
42
+ exit(1)
command/Tests.py ADDED
@@ -0,0 +1,31 @@
1
+ from api.Cli import Cli
2
+ from dev.Dev import Dev
3
+ from core.TimeKeeper import TimeKeeper
4
+
5
+ from .BaseCommand import BaseCommand
6
+
7
+
8
+ class Tests(BaseCommand):
9
+ def execute(self):
10
+ entities = []
11
+ if self.memory.entities is not None:
12
+ for entity in self.memory.entities:
13
+ entities.append(entity["name"])
14
+
15
+ if len(entities) == 0:
16
+ self.conversation.cant_no_entities(self.configuration.project.name)
17
+ exit(1)
18
+
19
+ time_keeper = TimeKeeper()
20
+
21
+ cli = Cli(self.configuration)
22
+ response = cli.code_testing(entities)
23
+
24
+ for entry in response["code"]:
25
+ Dev(self.configuration).tests(entry["entity"]["name"], entry["definition"])
26
+
27
+ if self.conversation.muted() is False:
28
+ print(entry["definition"])
29
+
30
+ if self.conversation.muted() is False:
31
+ time_keeper.display()