gemstack-cli 0.2.5 → 0.3.0

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -25
  3. data/README.md +6 -17
  4. data/exe/gemstack +8 -1
  5. metadata +6 -159
  6. data/lib/gemstack/cli/add_generator.rb +0 -239
  7. data/lib/gemstack/cli/app_generator.rb +0 -142
  8. data/lib/gemstack/cli/commands/db.rb +0 -135
  9. data/lib/gemstack/cli/commands/jobs.rb +0 -96
  10. data/lib/gemstack/cli/controller_generator.rb +0 -73
  11. data/lib/gemstack/cli/deploy_generator.rb +0 -102
  12. data/lib/gemstack/cli/doctor.rb +0 -308
  13. data/lib/gemstack/cli/generator.rb +0 -144
  14. data/lib/gemstack/cli/job_generator.rb +0 -48
  15. data/lib/gemstack/cli/migration_generator.rb +0 -52
  16. data/lib/gemstack/cli/policy_generator.rb +0 -35
  17. data/lib/gemstack/cli/project.rb +0 -53
  18. data/lib/gemstack/cli/resource_generator.rb +0 -170
  19. data/lib/gemstack/cli/resource_spec.rb +0 -95
  20. data/lib/gemstack/cli.rb +0 -304
  21. data/templates/app/Gemfile.tt +0 -44
  22. data/templates/app/README.md.tt +0 -29
  23. data/templates/app/app/controllers/application_controller.rb +0 -6
  24. data/templates/app/app/jobs/application_job.rb +0 -9
  25. data/templates/app/app/mailers/application_mailer.rb +0 -8
  26. data/templates/app/app/mailers/templates/dot_keep +0 -0
  27. data/templates/app/app/models/application_model.rb +0 -19
  28. data/templates/app/app/serializers/application_serializer.rb +0 -6
  29. data/templates/app/bin/gemstack +0 -7
  30. data/templates/app/config/app.rb.tt +0 -54
  31. data/templates/app/config/database.yml.tt +0 -61
  32. data/templates/app/config/environments/development.rb.tt +0 -35
  33. data/templates/app/config/environments/production.rb.tt +0 -40
  34. data/templates/app/config/environments/test.rb.tt +0 -21
  35. data/templates/app/config/puma.rb +0 -21
  36. data/templates/app/config/routes.rb +0 -10
  37. data/templates/app/config.ru +0 -6
  38. data/templates/app/db/migrations/dot_keep +0 -0
  39. data/templates/app/db/seeds.rb +0 -5
  40. data/templates/app/dot_env.example.tt +0 -19
  41. data/templates/app/dot_gitignore +0 -16
  42. data/templates/app/dot_node-version.tt +0 -1
  43. data/templates/app/dot_nvmrc.tt +0 -1
  44. data/templates/app/dot_ruby-version.tt +0 -1
  45. data/templates/app/dot_tool-versions.tt +0 -4
  46. data/templates/app/test/health_test.rb +0 -18
  47. data/templates/app/test/test_helper.rb.tt +0 -25
  48. data/templates/auth/app/controllers/api_tokens_controller.rb +0 -35
  49. data/templates/auth/app/controllers/email_verifications_controller.rb +0 -31
  50. data/templates/auth/app/controllers/password_resets_controller.rb +0 -40
  51. data/templates/auth/app/controllers/registrations_controller.rb +0 -19
  52. data/templates/auth/app/controllers/sessions_controller.rb +0 -29
  53. data/templates/auth/app/mailers/auth_mailer.rb +0 -20
  54. data/templates/auth/app/mailers/templates/auth_mailer/email_verification.html.erb +0 -2
  55. data/templates/auth/app/mailers/templates/auth_mailer/email_verification.text.erb +0 -2
  56. data/templates/auth/app/mailers/templates/auth_mailer/password_reset.html.erb +0 -3
  57. data/templates/auth/app/mailers/templates/auth_mailer/password_reset.text.erb +0 -6
  58. data/templates/auth/app/models/auth_token.rb +0 -15
  59. data/templates/auth/app/models/user.rb +0 -12
  60. data/templates/auth/app/policies/application_policy.rb +0 -6
  61. data/templates/auth/app/serializers/api_token_serializer.rb +0 -6
  62. data/templates/auth/app/serializers/new_api_token_serializer.rb +0 -9
  63. data/templates/auth/app/serializers/user_serializer.rb +0 -6
  64. data/templates/auth/db/migrations/%timestamp%_create_auth_tables.rb +0 -41
  65. data/templates/auth/frontend/app/account/page.tsx +0 -116
  66. data/templates/auth/frontend/app/forgot-password/page.tsx +0 -48
  67. data/templates/auth/frontend/app/login/page.tsx +0 -26
  68. data/templates/auth/frontend/app/reset-password/page.tsx +0 -11
  69. data/templates/auth/frontend/app/signup/page.tsx +0 -27
  70. data/templates/auth/frontend/app/verify-email/page.tsx +0 -11
  71. data/templates/auth/frontend/components/auth/CredentialsForm.tsx +0 -58
  72. data/templates/auth/frontend/components/auth/ResetPasswordForm.tsx +0 -43
  73. data/templates/auth/frontend/components/auth/VerifyEmail.tsx +0 -28
  74. data/templates/auth/frontend/lib/auth.ts +0 -113
  75. data/templates/auth/test/controllers/auth_test.rb +0 -108
  76. data/templates/controller/app/controllers/%file_name%_controller.rb.tt +0 -10
  77. data/templates/controller/test/controllers/%file_name%_controller_test.rb.tt +0 -14
  78. data/templates/deploy/Caddyfile.tt +0 -19
  79. data/templates/deploy/Dockerfile.tt +0 -63
  80. data/templates/deploy/Procfile.tt +0 -6
  81. data/templates/deploy/compose.yaml.tt +0 -129
  82. data/templates/deploy/dot_dockerignore +0 -14
  83. data/templates/frontend/app/globals.css +0 -171
  84. data/templates/frontend/app/layout.tsx.tt +0 -19
  85. data/templates/frontend/app/page.module.css +0 -315
  86. data/templates/frontend/app/page.tsx.tt +0 -183
  87. data/templates/frontend/app/providers.tsx +0 -24
  88. data/templates/frontend/lib/gemstack/client.ts +0 -125
  89. data/templates/frontend/next-env.d.ts +0 -5
  90. data/templates/frontend/next.config.ts +0 -17
  91. data/templates/frontend/package.json.tt +0 -23
  92. data/templates/frontend/tsconfig.json +0 -21
  93. data/templates/job/app/jobs/%file_name%.rb.tt +0 -15
  94. data/templates/job/test/jobs/%file_name%_test.rb.tt +0 -15
  95. data/templates/migration/db/migrations/%timestamp%_%file_name%.rb.tt +0 -17
  96. data/templates/policy/app/policies/%file_name%_policy.rb.tt +0 -21
  97. data/templates/policy/test/policies/%file_name%_policy_test.rb.tt +0 -9
  98. data/templates/realtime/config/channels.rb +0 -14
  99. data/templates/realtime/frontend/lib/gemstack/realtime.ts +0 -120
  100. data/templates/resource/controller/app/controllers/%plural%_controller.rb.tt +0 -51
  101. data/templates/resource/controller/test/controllers/%plural%_controller_test.rb.tt +0 -74
  102. data/templates/resource/frontend/frontend/app/%url_segment%/[id]/edit/page.tsx.tt +0 -45
  103. data/templates/resource/frontend/frontend/app/%url_segment%/[id]/page.tsx.tt +0 -49
  104. data/templates/resource/frontend/frontend/app/%url_segment%/new/page.tsx.tt +0 -27
  105. data/templates/resource/frontend/frontend/app/%url_segment%/page.tsx.tt +0 -51
  106. data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Card.tsx.tt +0 -15
  107. data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Form.tsx.tt +0 -98
  108. data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Table.tsx.tt +0 -36
  109. data/templates/resource/frontend/frontend/lib/format.ts +0 -12
  110. data/templates/resource/frontend/frontend/lib/queries/%url_segment%.ts.tt +0 -64
  111. data/templates/resource/migration/db/migrations/%timestamp%_create_%table%.rb.tt +0 -18
  112. data/templates/resource/model/app/models/%file_name%.rb.tt +0 -15
  113. data/templates/resource/model/test/models/%file_name%_test.rb.tt +0 -29
  114. data/templates/resource/serializer/app/serializers/%file_name%_serializer.rb.tt +0 -7
  115. data/templates/storage/app/controllers/uploads_controller.rb.tt +0 -33
  116. data/templates/storage/app/serializers/upload_serializer.rb +0 -11
  117. data/templates/storage/frontend/lib/upload.ts +0 -52
  118. data/templates/storage/test/controllers/uploads_test.rb.tt +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fece916078245099b1b1a2772b7e53645d7e2420dd1fe28703593beb5e99d6f
