brut 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1fd649346396f27b70064c601a639187c08fec7d38f4efc973c3a9839d2c163
4
- data.tar.gz: a06518da1bb198c89acfd13dca787fabb302546097e08d8917bf1c500d399f39
3
+ metadata.gz: d0a674e5f292d833626132e6cb0d634eb7432a5f814cfdde37456980c5066ace
4
+ data.tar.gz: dfe06bd16d1af502fc42512c1eb9c6500d2f13e3355587e705bb3e0f314f59be
5
5
  SHA512:
6
- metadata.gz: 0ecde01ea2f1cdc821e24e835fe18a7420848601d469435c74abe3d020187fccc73004ce063f7c242f663796d2470145981e6ace8a742ae885568abb0533eb74
7
- data.tar.gz: da0e5c69737041a6ff25366c4fd4cb41214f97b1ada9c78f878544f380f8370bcd155f8f7e6b77d52b50a77b6270b08847e5b1e10bec657b464d289d84747c4f
6
+ metadata.gz: d6c1dae45c7e5f30b6e01ff4add890fbc3bbe1581c2363fa872a627d040f1dbe08a99e2d07c1f56e15d4f542cb506fa5a3e1f4d4ce4f0e15accba0ae3976b2fb
7
+ data.tar.gz: bcdf28454960102dfc70dc7a2b74f52ab7b661a83cd6050473a3de28628c636fd02cb476b44c3ab7000d64500b494682780cd1f60b4d5da5f0747652d33917f9
data/Gemfile.lock CHANGED
@@ -1,11 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brut (0.0.2)
4
+ brut (0.0.3)
5
5
  concurrent-ruby
6
- dotenv
7
- factory_bot
8
- faker
9
6
  i18n
10
7
  irb
11
8
  nokogiri
@@ -188,6 +185,9 @@ DEPENDENCIES
188
185
  activesupport
189
186
  brut!
190
187
  bundler
188
+ dotenv
189
+ factory_bot
190
+ faker
191
191
  rake
192
192
  rdiscount
193
193
  rdoc
data/brut.gemspec CHANGED
@@ -35,11 +35,8 @@ Gem::Specification.new do |spec|
35
35
  spec.require_paths = ["lib"]
36
36
 
37
37
  spec.add_runtime_dependency "irb"
38
- spec.add_runtime_dependency "dotenv"
39
38
  spec.add_runtime_dependency "ostruct" # squelch some warning - this is not used
40
- spec.add_runtime_dependency "factory_bot"
41
39
  spec.add_runtime_dependency "concurrent-ruby"
42
- spec.add_runtime_dependency "faker"
43
40
  spec.add_runtime_dependency "i18n"
44
41
  spec.add_runtime_dependency "nokogiri"
45
42
  spec.add_runtime_dependency "prism"
@@ -64,4 +61,7 @@ Gem::Specification.new do |spec|
64
61
  spec.add_development_dependency "yard"
65
62
  spec.add_development_dependency "rdiscount"
66
63
  spec.add_development_dependency "rdoc"
64
+ spec.add_development_dependency "dotenv"
65
+ spec.add_development_dependency "factory_bot"
66
+ spec.add_development_dependency "faker"
67
67
  end
@@ -2,87 +2,54 @@ require_relative "container"
2
2
  require_relative "config"
3
3
  require_relative "../junk_drawer"
4
4
  require_relative "app"
5
+
5
6
  require "sequel"
7
+
6
8
  require "semantic_logger"
9
+ require_relative "patch_semantic_logger"
10
+
7
11
  require "i18n"
8
12
  require "zeitwerk"
9
13
  require "opentelemetry/sdk"
10
14
  require "opentelemetry/exporter/otlp"
11
15
 
12
-
13
16
  # The Master Control Program of Brut. This handles all the bootstrapping and setup of your app. You are not
14
17
  # intended to use or interact with this class at all. End of line.
15
18
  class Brut::Framework::MCP
16
19
 
