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.
Files changed (146) hide show
  1. {gibson_cli-0.7.3/gibson_cli.egg-info → gibson_cli-0.7.5}/PKG-INFO +2 -1
  2. gibson_cli-0.7.5/gibson/bin/gibson.py +19 -0
  3. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Help.py +2 -2
  4. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Version.py +3 -3
  5. gibson_cli-0.7.5/gibson/command/code/Entity.py +231 -0
  6. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Model.py +11 -9
  7. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Schema.py +11 -9
  8. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Test.py +11 -9
  9. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rewrite/Rewrite.py +0 -1
  10. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Colors.py +35 -15
  11. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Configuration.py +2 -1
  12. gibson_cli-0.7.5/gibson/core/Diff.py +34 -0
  13. gibson_cli-0.7.5/gibson/core/Spinner.py +37 -0
  14. gibson_cli-0.7.5/gibson/display/Header.py +11 -0
  15. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/WorkspaceFooter.py +3 -3
  16. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/WorkspaceHeader.py +3 -3
  17. gibson_cli-0.7.5/gibson/display/tests/test_display_Header.py +12 -0
  18. gibson_cli-0.7.5/gibson/display/tests/test_display_WorkspaceFooter.py +11 -0
  19. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/display/tests/test_display_WorkspaceHeader.py +2 -2
  20. {gibson_cli-0.7.3 → gibson_cli-0.7.5/gibson_cli.egg-info}/PKG-INFO +2 -1
  21. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/SOURCES.txt +2 -0
  22. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/requires.txt +1 -0
  23. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/pyproject.toml +1 -1
  24. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/requirements.txt +1 -0
  25. gibson_cli-0.7.3/gibson/bin/gibson.py +0 -16
  26. gibson_cli-0.7.3/gibson/command/code/Entity.py +0 -197
  27. gibson_cli-0.7.3/gibson/display/Header.py +0 -10
  28. gibson_cli-0.7.3/gibson/display/tests/test_display_Header.py +0 -10
  29. gibson_cli-0.7.3/gibson/display/tests/test_display_WorkspaceFooter.py +0 -11
  30. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/.gitignore +0 -0
  31. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/.pre-commit-config.yaml +0 -0
  32. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/README.md +0 -0
  33. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/build.sh +0 -0
  34. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/clean.sh +0 -0
  35. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/bin/release.sh +0 -0
  36. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/BaseApi.py +0 -0
  37. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/Cli.py +0 -0
  38. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/api/ProjectApi.py +0 -0
  39. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/BaseCommand.py +0 -0
  40. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Build.py +0 -0
  41. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Conf.py +0 -0
  42. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Count.py +0 -0
  43. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Dev.py +0 -0
  44. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Forget.py +0 -0
  45. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Merge.py +0 -0
  46. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Modify.py +0 -0
  47. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Question.py +0 -0
  48. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Remove.py +0 -0
  49. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Show.py +0 -0
  50. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/Tree.py +0 -0
  51. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/WarGames.py +0 -0
  52. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Auth.py +0 -0
  53. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Login.py +0 -0
  54. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/auth/Logout.py +0 -0
  55. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Api.py +0 -0
  56. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Base.py +0 -0
  57. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Code.py +0 -0
  58. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Models.py +0 -0
  59. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Schemas.py +0 -0
  60. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/code/Tests.py +0 -0
  61. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/importer/Import.py +0 -0
  62. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/importer/OpenApi.py +0 -0
  63. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/Entities.py +0 -0
  64. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/List.py +0 -0
  65. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/list/Projects.py +0 -0
  66. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/Module.py +0 -0
  67. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/New.py +0 -0
  68. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/new/Project.py +0 -0
  69. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rename/Entity.py +0 -0
  70. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/rename/Rename.py +0 -0
  71. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/tests/test_command_BaseCommand.py +0 -0
  72. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/command/tests/test_command_Conf.py +0 -0
  73. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Api.py +0 -0
  74. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Code.py +0 -0
  75. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Custom.py +0 -0
  76. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Datastore.py +0 -0
  77. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Dependencies.py +0 -0
  78. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Dev.py +0 -0
  79. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Frameworks.py +0 -0
  80. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Modeler.py +0 -0
  81. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Paths.py +0 -0
  82. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Platform.py +0 -0
  83. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Project.py +0 -0
  84. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/Version.py +0 -0
  85. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Api.py +0 -0
  86. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Base.py +0 -0
  87. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Model.py +0 -0
  88. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/dev/Schema.py +0 -0
  89. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/tests/test_conf_Dependencies.py +0 -0
  90. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/conf/tests/test_conf_Platform.py +0 -0
  91. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/CommandRouter.py +0 -0
  92. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Completions.py +0 -0
  93. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Conversation.py +0 -0
  94. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Env.py +0 -0
  95. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/Memory.py +0 -0
  96. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/PythonPath.py +0 -0
  97. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/TimeKeeper.py +0 -0
  98. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/core/utils.py +0 -0
  99. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/bash-completion.tmpl +0 -0
  100. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/mysql/default-ref-table.tmpl +0 -0
  101. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/mysql/default-table.tmpl +0 -0
  102. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/postgresql/default-ref-table.tmpl +0 -0
  103. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/data/postgresql/default-table.tmpl +0 -0
  104. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/db/TableExceptions.py +0 -0
  105. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/db/tests/test_db_TableExceptions.py +0 -0
  106. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/dev/Dev.py +0 -0
  107. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/lang/Python.py +0 -0
  108. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/lang/tests/test_lang_Python.py +0 -0
  109. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/auth/Server.py +0 -0
  110. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/DataDictionary.py +0 -0
  111. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/EntityKeys.py +0 -0
  112. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/Manager.py +0 -0
  113. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_DataDictionary.py +0 -0
  114. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_EntityKeys.py +0 -0
  115. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/context/schema/tests/test_code_context_schema_Manager.py +0 -0
  116. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/Authenticator.py +0 -0
  117. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/BaseCustomization.py +0 -0
  118. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/CustomizationManager.py +0 -0
  119. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/Index.py +0 -0
  120. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/tests/test_code_customization_Authenticator.py +0 -0
  121. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/services/code/customization/tests/test_code_customization_BaseCustomization.py +0 -0
  122. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/Entity.py +0 -0
  123. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/Entity.py +0 -0
  124. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/constraints/ReferenceConstraint.py +0 -0
  125. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/ForeignKey.py +0 -0
  126. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/Index.py +0 -0
  127. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/IndexAttribute.py +0 -0
  128. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_ForeignKey.py +0 -0
  129. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_Index.py +0 -0
  130. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/keys/tests/test_structure_mysql_keys_IndexAttribute.py +0 -0
  131. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/testing.py +0 -0
  132. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/mysql/tests/test_structure_mysql_Entity.py +0 -0
  133. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/Entity.py +0 -0
  134. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/References.py +0 -0
  135. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/table/ForeignKey.py +0 -0
  136. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/table/tests/test_structure_postgresql_table_ForeignKey.py +0 -0
  137. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/testing.py +0 -0
  138. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/postgresql/tests/test_structure_postgresql_Entity.py +0 -0
  139. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/structure/tests/test_structure_Entity.py +0 -0
  140. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_Env.py +0 -0
  141. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_Memory.py +0 -0
  142. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson/tests/test_utils.py +0 -0
  143. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/dependency_links.txt +0 -0
  144. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/entry_points.txt +0 -0
  145. {gibson_cli-0.7.3 → gibson_cli-0.7.5}/gibson_cli.egg-info/top_level.txt +0 -0
  146. {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
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
  [![GibsonAI](https://github.com/user-attachments/assets/26bc1002-f878-4995-a6c5-eb8d5eb69c28)](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.colorize(latest_version, Colors.Color.CYAN)}\n"
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.colorize(VersionConf.num, Colors.Color.VIOLET)}\n"
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.colorize(VersionConf.num, Colors.Color.CYAN)}\n"
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
- cli = Cli(self.configuration)
24
- response = cli.code_models([entity["name"]])
25
-
26
- Dev(self.configuration).model(
27
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
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"Gibson wrote the following {Colors.argument('model')} code to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('model')} code to your project:\n"
33
34
  )
34
35
 
35
- print(response["code"][0]["definition"])
36
- time_keeper.display()
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
- cli = Cli(self.configuration)
24
- response = cli.code_schemas([entity["name"]])
25
-
26
- Dev(self.configuration).schema(
27
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
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"Gibson wrote the following {Colors.argument('schema')} code to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('schema')} code to your project:\n"
33
34
  )
34
35
 
35
- print(response["code"][0]["definition"])
36
- time_keeper.display()
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
- cli = Cli(self.configuration)
24
- response = cli.code_testing([entity["name"]])
25
-
26
- Dev(self.configuration).tests(
27
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
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"Gibson wrote the following {Colors.argument('tests')} to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('tests')} to your project:\n"
33
34
  )
34
35
 
35
- print(response["code"][0]["definition"])
36
- time_keeper.display()
36
+ if not self.conversation.muted():
37
+ print(response["code"][0]["definition"])
38
+ time_keeper.display()
@@ -25,7 +25,6 @@ class Rewrite(BaseCommand):
25
25
  super().__init__(configuration)
26
26
  self.wipe = wipe
27
27
  self.with_header = with_header
28
- self.arguments = ["api", "base", "models", "schemas", "tests"]
29
28
 
30
29
  def execute(self):
31
30
  if len(sys.argv) == 2:
@@ -1,4 +1,4 @@
1
- class Color:
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}{Color.END}"
45
+ return f"{color}{text}{Constants.END}"
46
46
 