4
- data.tar.gz: 5f4d02f6371f8d95e05a2d9b8b942a70c7806f0848970d8be8d023bc6fc26d72
3
+ metadata.gz: ab399dd6760509d66d90e70758bce4f29efa781370b27efb79ed4d10d3af48f8
4
+ data.tar.gz: 66cbedd295830f20ef439a229ee9e99c2d8b4efc07fb77cce1386dc0eb42a555
5
5
  SHA512:
6
- metadata.gz: f2c6ca47b6f4d6297d5d5a4e1ef7fe54013c479319de64f8db9ffec9a9ad6816c079d956979fbbe0c0fdef720234e3c0dabe3319702d852dfbe2949aa25c101a
7
- data.tar.gz: fb4a50901dc646436500d6e934d9e0a51f9f211315740c887f147b476d96a3dd0f457993082b0b86c2ecafe4a7e19e5149ea8cc1b6a360423bb59eb55222ff5e
6
+ metadata.gz: a8b5b0134b58bb69bff5b2f1a8e415da32024c8ca5adc7a1820391166d3b382b584d152d991cd0b78114461a484bf10700bd1e6a2d8a0f53be78cd5e307bf474
7
+ data.tar.gz: f0d6dc52d9bbc96db7aa0c424798c04ca66ffc0636455fff3d9b122e45bbbcd91c437fe78601642e52b3520322a72dac8780aeea7cef383f23814deba556922a
data/CHANGELOG.md CHANGED
@@ -1,29 +1,7 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.5
3
+ ## 0.3.0
4
4
 