17
- # Create the MCP.
20
+ # Create and configure the MCP. The app will not work until {#boot!} has been called, however most of the core configuration
21
+ # will be available via `Brut.container`.
22
+ #
23
+ # In particular, when this initializer is done, the following will be set up:
24
+ #
25
+ # * Logging
26
+ # * I18n
27
+ # * Zeitwerk
28
+ # * Initial values and configuration from {Brut::Framework::Config#configure!}. Note that some values in there are static and some
29
+ # are lazily-evaluated, i.e. their values will only be calculated when fetched.
30
+ #
31
+ # In general, you shouldn't have to interact with this class directly, however for posterity, there are basically two ways in which
32
+ # to do so:
33
+ #
34
+ # * Create the instance and *do not* call `boot!`. This is what you'd do if you can't or don't want to connect to external services
35
+ # like the database. For example, when Brut builds assets, it does not call `boot!`.
36
+ # * Create the intance and immediately call `boot!`. This is what happens most of the time, in particular when the app is started
37
+ # up by Puma to start serving requests.
38
+ #
39
+ # What you should avoid doing is creating an instance of this class and performing logic before later calling `boot!`.
18
40
  #
19
41
  # @param [Class] app_klass subclass of {Brut::Framework::App} representing the Brut app being started up and managed.
20
42
  def initialize(app_klass:)
21
43
  @config = Brut::Framework::Config.new
22
44
  @booted = false
23
45
  @loader = Zeitwerk::Loader.new
24
- @app_klass = app_klass
25
- self.configure!
26
- end
27
-
28
- # Configure Brut and initialize the {Brut::Framework::App} subclass. This should, in theory, only set up values and other
29
- # ancillary data needed to start the app. It should not connect to databases.
30
- def configure!
31
46
  @config.configure!
32
47
 
33
- project_root = Brut.container.project_root
34
- project_env = Brut.container.project_env
35
-
36
- SemanticLogger.default_level = Brut.container.log_level
37
- semantic_logger_appenders = Brut.container.semantic_logger_appenders
38
- if semantic_logger_appenders.kind_of?(Hash)
39
- semantic_logger_appenders = [ semantic_logger_appenders ]
40
- end
41
- if semantic_logger_appenders.length == 0
42
- raise "No loggers are set up - something is wrong"
43
- end
44
- semantic_logger_appenders.each do |appender|
45
- SemanticLogger.add_appender(**appender)
46
- end
47
- SemanticLogger["Brut"].info("Logging set up")
48
-
49
- i18n_locales_dir = Brut.container.i18n_locales_dir
50
- locales = Dir[i18n_locales_dir / "*"].map { |_|
51
- Pathname(_).basename
52
- }
53
- ::I18n.load_path += Dir[i18n_locales_dir / "**/*.rb"]
54
- ::I18n.available_locales = locales.map(&:to_s).map(&:to_sym)
55
-
56
- Brut.container.store(
57
- "zeitwerk_loader",
58
- @loader.class,
59
- "Zeitwerk Loader configured for this app",
60
- @loader
61
- )
62
-
63
- Dir[Brut.container.front_end_src_dir / "*"].each do |dir|
64
- if Pathname(dir).directory?
65
- @loader.push_dir(dir)
66
- end
67
- end
68
- Dir[Brut.container.back_end_src_dir / "*"].each do |dir|
69
- if Pathname(dir).directory?
70
- @loader.push_dir(dir)
71
- end
72
- end
73
- @loader.ignore(Brut.container.migrations_dir)
74
- @loader.inflector.inflect(
75
- "db" => "DB"
76
- )
77
- if Brut.container.auto_reload_classes?
78
- SemanticLogger["Brut"].info("Auto-reloaded configured")
79
- @loader.enable_reloading
80
- else
81
- SemanticLogger["Brut"].info("Classes will not be auto-reloaded")
82
- end
48
+ setup_logging
49
+ setup_i18n
50
+ setup_zeitwerk
83
51
 
84
- @loader.setup
85
- @app = @app_klass.new
52
+ @app = app_klass.new
86
53
  end
87
54
 
88
55
  # Starts up the internals of Brut and that app so that it can receive requests from
@@ -102,6 +69,26 @@ class Brut::Framework::MCP
102
69
  SemanticLogger["Sequel::Database"].info "Not connected to database, so not disconnecting"
103
70
  end
104
71
  end
72
+ Sequel::Database.extension :pg_array
73
+
74
+ sequel_db = Brut.container.sequel_db_handle
75
+
76
+ Sequel::Model.db = sequel_db
77
+
78
+ Sequel::Model.plugin :find_bang
79
+ Sequel::Model.plugin :created_at
80
+ Sequel::Model.plugin :table_select
81
+ Sequel::Model.plugin :skip_saving_columns
82
+
83
+ if !Brut.container.external_id_prefix.nil?
84
+ Sequel::Model.plugin :external_id, global_prefix: Brut.container.external_id_prefix
85
+ end
86
+ if Brut.container.eager_load_classes?
87
+ SemanticLogger["Brut"].info("Eagerly loading app's classes")
88
+ @loader.eager_load
89
+ else
90
+ SemanticLogger["Brut"].info("Lazily loading app's classes")
91
+ end
105
92
  OpenTelemetry::SDK.configure do |c|
