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
api/BaseApi.py ADDED
@@ -0,0 +1,45 @@
1
+ import requests
2
+
3
+
4
+ class BaseApi:
5
+ def get_headers(self):
6
+ raise NotImplementedError
7
+
8
+ def _get(self, end_point):
9
+ r = requests.get(self.get_url(end_point), headers=self.get_headers())
10
+
11
+ self.__raise_for_status(r)
12
+
13
+ return r.json()
14
+
15
+ def _post(self, end_point, json: dict):
16
+ r = requests.post(
17
+ self.get_url(end_point), headers=self.get_headers(), json=json
18
+ )
19
+
20
+ self.__raise_for_status(r)
21
+
22
+ return r
23
+
24
+ def _put(self, end_point, json: dict):
25
+ r = requests.put(self.get_url(end_point), headers=self.get_headers(), json=json)
26
+
27
+ self.__raise_for_status(r)
28
+
29
+ return r
30
+
31
+ def __raise_for_status(self, r):
32
+ try:
33
+ r.raise_for_status()
34
+ except:
35
+ try:
36
+ message = r.json()
37
+
38
+ print("=" * 78)
39
+ print("Raw Response:\n")
40
+ print(message)
41
+ print("\n" + "=" * 78)
42
+ except requests.exceptions.JSONDecodeError:
43
+ pass
44
+
45
+ raise
api/Cli.py ADDED
@@ -0,0 +1,248 @@
1
+ import os
2
+ import requests
3
+
4
+ from services.auth.Server import Server as AuthServer
5
+ from core.Configuration import Configuration
6
+ from lang.Python import Python
7
+ from core.Memory import Memory
8
+
9
+ from .BaseApi import BaseApi
10
+
11
+
12
+ class Cli(BaseApi):
13
+ API_ENV = os.environ.get("GIBSONAI_API_ENV", "staging")
14
+ PREFIX = "cli"
15
+ VERSION = "v1"
16
+
17
+ def __init__(self, configuration: Configuration):
18
+ super().__init__()
19
+ self.configuration = configuration
20
+
21
+ def code_api(self):
22
+ return self._post(
23
+ "code/api",
24
+ self.__structure_context_payload(self.configuration, with_stored=True),
25
+ ).json()
26
+
27
+ def code_base(self):
28
+ return self._post(
29
+ "code/base",
30
+ self.__structure_context_payload(self.configuration, with_stored=True),
31
+ ).json()
32
+
33
+ def code_model_attributes(self, model_name, instructions):
34
+ payload = self.__structure_context_payload(self.configuration)
35
+ payload["model"] = {"name": model_name}
36
+ payload["q"] = instructions
37
+
38
+ return self._post("code/model/attributes", payload).json()
39
+
40
+ def code_models(self, entities: list):
41
+ payload = self.__structure_context_payload(self.configuration, with_stored=True)
42
+ payload["entities"] = entities
43
+
44
+ return self._post("code/models", payload).json()
45
+
46
+ def code_schemas(self, entities: list):
47
+ payload = self.__structure_context_payload(self.configuration, with_stored=True)
48
+ payload["entities"] = entities
49
+
50
+ return self._post("code/schemas", payload).json()
51
+
52
+ def code_testing(self, entities: list):
53
+ payload = self.__structure_context_payload(self.configuration, with_stored=True)
54
+ payload["entities"] = entities
55
+
56
+ return self._post("code/testing", payload).json()
57
+
58
+ def code_writer_entity_modifier(self, context, name, definition, instructions):
59
+ payload = self.__structure_context_payload(self.configuration)
60
+ payload["context"] = context
61
+ payload["entity"] = {"definition": definition, "name": name}
62
+ payload["q"] = instructions
63
+
64
+ return self._post("code/writer/entity/modifier", payload).json()
65
+
66
+ def code_writer_schema_context(self):
67
+ return self._post(
68
+ "code/writer/schema/context",
69
+ self.__structure_context_payload(self.configuration, with_stored=True),
70
+ ).json()
71
+
72
+ def get_client_id(self):
73
+ return {
74
+ "local": "9b0cbebd-3eb4-47be-89ac-4aa589316ff4",
75
+ "staging": "02459e16-f356-4c01-b689-59847ed04b0a",
76
+ "production": "da287371-240b-4b53-bfde-4b1581cca62a",
77
+ }[self.API_ENV]
78
+
79
+ def get_api_domain(self):
80
+ return {
81
+ "local": "http://localhost:8000",
82
+ "staging": "https://staging-api.gibsonai.com",
83
+ "production": "https://api.gibsonai.com",
84
+ }[self.API_ENV]
85
+
86
+ def get_app_domain(self):
87
+ return {
88
+ "local": "http://localhost:5173",
89
+ "staging": "https://staging-app.gibsonai.com",
90
+ "production": "https://app.gibsonai.com",
91
+ }[self.API_ENV]
92
+
93
+ def get_headers(self):
94
+ headers = {
95
+ "X-Gibson-Client-ID": self.get_client_id(),
96
+ "X-Gibson-API-Key": self.configuration.project.api.key,
97
+ }
98
+
99
+ token = self.configuration.get_access_token()
100
+ if token is not None:
101
+ headers["Authorization"] = f"Bearer {token}"
102
+
103
+ return headers
104
+
105
+ def get_url(self, end_point):
106
+ return f"{self.get_api_domain()}/{self.VERSION}/{self.PREFIX}/{end_point}"
107
+
108
+ def import_(self):
109
+ return self._get("import")
110
+
111
+ def llm_query(self, instructions, has_file, has_python, has_sql):
112
+ project_config = self.configuration.project
113
+ r = self._post(
114
+ "llm/query",
115
+ {
116
+ "content": {
117
+ "meta": {
118
+ "file": int(has_file),
119
+ "python": int(has_python),
120
+ "sql": int(has_sql),
121
+ }
122
+ },
123
+ "frameworks": {
124
+ "api": project_config.code.frameworks.api,
125
+ "model": project_config.code.frameworks.model,
126
+ "revision": project_config.code.frameworks.revision,
127
+ "schema_": project_config.code.frameworks.schema,
128
+ "test": project_config.code.frameworks.test,
129
+ },
130
+ "q": instructions,
131
+ },
132
+ )
133
+
134
+ return r.json()
135
+
136
+ def login(self):
137
+ token = AuthServer(self.get_app_domain()).get_token()
138
+ return token
139
+
140
+ def modeler_entity_modify(
141
+ self, modeler_version, project_description, entity: dict, modifications: str
142
+ ):
143
+ r = self._put(
144
+ "modeler/entity/modify",
145
+ {
146
+ "entity": entity,
147
+ "modeler": {"version": modeler_version},
148
+ "modifications": modifications,
149
+ "project": {"description": project_description},
150
+ },
151
+ )
152
+
153
+ return r.json()
154
+
155
+ def modeler_entity_remove(self, modeler_version, entities: list, entity_name):
156
+ r = self._put(
157
+ "modeler/entity/remove",
158
+ {
159
+ "entity": {"name": entity_name},
160
+ "modeler": {"version": modeler_version},
161
+ "schema_": entities,
162
+ },
163
+ )
164
+
165
+ return r.json()
166
+
167
+ def modeler_entity_rename(self, modeler_version, entities: list, current, new):
168
+ r = self._put(
169
+ "modeler/entity/rename",
170
+ {
171
+ "entity": {"current": current, "new": new},
172
+ "modeler": {"version": modeler_version},
173
+ "schema_": entities,
174
+ },
175
+ )
176
+
177
+ return r.json()
178
+
179
+ def modeler_module(self, modeler_version, project_description, module):
180
+ r = self._post(
181
+ "modeler/module",
182
+ {
183
+ "modeler": {"version": modeler_version},
184
+ "module": module,
185
+ "project": {"description": project_description},
186
+ },
187
+ )
188
+
189
+ return r.json()
190
+
191
+ def modeler_openapi(self, modeler_version, contents):
192
+ r = self._post(
193
+ "modeler/openapi",
194
+ {"contents": contents, "modeler": {"version": modeler_version}},
195
+ )
196
+
197
+ return r.json()
198
+
199
+ def modeler_reconcile(self, modeler_version, entities: list):
200
+ r = self._post(
201
+ "modeler/reconcile",
202
+ {"modeler": {"version": modeler_version}, "schema_": entities},
203
+ )
204
+
205
+ return r.json()
206
+
207
+ def __structure_context_payload(
208
+ self,
209
+ with_last=False,
210
+ with_merged=False,
211
+ with_stored=False,
212
+ ):
213
+ project_config = self.configuration.project
214
+ payload = {
215
+ "api": {
216
+ "prefix": project_config.dev.api.prefix,
217
+ "version": project_config.dev.api.version,
218
+ },
219
+ "frameworks": {
220
+ "api": project_config.code.frameworks.api,
221
+ "model": project_config.code.frameworks.model,
222
+ "revision": project_config.code.frameworks.revision,
223
+ "schema_": project_config.code.frameworks.schema,
224
+ "test": project_config.code.frameworks.test,
225
+ },
226
+ "language": project_config.code.language,
227
+ "path": {
228
+ "api": Python().make_import_path(project_config.dev.api.path),
229
+ "base": Python().make_import_path(project_config.dev.base.path),
230
+ "custom": {
231
+ "model": {
232
+ "class_": project_config.code.custom.model_class,
233
+ "path": project_config.code.custom.model_path,
234
+ }
235
+ },
236
+ "model": Python().make_import_path(project_config.dev.model.path),
237
+ "schema_": Python().make_import_path(project_config.dev.schema.path),
238
+ },
239
+ }
240
+
241
+ if with_last is True:
242
+ payload["schema_"] = Memory(self.configuration).recall_last()["entities"]
243
+ elif with_merged is True:
244
+ payload["schema_"] = Memory(self.configuration).recall_merged()
245
+ elif with_stored is True:
246
+ payload["schema_"] = Memory(self.configuration).recall_entities()
247
+
248
+ return payload
bin/gibson.py ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env python3
2
+
3
+ from core.CommandRouter import CommandRouter
4
+ from core.Configuration import Configuration
5
+
6
+
7
+ def main():
8
+ configuration = Configuration()
9
+ if configuration.settings is None:
10
+ configuration.initialize()
11
+ else:
12
+ router = CommandRouter(configuration).run()
13
+
14
+
15
+ if __name__ == "__main__":
16
+ main()
command/Api.py ADDED
@@ -0,0 +1,31 @@
1
+ from api.Cli import Cli
2
+ from dev.Dev import Dev
3
+ from services.code.customization.Authenticator import Authenticator
4
+ from core.TimeKeeper import TimeKeeper
5
+
6
+ from .BaseCommand import BaseCommand
7
+
8
+
9
+ class Api(BaseCommand):
10
+ def execute(self):
11
+ time_keeper = TimeKeeper()
12
+ dev = Dev(self.configuration)
13
+
14
+ cli = Cli(self.configuration)
15
+ response = cli.code_api()
16
+
17
+ if self.customization_management_is_enabled() is True:
18
+ authenticator = Authenticator(self.configuration).preserve()
19
+
20
+ try:
21
+ for entry in response["code"]:
22
+ dev.api_component(entry["name"], entry["definition"])
23
+
24
+ if self.conversation.muted() is False:
25
+ print(entry["definition"])
26
+ finally:
27
+ if self.customization_management_is_enabled() is True:
28
+ authenticator.restore()
29
+
30
+ if self.conversation.muted() is False:
31
+ time_keeper.display()
command/Base.py ADDED
@@ -0,0 +1,28 @@
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 Base(BaseCommand):
9
+ def execute(self):
10
+ entities = self.memory.recall_merged()
11
+ if len(entities) == 0:
12
+ self.conversation.cant_no_entities(self.configuration.project.name)
13
+ exit(1)
14
+
15
+ time_keeper = TimeKeeper()
16
+ dev = Dev(self.configuration)
17
+
18
+ cli = Cli(self.configuration)
19
+ response = cli.code_base()
20
+
21
+ for entry in response["code"]:
22
+ dev.base_component(entry["name"], entry["definition"])
23
+
24
+ if self.conversation.muted() is False:
25
+ print(entry["definition"])
26
+
27
+ if self.conversation.muted() is False:
28
+ time_keeper.display()
command/BaseCommand.py ADDED
@@ -0,0 +1,26 @@
1
+ from core.Configuration import Configuration
2
+ from core.Memory import Memory
3
+
4
+
5
+ class BaseCommand:
6
+ def __init__(self, configuration: Configuration):
7
+ self.__enable_customization_management = True
8
+ self.configuration = configuration
9
+ self.conversation = self.configuration.conversation
10
+ self.memory = Memory(self.configuration)
11
+
12
+ def customization_management_is_enabled(self):
13
+ return self.__enable_customization_management == True
14
+
15
+ def disable_customization_management(self):
16
+ self.__enable_customization_management = False
17
+ return self
18
+
19
+ def execute(self):
20
+ raise NotImplementedError
21
+
22
+ def num_required_args(self):
23
+ raise NotImplementedError
24
+
25
+ def usage(self):
26
+ return self
command/Build.py ADDED
@@ -0,0 +1,69 @@
1
+ import sys
2
+
3
+ from sqlalchemy import create_engine
4
+ from sqlalchemy.orm import sessionmaker
5
+
6
+ from db.TableExceptions import TableExceptions
7
+
8
+ from .BaseCommand import BaseCommand
9
+
10
+
11
+ class Build(BaseCommand):
12
+ def __build_datastore(self):
13
+ self.conversation.display_project(self.configuration.project.name)
14
+
15
+ db = create_engine(self.configuration.project.datastore.uri)
16
+ session = sessionmaker(autocommit=False, autoflush=False, bind=db)()
17
+ table_exceptions = TableExceptions().universal()
18
+
19
+ self.conversation.type("Connected to datastore...\n")
20
+
21
+ try:
22
+ if self.configuration.project.datastore.type == "mysql":
23
+ table_exceptions = TableExceptions().mysql()
24
+ session.execute("set foreign_key_checks = 0")
25
+ self.conversation.type(" foreign key checks have been disabled\n")
26
+
27
+ tables = session.execute("show tables").all()
28
+ if len(tables) > 0:
29
+ self.conversation.type(" dropping existing entities\n")
30
+
31
+ for table in tables:
32
+ if table not in table_exceptions:
33
+ self.conversation.type(f" {table[0]}\n", delay=0.002)
34
+ session.execute(f"drop table if exists {table[0]}")
35
+
36
+ self.conversation.type(" building entities\n")
37
+
38
+ for entity in self.memory.entities:
39
+ self.conversation.type(f" {entity['name']}\n", delay=0.002)
40
+ session.execute(entity["definition"])
41
+ finally:
42
+ if self.configuration.project.datastore.type == "mysql":
43
+ session.execute("set foreign_key_checks = 1")
44
+ self.conversation.type(" foreign key checks have been enabled\n")
45
+
46
+ self.conversation.newline()
47
+
48
+ def execute(self):
49
+ if len(sys.argv) != 3 or sys.argv[2] != "datastore":
50
+ self.usage()
51
+
52
+ if self.memory.entities is None or len(self.memory.entities) == 0:
53
+ self.no_entities()
54
+
55
+ self.__build_datastore()
56
+
57
+ def no_entities(self):
58
+ self.conversation.display_project(self.configuration.project.name)
59
+ self.conversation.type(
60
+ "Ahhh man. I would love to but there aren't any entities.\n"
61
+ )
62
+ self.conversation.newline()
63
+ exit(1)
64
+
65
+ def usage(self):
66
+ self.conversation.display_project(self.configuration.project.name)
67
+ self.conversation.type(f"usage: {self.configuration.command} build datastore\n")
68
+ self.conversation.newline()
69
+ exit(1)
command/Code.py ADDED
@@ -0,0 +1,198 @@
1
+ import os
2
+ import re
3
+ import sys
4
+ from string import Template
5
+
6
+ from api.Cli import Cli
7
+ from core.Configuration import Configuration
8
+ from display.Header import Header
9
+ from display.WorkspaceFooter import WorkspaceFooter
10
+ from display.WorkspaceHeader import WorkspaceHeader
11
+ from services.code.context.schema.Manager import Manager as CodeContextSchemaManager
12
+ from structure.Entity import Entity
13
+
14
+ from .BaseCommand import BaseCommand
15
+ from .Merge import Merge
16
+ from .Rewrite import Rewrite
17
+
18
+
19
+ class Code(BaseCommand):
20
+ CODE_WRITER_ENTITY_MODIFIER_NOOP = ""
21
+
22
+ def __init__(self, configuration: Configuration):
23
+ super().__init__(configuration)
24
+ self.__context = None
25
+
26
+ def __add_foreign_key(self, entity, entity_name):
27
+ entity_keys = self.__context.get_entity_keys(entity_name)
28
+ if entity_keys is None:
29
+ self.conversation.type(
30
+ f'\nThe entity you referenced, "{entity_name}", does not exist.\n'
31
+ )
32
+ self.conversation.wait()
33
+ return False
34
+
35
+ best_sql_foreign_key = entity_keys.best_sql_foreign_key()
36
+ if best_sql_foreign_key is None:
37
+ self.conversation.type(
38
+ f'\nYou cannot make a foreign key to "{entity_name}".\n'
39
+ + "It does not have primary or unique keys.\n"
40
+ )
41
+ self.conversation.wait()
42
+ return False
43
+
44
+ foreign_key, index, data_types = best_sql_foreign_key
45
+
46
+ for i in range(len(foreign_key.attributes)):
47
+ entity.add_attribute(
48
+ foreign_key.attributes[i],
49
+ data_types[i],
50
+ after="uuid",
51
+ before="date_created",
52
+ )
53
+
54
+ entity.add_foreign_key(foreign_key)
55
+ entity.add_index(index)
56
+
57
+ return True
58
+
59
+ def configure_definition(self):
60
+ existing_entity = self.memory.recall_entity(sys.argv[3])
61
+ if existing_entity is not None:
62
+ return existing_entity["definition"]
63
+
64
+ parts = sys.argv[3].split("_")
65
+ if len(parts) > 1 and parts[1] == "ref":
66
+ # This is a reference table implementation. We will handle this here.
67
+ with open(self.get_default_ref_table_template_path()) as f:
68
+ definition = Template(f.read()).substitute({"entity_name": sys.argv[3]})
69
+
70
+ self.memory.append_last({"definition": definition, "name": sys.argv[3]})
71
+
72
+ self.conversation.type(
73
+ "Reference table created and stored in last memory. What's next?\n"
74
+ )
75
+ self.conversation.newline()
76
+
77
+ exit(1)
78
+
79
+ with open(self.get_default_table_template_path()) as f:
80
+ return Template(f.read()).substitute({"entity_name": sys.argv[3]})
81
+
82
+ def execute(self):
83
+ if len(sys.argv) != 4 or sys.argv[2] not in ["entity"]:
84
+ self.usage()
85
+
86
+ cli = Cli(self.configuration)
87
+
88
+ self.conversation.display_project(self.configuration.project.name)
89
+ definition = self.configure_definition()
90
+
91
+ self.conversation.c64_boot_search()
92
+
93
+ self.__context = CodeContextSchemaManager().from_code_writer_schema_context(
94
+ cli.code_writer_schema_context()
95
+ )
96
+
97
+ self.conversation.c64_boot_loading()
98
+
99
+ data = cli.code_writer_entity_modifier(
100
+ self.__context.json,
101
+ sys.argv[3],
102
+ definition,
103
+ self.CODE_WRITER_ENTITY_MODIFIER_NOOP,
104
+ )
105
+ entity = Entity().import_from_struct(data)
106
+
107
+ self.conversation.c64_ready_run()
108
+
109
+ while True:
110
+ self.__render_workspace(entity, data["code"][0]["definition"])
111
+
112
+ input_ = input("> ")
113
+ if input_ in [".", ":q", ":w"]:
114
+ self.conversation.newline()
115
+
116
+ if input_ == ":q":
117
+ exit(1)
118
+
119
+ self.memory.remember_last({"entities": [data["entity"]]})
120
+
121
+ if input_ == ".":
122
+ self.conversation.type(
123
+ "Damn we write good code. I stored this in last memory. "
124
+ + "Your move.\n"
125
+ )
126
+ else:
127
+ self.conversation.mute()
128
+ Merge(self.configuration).execute()
129
+ self.conversation.unmute()
130
+
131
+ Rewrite(self.configuration, wipe=False).execute()
132
+
133
+ self.conversation.newline()
134
+
135
+ exit(1)
136
+ elif input_ == "":
137
+ continue
138
+
139
+ talk_to_gibsonai = True
140
+
141
+ parts = input_.split(" ")
142
+ if parts[0] == "fk":
143
+ input_ = self.CODE_WRITER_ENTITY_MODIFIER_NOOP
144
+ if not self.__add_foreign_key(entity, parts[1]):
145
+ # If the entity was not modified, likely because the table
146
+ # referenced does not exist or does not contain indexes which
147
+ # can be used for a foreign key, do not waste the network call
148
+ # to GibsonAI since there is nothing to do.
149
+ talk_to_gibsonai = False
150
+
151
+ if talk_to_gibsonai is True:
152
+ data = cli.code_writer_entity_modifier(
153
+ self.__context.json,
154
+ data["entity"]["name"],
155
+ entity.create_statement(),
156
+ input_,
157
+ )
158
+ entity = Entity().import_from_struct(data)
159
+
160
+ def get_default_ref_table_template_path(self):
161
+ return os.path.dirname(__file__) + "/../data/default-ref-table.tmpl"
162
+
163
+ def get_default_table_template_path(self):
164
+ return os.path.dirname(__file__) + "/../data/default-table.tmpl"
165
+
166
+ def __render_workspace(self, entity: Entity, model):
167
+ self.configuration.platform.cmd_clear()
168
+
169
+ print("")
170
+ print(WorkspaceHeader().render(self.configuration.project.name))
171
+
172
+ print("")
173
+ print(Header().render("SQL"))
174
+ print("")
175
+ print(entity.create_statement())
176
+
177
+ print("")
178
+ print(Header().render("Model"))
179
+ print("")
180
+ print(model)
181
+
182
+ print("")
183
+ print(WorkspaceFooter().render())
184
+
185
+ def usage(self):
186
+ self.conversation.display_project(self.configuration.project.name)
187
+ self.conversation.type(
188
+ f"usage: {self.configuration.command} code [thing] [name]\n"
189
+ + ' where [thing] can only be "entity", for now\n'
190
+ + " and [name] is what you want [thing] to be called\n"
191
+ )
192
+ self.conversation.newline()
193
+ self.conversation.type(
194
+ ' To create a new entity called "user":\n'
195
+ " gibson code entity user\n"
196
+ )
197
+ self.conversation.newline()
198
+ exit(1)