5
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
5
+ Only the `gemstack` executable; the CLI code moved into the gemstack gem. See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
6
6
 
7
- ## 0.2.4
8
-
9
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
10
-
11
- ## 0.2.3
12
-
13
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
14
-
15
- ## 0.2.2
16
-
17
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
18
-
19
- ## 0.2.1
20
-
21
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
22
-
23
- ## 0.2.0
24
-
25
- See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
26
-
27
- ## 0.1.0
28
-
29
- First release. See the [GemStack changelog](https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md).
7
+ Earlier versions: see the GemStack changelog.
data/README.md CHANGED
@@ -1,23 +1,12 @@
1
1
  # gemstack-cli
2
2
 
3
- GemStack command-line interface and generators.
3
+ The `gemstack` command. It is installed with the [`gemstack`](https://rubygems.org/gems/gemstack) gem —
4
+ `gem install gemstack` — and its code (generators, development server, `db:*` and `jobs` commands) lives
5
+ there; this gem only provides the executable.
4
6
 
5
- Part of [GemStack](https://github.com/gemstack-rb/gemstack), a modular Ruby API framework for Next.js
6
- applications by [Adware Technologies](https://www.adwaretech.com). All GemStack gems are developed together in that repository and released with the same
7
- version.
8
-
9
- ## Installation
10
-
11
- Installed with the `gemstack` gem; you rarely need to add it yourself.
12
-
13
- ## Documentation
14
-
15
- - [Guide](https://github.com/gemstack-rb/gemstack/blob/main/docs/getting-started.md)
16
- - [All guides](https://github.com/gemstack-rb/gemstack/tree/main/docs) ·
17
- [Architecture](https://github.com/gemstack-rb/gemstack/blob/main/ARCHITECTURE.md)
18
-
19
- Source, issues and pull requests: [gemstack-rb/gemstack](https://github.com/gemstack-rb/gemstack)
20
- (this gem lives in `gems/gemstack-cli`).
7
+ GemStack is a modular Ruby API framework for Next.js applications by
8
+ [Adware Technologies](https://www.adwaretech.com) — [gemstack-rb/gemstack](https://github.com/gemstack-rb/gemstack).
9
+ Command reference: [docs/cli.md](https://github.com/gemstack-rb/gemstack/blob/main/docs/cli.md).
21
10
 
22
11
  ## License
23
12
 
data/exe/gemstack CHANGED
@@ -1,6 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "gemstack/cli"
4
+ # The `gemstack` command. Its code lives in the gemstack gem (lib/gemstack/cli);
5
+ # this gem only owns the executable, so installs from before 0.3.0 upgrade
6
+ # without an executable conflict.
7
+ begin
8
+ require "gemstack/cli"
9
+ rescue LoadError
10
+ abort "gemstack: the gemstack gem is missing — install it with: gem install gemstack"
11
+ end
5
12
 
6
13
  GemStack::CLI.start(ARGV)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemstack-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adware Technologies
@@ -9,49 +9,9 @@ authors:
9
9
  bindir: exe
10
10
  cert_chain: []
11
11
  date: 1980-01-02 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: gemstack-core
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 0.2.5
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '='
25
- - !ruby/object:Gem::Version
26
- version: 0.2.5
27
- - !ruby/object:Gem::Dependency
28
- name: gemstack-dev
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 0.2.5
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 0.2.5
41
- - !ruby/object:Gem::Dependency
42
- name: thor
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.3'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.3'
12
+ dependencies: []
13
+ description: Owns the gemstack executable. The CLI itself — generators, dev server,
14
+ db and jobs commands — is part of the gemstack gem, which installs this one.
55
15
  email:
56
16
  - gemstack26@gmail.com
57
17
  executables:
@@ -63,126 +23,13 @@ files:
63
23
  - LICENSE.txt
64
24
  - README.md
65
25
  - exe/gemstack
66
- - lib/gemstack/cli.rb
67
- - lib/gemstack/cli/add_generator.rb
68
- - lib/gemstack/cli/app_generator.rb
69
- - lib/gemstack/cli/commands/db.rb
70
- - lib/gemstack/cli/commands/jobs.rb
71
- - lib/gemstack/cli/controller_generator.rb
72
- - lib/gemstack/cli/deploy_generator.rb
73
- - lib/gemstack/cli/doctor.rb
74
- - lib/gemstack/cli/generator.rb
75
- - lib/gemstack/cli/job_generator.rb
76
- - lib/gemstack/cli/migration_generator.rb
77
- - lib/gemstack/cli/policy_generator.rb
78
- - lib/gemstack/cli/project.rb
79
- - lib/gemstack/cli/resource_generator.rb
80
- - lib/gemstack/cli/resource_spec.rb
81
- - templates/app/Gemfile.tt
82
- - templates/app/README.md.tt
83
- - templates/app/app/controllers/application_controller.rb
84
- - templates/app/app/jobs/application_job.rb
85
- - templates/app/app/mailers/application_mailer.rb
86
- - templates/app/app/mailers/templates/dot_keep
87
- - templates/app/app/models/application_model.rb
88
- - templates/app/app/serializers/application_serializer.rb
89
- - templates/app/bin/gemstack
90
- - templates/app/config.ru
91
- - templates/app/config/app.rb.tt
92
- - templates/app/config/database.yml.tt
93
- - templates/app/config/environments/development.rb.tt
94
- - templates/app/config/environments/production.rb.tt
95
- - templates/app/config/environments/test.rb.tt
96
- - templates/app/config/puma.rb
97
- - templates/app/config/routes.rb
98
- - templates/app/db/migrations/dot_keep
99
- - templates/app/db/seeds.rb
100
- - templates/app/dot_env.example.tt
101
- - templates/app/dot_gitignore
102
- - templates/app/dot_node-version.tt
103
- - templates/app/dot_nvmrc.tt
104
- - templates/app/dot_ruby-version.tt
105
- - templates/app/dot_tool-versions.tt
106
- - templates/app/test/health_test.rb
107
- - templates/app/test/test_helper.rb.tt
108
- - templates/auth/app/controllers/api_tokens_controller.rb
109
- - templates/auth/app/controllers/email_verifications_controller.rb
110
- - templates/auth/app/controllers/password_resets_controller.rb
111
- - templates/auth/app/controllers/registrations_controller.rb
112
- - templates/auth/app/controllers/sessions_controller.rb
113
- - templates/auth/app/mailers/auth_mailer.rb
114
- - templates/auth/app/mailers/templates/auth_mailer/email_verification.html.erb
115
- - templates/auth/app/mailers/templates/auth_mailer/email_verification.text.erb
116
- - templates/auth/app/mailers/templates/auth_mailer/password_reset.html.erb
117
- - templates/auth/app/mailers/templates/auth_mailer/password_reset.text.erb
118
- - templates/auth/app/models/auth_token.rb
119
- - templates/auth/app/models/user.rb
120
- - templates/auth/app/policies/application_policy.rb
121
- - templates/auth/app/serializers/api_token_serializer.rb
122
- - templates/auth/app/serializers/new_api_token_serializer.rb
123
- - templates/auth/app/serializers/user_serializer.rb
124
- - templates/auth/db/migrations/%timestamp%_create_auth_tables.rb
125
- - templates/auth/frontend/app/account/page.tsx
126
- - templates/auth/frontend/app/forgot-password/page.tsx
127
- - templates/auth/frontend/app/login/page.tsx
128
- - templates/auth/frontend/app/reset-password/page.tsx
129
- - templates/auth/frontend/app/signup/page.tsx
130
- - templates/auth/frontend/app/verify-email/page.tsx
131
- - templates/auth/frontend/components/auth/CredentialsForm.tsx
132
- - templates/auth/frontend/components/auth/ResetPasswordForm.tsx
133
- - templates/auth/frontend/components/auth/VerifyEmail.tsx
134
- - templates/auth/frontend/lib/auth.ts
135
- - templates/auth/test/controllers/auth_test.rb
136
- - templates/controller/app/controllers/%file_name%_controller.rb.tt
137
- - templates/controller/test/controllers/%file_name%_controller_test.rb.tt
138
- - templates/deploy/Caddyfile.tt
139
- - templates/deploy/Dockerfile.tt
140
- - templates/deploy/Procfile.tt
141
- - templates/deploy/compose.yaml.tt
142
- - templates/deploy/dot_dockerignore
143
- - templates/frontend/app/globals.css
144
- - templates/frontend/app/layout.tsx.tt
145
- - templates/frontend/app/page.module.css
146
- - templates/frontend/app/page.tsx.tt
147
- - templates/frontend/app/providers.tsx
148
- - templates/frontend/lib/gemstack/client.ts
149
- - templates/frontend/next-env.d.ts
150
- - templates/frontend/next.config.ts
151
- - templates/frontend/package.json.tt
152
- - templates/frontend/tsconfig.json
153
- - templates/job/app/jobs/%file_name%.rb.tt
154
- - templates/job/test/jobs/%file_name%_test.rb.tt
155
- - templates/migration/db/migrations/%timestamp%_%file_name%.rb.tt
156
- - templates/policy/app/policies/%file_name%_policy.rb.tt
157
- - templates/policy/test/policies/%file_name%_policy_test.rb.tt
158
- - templates/realtime/config/channels.rb
159
- - templates/realtime/frontend/lib/gemstack/realtime.ts
160
- - templates/resource/controller/app/controllers/%plural%_controller.rb.tt
161
- - templates/resource/controller/test/controllers/%plural%_controller_test.rb.tt
162
- - templates/resource/frontend/frontend/app/%url_segment%/[id]/edit/page.tsx.tt
163
- - templates/resource/frontend/frontend/app/%url_segment%/[id]/page.tsx.tt
164
- - templates/resource/frontend/frontend/app/%url_segment%/new/page.tsx.tt
165
- - templates/resource/frontend/frontend/app/%url_segment%/page.tsx.tt
166
- - templates/resource/frontend/frontend/components/%url_segment%/%class_name%Card.tsx.tt
167
- - templates/resource/frontend/frontend/components/%url_segment%/%class_name%Form.tsx.tt
168
- - templates/resource/frontend/frontend/components/%url_segment%/%class_name%Table.tsx.tt
169
- - templates/resource/frontend/frontend/lib/format.ts
170
- - templates/resource/frontend/frontend/lib/queries/%url_segment%.ts.tt
171
- - templates/resource/migration/db/migrations/%timestamp%_create_%table%.rb.tt
172
- - templates/resource/model/app/models/%file_name%.rb.tt
173
- - templates/resource/model/test/models/%file_name%_test.rb.tt
174
- - templates/resource/serializer/app/serializers/%file_name%_serializer.rb.tt
175
- - templates/storage/app/controllers/uploads_controller.rb.tt
176
- - templates/storage/app/serializers/upload_serializer.rb
177
- - templates/storage/frontend/lib/upload.ts
178
- - templates/storage/test/controllers/uploads_test.rb.tt
179
26
  homepage: https://github.com/gemstack-rb/gemstack
180
27
  licenses:
181
28
  - MIT
182
29
  metadata:
183
30
  rubygems_mfa_required: 'true'
184
31
  source_code_uri: https://github.com/gemstack-rb/gemstack/tree/main/gems/gemstack-cli
185
- changelog_uri: https://github.com/gemstack-rb/gemstack/blob/main/gems/gemstack-cli/CHANGELOG.md
32
+ changelog_uri: https://github.com/gemstack-rb/gemstack/blob/main/CHANGELOG.md
186
33
  bug_tracker_uri: https://github.com/gemstack-rb/gemstack/issues
187
34
  documentation_uri: https://github.com/gemstack-rb/gemstack/tree/main/docs
188
35
  rdoc_options: []
@@ -201,5 +48,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
48
  requirements: []
202
49
  rubygems_version: 4.0.20
203
50
  specification_version: 4
204
- summary: GemStack command-line interface and generators
51
+ summary: The gemstack command (installed with the gemstack gem)
205
52
  test_files: []
@@ -1,239 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemStack
4
- class CLI < Thor
5
- # `gemstack add FEATURE` — opt-in modules, so apps that don't use them
6
- # pay nothing: realtime, auth, storage.
7
- class AddGenerator < Generator
8
- FEATURES = %w[realtime auth storage].freeze
9
-
10
- AUTH_ROUTES = <<~RUBY
11
- # Authentication (gemstack add auth) — docs/authentication.md
12
- post "/auth/signup", to: "registrations#create"
13
- post "/auth/login", to: "sessions#create"
14
- get "/auth/me", to: "sessions#show"
15
- delete "/auth/logout", to: "sessions#destroy"
16
- post "/auth/password/forgot", to: "password_resets#create"
17
- post "/auth/password/reset", to: "password_resets#update"
18
- post "/auth/email/resend", to: "email_verifications#create"
19
- post "/auth/email/verify", to: "email_verifications#update"
20
- get "/auth/tokens", to: "api_tokens#index"
21
- post "/auth/tokens", to: "api_tokens#create"
22
- delete "/auth/tokens/:id", to: "api_tokens#destroy"
23
- RUBY
24
-
25
- MAIL_ENV = <<~ENV
26
-
27
- # Email. In development messages are saved to tmp/mail instead of being sent.
28
- # SMTP_URL=smtp://user:password@smtp.example.com:587
29
- # MAIL_FROM="My App <hello@example.com>"
30
- # APP_URL=https://example.com # the frontend, for links in emails (default http://localhost:3000)
31
- ENV
32
-
33
- def initialize(feature, root:, output: $stdout, install: true)
34
- super(output: output)
35
- unless FEATURES.include?(feature)
36
- raise Thor::Error,
37
- "Unknown feature #{feature.inspect}. Available: #{FEATURES.join(", ")}"
38
- end
39
-
40
- @feature = feature
41
- @root = root
42
- @install = install
43
- end
44
-
45
- def run
46
- public_send(:"add_#{@feature}")
47
- self
48
- end
49
-
50
- def add_realtime
51
- add_gem("gemstack-realtime")
52
- template_files("realtime", override_root: @root).each do |rel, source|
53
- next if rel.start_with?("frontend/") && !File.directory?(File.join(@root, "frontend"))
54
-
55
- write(File.join(@root, rel), File.read(source))
56
- end
57
- add_test_support('require "gemstack/realtime/testing"', "GemStack::Realtime::Testing")
58
- bundle_install
59
- end
60
-
61
- STORAGE_ENV = <<~ENV
62
-
63
- # File storage. Development and tests store files under storage/ (git-ignored).
64
- # STORAGE_SERVICE=s3 # production default
65
- # S3_BUCKET=my-app-uploads
66
- # AWS_REGION=eu-west-3
67
- # AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... (or an instance role)
68
- # S3_ENDPOINT=https://<account>.r2.cloudflarestorage.com # S3-compatible services
69
- ENV
70
-
71
- def add_storage
72
- add_gem("gemstack-storage")
73
- ensure_base_classes(@root, :serializer)
74
- copy_feature_templates("storage")
75
- add_routes(%(post "/uploads", to: "uploads#create" # direct uploads (gemstack add storage)\n),
76
- marker: "uploads#create")
77
- append_env_example(STORAGE_ENV, marker: "STORAGE_SERVICE")
78
- append_line(".gitignore", "/storage/")
79
- add_test_support('require "gemstack/storage/testing"', "GemStack::Storage::Testing")
80
- status("note", "Gemfile", "add gem \"aws-sdk-s3\" for S3 in production (docs/storage.md)")
81
- bundle_install
82
- end
83
-
84
- # For templates: whether `gemstack add auth` ran.
85
- def auth? = File.read(File.join(@root, "Gemfile")).match?(/^\s*gem "gemstack-auth"/)
86
-
87
- def add_auth
88
- require_database!("auth")
89
- user_model = File.join(@root, "app/models/user.rb")
90
- if File.file?(user_model) && !File.read(user_model).include?("GemStack::Auth::User")
91
- raise Thor::Error, "app/models/user.rb already exists. Add `include GemStack::Auth::User` to it and " \
92
- "see docs/authentication.md (\"Existing users table\") instead."
93
- end
94
-
95
- add_gem("gemstack-mail")
96
- add_gem("gemstack-auth")
97
- JobGenerator.install_migration(@root, output: @output) # emails are sent from background jobs
98
- ensure_base_classes(@root, :model, :serializer, :mailer)
99
- copy_feature_templates("auth", skip_migration: "*_create_auth_tables.rb")
100
- include_in_application_controller("GemStack::Auth::Controller")
101
- add_routes(AUTH_ROUTES, marker: "/auth/login")
102
- append_env_example(MAIL_ENV, marker: "SMTP_URL")
103
- add_test_support('require "gemstack/mail/testing"', "GemStack::Mail::Testing")
104
- add_test_support('require "gemstack/auth/testing"', "GemStack::Auth::Testing")
105
- bundle_install
106
- end
107
-
108
- private
109
-
110
- def frontend? = File.directory?(File.join(@root, "frontend"))
111
-
112
- def require_database!(feature)
113
- return if File.read(File.join(@root, "Gemfile")).match?(/^\s*gem "gemstack-db"/)
114
-
115
- raise Thor::Error, "#{feature} stores its data in PostgreSQL; this app was created without a database " \
116
- "(add gem \"gemstack-db\" first — docs/database.md)"
117
- end
118
-
119
- # Writes a feature's templates (frontend/ files only when the app has
120
- # one). %timestamp% in a path becomes a fresh migration version, unless a
121
- # migration matching skip_migration already exists.
122
- def copy_feature_templates(name, skip_migration: nil)
123
- has_migration = skip_migration && !Dir.glob(File.join(@root, "db/migrations", skip_migration)).empty?
124
- template_files(name, override_root: @root).sort.each do |rel, source|
125
- next if rel.start_with?("frontend/") && !frontend?
126
-
127
- if rel.include?("%timestamp%")
128
- next status("identical", rel, "migration already present") if has_migration
129
-
130
- rel = rel.sub("%timestamp%", Generator.migration_timestamp(@root))
131
- end
132
- content = File.read(source)
133
- content = render(content, source) if rel.end_with?(".tt")
134
- write(File.join(@root, rel.delete_suffix(".tt")), content)
135
- end
136
- end
137
-
138
- def include_in_application_controller(mixin)
139
- path = File.join(@root, "app/controllers/application_controller.rb")
140
- return status("skip", path, "not found — add `include #{mixin}` yourself") unless File.file?(path)
141
-
142
- content = File.read(path)
143
- return status("identical", path, mixin) if content.include?(mixin)
144
-
145
- updated = content.sub(/^class ApplicationController < .*\n/) { |line| "#{line} include #{mixin}\n" }
146
- return status("skip", path, "add `include #{mixin}` yourself") if updated == content
147
-
148
- File.write(path, updated)
149
- status("update", path, mixin)
150
- end
151
-
152
- def add_routes(block, marker:)
153
- path = File.join(@root, "config/routes.rb")
154
- content = File.file?(path) ? File.read(path) : ""
155
- return status("identical", path, "routes") if content.include?(marker)
156
- return status("skip", path, "no `GemStack.routes do` block — add the routes yourself") unless
157
- content.match?(ControllerGenerator::ROUTES_BLOCK)
158
-
159
- File.write(path, content.sub(ControllerGenerator::ROUTES_BLOCK) { |open| open + block.gsub(/^/, " ") })
160
- status("route", path)
161
- end
162
-
163
- def append_line(file, line)
164
- path = File.join(@root, file)
165
- return unless File.file?(path)
166
-
167
- content = File.read(path)
168
- return if content.lines.map(&:strip).include?(line)
169
-
170
- File.write(path, "#{content.rstrip}\n#{line}\n")
171
- status("update", path, line)
172
- end
173
-
174
- def append_env_example(text, marker:)
175
- path = File.join(@root, ".env.example")
176
- return unless File.file?(path)
177
-
178
- content = File.read(path)
179
- return if content.include?(marker)
180
-
181
- File.write(path, "#{content.rstrip}\n#{text}")
182
- status("update", path)
183
- end
184
-
185
- # Adds the gem inside the GemStack `path` block (checkout apps) or as a
186
- # versioned dependency next to gem "gemstack".
187
- def add_gem(name)
188
- path = File.join(@root, "Gemfile")
189
- content = File.read(path)
190
- return status("identical", path, name) if content.match?(/^\s*gem "#{name}"/)
191
-
192
- updated = content.match?(/^path ".*" do\n/) ? add_to_path_block(content, name) : add_versioned(content, name)
193
- if updated == content
194
- raise Thor::Error,
195
- "couldn't find where to add #{name} in the Gemfile; add `gem \"#{name}\"` yourself"
196
- end
197
-
198
- File.write(path, updated)
199
- status("gemfile", path, name)
200
- end
201
-
202
- # Keeps the block's gems in alphabetical order (Bundler/OrderedGems).
203
- def add_to_path_block(content, name)
204
- content.sub(/^(path ".*" do\n)((?: gem .*\n)*)/) do
205
- opening = ::Regexp.last_match(1)
206
- lines = ::Regexp.last_match(2) # before sort_by's regexes reset last_match
207
- gems = (lines.lines + [" gem \"#{name}\"\n"]).sort_by { |line| line[/"([^"]+)"/, 1] }
208
- opening + gems.join
209
- end
210
- end
211
-
212
- def add_versioned(content, name)
213
- content.sub(/^gem "gemstack",.*\n/) { |line| "#{line}gem \"#{name}\", \"~> #{GemStack::VERSION}\"\n" }
214
- end
215
-
216
- def add_test_support(require_line, mixin)
217
- path = File.join(@root, "test/test_helper.rb")
218
- return unless File.file?(path)
219
-
220
- content = File.read(path)
221
- return status("identical", path) if content.include?(mixin)
222
-
223
- content = content.sub(%(require "gemstack/testing"\n)) { |line| "#{line}#{require_line}\n" }
224
- content = "#{content.rstrip}\nGemStack::TestCase.include #{mixin}\n"
225
- File.write(path, content)
226
- status("update", path, mixin)
227
- end
228
-
229
- def bundle_install
230
- return unless @install
231
-
232
- status("run", "bundle install")
233
- install = -> { system("bundle", "install", "--quiet", chdir: @root) }
234
- ok = defined?(Bundler) ? Bundler.with_unbundled_env(&install) : install.call
235
- status("warning", "bundle install failed — run it yourself") unless ok
236
- end
237
- end
238
- end
239
- end
@@ -1,142 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "gemstack/dev"
4
-
5
- module GemStack
6
- class CLI < Thor
7
- # `gemstack new NAME` — a Ruby API + Next.js application containing the
8
- # framework infrastructure and deliberately no business resources.
9
- class AppGenerator < Generator
10
- NAME = /\A[a-z][a-z0-9_-]*\z/
11
- # `--database` values (Rails' names) and aliases.
12
- DATABASES = { "sqlite3" => "sqlite3", "sqlite" => "sqlite3", "postgresql" => "postgresql",
13
- "postgres" => "postgresql", "pg" => "postgresql", "mysql2" => "mysql2", "mysql" => "mysql2",
14
- "trilogy" => "trilogy" }.freeze
15
- DRIVERS = { "sqlite3" => ["sqlite3", "~> 2.0"], "postgresql" => ["pg", "~> 1.5"],
16
- "mysql2" => ["mysql2", "~> 0.5"], "trilogy" => ["trilogy", "~> 2.9"] }.freeze
17
-
18
- # The gems/ directory of the GemStack checkout this CLI runs from, if any.
19
- CHECKOUT = File.expand_path("../../../..", __dir__)
20
-
21
- attr_reader :name, :module_name, :destination, :gemstack_path, :api_path
22
-
23
- def initialize(name, options = {}, output: $stdout)
24
- super(output: output)
25
- @name = File.basename(name.to_s)
26
- @destination = File.expand_path(name.to_s)
27
- @options = options
28
- @module_name = Inflector.camelize(@name.tr("-", "_"))
29
- @gemstack_path = options[:gemstack_path] ? File.expand_path(options[:gemstack_path]) : detect_checkout
30
- @api_path = "/api"
31
- end
32
-
33
- def version = GemStack::VERSION
34
-
35
- # Pins the app to the Ruby that generated it, in files every version
36
- # manager reads (.ruby-version: rbenv, rvm, chruby, asdf, mise;
37
- # .tool-versions: asdf, mise), and Node.js likewise (.node-version,
38
- # .nvmrc, .tool-versions).
39
- def ruby_version = RUBY_VERSION
40
- def node_version = @node_version ||= Dev::Toolchain.pinned_node_version
41
- def frontend? = !@options[:skip_frontend]
42
- def database? = !@options[:skip_database]
43
-
44
- # sqlite3 (default), postgresql, mysql2 or trilogy.
45
- def database_adapter
46
- @database_adapter ||= DATABASES.fetch(@options[:database].to_s.downcase.then do |d|
47
- d.empty? ? "sqlite3" : d
48
- end) do
49
- raise Thor::Error,
50
- "Unknown --database #{@options[:database].inspect}. Use: sqlite3, postgresql, mysql2, trilogy"
51
- end
52
- end
53
-
54
- def driver_gem = DRIVERS.fetch(database_adapter).first
55
- def driver_version = DRIVERS.fetch(database_adapter).last
56
- def database_name = name.tr("-", "_")
57
-
58
- def run
59
- validate!
60
- database_adapter if database? # fail early on an unknown --database
61
- @output.puts("Creating GemStack application #{name} in #{destination}")
62
- render_directory("app", destination, skip: lambda { |rel|
63
- (!database? && (rel.start_with?("db/", "app/models/") || rel == "config/database.yml.tt")) ||
64
- (!frontend? && %w[dot_node-version.tt dot_nvmrc.tt].include?(rel))
65
- })
66
- render_directory("frontend", File.join(destination, "frontend")) if frontend?
67
- install unless @options[:skip_install]
68
- git_init unless @options[:skip_git]
69
- summary
70
- self
71
- end
72
-
73
- private
74
-
75
- def validate!
76
- unless NAME.match?(name)
77
- raise Thor::Error,
78
- "Invalid name #{name.inspect}: use lowercase letters, digits, - and _, starting with a letter"
79
- end
80
- return unless File.exist?(destination) && !Dir.empty?(destination)
81
-
82
- raise Thor::Error, "#{destination} already exists and is not empty"
83
- end
84
-
85
- def detect_checkout
86
- File.file?(File.join(CHECKOUT, "gemstack", "gemstack.gemspec")) ? CHECKOUT : nil
87
- end
88
-
89
- def install
90
- bundled = run_step("bundle install", destination, "bundle", "install", "--quiet")
91
- create_database if bundled && database?
92
- return unless frontend?
93
-
94
- run_step("npm install", File.join(destination, "frontend"), "npm", "install", "--no-fund",
95
- "--no-audit")
96
- # The TypeScript contract, so frontend/lib/api/generated exists from the start.
97
- run_step("gemstack contract", destination, "bin/gemstack", "contract", "--quiet") if bundled
98
- end
99
-
100
- # Best effort: a missing or password-protected database server shouldn't fail `new`.
101
- def create_database
102
- @output.puts(" #{"run".rjust(9)} gemstack db:create")
103
- ok = unbundled { system("bin/gemstack", "db:create", chdir: destination, out: File::NULL, err: File::NULL) }
104
- return if ok
105
-
106
- @output.puts(" #{"warning".rjust(9)} couldn't create the database — " \
107
- "check config/database.yml (or set DATABASE_URL in .env), then run `gemstack db:create`")
108
- end
109
-
110
- def git_init
111
- return if File.directory?(File.join(destination, ".git")) || !system("git --version", out: File::NULL)
112
-
113
- run_step("git init", destination, "git", "init", "--quiet")
114
- end
115
-
116
- def run_step(label, dir, *command)
117
- @output.puts(" #{"run".rjust(9)} #{label}")
118
- ok = unbundled { system(*command, chdir: dir) }
119
- @output.puts(" #{"warning".rjust(9)} `#{label}` failed — run it manually in #{dir}") unless ok
120
- ok
121
- end
122
-
123
- # Run child commands with the new app's bundle, not the CLI's.
124
- def unbundled(&)
125
- defined?(Bundler) ? Bundler.with_unbundled_env(&) : yield
126
- end
127
-
128
- def summary
129
- @output.puts <<~TEXT
130
-
131
- GemStack application #{name} created.
132
-
133
- cd #{name}
134
- gemstack dev # → http://localhost:3000
135
-
136
- Next: gemstack generate resource Product name:string price:decimal
137
- Useful commands: gemstack routes · gemstack test · gemstack console · gemstack db:migrate
138
- TEXT
139
- end
140
- end
141
- end
142
- end