106
93
  c.service_name = @app.id
107
94
  if ENV["OTEL_TRACES_EXPORTER"]
@@ -121,28 +108,8 @@ class Brut::Framework::MCP
121
108
  "Tracer for Open Telemetry",
122
109
  OpenTelemetry.tracer_provider.tracer(@app.id)
123
110
  )
124
-
125
- Sequel::Database.extension :pg_array
126
111
  Sequel::Database.extension :brut_instrumentation
127
112
 
128
- sequel_db = Brut.container.sequel_db_handle
129
-
130
- Sequel::Model.db = sequel_db
131
-
132
- Sequel::Model.plugin :find_bang
133
- Sequel::Model.plugin :created_at
134
- Sequel::Model.plugin :table_select
135
- Sequel::Model.plugin :skip_saving_columns
136
-
137
- if !Brut.container.external_id_prefix.nil?
138
- Sequel::Model.plugin :external_id, global_prefix: Brut.container.external_id_prefix
139
- end
140
- if Brut.container.eager_load_classes?
141
- SemanticLogger["Brut"].info("Eagerly loading app's classes")
142
- @loader.eager_load
143
- else
144
- SemanticLogger["Brut"].info("Lazily loading app's classes")
145
- end
146
113
  @app.boot!
147
114
 
148
115
  require "sinatra/base"
@@ -264,9 +231,68 @@ class Brut::Framework::MCP
264
231
 
265
232
  @booted = true
266
233
  end
234
+
267
235
  # @!visibility private
268
236
  def sinatra_app = @sinatra_app
269
237
  # @!visibility private
270
238
  def app = @app
271
239
 
240
+ private
241
+
242
+ def setup_logging
243
+ SemanticLogger.default_level = Brut.container.log_level
244
+ semantic_logger_appenders = Brut.container.semantic_logger_appenders
245
+ if semantic_logger_appenders.kind_of?(Hash)
246
+ semantic_logger_appenders = [ semantic_logger_appenders ]
247
+ end
248
+ if semantic_logger_appenders.length == 0
249
+ raise "No loggers are set up - something is wrong"
250
+ end
251
+ semantic_logger_appenders.each do |appender|
252
+ SemanticLogger.add_appender(**appender)
253
+ end
254
+ SemanticLogger["Brut"].info("Logging set up")
255
+ end
256
+
257
+ def setup_i18n
258
+
259
+ i18n_locales_dir = Brut.container.i18n_locales_dir
260
+ locales = Dir[i18n_locales_dir / "*"].map { Pathname(it).basename }
261
+ ::I18n.load_path += Dir[i18n_locales_dir / "**/*.rb"]
262
+ ::I18n.available_locales = locales.map(&:to_s).map(&:to_sym)
263
+ end
264
+
265
+ def setup_zeitwerk
266
+
267
+ Brut.container.store(
268
+ "zeitwerk_loader",
269
+ @loader.class,
270
+ "Zeitwerk Loader configured for this app",
271
+ @loader
272
+ )
273
+
274
+ Dir[Brut.container.front_end_src_dir / "*"].each do |dir|
275
+ if Pathname(dir).directory?
276
+ @loader.push_dir(dir)
277
+ end
278
+ end
279
+ Dir[Brut.container.back_end_src_dir / "*"].each do |dir|
280
+ if Pathname(dir).directory?
281
+ @loader.push_dir(dir)
282
+ end
283
+ end
284
+ @loader.ignore(Brut.container.migrations_dir)
285
+ @loader.ignore(Brut.container.db_seeds_dir)
286
+ @loader.inflector.inflect(
287
+ "db" => "DB"
288
+ )
289
+ if Brut.container.auto_reload_classes?
290
+ SemanticLogger["Brut"].info("Auto-reloaded configured")
291
+ @loader.enable_reloading
292
+ else
293
+ SemanticLogger["Brut"].info("Classes will not be auto-reloaded")
294
+ end
295
+
296
+ @loader.setup
297
+ end
272
298
  end
