belt 0.2.9 → 0.2.11

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +119 -0
  3. data/README.md +217 -8
  4. data/lib/belt/action_router.rb +33 -5
  5. data/lib/belt/assets/welcome.css +119 -47
  6. data/lib/belt/cli/bucket_security.rb +10 -4
  7. data/lib/belt/cli/deploy_command.rb +48 -0
  8. data/lib/belt/cli/destroy_command.rb +119 -10
  9. data/lib/belt/cli/doctor_command.rb +208 -0
  10. data/lib/belt/cli/environment_command.rb +38 -6
  11. data/lib/belt/cli/frontend_command.rb +25 -12
  12. data/lib/belt/cli/frontend_setup_command.rb +41 -0
  13. data/lib/belt/cli/new_command.rb +106 -38
  14. data/lib/belt/cli/path_gem_materializer.rb +141 -0
  15. data/lib/belt/cli/plugin_command.rb +221 -0
  16. data/lib/belt/cli/setup_command.rb +35 -10
  17. data/lib/belt/cli.rb +8 -0
  18. data/lib/belt/configuration.rb +30 -0
  19. data/lib/belt/controllers/welcome_controller.rb +69 -2
  20. data/lib/belt/helpers/cors_origin.rb +19 -2
  21. data/lib/belt/helpers/response.rb +48 -6
  22. data/lib/belt/http_status.rb +89 -0
  23. data/lib/belt/lambda_handler.rb +14 -5
  24. data/lib/belt/rendering.rb +1 -0
  25. data/lib/belt/version.rb +1 -1
  26. data/lib/belt/views/welcome/show.html.erb +31 -31
  27. data/lib/belt.rb +16 -0
  28. data/lib/belt_controller/base.rb +24 -1
  29. data/lib/belt_controller/implicit_response.rb +104 -0
  30. data/lib/templates/environment/backend.tf.erb +1 -1
  31. data/lib/templates/frontend/react/src/index.css +4 -4
  32. data/lib/templates/frontend/react/src/lib/apiClient.js.erb +20 -3
  33. data/lib/templates/frontend/react/src/pages/Home.jsx.erb +283 -4
  34. data/lib/templates/module/main.tf.erb +13 -3
  35. data/lib/templates/new_app/config/routes.tf.rb.erb +2 -1
  36. data/lib/templates/plugin/AGENTS.md.erb +135 -0
  37. data/lib/templates/plugin/CHANGELOG.md.erb +5 -0
  38. data/lib/templates/plugin/Gemfile.erb +11 -0
  39. data/lib/templates/plugin/LICENSE.erb +21 -0
  40. data/lib/templates/plugin/README.md.erb +63 -0
  41. data/lib/templates/plugin/Rakefile.erb +7 -0
  42. data/lib/templates/plugin/gemspec.erb +26 -0
  43. data/lib/templates/plugin/gitignore.erb +11 -0
  44. data/lib/templates/plugin/lib/belt/generators/generator.rb.erb +122 -0
  45. data/lib/templates/plugin/lib/belt/module/configuration.rb.erb +15 -0
  46. data/lib/templates/plugin/lib/belt/module/version.rb.erb +7 -0
  47. data/lib/templates/plugin/lib/belt/module.rb.erb +27 -0
  48. data/lib/templates/plugin/lib/entry.rb.erb +3 -0
  49. data/lib/templates/plugin/rspec.erb +3 -0
  50. data/lib/templates/plugin/spec/configuration_spec.rb.erb +17 -0
  51. data/lib/templates/plugin/spec/spec_helper.rb.erb +19 -0
  52. metadata +37 -1
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development, :test do
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rubocop', '~> 1.0', require: false
11
+ end
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) <%= Time.now.year %>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,63 @@
1
+ # <%= gem_name %>
2
+
3
+ <%= summary %>.
4
+
5
+ A [Belt](https://github.com/stowzilla/belt) plugin. Add the gem to a Belt app, then run the generator to install infrastructure and app wiring.
6
+
7
+ ## Installation
8
+
9
+ Add to your Belt app's Gemfile:
10
+
11
+ ```ruby
12
+ gem '<%= gem_name %>'
13
+ # Or during development:
14
+ # gem '<%= gem_name %>', path: '../<%= gem_name %>'
15
+ ```
16
+
17
+ Then:
18
+
19
+ ```bash
20
+ bundle install
21
+ belt generate <%= plugin_name %>
22
+ ```
23
+
24
+ ## What You Get
25
+
26
+ ### From the gem (no generation needed)
27
+
28
+ ```ruby
29
+ # Configure
30
+ <%= constant_path %>.configure do |config|
31
+ # config.option = value
32
+ end
33
+ ```
34
+
35
+ ### From the generator (`belt g <%= plugin_name %>`)
36
+
37
+ Edit `lib/belt/generators/<%= underscored %>_generator.rb` and templates under
38
+ `lib/belt/<%= underscored %>/templates/` to define what gets installed into apps.
39
+
40
+ Typical plugin generators create some combination of:
41
+
42
+ - **Terraform module** — `infrastructure/modules/<%= plugin_name %>/`
43
+ - **Lambda entry point** — `lambda/<%= plugin_name %>.rb`
44
+ - **Lambda config** — `config/lambda/<%= plugin_name %>.yml`
45
+ - **Route / schema injection** — updates to `routes.tf.rb` / `schema.tf.rb`
46
+ - **Optional controller overrides** — `belt g <%= plugin_name %> --controllers`
47
+
48
+ ## Development
49
+
50
+ ```bash
51
+ bundle install
52
+ bundle exec rspec
53
+ ```
54
+
55
+ ## Removing
56
+
57
+ ```bash
58
+ belt destroy <%= plugin_name %>
59
+ ```
60
+
61
+ ## License
62
+
63
+ MIT
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/belt/<%= underscored %>/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = '<%= gem_name %>'
7
+ spec.version = <%= constant_path %>::VERSION
8
+ spec.authors = ['Your Name']
9
+ spec.email = ['you@example.com']
10
+
11
+ spec.summary = '<%= summary %>'
12
+ spec.description = '<%= summary %>. A Belt plugin gem — add to a Belt app Gemfile, then run `belt generate <%= plugin_name %>`.'
13
+ spec.homepage = 'https://github.com/example/<%= gem_name %>'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.3'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+ spec.metadata['rubygems_mfa_required'] = 'true'
21
+
22
+ spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md']
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'belt', '~> 0.2'
26
+ end
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.gem
10
+ Gemfile.lock
11
+ .rspec_status
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'erb'
5
+
6
+ module Belt
7
+ module Generators
8
+ # Generator registered automatically by Belt::CLI::GeneratorRegistry.
9
+ # File must live at: lib/belt/generators/<%= underscored %>_generator.rb
10
+ #
11
+ # Available as:
12
+ # belt generate <%= plugin_name %>
13
+ # belt destroy <%= plugin_name %>
14
+ class <%= generator_class %>
15
+ TEMPLATE_DIR = File.expand_path('../<%= underscored %>/templates', __dir__)
16
+
17
+ def self.description
18
+ 'Install <%= summary %>'
19
+ end
20
+
21
+ def self.run(args)
22
+ if args.include?('--help') || args.include?('-h')
23
+ print_help
24
+ return
25
+ end
26
+
27
+ new(args).generate
28
+ end
29
+
30
+ def self.destroy(args)
31
+ new(args).destroy
32
+ end
33
+
34
+ def self.print_help
35
+ puts <<~HELP
36
+ Install <%= gem_name %> into a Belt application.
37
+
38
+ Usage: belt generate <%= plugin_name %> [options]
39
+
40
+ Options:
41
+ --force Overwrite existing files
42
+ -h, --help Show this help
43
+
44
+ What gets created (customize this generator):
45
+ infrastructure/modules/<%= plugin_name %>/ Terraform module (optional)
46
+ config/lambda/<%= plugin_name %>.yml Lambda configuration (optional)
47
+ lambda/<%= plugin_name %>.rb Lambda entry point (optional)
48
+
49
+ What stays in the gem (no generation needed):
50
+ <%= constant_path %> Runtime library API
51
+
52
+ After generation:
53
+ 1. Wire any Terraform module into your environment main.tf
54
+ 2. Configure environment variables / secrets
55
+ 3. Deploy: belt deploy <env>
56
+
57
+ Examples:
58
+ belt g <%= plugin_name %>
59
+ belt d <%= plugin_name %>
60
+ HELP
61
+ end
62
+
63
+ def initialize(args)
64
+ @force = args.include?('--force')
65
+ end
66
+
67
+ def generate
68
+ # TODO: copy templates into the host app.
69
+ # Pattern used by belt-messaging / belt-pay:
70
+ #
71
+ # generate_terraform_module
72
+ # generate_lambda_config
73
+ # generate_lambda_entry_point
74
+ # inject_routes
75
+ #
76
+ # Templates live under TEMPLATE_DIR. Use ERB + FileUtils.
77
+ puts " # TODO: implement <%= generator_class %>#generate"
78
+ puts " # Templates directory: #{TEMPLATE_DIR}"
79
+ print_success
80
+ end
81
+
82
+ def destroy
83
+ # TODO: remove files created by #generate
84
+ puts " # TODO: implement <%= generator_class %>#destroy"
85
+ puts "\n✓ <%= module_name %> removed!"
86
+ puts ' Don\'t forget to remove any module references from environment main.tf files.'
87
+ end
88
+
89
+ private
90
+
91
+ def print_success
92
+ puts ''
93
+ puts "✓ <%= module_name %> installed (scaffold — implement the generator next)!"
94
+ puts ''
95
+ puts 'Next steps:'
96
+ puts " 1. Add ERB templates under lib/belt/<%= underscored %>/templates/"
97
+ puts " 2. Implement generate/destroy in lib/belt/generators/<%= underscored %>_generator.rb"
98
+ puts ' 3. See belt-messaging or belt-pay for full working examples'
99
+ end
100
+
101
+ # ---- helpers (copy patterns from belt-messaging / belt-pay) ----
102
+
103
+ def write_template(relative_template, destination, binding_context = binding)
104
+ source = File.join(TEMPLATE_DIR, relative_template)
105
+ unless File.exist?(source)
106
+ puts " skip missing template #{relative_template}"
107
+ return
108
+ end
109
+
110
+ if File.exist?(destination) && !@force
111
+ puts " skip #{destination} (already exists, use --force to overwrite)"
112
+ return
113
+ end
114
+
115
+ FileUtils.mkdir_p(File.dirname(destination))
116
+ content = ERB.new(File.read(source), trim_mode: '-').result(binding_context)
117
+ File.write(destination, content)
118
+ puts " create #{destination}"
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Belt
4
+ module <%= module_name %>
5
+ class Configuration
6
+ # Add plugin-specific settings here.
7
+ # attr_accessor :api_key, :logger
8
+ attr_accessor :logger
9
+
10
+ def initialize
11
+ @logger = nil # Falls back to Belt::Observability::Logger if available
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Belt
4
+ module <%= module_name %>
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '<%= underscored %>/version'
4
+ require_relative '<%= underscored %>/configuration'
5
+
6
+ module Belt
7
+ module <%= module_name %>
8
+ class Error < StandardError; end
9
+ class ConfigurationError < Error; end
10
+
11
+ class << self
12
+ attr_writer :configuration
13
+
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def configure
19
+ yield(configuration)
20
+ end
21
+
22
+ def reset_configuration!
23
+ @configuration = Configuration.new
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'belt/<%= underscored %>'
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe <%= constant_path %>::Configuration do
6
+ it 'has a default configuration' do
7
+ expect(<%= constant_path %>.configuration).to be_a(described_class)
8
+ end
9
+
10
+ it 'accepts configure block' do
11
+ <%= constant_path %>.configure do |config|
12
+ config.logger = :test_logger
13
+ end
14
+
15
+ expect(<%= constant_path %>.configuration.logger).to eq(:test_logger)
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'belt/<%= underscored %>'
4
+
5
+ RSpec.configure do |config|
6
+ config.expect_with :rspec do |expectations|
7
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
8
+ end
9
+
10
+ config.mock_with :rspec do |mocks|
11
+ mocks.verify_partial_doubles = true
12
+ end
13
+
14
+ config.shared_context_metadata_behavior = :apply_to_host_groups
15
+
16
+ config.before do
17
+ <%= constant_path %>.reset_configuration!
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: belt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.2.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stowzilla
@@ -76,6 +76,7 @@ files:
76
76
  - lib/belt/cli/console_command.rb
77
77
  - lib/belt/cli/deploy_command.rb
78
78
  - lib/belt/cli/destroy_command.rb
79
+ - lib/belt/cli/doctor_command.rb
79
80
  - lib/belt/cli/env_resolver.rb
80
81
  - lib/belt/cli/environment_command.rb
81
82
  - lib/belt/cli/environment_config.rb
@@ -88,6 +89,8 @@ files:
88
89
  - lib/belt/cli/generator_registry.rb
89
90
  - lib/belt/cli/lambda_config_command.rb
90
91
  - lib/belt/cli/new_command.rb
92
+ - lib/belt/cli/path_gem_materializer.rb
93
+ - lib/belt/cli/plugin_command.rb
91
94
  - lib/belt/cli/routes_command.rb
92
95
  - lib/belt/cli/routes_command/route_inference.rb
93
96
  - lib/belt/cli/routes_command/schema_loader.rb
@@ -97,10 +100,12 @@ files:
97
100
  - lib/belt/cli/tasks_command.rb
98
101
  - lib/belt/cli/terraform_command.rb
99
102
  - lib/belt/cli/views_command.rb
103
+ - lib/belt/configuration.rb
100
104
  - lib/belt/controllers/welcome_controller.rb
101
105
  - lib/belt/helpers/cors_origin.rb
102
106
  - lib/belt/helpers/error_logging.rb
103
107
  - lib/belt/helpers/response.rb
108
+ - lib/belt/http_status.rb
104
109
  - lib/belt/inflector.rb
105
110
  - lib/belt/lambda_handler.rb
106
111
  - lib/belt/observability.rb
@@ -112,6 +117,7 @@ files:
112
117
  - lib/belt/version.rb
113
118
  - lib/belt/views/welcome/show.html.erb
114
119
  - lib/belt_controller/base.rb
120
+ - lib/belt_controller/implicit_response.rb
115
121
  - lib/templates/environment/backend.tf.erb
116
122
  - lib/templates/environment/main.tf.erb
117
123
  - lib/templates/environment/outputs.tf.erb
@@ -147,6 +153,22 @@ files:
147
153
  - lib/templates/new_app/lambda/controllers/application_controller.rb.erb
148
154
  - lib/templates/new_app/lambda/lib/routes/routes.rb.erb
149
155
  - lib/templates/new_app/lambda/models/application_record.rb.erb
156
+ - lib/templates/plugin/AGENTS.md.erb
157
+ - lib/templates/plugin/CHANGELOG.md.erb
158
+ - lib/templates/plugin/Gemfile.erb
159
+ - lib/templates/plugin/LICENSE.erb
160
+ - lib/templates/plugin/README.md.erb
161
+ - lib/templates/plugin/Rakefile.erb
162
+ - lib/templates/plugin/gemspec.erb
163
+ - lib/templates/plugin/gitignore.erb
164
+ - lib/templates/plugin/lib/belt/generators/generator.rb.erb
165
+ - lib/templates/plugin/lib/belt/module.rb.erb
166
+ - lib/templates/plugin/lib/belt/module/configuration.rb.erb
167
+ - lib/templates/plugin/lib/belt/module/version.rb.erb
168
+ - lib/templates/plugin/lib/entry.rb.erb
169
+ - lib/templates/plugin/rspec.erb
170
+ - lib/templates/plugin/spec/configuration_spec.rb.erb
171
+ - lib/templates/plugin/spec/spec_helper.rb.erb
150
172
  - lib/templates/views/Edit.jsx.erb
151
173
  - lib/templates/views/Form.jsx.erb
152
174
  - lib/templates/views/Index.jsx.erb
@@ -160,6 +182,19 @@ metadata:
160
182
  source_code_uri: https://github.com/stowzilla/belt
161
183
  changelog_uri: https://github.com/stowzilla/belt/blob/master/CHANGELOG.md
162
184
  rubygems_mfa_required: 'true'
185
+ post_install_message: |2+
186
+
187
+ ╭────────────────────────────────────────────╮
188
+ │ Belt installed successfully! │
189
+ │ │
190
+ │ Run `belt doctor` to verify your setup: │
191
+ │ • AWS CLI │
192
+ │ • Terraform │
193
+ │ • AWS credentials & authentication │
194
+ │ │
195
+ │ Then: belt new <app_name> │
196
+ ╰────────────────────────────────────────────╯
197
+
163
198
  rdoc_options: []
164
199
  require_paths:
165
200
  - lib
@@ -178,3 +213,4 @@ rubygems_version: 3.6.9
178
213
  specification_version: 4
179
214
  summary: Belt - a utility toolkit for Ruby applications
180
215
  test_files: []
216
+ ...