47
47
 
48
48
  # Colorize a command
49
49
  def command(text):
50
- return colorize(text, Color.GREEN)
50
+ return green(text)
51
51
 
52
52
 
53
53
  # Colorize a subcommand
54
54
  def subcommand(text):
55
- return colorize(text, Color.YELLOW)
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 colorize(text, Color.WHITE2)
70
+ return white(text)
71
71
 
72
72
 
73
73
  # Colorize a command option
74
74
  def option(text):
75
- return colorize(text, Color.CYAN)
75
+ return cyan(text)
76
76
 
77
77
 
78
78
  # Colorize a hint
79
79
  def hint(text):
80
- return colorize(text, Color.GREY)
80
+ return grey(text)
81
81
 
82
82
 
83
83
  # Colorize a project name
84
84
  def project(text):
85
- return colorize(text, Color.BOLD)
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 colorize(colorize(text, Color.BLUE), Color.UNDERLINE)
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 colorize(text, Color.GREEN)
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, Color.CYAN)
123
+ return colorize(text, Constants.CYAN)
112
124
 
113
125
 
114
126
  def green(text):
115
- return colorize(text, Color.GREEN)
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, Color.RED)
135
+ return colorize(text, Constants.RED)
120
136
 
121
137
 
122
138
  def violet(text):
123
- return colorize(text, Color.VIOLET)
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, Color.YELLOW)
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
- "=" * 79
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
- + " " * 12
9
- + "[PAIR PROGRAMMER]\n"
10
- + "=" * 79
8
+ + " " * 14
9
+ + f"{Colors.bold('PAIR PROGRAMMER')}\n"
10
+ + "-" * 79
11
11
  ).replace(project_name, Colors.project(project_name))