@@ -0,0 +1,21 @@
1
+ class SemanticLogger::Appender::Async
2
+ # Set the thread created by SemanticLogger as fork safe to avoid
3
+ # a warning.
4
+ #
5
+ # Here is where Puma uses this
6
+ #
7
+ # https://github.com/puma/puma/blob/ca201ef69757f8830b636251b0af7a51270eb68a/lib/puma/cluster.rb#L377
8
+ #
9
+ # Of note, this change is only OK because on_worker_boot is set up to reopen
10
+ # SemanticLogger's appenders. Otherwise, the warning is legit.
11
+ #
12
+ def thread_with_puma_magic_variable
13
+ thread = thread_without_puma_magic_variable
14
+ thread.thread_variable_set(:fork_safe, true)
15
+ thread
16
+ end
17
+
18
+ alias_method :thread_without_puma_magic_variable, :thread
19
+ alias_method :thread, :thread_with_puma_magic_variable
20
+
21
+ end
@@ -77,9 +77,11 @@ class Brut::FrontEnd::Component
77
77
  #
78
78
  # @return [Brut::FrontEnd::Templates::HTMLSafeString] string containing the component's HTML.
79
79
  def render
80
- Brut.container.component_locator.locate(self.template_name).
81
- then { |erb_file| Brut::FrontEnd::Template.new(erb_file) }.
82
- then { |template| template.render_template(self).html_safe! }
80
+ Brut.container.instrumentation.span("#{self.class}.render") do |span|
81
+ Brut.container.component_locator.locate(self.template_name).
82
+ then { Brut::FrontEnd::Template.new(it) }.
83
+ then { it.render_template(self).html_safe! }
84
+ end
83
85
  end
84
86
 
85
87
  # For components that are private to a page, this returns the name of the page they are a part of.
@@ -130,25 +132,25 @@ class Brut::FrontEnd::Component
130
132
  def component(component_instance,&block)
131
133
  component_name = component_instance.kind_of?(Class) ? component_instance.name : component_instance.class.name
132
134
  Brut.container.instrumentation.span(component_name) do |span|
133
- if component_instance.kind_of?(Class)
134
- if !component_instance.ancestors.include?(Brut::FrontEnd::Component)
135
- raise ArgumentError,"#{component_instance} is not a component and cannot be created"
135
+ if component_instance.kind_of?(Class)
136
+ if !component_instance.ancestors.include?(Brut::FrontEnd::Component)
137
+ raise ArgumentError,"#{component_instance} is not a component and cannot be created"
138
+ end
139
+ component_instance = Thread.current.thread_variable_get(:request_context).
140
+ then { |request_context| request_context.as_constructor_args(component_instance,request_params: nil)
141
+ }.then { |constructor_args| component_instance.new(**constructor_args) }
142
+ span.add_attributes("global_component" => true, "class" => component_instance.class.name)
143
+ else
144
+ span.add_attributes("global_component" => false, "class" => component_instance.class.name)
136
145
  end
137
- component_instance = Thread.current.thread_variable_get(:request_context).
138
- then { |request_context| request_context.as_constructor_args(component_instance,request_params: nil)
139
- }.then { |constructor_args| component_instance.new(**constructor_args) }
140
- span.add_attributes("global_component" => true, "class" => component_instance.class.name)
141
- else
142
- span.add_attributes("global_component" => false, "class" => component_instance.class.name)
143
- end
144
- if !block.nil?
145
- component_instance.yielded_block = block
146
- end
147
- Thread.current.thread_variable_get(:request_context).then {
148
- it.as_method_args(component_instance,:render,request_params: nil, form: nil)
149
- }.then { |render_args|
150
- component_instance.render(**render_args).html_safe!
151
- }
146
+ if !block.nil?
147
+ component_instance.yielded_block = block
148
+ end
149
+ Thread.current.thread_variable_get(:request_context).then {
150
+ it.as_method_args(component_instance,:render,request_params: nil, form: nil)
151
+ }.then { |render_args|
152
+ component_instance.render(**render_args).html_safe!
153
+ }
152
154
  end
153
155
  end
154
156
 
data/lib/brut/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Brut
2
2
  # @!visibility private
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Bryant Copeland
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-18 00:00:00.000000000 Z
10
+ date: 2025-02-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: irb
@@ -24,7 +24,7 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
26
  - !ruby/object:Gem::Dependency
