kaal-roda 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 877e7b001a2749328e275dbf9ed9c2293e83bf49db746733319936e82c0ce57e
4
+ data.tar.gz: fc14cad8e2f00b0283c085d198dd4d46629f957c42311ca4d046c55b8002905d
5
+ SHA512:
6
+ metadata.gz: 03aeef8421ff4eeb01f7c71c0940b48a21cfa5ba55a977a9b6c91ce68003c8ec5bce0d2198c8279c59c5620e00c459e4d3fac83b7782a914d67c6337463d28d7
7
+ data.tar.gz: '078d579977b00c9cebb16bd553cdf1732be38249ea9863b2016b4aefa3f6015ca8437ef63ec4a9b15f4c6c6965be11630d981c64712f12cc0d0a15dfad238e63'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Codevedas Inc.
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.
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Kaal::Roda
2
+
3
+ Roda integration gem for Kaal.
4
+
5
+ `kaal-roda` depends on:
6
+
7
+ - `kaal`
8
+ - `kaal-sequel`
9
+ - `roda`
10
+
11
+ It owns the Roda integration surface:
12
+
13
+ - explicit boot wiring for Roda apps
14
+ - backend wiring for memory, redis, SQLite, PostgreSQL, and MySQL
15
+ - scheduler file boot loading relative to the Roda app root
16
+ - opt-in scheduler startup and shutdown helpers
17
+ - Roda-specific test coverage and a dummy app
18
+
19
+ ## Install
20
+
21
+ ```ruby
22
+ gem 'kaal-roda'
23
+ gem 'redis' # for redis
24
+ gem 'sqlite3' # or pg / mysql2 for SQL
25
+ ```
26
+
27
+ If you use SQL persistence, create the Kaal tables using Sequel migrations. `kaal-sequel` exposes templates for:
28
+
29
+ - SQLite: `kaal_dispatches`, `kaal_locks`, `kaal_definitions`
30
+ - PostgreSQL: `kaal_dispatches`, `kaal_definitions`
31
+ - MySQL: `kaal_dispatches`, `kaal_definitions`
32
+
33
+ Your app should also provide `config/scheduler.yml`.
34
+
35
+ ## What It Provides
36
+
37
+ - Roda-native wiring on top of the Kaal engine
38
+ - explicit backend injection for memory and custom backends
39
+ - redis convenience wiring when the app passes a redis client
40
+ - automatic SQL backend selection from the Sequel adapter unless the app passes `adapter:`
41
+ - explicit lifecycle helpers so web processes do not implicitly start background scheduler threads
42
+
43
+ ## Minimal Roda
44
+
45
+ ```ruby
46
+ require 'roda'
47
+ require 'kaal/roda'
48
+
49
+ class ExampleHeartbeatJob
50
+ def self.perform(*)
51
+ puts 'heartbeat'
52
+ end
53
+ end
54
+
55
+ class App < Roda
56
+ plugin :kaal
57
+
58
+ kaal backend: Kaal::Backend::MemoryAdapter.new,
59
+ scheduler_config_path: 'config/scheduler.yml',
60
+ namespace: 'my-app',
61
+ start_scheduler: false
62
+
63
+ route do |r|
64
+ r.root { 'ok' }
65
+ end
66
+ end
67
+ ```
68
+
69
+ ## Redis
70
+
71
+ ```ruby
72
+ require 'roda'
73
+ require 'redis'
74
+ require 'kaal/roda'
75
+
76
+ class App < Roda
77
+ REDIS = Redis.new(url: ENV.fetch('REDIS_URL'))
78
+
79
+ plugin :kaal
80
+
81
+ kaal redis: REDIS,
82
+ scheduler_config_path: 'config/scheduler.yml',
83
+ namespace: 'my-app',
84
+ start_scheduler: false
85
+ end
86
+ ```
87
+
88
+ ## SQL Backends
89
+
90
+ For SQL-backed Roda apps, pass a Sequel connection:
91
+
92
+ ```ruby
93
+ require 'sequel'
94
+
95
+ database = Sequel.connect(ENV.fetch('DATABASE_URL'))
96
+
97
+ class App < Roda
98
+ plugin :kaal
99
+
100
+ kaal database: database,
101
+ adapter: 'postgres', # optional when Sequel can infer it
102
+ scheduler_config_path: 'config/scheduler.yml'
103
+ end
104
+ ```
105
+
106
+ ## Lifecycle
107
+
108
+ `kaal-roda` does not auto-start the scheduler by default.
109
+
110
+ If you want the web process to run it:
111
+
112
+ ```ruby
113
+ Kaal::Roda.start!
114
+ ```
115
+
116
+ To stop it explicitly:
117
+
118
+ ```ruby
119
+ Kaal::Roda.stop!
120
+ ```
121
+
122
+ If you pass `start_scheduler: true` to `kaal`, the addon starts the scheduler and installs an `at_exit` shutdown hook for that managed scheduler instance.
123
+
124
+ Preferred deployment model:
125
+
126
+ - run the scheduler in a dedicated process when possible
127
+ - use web-process startup only when you intentionally want co-located scheduling
128
+
129
+ ## Public API
130
+
131
+ - `Kaal::Roda.register!(app, backend: nil, database: nil, redis: nil, scheduler_config_path: 'config/scheduler.yml', namespace: nil, start_scheduler: false, adapter: nil, root: nil, environment: nil)`
132
+ - `Kaal::Roda.configure_backend!(backend: nil, database: nil, redis: nil, adapter: nil, configuration: Kaal.configuration)`
133
+ - `Kaal::Roda.detect_backend_name(database, adapter: nil)`
134
+ - `Kaal::Roda.load_scheduler_file!(root:, environment: nil)`
135
+ - `Kaal::Roda.start!`
136
+ - `Kaal::Roda.stop!`
137
+
138
+ ## Development
139
+
140
+ ```bash
141
+ bin/rspec-unit
142
+ bin/rspec-e2e memory
143
+ REDIS_URL=redis://127.0.0.1:6379/0 bin/rspec-e2e redis
144
+ bin/rspec-e2e sqlite
145
+ DATABASE_URL=postgres://postgres:postgres@localhost:5432/kaal_test_auto bin/rspec-e2e pg
146
+ DATABASE_URL=mysql2://root:rootROOT!1@127.0.0.1:3306/kaal_test_auto bin/rspec-e2e mysql
147
+ bin/rubocop
148
+ bin/reek
149
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Codevedas Inc. 2025-present
4
+ #
5
+ # This source code is licensed under the MIT license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ require 'bundler/setup'
8
+ require 'bundler/gem_tasks'
data/bin/reek ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright Codevedas Inc. 2025-present
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ require 'pty'
9
+
10
+ root_dir = File.expand_path('..', __dir__)
11
+ Dir.chdir(root_dir)
12
+
13
+ command = ['bundle', 'exec', 'reek', *ARGV]
14
+ output = +''
15
+ status = nil
16
+
17
+ PTY.spawn(*command) do |reader, _writer, pid|
18
+ reader.each { |line| output << line }
19
+ rescue Errno::EIO
20
+ nil
21
+ ensure
22
+ _, status = Process.wait2(pid)
23
+ end
24
+
25
+ print(output.gsub("\r\n", "\n"))
26
+ exit(status.exitstatus || 1)
data/bin/rspec ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright Codevedas Inc. 2025-present
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+ # This file was generated by Bundler.
10
+ #
11
+ # The application 'rspec' is installed as part of a gem, and
12
+ # this file is here to facilitate running it.
13
+ #
14
+
15
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
16
+
17
+ bundle_binstub = File.expand_path('bundle', __dir__)
18
+
19
+ if File.file?(bundle_binstub)
20
+ if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
21
+ load(bundle_binstub)
22
+ else
23
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
24
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
25
+ end
26
+ end
27
+
28
+ require 'rubygems'
29
+ require 'bundler/setup'
30
+
31
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/rspec-e2e ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ADAPTER="${1:-memory}"
5
+ shift || true
6
+
7
+ E2E="1" NO_COVERAGE=1 bin/rspec spec/e2e --tag "integration:${ADAPTER}" "$@"
data/bin/rspec-unit ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ bin/rspec spec/kaal --tag ~feature --tag ~integration "$@"
data/bin/rubocop ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright Codevedas Inc. 2025-present
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+ # This file was generated by Bundler.
10
+ #
11
+ # The application 'rubocop' is installed as part of a gem, and
12
+ # this file is here to facilitate running it.
13
+ #
14
+
15
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
16
+
17
+ bundle_binstub = File.expand_path('bundle', __dir__)
18
+
19
+ if File.file?(bundle_binstub)
20
+ if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
21
+ load(bundle_binstub)
22
+ else
23
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
24
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
25
+ end
26
+ end
27
+
28
+ require 'rubygems'
29
+ require 'bundler/setup'
30
+
31
+ load Gem.bin_path('rubocop', 'rubocop')
data/bin/update-bundle ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ bundle update
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Codevedas Inc. 2025-present
4
+ #
5
+ # This source code is licensed under the MIT license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ module Kaal
8
+ module Roda
9
+ VERSION = '0.3.0'
10
+ end
11
+ end
data/lib/kaal/roda.rb ADDED
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Codevedas Inc. 2025-present
4
+ #
5
+ # This source code is licensed under the MIT license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ require 'pathname'
8
+ require 'kaal/sequel'
9
+ require 'roda'
10
+ require 'kaal/roda/version'
11
+
12
+ module Kaal
13
+ # Roda integration surface for Kaal.
14
+ module Roda
15
+ class << self
16
+ def register!(
17
+ app,
18
+ backend: nil,
19
+ database: nil,
20
+ redis: nil,
21
+ scheduler_config_path: 'config/scheduler.yml',
22
+ namespace: nil,
23
+ start_scheduler: false,
24
+ adapter: nil,
25
+ root: nil,
26
+ environment: nil
27
+ )
28
+ configuration = Kaal.configuration
29
+ normalized_scheduler_config_path = scheduler_config_path.to_s.strip
30
+ normalized_namespace = namespace.to_s.strip
31
+ configuration.scheduler_config_path = normalized_scheduler_config_path unless normalized_scheduler_config_path.empty?
32
+ configuration.namespace = normalized_namespace unless normalized_namespace.empty?
33
+
34
+ configure_backend!(backend:, database:, redis:, adapter:, configuration:)
35
+ load_scheduler_file!(
36
+ root: root_path_for(app, root:),
37
+ environment: environment_name_for(app, environment:)
38
+ )
39
+
40
+ start_managed_scheduler! if start_scheduler
41
+ app
42
+ end
43
+
44
+ def configure_backend!(backend: nil, database: nil, redis: nil, adapter: nil, configuration: Kaal.configuration)
45
+ current_backend = configuration.backend
46
+ return current_backend if current_backend
47
+
48
+ return configuration.backend = backend if backend
49
+ return configuration.backend = build_redis_backend(redis, configuration) if redis
50
+
51
+ explicit_adapter = adapter.to_s.strip
52
+ unless explicit_adapter.empty?
53
+ raise ArgumentError, 'database is required when adapter is provided' unless database
54
+
55
+ backend_name = normalize_backend_name(explicit_adapter)
56
+ raise ArgumentError, "Unsupported Roda datastore backend: #{adapter.inspect}" unless backend_name
57
+
58
+ return configuration.backend = build_backend(backend_name, database)
59
+ end
60
+
61
+ return configuration.backend = Kaal::Backend::MemoryAdapter.new unless database
62
+
63
+ backend_name = detect_backend_name(database, adapter:)
64
+ raise ArgumentError, 'Unsupported Roda datastore backend; use memory, redis, sqlite, postgres, or mysql' unless backend_name
65
+
66
+ configuration.backend = build_backend(backend_name, database)
67
+ end
68
+
69
+ def detect_backend_name(database, adapter: nil)
70
+ explicit_adapter = normalize_backend_name(adapter)
71
+ return explicit_adapter if explicit_adapter
72
+
73
+ inferred_adapter = database_adapter_name(database)
74
+ normalize_backend_name(inferred_adapter)
75
+ end
76
+
77
+ def load_scheduler_file!(root:, environment: nil)
78
+ runtime_context = Kaal::Runtime::RuntimeContext.new(
79
+ root_path: root,
80
+ environment_name: environment || Kaal::Runtime::RuntimeContext.environment_name_from(ENV)
81
+ )
82
+
83
+ Kaal::Runtime::SchedulerBootLoader.new(
84
+ configuration_provider: -> { Kaal.configuration },
85
+ logger: Kaal.configuration.logger,
86
+ runtime_context: runtime_context,
87
+ load_scheduler_file: -> { Kaal.load_scheduler_file!(runtime_context:) }
88
+ ).load_on_boot!
89
+ end
90
+
91
+ def start!
92
+ Kaal.start!
93
+ end
94
+
95
+ def stop!(timeout: 30)
96
+ Kaal.stop!(timeout:)
97
+ end
98
+
99
+ private
100
+
101
+ def build_redis_backend(redis, configuration)
102
+ Kaal::Backend::RedisAdapter.new(redis, namespace: configuration.namespace)
103
+ end
104
+
105
+ def build_backend(backend_name, database)
106
+ case backend_name
107
+ when 'sqlite'
108
+ Kaal::Backend::DatabaseAdapter.new(database)
109
+ when 'postgres'
110
+ Kaal::Backend::PostgresAdapter.new(database)
111
+ when 'mysql'
112
+ Kaal::Backend::MySQLAdapter.new(database)
113
+ end
114
+ end
115
+
116
+ def database_adapter_name(database)
117
+ return if database.nil?
118
+
119
+ database_type = database.database_type if database.respond_to?(:database_type)
120
+ return database_type.to_s unless database_type.to_s.strip.empty?
121
+
122
+ adapter_scheme = database.adapter_scheme if database.respond_to?(:adapter_scheme)
123
+ adapter_scheme.to_s
124
+ end
125
+
126
+ def normalize_backend_name(adapter_name)
127
+ adapter = adapter_name.to_s.strip.downcase
128
+ return if adapter.empty?
129
+ return 'sqlite' if adapter.include?('sqlite')
130
+ return 'postgres' if adapter.include?('postgres')
131
+ return 'mysql' if adapter.include?('mysql') || adapter.include?('trilogy')
132
+
133
+ nil
134
+ end
135
+
136
+ def root_path_for(app, root: nil)
137
+ explicit_root = root.to_s.strip
138
+ return Pathname.new(explicit_root) unless explicit_root.empty?
139
+
140
+ app_root = app.opts[:root] if app.respond_to?(:opts)
141
+ Pathname.new(app_root || Dir.pwd)
142
+ end
143
+
144
+ def environment_name_for(app, environment: nil)
145
+ explicit_environment = environment.to_s.strip
146
+ return explicit_environment unless explicit_environment.empty?
147
+
148
+ app_environment = app.opts[:environment] if app.respond_to?(:opts)
149
+ app_environment.to_s.empty? ? Kaal::Runtime::RuntimeContext.environment_name_from(ENV) : app_environment.to_s
150
+ end
151
+
152
+ def start_managed_scheduler!
153
+ return if Kaal.running?
154
+
155
+ start!
156
+ install_shutdown_hook
157
+ end
158
+
159
+ def install_shutdown_hook
160
+ @shutdown_hook_mutex ||= Mutex.new
161
+ @shutdown_hook_mutex.synchronize do
162
+ return if @shutdown_hook_installed
163
+
164
+ @shutdown_hook_installed = true
165
+ Kernel.at_exit do
166
+ if Kaal.running?
167
+ begin
168
+ stop!
169
+ rescue StandardError => e
170
+ Kaal.configuration.logger&.error("Failed to stop Kaal during Roda shutdown: #{e.message}")
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ # Load the plugin after Kaal::Roda is defined so `require 'kaal/roda'`
181
+ # makes `plugin :kaal` available without relying on `roda/plugins/kaal`.
182
+ require 'roda/plugins/kaal'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright Codevedas Inc. 2025-present
4
+ #
5
+ # This source code is licensed under the MIT license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ require 'kaal/roda'
8
+
9
+ class Roda
10
+ # Roda plugin registry namespace.
11
+ module RodaPlugins
12
+ # Plugin that wires Kaal into Roda applications.
13
+ module Kaal
14
+ # Class-level DSL added by the plugin.
15
+ module ClassMethods
16
+ def kaal(**)
17
+ ::Kaal::Roda.register!(self, **)
18
+ end
19
+ end
20
+ end
21
+
22
+ register_plugin(:kaal, Kaal)
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kaal-roda
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Nitesh Purohit
8
+ - Codevedas Inc.
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kaal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: kaal-sequel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '2.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: roda
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '5.0'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '3.0'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.0'
75
+ description: " Kaal-Roda provides a thin integration layer that wires Kaal and
76
+ Kaal-Sequel into Roda applications with explicit lifecycle control.\n"
77
+ email:
78
+ - nitesh.purohit.it@gmail.com
79
+ - team@codevedas.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - LICENSE
85
+ - README.md
86
+ - Rakefile
87
+ - bin/reek
88
+ - bin/rspec
89
+ - bin/rspec-e2e
90
+ - bin/rspec-unit
91
+ - bin/rubocop
92
+ - bin/update-bundle
93
+ - lib/kaal/roda.rb
94
+ - lib/kaal/roda/version.rb
95
+ - lib/roda/plugins/kaal.rb
96
+ homepage: https://github.com/Code-Vedas/kaal
97
+ licenses:
98
+ - MIT
99
+ metadata:
100
+ bug_tracker_uri: https://github.com/Code-Vedas/kaal/issues
101
+ changelog_uri: https://github.com/Code-Vedas/kaal/blob/main/CHANGELOG.md
102
+ documentation_uri: https://kaal.codevedas.com
103
+ homepage_uri: https://github.com/Code-Vedas/kaal
104
+ source_code_uri: https://github.com/Code-Vedas/kaal.git
105
+ funding_uri: https://github.com/sponsors/Code-Vedas
106
+ support_uri: https://kaal.codevedas.com/support
107
+ rubygems_uri: https://rubygems.org/gems/kaal-roda
108
+ rubygems_mfa_required: 'true'
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '3.2'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubygems_version: 3.6.7
124
+ specification_version: 4
125
+ summary: Roda integration for Kaal, a distributed cron scheduler for Ruby.
126
+ test_files: []