rage-rb 1.26.1 → 1.28.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -1
- data/CONTRIBUTING.md +10 -1
- data/README.md +1 -1
- data/exe/rage +1 -1
- data/lib/rage/cable/channel.rb +7 -11
- data/lib/rage/cli/base.rb +27 -0
- data/lib/rage/cli/code_generator.rb +58 -0
- data/lib/rage/cli/new_app_generator.rb +66 -0
- data/lib/rage/cli/openapi.rb +20 -0
- data/lib/rage/cli/skills.rb +222 -220
- data/lib/rage/cli.rb +12 -143
- data/lib/rage/code_loader.rb +5 -1
- data/lib/rage/configuration.rb +73 -2
- data/lib/rage/cookies.rb +11 -9
- data/lib/rage/daemon.rb +5 -2
- data/lib/rage/deferred/backends/disk.rb +544 -199
- data/lib/rage/deferred/backends/nil.rb +16 -2
- data/lib/rage/deferred/deferred.rb +5 -1
- data/lib/rage/deferred/queue.rb +8 -3
- data/lib/rage/deferred/task.rb +1 -0
- data/lib/rage/fiber_scheduler.rb +17 -13
- data/lib/rage/hooks.rb +6 -1
- data/lib/rage/logger/logger.rb +55 -4
- data/lib/rage/openapi/index.html.erb +1 -1
- data/lib/rage/openapi/openapi.rb +14 -5
- data/lib/rage/openapi/parsers/ext/blueprinter.rb +20 -12
- data/lib/rage/router/README.md +1 -1
- data/lib/rage/router/backend.rb +8 -4
- data/lib/rage/router/dsl.rb +5 -7
- data/lib/rage/tasks.rb +5 -0
- data/lib/rage/telemetry/capacity.rb +42 -0
- data/lib/rage/telemetry/telemetry.rb +19 -0
- data/lib/rage/version.rb +1 -1
- data/lib/rage-rb.rb +3 -0
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bbfe0ad2460e5d9f51317d8be527259b500e28de3dd2817fe50017d6d44558fe
|
|
4
|
+
data.tar.gz: d55249b98d2daad91122eb8f1a0f47618df0775edeaaee1203576d034fc32a18
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d7a3af0e96961ff51803cb02e4e5d15de02e92d076a76a6cc3f8f27c2e0ae0d6e413f97079db7590a1b476c2feace91795f1ea2c46d01aab1e16ff35581a4b0
|
|
7
|
+
data.tar.gz: 77852270e3ef3c276f0941ce346741b69f28595e03ff53d6350ca4e58423b88527baa81701365599b2fbeec3d823b6e816f37772a5c1e7d62f94936c66701db7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.28.0] - 2026-09-15
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [OpenAPI] Add `openapi:validate` Rake task for OpenAPI tags validation (#163).
|
|
8
|
+
- [Logger] Add `config.log_redact_keys=` for redacting structured log context (#386).
|
|
9
|
+
- [Telemetry] Add `Rage::Telemetry::Capacity` (#396).
|
|
10
|
+
- [Telemetry] Add `Rage::Telemetry.every` (#381).
|
|
11
|
+
- Add `Rage::Configuration.after_reload` (#398).
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Correctly enqueue deferred tasks with only positional arguments on Ruby < 3.3.4 (#385).
|
|
16
|
+
- Improve restart logs in daemon (#391).
|
|
17
|
+
- Ensure no duplicate daemons or error reporters can be registered (#392).
|
|
18
|
+
|
|
19
|
+
## [1.27.0] - 2026-08-06
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- [OpenAPI] Add support for the `root:` option in Blueprinter response annotations (#343).
|
|
24
|
+
- Add `FiberScheduler#timeout_after` (#374).
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- [OpenAPI] Avoid caching a request-specific spec URL in the HTML docs page.
|
|
29
|
+
- [Router] Compose and restore `SCRIPT_NAME` correctly for mounted Rack apps.
|
|
30
|
+
- [OpenAPI] Fix schema registry key collisions for Blueprinter classes referenced under different views.
|
|
31
|
+
- Fixed RbNaCl dependency check to produce correct error message (#361).
|
|
32
|
+
|
|
3
33
|
## [1.26.1] - 2026-07-17
|
|
4
34
|
|
|
5
35
|
### Fixed
|
|
@@ -22,7 +52,6 @@
|
|
|
22
52
|
|
|
23
53
|
### Fixed
|
|
24
54
|
|
|
25
|
-
- [CI] Check all changed PR file pages when requiring changelog updates.
|
|
26
55
|
- [API] Ignore `If-Modified-Since` when `If-None-Match` is present.
|
|
27
56
|
- [API] Use weak comparison for `If-None-Match` validation.
|
|
28
57
|
- [Deferred] Ignore missing temp files during async disk storage cleanup.
|
data/CONTRIBUTING.md
CHANGED
|
@@ -6,6 +6,7 @@ This guide is designed to help contributors understand the project's internals,
|
|
|
6
6
|
|
|
7
7
|
- [Design Principles](#design-principles)
|
|
8
8
|
- [Documentation Standards](#documentation-standards)
|
|
9
|
+
- [Changelog](#changelog)
|
|
9
10
|
- [Dynamic Code Generation](#dynamic-code-generation)
|
|
10
11
|
- [Iodine Integration](#iodine-integration)
|
|
11
12
|
- [The Fiber Runtime](#the-fiber-runtime)
|
|
@@ -81,6 +82,14 @@ The `@private` tag signals to contributors:
|
|
|
81
82
|
- It can be modified or removed without deprecation
|
|
82
83
|
- It can be used freely within the framework codebase
|
|
83
84
|
|
|
85
|
+
## Changelog
|
|
86
|
+
|
|
87
|
+
Pull requests that introduce new features or change existing behavior must include an entry in `CHANGELOG.md`. This helps users understand what changed between versions.
|
|
88
|
+
|
|
89
|
+
Not all changes require a changelog entry. For changes that don't affect users, a maintainer will add the `skip-changelog` label to your PR instead. This includes:
|
|
90
|
+
- Internal refactoring, CI updates, and documentation fixes
|
|
91
|
+
- Intermediary changes for larger features that aren't used yet - the changelog entry should be added when the feature is complete
|
|
92
|
+
|
|
84
93
|
## Dynamic Code Generation
|
|
85
94
|
|
|
86
95
|
Rage relies heavily on dynamic code generation for both performance and flexibility. Understanding this pattern is essential for contributing to the framework.
|
|
@@ -223,7 +232,7 @@ end
|
|
|
223
232
|
1. Wraps every request in a Fiber
|
|
224
233
|
2. Implements the defer protocol for pausing/resuming async requests
|
|
225
234
|
|
|
226
|
-
When a request encounters blocking I/O (database query, HTTP request, etc.), the fiber yields. `FiberWrapper` detects this (`fiber.alive?`) and returns
|
|
235
|
+
When a request encounters blocking I/O (database query, HTTP request, etc.), the fiber yields. `FiberWrapper` detects this (`fiber.alive?`) and returns the special `[:__http_defer__, fiber]` tuple to Iodine, which pauses the connection.
|
|
227
236
|
|
|
228
237
|
When the I/O completes, the fiber resumes and publishes a message to notify Iodine that the response is ready. This is the mechanism that enables transparent, non-blocking concurrency.
|
|
229
238
|
|
data/README.md
CHANGED
|
@@ -145,7 +145,7 @@ Rage prioritizes stable public APIs, long deprecation cycles, and minimal extern
|
|
|
145
145
|
|
|
146
146
|
## Learn More
|
|
147
147
|
|
|
148
|
-
- Documentation: [https://rage-rb.dev](https://rage-rb.dev/docs/intro)
|
|
148
|
+
- Documentation: [https://rage-rb.dev/docs/intro](https://rage-rb.dev/docs/intro)
|
|
149
149
|
- API Reference: [https://rage-rb.dev/api](https://rage-rb.dev/api)
|
|
150
150
|
- Architecture: [ARCHITECTURE.md](https://github.com/rage-rb/rage/blob/main/ARCHITECTURE.md)
|
|
151
151
|
- Contributing: [CONTRIBUTING.md](https://github.com/rage-rb/rage/blob/main/CONTRIBUTING.md)
|
data/exe/rage
CHANGED
data/lib/rage/cable/channel.rb
CHANGED
|
@@ -169,6 +169,12 @@ class Rage::Cable::Channel
|
|
|
169
169
|
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
|
170
170
|
RUBY
|
|
171
171
|
end}
|
|
172
|
+
|
|
173
|
+
#{if is_subscribing
|
|
174
|
+
<<~RUBY
|
|
175
|
+
@__is_subscribing = false
|
|
176
|
+
RUBY
|
|
177
|
+
end}
|
|
172
178
|
end
|
|
173
179
|
RUBY
|
|
174
180
|
|
|
@@ -302,17 +308,7 @@ class Rage::Cable::Channel
|
|
|
302
308
|
|
|
303
309
|
# @private
|
|
304
310
|
def __stream_name_for(streamables)
|
|
305
|
-
|
|
306
|
-
if streamable.respond_to?(:id)
|
|
307
|
-
"#{streamable.class.name}:#{streamable.id}"
|
|
308
|
-
elsif streamable.is_a?(String) || streamable.is_a?(Symbol) || streamable.is_a?(Numeric)
|
|
309
|
-
streamable
|
|
310
|
-
else
|
|
311
|
-
raise ArgumentError, "Unable to generate stream name. Expected an object that responds to `id`, got: #{streamable.class}"
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
"#{name}:#{stream_name.join(":")}"
|
|
311
|
+
"#{name}:#{Rage::Internal.stream_name_for(streamables)}"
|
|
316
312
|
end
|
|
317
313
|
|
|
318
314
|
protected
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rage::CLI
|
|
4
|
+
class Base < Thor
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def environment
|
|
8
|
+
require File.expand_path("config/application.rb", Dir.pwd)
|
|
9
|
+
|
|
10
|
+
if Rage.config.internal.rails_mode
|
|
11
|
+
require File.expand_path("config/environment.rb", Dir.pwd)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def set_env(options)
|
|
16
|
+
if options[:environment]
|
|
17
|
+
ENV["RAGE_ENV"] = ENV["RAILS_ENV"] = options[:environment]
|
|
18
|
+
elsif ENV["RAGE_ENV"]
|
|
19
|
+
ENV["RAILS_ENV"] = ENV["RAGE_ENV"]
|
|
20
|
+
elsif ENV["RAILS_ENV"]
|
|
21
|
+
ENV["RAGE_ENV"] = ENV["RAILS_ENV"]
|
|
22
|
+
else
|
|
23
|
+
ENV["RAGE_ENV"] = ENV["RAILS_ENV"] = "development"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rage::CLI
|
|
4
|
+
class CodeGenerator < Base
|
|
5
|
+
include Thor::Actions
|
|
6
|
+
|
|
7
|
+
def self.source_root
|
|
8
|
+
File.expand_path("../templates", __dir__)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc "migration NAME", "Generate a new migration"
|
|
12
|
+
def migration(name = nil)
|
|
13
|
+
return help("migration") if name.nil?
|
|
14
|
+
|
|
15
|
+
setup
|
|
16
|
+
Rake::Task["db:new_migration"].invoke(name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "model NAME", "Generate a new model"
|
|
20
|
+
def model(name = nil)
|
|
21
|
+
return help("model") if name.nil?
|
|
22
|
+
|
|
23
|
+
setup
|
|
24
|
+
migration("create_#{name.pluralize}")
|
|
25
|
+
@model_name = name.classify
|
|
26
|
+
template("model-template/model.rb", "app/models/#{name.singularize.underscore}.rb")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "controller NAME", "Generate a new controller"
|
|
30
|
+
def controller(name = nil)
|
|
31
|
+
return help("controller") if name.nil?
|
|
32
|
+
|
|
33
|
+
setup
|
|
34
|
+
unless defined?(ActiveSupport::Inflector)
|
|
35
|
+
raise LoadError, <<~ERR
|
|
36
|
+
ActiveSupport::Inflector is required to run this command. Add the following line to your Gemfile:
|
|
37
|
+
gem "activesupport", require: "active_support/inflector"
|
|
38
|
+
ERR
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# remove trailing Controller if already present
|
|
42
|
+
normalized_name = name.sub(/_?controller$/i, "")
|
|
43
|
+
@controller_name = "#{normalized_name.camelize}Controller"
|
|
44
|
+
file_name = "#{normalized_name.underscore}_controller.rb"
|
|
45
|
+
|
|
46
|
+
template("controller-template/controller.rb", "app/controllers/#{file_name}")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def setup
|
|
52
|
+
@setup ||= begin
|
|
53
|
+
require "rake"
|
|
54
|
+
load "Rakefile"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rage::CLI
|
|
4
|
+
class NewAppGenerator < Thor::Group
|
|
5
|
+
include Thor::Actions
|
|
6
|
+
argument :path, type: :string
|
|
7
|
+
argument :database, type: :string, required: false
|
|
8
|
+
|
|
9
|
+
def self.source_root
|
|
10
|
+
File.expand_path("../templates", __dir__)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
@use_database = !database.nil?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_directory
|
|
18
|
+
empty_directory(path)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def copy_files
|
|
22
|
+
inject_templates
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def install_database
|
|
26
|
+
return unless @use_database
|
|
27
|
+
|
|
28
|
+
@app_name = path.tr("-", "_").downcase
|
|
29
|
+
append_to_file "#{path}/Gemfile", <<~RUBY
|
|
30
|
+
|
|
31
|
+
gem "#{get_db_gem_name}"
|
|
32
|
+
gem "activerecord"
|
|
33
|
+
gem "standalone_migrations", require: false
|
|
34
|
+
RUBY
|
|
35
|
+
|
|
36
|
+
inject_templates("db-templates")
|
|
37
|
+
inject_templates("db-templates/#{database}")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def inject_templates(from = nil)
|
|
43
|
+
root = "#{self.class.source_root}/#{from}"
|
|
44
|
+
|
|
45
|
+
Dir.glob("*", base: root).each do |template|
|
|
46
|
+
next if File.directory?("#{root}/#{template}")
|
|
47
|
+
|
|
48
|
+
*template_path_parts, template_name = template.split("-")
|
|
49
|
+
template("#{root}/#{template}", [path, *template_path_parts, template_name].join("/"))
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_db_gem_name
|
|
54
|
+
case database
|
|
55
|
+
when "mysql"
|
|
56
|
+
"mysql2"
|
|
57
|
+
when "trilogy"
|
|
58
|
+
"trilogy"
|
|
59
|
+
when "postgresql"
|
|
60
|
+
"pg"
|
|
61
|
+
when "sqlite3"
|
|
62
|
+
"sqlite3"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rage::CLI
|
|
4
|
+
class OpenAPI < Base
|
|
5
|
+
desc "validate", "Validate OpenAPI tags and fail if any warnings were produced"
|
|
6
|
+
def validate
|
|
7
|
+
environment
|
|
8
|
+
|
|
9
|
+
abort "OpenAPI validation requires a booted application." unless Rage.config.internal.initialized?
|
|
10
|
+
|
|
11
|
+
warnings = Rage::OpenAPI.__collect_warnings { Rage::OpenAPI.build }
|
|
12
|
+
|
|
13
|
+
if warnings.any?
|
|
14
|
+
abort "#{set_color("𐄂", :red, :bold)} OpenAPI validation failed with #{warnings.size} warning(s)."
|
|
15
|
+
else
|
|
16
|
+
say "#{set_color("✓", :green, :bold)} OpenAPI validation passed without warnings."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|