27
- name: dotenv
27
+ name: ostruct
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
@@ -38,7 +38,7 @@ dependencies:
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  - !ruby/object:Gem::Dependency
41
- name: ostruct
41
+ name: concurrent-ruby
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
@@ -52,7 +52,7 @@ dependencies:
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  - !ruby/object:Gem::Dependency
55
- name: factory_bot
55
+ name: i18n
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
@@ -66,7 +66,7 @@ dependencies:
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  - !ruby/object:Gem::Dependency
69
- name: concurrent-ruby
69
+ name: nokogiri
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - ">="
@@ -80,7 +80,7 @@ dependencies:
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  - !ruby/object:Gem::Dependency
83
- name: faker
83
+ name: prism
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - ">="
@@ -94,7 +94,7 @@ dependencies:
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  - !ruby/object:Gem::Dependency
97
- name: i18n
97
+ name: rack-protection
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - ">="
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: nokogiri
111
+ name: rackup
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
@@ -122,7 +122,7 @@ dependencies:
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  - !ruby/object:Gem::Dependency
125
- name: prism
125
+ name: rexml
126
126
  requirement: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - ">="
@@ -136,7 +136,7 @@ dependencies:
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  - !ruby/object:Gem::Dependency
139
- name: rack-protection
139
+ name: semantic_logger
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - ">="
@@ -150,7 +150,7 @@ dependencies:
150
150
  - !ruby/object:Gem::Version
151
151
  version: '0'
152
152
  - !ruby/object:Gem::Dependency
153
- name: rackup
153
+ name: sequel
154
154
  requirement: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - ">="
@@ -164,7 +164,7 @@ dependencies:
164
164
  - !ruby/object:Gem::Version
165
165
  version: '0'
166
166
  - !ruby/object:Gem::Dependency
167
- name: rexml
167
+ name: sinatra
168
168
  requirement: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - ">="
@@ -178,7 +178,7 @@ dependencies:
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0'
180
180
  - !ruby/object:Gem::Dependency
181
- name: semantic_logger
181
+ name: temple
182
182
  requirement: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - ">="
@@ -192,7 +192,7 @@ dependencies:
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
194
  - !ruby/object:Gem::Dependency
195
- name: sequel
195
+ name: tilt
196
196
  requirement: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - ">="
@@ -206,7 +206,7 @@ dependencies:
206
206
  - !ruby/object:Gem::Version
207
207
  version: '0'
208
208
  - !ruby/object:Gem::Dependency
209
- name: sinatra
209
+ name: tzinfo
210
210
  requirement: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - ">="
@@ -220,7 +220,7 @@ dependencies:
220
220
  - !ruby/object:Gem::Version
221
221
  version: '0'
222
222
  - !ruby/object:Gem::Dependency
223
- name: temple
223
+ name: tzinfo-data
224
224
  requirement: !ruby/object:Gem::Requirement
225
225
  requirements:
226
226
  - - ">="
@@ -234,7 +234,7 @@ dependencies:
234
234
  - !ruby/object:Gem::Version
235
235
  version: '0'
236
236
  - !ruby/object:Gem::Dependency
237
- name: tilt
237
+ name: zeitwerk
238
238
  requirement: !ruby/object:Gem::Requirement
239
239
  requirements:
240
240
  - - ">="
@@ -248,7 +248,7 @@ dependencies:
248
248
  - !ruby/object:Gem::Version
249
249
  version: '0'
250
250
  - !ruby/object:Gem::Dependency
251
- name: tzinfo
251
+ name: opentelemetry-sdk
252
252
  requirement: !ruby/object:Gem::Requirement
253
253
  requirements:
254
254
  - - ">="
@@ -262,7 +262,7 @@ dependencies:
262
262
  - !ruby/object:Gem::Version
263
263
  version: '0'
264
264
  - !ruby/object:Gem::Dependency
265
- name: tzinfo-data
265
+ name: opentelemetry-exporter-otlp
266
266
  requirement: !ruby/object:Gem::Requirement
267
267
  requirements:
268
268
  - - ">="
@@ -276,13 +276,13 @@ dependencies:
276
276
  - !ruby/object:Gem::Version
277
277
  version: '0'
278
278
  - !ruby/object:Gem::Dependency
279
- name: zeitwerk
279
+ name: activesupport
280
280
  requirement: !ruby/object:Gem::Requirement
281
281
  requirements:
282
282
  - - ">="
283
283
  - !ruby/object:Gem::Version
284
284
  version: '0'
285
- type: :runtime
285
+ type: :development
286
286
  prerelease: false
287
287
  version_requirements: !ruby/object:Gem::Requirement
288
288
  requirements:
@@ -290,27 +290,27 @@ dependencies:
290
290
  - !ruby/object:Gem::Version
