gibson-cli 0.7.3__tar.gz → 0.7.5__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.
- {gibson_cli-0.7.3/gibson_cli.egg-info → gibson_cli-0.7.5}/PKG-INFO +2 -1
- gibson_cli-0.7.5/gibson/bin/gibson.py +19 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Help.py +2 -2
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Version.py +3 -3
- gibson_cli-0.7.5/gibson/command/code/Entity.py +231 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Model.py +11 -9
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Schema.py +11 -9
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Test.py +11 -9
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rewrite/Rewrite.py +0 -1
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Colors.py +35 -15
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Configuration.py +2 -1
- gibson_cli-0.7.5/gibson/core/Diff.py +34 -0
- gibson_cli-0.7.5/gibson/core/Spinner.py +37 -0
- gibson_cli-0.7.5/gibson/display/Header.py +11 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/WorkspaceFooter.py +3 -3
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/WorkspaceHeader.py +3 -3
- gibson_cli-0.7.5/gibson/display/tests/test_display_Header.py +12 -0
- gibson_cli-0.7.5/gibson/display/tests/test_display_WorkspaceFooter.py +11 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/tests/test_display_WorkspaceHeader.py +2 -2
- {gibson_cli-0.7.3 → gibson_cli-0.7.5/gibson_cli.egg-info}/PKG-INFO +2 -1
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/SOURCES.txt +2 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/requires.txt +1 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/pyproject.toml +1 -1
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/requirements.txt +1 -0
- gibson_cli-0.7.3/gibson/bin/gibson.py +0 -16
- gibson_cli-0.7.3/gibson/command/code/Entity.py +0 -197
- gibson_cli-0.7.3/gibson/display/Header.py +0 -10
- gibson_cli-0.7.3/gibson/display/tests/test_display_Header.py +0 -10
- gibson_cli-0.7.3/gibson/display/tests/test_display_WorkspaceFooter.py +0 -11
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/.gitignore +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/.pre-commit-config.yaml +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/README.md +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/build.sh +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/clean.sh +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/release.sh +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/BaseApi.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/Cli.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/ProjectApi.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/BaseCommand.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Build.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Conf.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Count.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Dev.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Forget.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Merge.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Modify.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Question.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Remove.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Show.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Tree.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/WarGames.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Auth.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Login.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Logout.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Api.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Base.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Code.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Models.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Schemas.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Tests.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/importer/Import.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/importer/OpenApi.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/Entities.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/List.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/Projects.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/Module.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/New.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/Project.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rename/Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rename/Rename.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/tests/test_command_BaseCommand.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/tests/test_command_Conf.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Api.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Code.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Custom.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Datastore.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Dependencies.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Dev.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Frameworks.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Modeler.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Paths.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Platform.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Project.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Version.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Api.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Base.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Model.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Schema.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/tests/test_conf_Dependencies.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/tests/test_conf_Platform.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/CommandRouter.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Completions.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Conversation.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Env.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Memory.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/PythonPath.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/TimeKeeper.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/utils.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/bash-completion.tmpl +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/mysql/default-ref-table.tmpl +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/mysql/default-table.tmpl +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/postgresql/default-ref-table.tmpl +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/postgresql/default-table.tmpl +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/db/TableExceptions.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/db/tests/test_db_TableExceptions.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/dev/Dev.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/lang/Python.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/lang/tests/test_lang_Python.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/auth/Server.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/DataDictionary.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/EntityKeys.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/Manager.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_DataDictionary.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_EntityKeys.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_Manager.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/Authenticator.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/BaseCustomization.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/CustomizationManager.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/Index.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/tests/test_code_customization_Authenticator.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/tests/test_code_customization_BaseCustomization.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/constraints/ReferenceConstraint.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/ForeignKey.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/Index.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/IndexAttribute.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_ForeignKey.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_Index.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_IndexAttribute.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/testing.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/tests/test_structure_mysql_Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/References.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/table/ForeignKey.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/table/tests/test_structure_postgresql_table_ForeignKey.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/testing.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/tests/test_structure_postgresql_Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/tests/test_structure_Entity.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_Env.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_Memory.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_utils.py +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/dependency_links.txt +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/entry_points.txt +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/top_level.txt +0 -0
- {gibson_cli-0.7.3 → gibson_cli-0.7.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: gibson-cli
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.5
|
4
4
|
Summary: Gibson Command Line Interface
|
5
5
|
Author-email: GibsonAI <noc@gibsonai.com>
|
6
6
|
Project-URL: Homepage, https://gibsonai.com/
|
@@ -65,6 +65,7 @@ Requires-Dist: uvicorn==0.29.0
|
|
65
65
|
Requires-Dist: uvloop==0.19.0
|
66
66
|
Requires-Dist: watchfiles==0.21.0
|
67
67
|
Requires-Dist: websockets==12.0
|
68
|
+
Requires-Dist: yaspin==3.1.0
|
68
69
|
|
69
70
|
|
70
71
|
[](https://gibsonai.com/)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
from gibson.core.CommandRouter import CommandRouter
|
4
|
+
from gibson.core.Configuration import Configuration
|
5
|
+
|
6
|
+
|
7
|
+
def main():
|
8
|
+
try:
|
9
|
+
configuration = Configuration()
|
10
|
+
if configuration.settings is None:
|
11
|
+
configuration.initialize()
|
12
|
+
else:
|
13
|
+
CommandRouter(configuration).run()
|
14
|
+
except KeyboardInterrupt:
|
15
|
+
exit(1)
|
16
|
+
|
17
|
+
|
18
|
+
if __name__ == "__main__":
|
19
|
+
main()
|
@@ -21,7 +21,7 @@ class Help(BaseCommand):
|
|
21
21
|
"description": "create the entities in the datastore",
|
22
22
|
"memory": "stored",
|
23
23
|
},
|
24
|
-
"code": {"description": "pair program", "memory": None},
|
24
|
+
"code": {"description": "pair program with gibson", "memory": None},
|
25
25
|
"conf": {"description": "set a configuration variable", "memory": None},
|
26
26
|
"count": {
|
27
27
|
"description": "show the number of entities stored",
|
@@ -62,7 +62,7 @@ class Help(BaseCommand):
|
|
62
62
|
"memory": "last > stored",
|
63
63
|
},
|
64
64
|
"rewrite": {
|
65
|
-
"description": "rewrite code",
|
65
|
+
"description": "rewrite all code",
|
66
66
|
"memory": "stored",
|
67
67
|
},
|
68
68
|
"show": {"description": "display an entity", "memory": "last > stored"},
|
@@ -15,15 +15,15 @@ class Version(BaseCommand):
|
|
15
15
|
|
16
16
|
if latest_version != VersionConf.num:
|
17
17
|
self.conversation.type(
|
18
|
-
f"A new version of {Colors.command(self.configuration.command)} is available: {Colors.
|
18
|
+
f"A new version of {Colors.command(self.configuration.command)} is available: {Colors.cyan(latest_version)}\n"
|
19
19
|
)
|
20
20
|
self.conversation.type(
|
21
|
-
f"You are currently using version: {Colors.
|
21
|
+
f"You are currently using version: {Colors.violet(VersionConf.num)}\n"
|
22
22
|
)
|
23
23
|
self.conversation.type(
|
24
24
|
f"Please update to the latest version by running: {Colors.command('pip3')} {Colors.subcommand('install')} {Colors.option('--upgrade')} gibson-cli\n"
|
25
25
|
)
|
26
26
|
else:
|
27
27
|
self.conversation.type(
|
28
|
-
f"Nice! 🎉 You are using the latest version of {Colors.command(self.configuration.command)}: {Colors.
|
28
|
+
f"Nice! 🎉 You are using the latest version of {Colors.command(self.configuration.command)}: {Colors.cyan(VersionConf.num)}\n"
|
29
29
|
)
|
@@ -0,0 +1,231 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import os
|
4
|
+
import sys
|
5
|
+
from string import Template
|
6
|
+
|
7
|
+
import gibson.core.Colors as Colors
|
8
|
+
from gibson.api.Cli import Cli
|
9
|
+
from gibson.command.BaseCommand import BaseCommand
|
10
|
+
from gibson.command.code.Model import Model
|
11
|
+
from gibson.command.code.Schema import Schema
|
12
|
+
from gibson.command.code.Test import Test
|
13
|
+
from gibson.command.Merge import Merge
|
14
|
+
from gibson.core.Configuration import Configuration
|
15
|
+
from gibson.core.Diff import additions, diff
|
16
|
+
from gibson.core.Spinner import ComputingSpinner, Spinner
|
17
|
+
from gibson.display.Header import Header
|
18
|
+
from gibson.display.WorkspaceFooter import WorkspaceFooter
|
19
|
+
from gibson.display.WorkspaceHeader import WorkspaceHeader
|
20
|
+
from gibson.services.code.context.schema.Manager import (
|
21
|
+
Manager as CodeContextSchemaManager,
|
22
|
+
)
|
23
|
+
from gibson.structure.Entity import Entity as StructureEntity
|
24
|
+
|
25
|
+
|
26
|
+
class Entity(BaseCommand):
|
27
|
+
CODE_WRITER_ENTITY_MODIFIER_NOOP = ""
|
28
|
+
|
29
|
+
def __init__(self, configuration: Configuration):
|
30
|
+
super().__init__(configuration)
|
31
|
+
self.__context = None
|
32
|
+
|
33
|
+
def __add_foreign_key(self, entity, entity_name):
|
34
|
+
entity_keys = self.__context.get_entity_keys(entity_name)
|
35
|
+
if entity_keys is None:
|
36
|
+
self.conversation.type(
|
37
|
+
f'\nThe entity you referenced, "{entity_name}", does not exist.\n'
|
38
|
+
)
|
39
|
+
self.conversation.wait()
|
40
|
+
return False
|
41
|
+
|
42
|
+
best_sql_foreign_key = entity_keys.best_sql_foreign_key()
|
43
|
+
if best_sql_foreign_key is None:
|
44
|
+
self.conversation.type(
|
45
|
+
f'\nYou cannot make a foreign key to "{entity_name}".\n'
|
46
|
+
+ "It does not have primary or unique keys.\n"
|
47
|
+
)
|
48
|
+
self.conversation.wait()
|
49
|
+
return False
|
50
|
+
|
51
|
+
foreign_key, index, data_types = best_sql_foreign_key
|
52
|
+
|
53
|
+
for i in range(len(foreign_key.attributes)):
|
54
|
+
entity.add_attribute(
|
55
|
+
foreign_key.attributes[i],
|
56
|
+
data_types[i],
|
57
|
+
after="uuid",
|
58
|
+
before="date_created",
|
59
|
+
)
|
60
|
+
|
61
|
+
entity.add_foreign_key(foreign_key)
|
62
|
+
entity.add_index(index)
|
63
|
+
|
64
|
+
return True
|
65
|
+
|
66
|
+
def execute(self):
|
67
|
+
cli = Cli(self.configuration)
|
68
|
+
entity_name = sys.argv[3]
|
69
|
+
existing_entity = self.memory.recall_entity(entity_name)
|
70
|
+
definition = (
|
71
|
+
existing_entity["definition"]
|
72
|
+
if existing_entity
|
73
|
+
else self.template_definition(entity_name)
|
74
|
+
)
|
75
|
+
|
76
|
+
with ComputingSpinner():
|
77
|
+
self.__context = CodeContextSchemaManager().from_code_writer_schema_context(
|
78
|
+
cli.code_writer_schema_context()
|
79
|
+
)
|
80
|
+
data = cli.code_writer_entity_modifier(
|
81
|
+
self.__context.json,
|
82
|
+
sys.argv[3],
|
83
|
+
definition,
|
84
|
+
self.CODE_WRITER_ENTITY_MODIFIER_NOOP,
|
85
|
+
)
|
86
|
+
entity = (
|
87
|
+
StructureEntity()
|
88
|
+
.instantiate(self.configuration.project.datastore.type)
|
89
|
+
.import_from_struct(data)
|
90
|
+
)
|
91
|
+
original_entity = entity if existing_entity else None
|
92
|
+
original_model_code = (
|
93
|
+
data["code"][0]["definition"] if existing_entity else None
|
94
|
+
)
|
95
|
+
|
96
|
+
while True:
|
97
|
+
try:
|
98
|
+
self.__render_workspace(
|
99
|
+
original_entity,
|
100
|
+
entity,
|
101
|
+
original_model_code,
|
102
|
+
data["code"][0]["definition"],
|
103
|
+
)
|
104
|
+
input_ = input("> ")
|
105
|
+
if input_.lower() in [":q", ":q!", ":wq"]:
|
106
|
+
self.conversation.newline()
|
107
|
+
|
108
|
+
if input_.lower() == ":q":
|
109
|
+
self.conversation.type("Exiting without saving.\n")
|
110
|
+
|
111
|
+
if input_.lower() in [":q", ":q!"]:
|
112
|
+
exit(1)
|
113
|
+
|
114
|
+
# Mute output from individual merge + rewrite operations
|
115
|
+
self.conversation.mute()
|
116
|
+
|
117
|
+
with Spinner(
|
118
|
+
"Gibson is saving your changes to the entity...",
|
119
|
+
"Entity saved",
|
120
|
+
):
|
121
|
+
self.memory.remember_last({"entities": [data["entity"]]})
|
122
|
+
Merge(self.configuration).execute()
|
123
|
+
|
124
|
+
# Rewrite each category of code with the new entity definition
|
125
|
+
Model(self.configuration).execute(entity_name=entity.name)
|
126
|
+
Schema(self.configuration).execute(entity_name=entity.name)
|
127
|
+
Test(self.configuration).execute(entity_name=entity.name)
|
128
|
+
|
129
|
+
self.conversation.unmute()
|
130
|
+
self.conversation.type(
|
131
|
+
f"\nAll code for the {Colors.violet(entity.name)} entity has been written 🎉\n\n"
|
132
|
+
)
|
133
|
+
exit()
|
134
|
+
elif input_ == "":
|
135
|
+
continue
|
136
|
+
|
137
|
+
with ComputingSpinner():
|
138
|
+
talk_to_gibsonai = True
|
139
|
+
parts = input_.split(" ")
|
140
|
+
if parts[0] == "fk":
|
141
|
+
input_ = self.CODE_WRITER_ENTITY_MODIFIER_NOOP
|
142
|
+
if not self.__add_foreign_key(entity, parts[1]):
|
143
|
+
# If the entity was not modified, likely because the table
|
144
|
+
# referenced does not exist or does not contain indexes which
|
145
|
+
# can be used for a foreign key, do not waste the network call
|
146
|
+
# to GibsonAI since there is nothing to do.
|
147
|
+
talk_to_gibsonai = False
|
148
|
+
|
149
|
+
if talk_to_gibsonai is True:
|
150
|
+
data = cli.code_writer_entity_modifier(
|
151
|
+
self.__context.json,
|
152
|
+
data["entity"]["name"],
|
153
|
+
entity.create_statement(),
|
154
|
+
input_,
|
155
|
+
)
|
156
|
+
entity = (
|
157
|
+
StructureEntity()
|
158
|
+
.instantiate(self.configuration.project.datastore.type)
|
159
|
+
.import_from_struct(data)
|
160
|
+
)
|
161
|
+
except KeyboardInterrupt:
|
162
|
+
self.conversation.type("\nExiting without saving.\n")
|
163
|
+
exit(1)
|
164
|
+
|
165
|
+
def get_default_ref_table_template_path(self):
|
166
|
+
return (
|
167
|
+
os.path.dirname(__file__)
|
168
|
+
+ "/../../data/"
|
169
|
+
+ self.configuration.project.datastore.type
|
170
|
+
+ "/default-ref-table.tmpl"
|
171
|
+
)
|
172
|
+
|
173
|
+
def get_default_table_template_path(self):
|
174
|
+
return (
|
175
|
+
os.path.dirname(__file__)
|
176
|
+
+ "/../../data/"
|
177
|
+
+ self.configuration.project.datastore.type
|
178
|
+
+ "/default-table.tmpl"
|
179
|
+
)
|
180
|
+
|
181
|
+
def __render_workspace(
|
182
|
+
self,
|
183
|
+
original_entity: StructureEntity | None,
|
184
|
+
entity: StructureEntity,
|
185
|
+
original_model_code: str | None,
|
186
|
+
model_code: str,
|
187
|
+
):
|
188
|
+
self.configuration.platform.cmd_clear()
|
189
|
+
create_table_statement_diff = (
|
190
|
+
diff(original_entity.create_statement(), entity.create_statement())
|
191
|
+
if original_entity
|
192
|
+
else additions(entity.create_statement())
|
193
|
+
)
|
194
|
+
model_code_diff = (
|
195
|
+
diff(original_model_code, model_code)
|
196
|
+
if original_model_code
|
197
|
+
else additions(model_code)
|
198
|
+
)
|
199
|
+
|
200
|
+
print("")
|
201
|
+
print(WorkspaceHeader().render(self.configuration.project.name))
|
202
|
+
|
203
|
+
print("")
|
204
|
+
print(Header().render("SQL", Colors.cyan))
|
205
|
+
print("")
|
206
|
+
print(Colors.table(create_table_statement_diff, entity.name))
|
207
|
+
|
208
|
+
print("")
|
209
|
+
print(Header().render("Model", Colors.yellow))
|
210
|
+
print("")
|
211
|
+
print(Colors.model(model_code_diff, entity.name))
|
212
|
+
print(WorkspaceFooter().render())
|
213
|
+
|
214
|
+
def template_definition(self, entity_name):
|
215
|
+
parts = entity_name.split("_")
|
216
|
+
if len(parts) > 1 and parts[1] == "ref":
|
217
|
+
# This is a reference table implementation. We will handle this here.
|
218
|
+
with open(self.get_default_ref_table_template_path()) as f:
|
219
|
+
definition = Template(f.read()).substitute({"entity_name": entity_name})
|
220
|
+
|
221
|
+
self.memory.append_last({"definition": definition, "name": entity_name})
|
222
|
+
|
223
|
+
self.conversation.type(
|
224
|
+
"Reference table created and stored in last memory. What's next?\n"
|
225
|
+
)
|
226
|
+
self.conversation.newline()
|
227
|
+
|
228
|
+
exit(1)
|
229
|
+
|
230
|
+
with open(self.get_default_table_template_path()) as f:
|
231
|
+
return Template(f.read()).substitute({"entity_name": entity_name})
|
@@ -3,6 +3,7 @@ import sys
|
|
3
3
|
import gibson.core.Colors as Colors
|
4
4
|
from gibson.api.Cli import Cli
|
5
5
|
from gibson.command.BaseCommand import BaseCommand
|
6
|
+
from gibson.core.Spinner import Spinner
|
6
7
|
from gibson.core.TimeKeeper import TimeKeeper
|
7
8
|
from gibson.dev.Dev import Dev
|
8
9
|
|
@@ -20,17 +21,18 @@ class Model(BaseCommand):
|
|
20
21
|
|
21
22
|
time_keeper = TimeKeeper()
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
with Spinner("Gibson is writing the models...", "Models written"):
|
25
|
+
cli = Cli(self.configuration)
|
26
|
+
response = cli.code_models([entity["name"]])
|
27
|
+
Dev(self.configuration).model(
|
28
|
+
response["code"][0]["entity"]["name"], response["code"][0]["definition"]
|
29
|
+
)
|
29
30
|
|
30
31
|
if self.configuration.project.dev.active is True:
|
31
32
|
self.conversation.type(
|
32
|
-
f"
|
33
|
+
f"\nGibson wrote the following {Colors.argument('model')} code to your project:\n"
|
33
34
|
)
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
if not self.conversation.muted():
|
37
|
+
print(response["code"][0]["definition"])
|
38
|
+
time_keeper.display()
|
@@ -3,6 +3,7 @@ import sys
|
|
3
3
|
import gibson.core.Colors as Colors
|
4
4
|
from gibson.api.Cli import Cli
|
5
5
|
from gibson.command.BaseCommand import BaseCommand
|
6
|
+
from gibson.core.Spinner import Spinner
|
6
7
|
from gibson.core.TimeKeeper import TimeKeeper
|
7
8
|
from gibson.dev.Dev import Dev
|
8
9
|
|
@@ -20,17 +21,18 @@ class Schema(BaseCommand):
|
|
20
21
|
|
21
22
|
time_keeper = TimeKeeper()
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
with Spinner("Gibson is writing the schemas...", "Schemas written"):
|
25
|
+
cli = Cli(self.configuration)
|
26
|
+
response = cli.code_schemas([entity["name"]])
|
27
|
+
Dev(self.configuration).schema(
|
28
|
+
response["code"][0]["entity"]["name"], response["code"][0]["definition"]
|
29
|
+
)
|
29
30
|
|
30
31
|
if self.configuration.project.dev.active is True:
|
31
32
|
self.conversation.type(
|
32
|
-
f"
|
33
|
+
f"\nGibson wrote the following {Colors.argument('schema')} code to your project:\n"
|
33
34
|
)
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
if not self.conversation.muted():
|
37
|
+
print(response["code"][0]["definition"])
|
38
|
+
time_keeper.display()
|
@@ -3,6 +3,7 @@ import sys
|
|
3
3
|
import gibson.core.Colors as Colors
|
4
4
|
from gibson.api.Cli import Cli
|
5
5
|
from gibson.command.BaseCommand import BaseCommand
|
6
|
+
from gibson.core.Spinner import Spinner
|
6
7
|
from gibson.core.TimeKeeper import TimeKeeper
|
7
8
|
from gibson.dev.Dev import Dev
|
8
9
|
|
@@ -20,17 +21,18 @@ class Test(BaseCommand):
|
|
20
21
|
|
21
22
|
time_keeper = TimeKeeper()
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
with Spinner("Gibson is writing the tests...", "Tests written"):
|
25
|
+
cli = Cli(self.configuration)
|
26
|
+
response = cli.code_testing([entity["name"]])
|
27
|
+
Dev(self.configuration).tests(
|
28
|
+
response["code"][0]["entity"]["name"], response["code"][0]["definition"]
|
29
|
+
)
|
29
30
|
|
30
31
|
if self.configuration.project.dev.active is True:
|
31
32
|
self.conversation.type(
|
32
|
-
f"
|
33
|
+
f"\nGibson wrote the following {Colors.argument('tests')} to your project:\n"
|
33
34
|
)
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
if not self.conversation.muted():
|
37
|
+
print(response["code"][0]["definition"])
|
38
|
+
time_keeper.display()
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class Constants:
|
2
2
|
BLACK = "\033[30m"
|
3
3
|
BLACK_BG = "\033[40m"
|
4
4
|
BLINK = "\033[5m"
|
@@ -42,17 +42,17 @@ class Color:
|
|
42
42
|
|
43
43
|
# Colorize text with a given color
|
44
44
|
def colorize(text, color):
|
45
|
-
return f"{color}{text}{
|
45
|
+
return f"{color}{text}{Constants.END}"
|
46
46
|
|
47
47
|
|
48
48
|
# Colorize a command
|
49
49
|
def command(text):
|
50
|
-
return
|
50
|
+
return green(text)
|
51
51
|
|
52
52
|
|
53
53
|
# Colorize a subcommand
|
54
54
|
def subcommand(text):
|
55
|
-
return
|
55
|
+
return yellow(text)
|
56
56
|
|
57
57
|
|
58
58
|
# Colorize an argument
|
@@ -67,27 +67,27 @@ def arguments(list):
|
|
67
67
|
|
68
68
|
# Colorize user input
|
69
69
|
def input(text):
|
70
|
-
return
|
70
|
+
return white(text)
|
71
71
|
|
72
72
|
|
73
73
|
# Colorize a command option
|
74
74
|
def option(text):
|
75
|
-
return
|
75
|
+
return cyan(text)
|
76
76
|
|
77
77
|
|
78
78
|
# Colorize a hint
|
79
79
|
def hint(text):
|
80
|
-
return
|
80
|
+
return grey(text)
|
81
81
|
|
82
82
|
|
83
83
|
# Colorize a project name
|
84
84
|
def project(text):
|
85
|
-
return
|
85
|
+
return bold(text)
|
86
86
|
|
87
87
|
|
88
88
|
# Colorize a URL to appear as a link
|
89
89
|
def link(text):
|
90
|
-
return
|
90
|
+
return underline(blue(text))
|
91
91
|
|
92
92
|
|
93
93
|
# Colorize the table name in a SQL statement
|
@@ -104,24 +104,44 @@ def model(code, name):
|
|
104
104
|
|
105
105
|
# Colorize a time/duration output
|
106
106
|
def time(text):
|
107
|
-
return
|
107
|
+
return green(text)
|
108
|
+
|
109
|
+
|
110
|
+
def bold(text):
|
111
|
+
return colorize(text, Constants.BOLD)
|
112
|
+
|
113
|
+
|
114
|
+
def underline(text):
|
115
|
+
return colorize(text, Constants.UNDERLINE)
|
116
|
+
|
117
|
+
|
118
|
+
def blue(text):
|
119
|
+
return colorize(text, Constants.BLUE)
|
108
120
|
|
109
121
|
|
110
122
|
def cyan(text):
|
111
|
-
return colorize(text,
|
123
|
+
return colorize(text, Constants.CYAN)
|
112
124
|
|
113
125
|
|
114
126
|
def green(text):
|
115
|
-
return colorize(text,
|
127
|
+
return colorize(text, Constants.GREEN)
|
128
|
+
|
129
|
+
|
130
|
+
def grey(text):
|
131
|
+
return colorize(text, Constants.GREY)
|
116
132
|
|
117
133
|
|
118
134
|
def red(text):
|
119
|
-
return colorize(text,
|
135
|
+
return colorize(text, Constants.RED)
|
120
136
|
|
121
137
|
|
122
138
|
def violet(text):
|
123
|
-
return colorize(text,
|
139
|
+
return colorize(text, Constants.VIOLET)
|
140
|
+
|
141
|
+
|
142
|
+
def white(text):
|
143
|
+
return colorize(text, Constants.WHITE2)
|
124
144
|
|
125
145
|
|
126
146
|
def yellow(text):
|
127
|
-
return colorize(text,
|
147
|
+
return colorize(text, Constants.YELLOW)
|
@@ -347,6 +347,7 @@ class Configuration:
|
|
347
347
|
json.dump(data, f, indent=2)
|
348
348
|
|
349
349
|
def set_config_paths(self):
|
350
|
+
config_path = os.environ.get("GIBSONAI_CONFIG_PATH", None)
|
350
351
|
gibson_config_dir = ".gibsonai"
|
351
352
|
user_home = os.environ.get("HOME")
|
352
353
|
if user_home is None:
|
@@ -354,7 +355,7 @@ class Configuration:
|
|
354
355
|
"Gibson here. Please set your HOME environment variable."
|
355
356
|
)
|
356
357
|
|
357
|
-
self.paths.top = f"{user_home}/{gibson_config_dir}"
|
358
|
+
self.paths.top = config_path or f"{user_home}/{gibson_config_dir}"
|
358
359
|
self.paths.auth = f"{self.paths.top}/auth"
|
359
360
|
self.paths.config = f"{self.paths.top}/config"
|
360
361
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from difflib import Differ
|
2
|
+
|
3
|
+
from gibson.core.Colors import green, red
|
4
|
+
|
5
|
+
|
6
|
+
# Highlights all lines as additions with a green + at the beginning
|
7
|
+
# This keeps visual clutter to a minimum when showing the diff of an entirely new entity
|
8
|
+
def additions(input: str):
|
9
|
+
lines = input.splitlines(keepends=True)
|
10
|
+
result = []
|
11
|
+
for line in lines:
|
12
|
+
result.append(f"{green('+')} {line}")
|
13
|
+
return "".join(result)
|
14
|
+
|
15
|
+
|
16
|
+
# Highlights the diffs between two strings, showing the additions and removals as distinct colored lines
|
17
|
+
def diff(original: str, modified: str):
|
18
|
+
diffs = list(
|
19
|
+
Differ().compare(
|
20
|
+
original.splitlines(keepends=True), modified.splitlines(keepends=True)
|
21
|
+
)
|
22
|
+
)
|
23
|
+
|
24
|
+
result = []
|
25
|
+
for line in diffs:
|
26
|
+
if line.startswith("+ "):
|
27
|
+
result.append(green(line))
|
28
|
+
elif line.startswith("- "):
|
29
|
+
result.append(red(line))
|
30
|
+
elif line.startswith(" "):
|
31
|
+
result.append(line)
|
32
|
+
# Ignore lines starting with '? ' as they are not needed for this highlighting
|
33
|
+
|
34
|
+
return "".join(result)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from yaspin import yaspin
|
2
|
+
from yaspin.spinners import Spinners
|
3
|
+
|
4
|
+
|
5
|
+
class Spinner:
|
6
|
+
def __init__(
|
7
|
+
self, start_text, success_text=None, fail_text=None, disappearing=False
|
8
|
+
):
|
9
|
+
self.success_text = success_text or start_text
|
10
|
+
self.fail_text = fail_text or start_text
|
11
|
+
self.disappearing = disappearing
|
12
|
+
self.spinner = yaspin(
|
13
|
+
Spinners.binary,
|
14
|
+
text=start_text,
|
15
|
+
color="green",
|
16
|
+
)
|
17
|
+
|
18
|
+
def __enter__(self):
|
19
|
+
self.spinner.start()
|
20
|
+
|
21
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
22
|
+
if exc_type is not None:
|
23
|
+
self.spinner.text = self.fail_text
|
24
|
+
self.spinner.fail("❌")
|
25
|
+
elif self.disappearing:
|
26
|
+
self.spinner.text = ""
|
27
|
+
self.spinner.stop()
|
28
|
+
else:
|
29
|
+
self.spinner.text = self.success_text
|
30
|
+
self.spinner.ok("✅")
|
31
|
+
|
32
|
+
self.spinner.stop()
|
33
|
+
|
34
|
+
|
35
|
+
class ComputingSpinner(Spinner):
|
36
|
+
def __init__(self):
|
37
|
+
super().__init__("Gibson is computing...", disappearing=True)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import math
|
2
|
+
|
3
|
+
from gibson.core.Colors import bold
|
4
|
+
|
5
|
+
|
6
|
+
class Header:
|
7
|
+
def render(self, text, colorizer=None):
|
8
|
+
output = text if colorizer is None else colorizer(text)
|
9
|
+
half = math.floor((78 - len(text)) / 2) # 80 line length - 2 spaces
|
10
|
+
header = "/" * half + f" {bold(output)} " + "/" * half
|
11
|
+
return header
|
@@ -4,9 +4,9 @@ import gibson.core.Colors as Colors
|
|
4
4
|
class WorkspaceFooter:
|
5
5
|
def render(self):
|
6
6
|
return (
|
7
|
-
"
|
7
|
+
"-" * 79
|
8
8
|
+ "\n"
|
9
|
-
+ f"[{Colors.red(':q')} + enter = {Colors.red('discard')} changes]
|
9
|
+
+ f"[{Colors.red(':q')} + enter = {Colors.red('discard')} changes] "
|
10
10
|
+ f"[{Colors.green(':wq')} + enter = {Colors.green('save')} changes + write code]\n\n"
|
11
|
-
+ "Using natural language, tell me how I can modify this entity
|
11
|
+
+ "Using natural language, tell me how I can modify this entity:"
|
12
12
|
)
|
@@ -5,7 +5,7 @@ class WorkspaceHeader:
|
|
5
5
|
def render(self, project_name):
|
6
6
|
return (
|
7
7
|
f"Project {project_name}".ljust(50)
|
8
|
-
+ " " *
|
9
|
-
+ "
|
10
|
-
+ "
|
8
|
+
+ " " * 14
|
9
|
+
+ f"{Colors.bold('PAIR PROGRAMMER')}\n"
|
10
|
+
+ "-" * 79
|
11
11
|
).replace(project_name, Colors.project(project_name))
|