291
291
  version: '0'
292
292
  - !ruby/object:Gem::Dependency
293
- name: opentelemetry-sdk
293
+ name: rspec
294
294
  requirement: !ruby/object:Gem::Requirement
295
295
  requirements:
296
- - - ">="
296
+ - - "~>"
297
297
  - !ruby/object:Gem::Version
298
- version: '0'
299
- type: :runtime
298
+ version: '3.0'
299
+ type: :development
300
300
  prerelease: false
301
301
  version_requirements: !ruby/object:Gem::Requirement
302
302
  requirements:
303
- - - ">="
303
+ - - "~>"
304
304
  - !ruby/object:Gem::Version
305
- version: '0'
305
+ version: '3.0'
306
306
  - !ruby/object:Gem::Dependency
307
- name: opentelemetry-exporter-otlp
307
+ name: bundler
308
308
  requirement: !ruby/object:Gem::Requirement
309
309
  requirements:
310
310
  - - ">="
311
311
  - !ruby/object:Gem::Version
312
312
  version: '0'
313
- type: :runtime
313
+ type: :development
314
314
  prerelease: false
315
315
  version_requirements: !ruby/object:Gem::Requirement
316
316
  requirements:
@@ -318,7 +318,7 @@ dependencies:
318
318
  - !ruby/object:Gem::Version
319
319
  version: '0'
320
320
  - !ruby/object:Gem::Dependency
321
- name: activesupport
321
+ name: rake
322
322
  requirement: !ruby/object:Gem::Requirement
323
323
  requirements:
324
324
  - - ">="
@@ -332,21 +332,21 @@ dependencies:
332
332
  - !ruby/object:Gem::Version
333
333
  version: '0'
334
334
  - !ruby/object:Gem::Dependency
335
- name: rspec
335
+ name: yard
336
336
  requirement: !ruby/object:Gem::Requirement
337
337
  requirements:
338
- - - "~>"
338
+ - - ">="
339
339
  - !ruby/object:Gem::Version
340
- version: '3.0'
340
+ version: '0'
341
341
  type: :development
342
342
  prerelease: false
343
343
  version_requirements: !ruby/object:Gem::Requirement
344
344
  requirements:
345
- - - "~>"
345
+ - - ">="
346
346
  - !ruby/object:Gem::Version
347
- version: '3.0'
347
+ version: '0'
348
348
  - !ruby/object:Gem::Dependency
349
- name: bundler
349
+ name: rdiscount
350
350
  requirement: !ruby/object:Gem::Requirement
351
351
  requirements:
352
352
  - - ">="
@@ -360,7 +360,7 @@ dependencies:
360
360
  - !ruby/object:Gem::Version
361
361
  version: '0'
362
362
  - !ruby/object:Gem::Dependency
363
- name: rake
363
+ name: rdoc
364
364
  requirement: !ruby/object:Gem::Requirement
365
365
  requirements:
366
366
  - - ">="
@@ -374,7 +374,7 @@ dependencies:
374
374
  - !ruby/object:Gem::Version
375
375
  version: '0'
376
376
  - !ruby/object:Gem::Dependency
377
- name: yard
377
+ name: dotenv
378
378
  requirement: !ruby/object:Gem::Requirement
379
379
  requirements:
380
380
  - - ">="
@@ -388,7 +388,7 @@ dependencies:
388
388
  - !ruby/object:Gem::Version
389
389
  version: '0'
390
390
  - !ruby/object:Gem::Dependency
391
- name: rdiscount
391
+ name: factory_bot
392
392
  requirement: !ruby/object:Gem::Requirement
393
393
  requirements:
394
394
  - - ">="
@@ -402,7 +402,7 @@ dependencies:
402
402
  - !ruby/object:Gem::Version
403
403
  version: '0'
404
404
  - !ruby/object:Gem::Dependency
405
- name: rdoc
405
+ name: faker
406
406
  requirement: !ruby/object:Gem::Requirement
407
407
  requirements:
408
408
  - - ">="
@@ -484,6 +484,7 @@ files:
484
484
  - lib/brut/framework/errors/not_implemented.rb
485
485
  - lib/brut/framework/fussy_type_enforcement.rb
486
486
  - lib/brut/framework/mcp.rb
487
+ - lib/brut/framework/patch_semantic_logger.rb
487
488
  - lib/brut/framework/project_environment.rb
488
489
  - lib/brut/front_end/asset_metadata.rb
489
490
  - lib/brut/front_end/component.rb