jcl 1.0.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 +7 -0
- data/Cargo.toml +20 -0
- data/README.md +518 -0
- data/ext/jcl/extconf.rb +4 -0
- data/lib/jcl.rb +12 -0
- metadata +110 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 97b378edcc86445b770dba35e3fc3cc9c496e7795da0a6397cb9c2deed925cbb
|
|
4
|
+
data.tar.gz: 6108344b578fa4de6f960d20943aab27ae390839b5bcdab412bfa374402510a8
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d75fe410fe2cea2547f0a2bca47513a4617057d1a6b1c11bf6f58ed3ab7bac05d5cba05ebbe47994759e52e0e7c0f4b8ff5a3229db3c203f8991060fdcd5c3b0
|
|
7
|
+
data.tar.gz: d098faf0fd5dfda77d7387b69f430b366c31e1838c7ea0f046ff26e49241ac6ad7b8234ddab718392f239cc7e003fd1a388a0c74d9a0440bb0f2cd95eef71689
|
data/Cargo.toml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "jcl-ruby"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
authors = ["Hemmer IO <info@hemmer.io>"]
|
|
6
|
+
description = "Ruby bindings for JCL (Jack-of-All Configuration Language)"
|
|
7
|
+
license = "MIT OR Apache-2.0"
|
|
8
|
+
repository = "https://github.com/hemmer-io/jcl"
|
|
9
|
+
|
|
10
|
+
[lib]
|
|
11
|
+
crate-type = ["cdylib"]
|
|
12
|
+
name = "jcl"
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
jcl = { path = "../..", version = "1.0.0" }
|
|
16
|
+
magnus = "0.6"
|
|
17
|
+
serde_json = "1.0"
|
|
18
|
+
|
|
19
|
+
[package.metadata.rb_sys]
|
|
20
|
+
required_ruby_version = ">= 2.7.0"
|
data/README.md
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# JCL Ruby Bindings
|
|
2
|
+
|
|
3
|
+
Ruby bindings for JCL (Jack-of-All Configuration Language) using Magnus.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### From RubyGems (once published)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gem install jcl
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or add to your `Gemfile`:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem 'jcl'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then run:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bundle install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Building from Source
|
|
26
|
+
|
|
27
|
+
1. Ensure you have Rust installed
|
|
28
|
+
2. Build the gem:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cargo build --release --features ruby
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
3. The compiled extension will be in `target/release/`
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Basic Example
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
require 'jcl'
|
|
42
|
+
|
|
43
|
+
# Evaluate JCL code
|
|
44
|
+
jcl_code = <<~JCL
|
|
45
|
+
version = "1.0.0"
|
|
46
|
+
port = 8080
|
|
47
|
+
debug = true
|
|
48
|
+
JCL
|
|
49
|
+
|
|
50
|
+
config = JCL.eval(jcl_code)
|
|
51
|
+
|
|
52
|
+
puts "Version: #{config['version']}"
|
|
53
|
+
puts "Port: #{config['port']}"
|
|
54
|
+
puts "Debug: #{config['debug']}"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Parsing
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
# Parse JCL code to check syntax
|
|
61
|
+
result = JCL.parse('version = "1.0.0"')
|
|
62
|
+
puts result # "Parsed 1 statements"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Evaluation
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# Evaluate JCL and get results as Hash
|
|
69
|
+
jcl_code = <<~JCL
|
|
70
|
+
app = {
|
|
71
|
+
name = "MyApp"
|
|
72
|
+
port = 8080
|
|
73
|
+
features = ["auth", "api", "admin"]
|
|
74
|
+
}
|
|
75
|
+
JCL
|
|
76
|
+
|
|
77
|
+
config = JCL.eval(jcl_code)
|
|
78
|
+
|
|
79
|
+
# Access nested values
|
|
80
|
+
puts "App name: #{config['app']['name']}"
|
|
81
|
+
puts "Port: #{config['app']['port']}"
|
|
82
|
+
puts "Features: #{config['app']['features'].join(', ')}"
|
|
83
|
+
|
|
84
|
+
# Evaluate from file
|
|
85
|
+
file_config = JCL.eval_file('config.jcl')
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Formatting
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
unformatted = 'version="1.0.0" port=8080'
|
|
92
|
+
formatted = JCL.format(unformatted)
|
|
93
|
+
puts formatted
|
|
94
|
+
# Output:
|
|
95
|
+
# version = "1.0.0"
|
|
96
|
+
# port = 8080
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Linting
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
jcl_code = <<~JCL
|
|
103
|
+
unused_var = 42
|
|
104
|
+
result = 10
|
|
105
|
+
JCL
|
|
106
|
+
|
|
107
|
+
issues = JCL.lint(jcl_code)
|
|
108
|
+
|
|
109
|
+
issues.each do |issue|
|
|
110
|
+
puts "#{issue['severity']}: #{issue['message']}"
|
|
111
|
+
puts " Rule: #{issue['rule']}"
|
|
112
|
+
puts " Suggestion: #{issue['suggestion']}" if issue['suggestion']
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Version Information
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
version = JCL.version
|
|
120
|
+
puts "JCL version: #{version}"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## API Reference
|
|
124
|
+
|
|
125
|
+
### Module Methods
|
|
126
|
+
|
|
127
|
+
#### `JCL.parse(source)`
|
|
128
|
+
Parse JCL source code and return a status message.
|
|
129
|
+
- **Parameters:** `source` (String) - The JCL source code
|
|
130
|
+
- **Returns:** String - Status message with number of statements parsed
|
|
131
|
+
- **Raises:** `RuntimeError` on parse error
|
|
132
|
+
|
|
133
|
+
#### `JCL.eval(source)`
|
|
134
|
+
Evaluate JCL source code and return variables as a Hash.
|
|
135
|
+
- **Parameters:** `source` (String) - The JCL source code
|
|
136
|
+
- **Returns:** Hash - Evaluated variables
|
|
137
|
+
- **Raises:** `RuntimeError` on evaluation error
|
|
138
|
+
|
|
139
|
+
#### `JCL.eval_file(path)`
|
|
140
|
+
Evaluate JCL from a file and return variables as a Hash.
|
|
141
|
+
- **Parameters:** `path` (String) - Path to the JCL file
|
|
142
|
+
- **Returns:** Hash - Evaluated variables
|
|
143
|
+
- **Raises:** `RuntimeError` on file read or evaluation error
|
|
144
|
+
|
|
145
|
+
#### `JCL.format(source)`
|
|
146
|
+
Format JCL source code.
|
|
147
|
+
- **Parameters:** `source` (String) - The JCL source code
|
|
148
|
+
- **Returns:** String - Formatted JCL source code
|
|
149
|
+
- **Raises:** `RuntimeError` on format error
|
|
150
|
+
|
|
151
|
+
#### `JCL.lint(source)`
|
|
152
|
+
Lint JCL source code and return issues as an Array.
|
|
153
|
+
- **Parameters:** `source` (String) - The JCL source code
|
|
154
|
+
- **Returns:** Array<Hash> - Lint issues with keys: `rule`, `message`, `severity`, `suggestion` (optional)
|
|
155
|
+
- **Raises:** `RuntimeError` on lint error
|
|
156
|
+
|
|
157
|
+
#### `JCL.version`
|
|
158
|
+
Get the JCL version.
|
|
159
|
+
- **Returns:** String - Version string
|
|
160
|
+
|
|
161
|
+
## Type Conversions
|
|
162
|
+
|
|
163
|
+
JCL types are converted to Ruby types as follows:
|
|
164
|
+
|
|
165
|
+
| JCL Type | Ruby Type |
|
|
166
|
+
|----------|-----------|
|
|
167
|
+
| String | `String` |
|
|
168
|
+
| Int | `Integer` |
|
|
169
|
+
| Float | `Float` |
|
|
170
|
+
| Bool | `TrueClass` / `FalseClass` |
|
|
171
|
+
| Null | `NilClass` |
|
|
172
|
+
| List | `Array` |
|
|
173
|
+
| Map | `Hash` |
|
|
174
|
+
| Function | `String` ("<function>") |
|
|
175
|
+
|
|
176
|
+
## Use Cases
|
|
177
|
+
|
|
178
|
+
### Rails Configuration
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
# config/initializers/jcl_config.rb
|
|
182
|
+
require 'jcl'
|
|
183
|
+
|
|
184
|
+
module MyApp
|
|
185
|
+
class Application < Rails::Application
|
|
186
|
+
jcl_config = JCL.eval_file(Rails.root.join('config', 'app.jcl'))
|
|
187
|
+
|
|
188
|
+
config.app_name = jcl_config['app']['name']
|
|
189
|
+
config.api_endpoint = jcl_config['api']['endpoint']
|
|
190
|
+
config.feature_flags = jcl_config['features']
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Chef Recipe
|
|
196
|
+
|
|
197
|
+
```ruby
|
|
198
|
+
# recipes/default.rb
|
|
199
|
+
require 'jcl'
|
|
200
|
+
|
|
201
|
+
# Load configuration from JCL
|
|
202
|
+
config = JCL.eval_file('/etc/app/config.jcl')
|
|
203
|
+
|
|
204
|
+
# Use configuration in Chef resources
|
|
205
|
+
template '/etc/nginx/nginx.conf' do
|
|
206
|
+
source 'nginx.conf.erb'
|
|
207
|
+
variables(
|
|
208
|
+
port: config['server']['port'],
|
|
209
|
+
worker_processes: config['server']['workers'],
|
|
210
|
+
ssl_enabled: config['server']['ssl']
|
|
211
|
+
)
|
|
212
|
+
notifies :reload, 'service[nginx]'
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
service 'nginx' do
|
|
216
|
+
action [:enable, :start]
|
|
217
|
+
end
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Puppet Module
|
|
221
|
+
|
|
222
|
+
```ruby
|
|
223
|
+
# lib/puppet/functions/jcl_eval.rb
|
|
224
|
+
Puppet::Functions.create_function(:jcl_eval) do
|
|
225
|
+
dispatch :jcl_eval do
|
|
226
|
+
param 'String', :path
|
|
227
|
+
return_type 'Hash'
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def jcl_eval(path)
|
|
231
|
+
require 'jcl'
|
|
232
|
+
JCL.eval_file(path)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Then in your manifest:
|
|
238
|
+
|
|
239
|
+
```puppet
|
|
240
|
+
# manifests/config.pp
|
|
241
|
+
$config = jcl_eval('/etc/app/config.jcl')
|
|
242
|
+
|
|
243
|
+
file { '/etc/app/settings.json':
|
|
244
|
+
ensure => file,
|
|
245
|
+
content => inline_template('<%= JSON.pretty_generate(@config) %>'),
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Rake Task
|
|
250
|
+
|
|
251
|
+
```ruby
|
|
252
|
+
# lib/tasks/jcl.rake
|
|
253
|
+
require 'jcl'
|
|
254
|
+
|
|
255
|
+
namespace :jcl do
|
|
256
|
+
desc 'Validate JCL configuration files'
|
|
257
|
+
task :validate do
|
|
258
|
+
Dir.glob('config/**/*.jcl').each do |file|
|
|
259
|
+
puts "Validating #{file}..."
|
|
260
|
+
|
|
261
|
+
begin
|
|
262
|
+
content = File.read(file)
|
|
263
|
+
issues = JCL.lint(content)
|
|
264
|
+
|
|
265
|
+
if issues.any? { |i| i['severity'] == 'error' }
|
|
266
|
+
puts " ✗ Errors found:"
|
|
267
|
+
issues.each do |issue|
|
|
268
|
+
puts " [#{issue['severity']}] #{issue['message']}"
|
|
269
|
+
end
|
|
270
|
+
exit 1
|
|
271
|
+
else
|
|
272
|
+
puts " ✓ Valid"
|
|
273
|
+
end
|
|
274
|
+
rescue StandardError => e
|
|
275
|
+
puts " ✗ Error: #{e.message}"
|
|
276
|
+
exit 1
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
desc 'Format JCL configuration files'
|
|
282
|
+
task :format do
|
|
283
|
+
Dir.glob('config/**/*.jcl').each do |file|
|
|
284
|
+
puts "Formatting #{file}..."
|
|
285
|
+
|
|
286
|
+
begin
|
|
287
|
+
content = File.read(file)
|
|
288
|
+
formatted = JCL.format(content)
|
|
289
|
+
File.write(file, formatted)
|
|
290
|
+
puts " ✓ Formatted"
|
|
291
|
+
rescue StandardError => e
|
|
292
|
+
puts " ✗ Error: #{e.message}"
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Sinatra Application
|
|
300
|
+
|
|
301
|
+
```ruby
|
|
302
|
+
require 'sinatra'
|
|
303
|
+
require 'jcl'
|
|
304
|
+
|
|
305
|
+
configure do
|
|
306
|
+
config = JCL.eval_file('config/app.jcl')
|
|
307
|
+
|
|
308
|
+
set :port, config['server']['port']
|
|
309
|
+
set :environment, config['environment']
|
|
310
|
+
set :api_key, config['api']['key']
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
get '/config' do
|
|
314
|
+
content_type :json
|
|
315
|
+
config = JCL.eval_file('config/app.jcl')
|
|
316
|
+
config.to_json
|
|
317
|
+
end
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Configuration Loader Class
|
|
321
|
+
|
|
322
|
+
```ruby
|
|
323
|
+
# lib/config_loader.rb
|
|
324
|
+
require 'jcl'
|
|
325
|
+
|
|
326
|
+
class ConfigLoader
|
|
327
|
+
def initialize(path)
|
|
328
|
+
@path = path
|
|
329
|
+
@config = nil
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def load
|
|
333
|
+
@config ||= JCL.eval_file(@path)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def reload
|
|
337
|
+
@config = nil
|
|
338
|
+
load
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def get(key_path)
|
|
342
|
+
keys = key_path.split('.')
|
|
343
|
+
keys.reduce(load) { |hash, key| hash[key] }
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def method_missing(method_name, *args)
|
|
347
|
+
if args.empty? && load.key?(method_name.to_s)
|
|
348
|
+
load[method_name.to_s]
|
|
349
|
+
else
|
|
350
|
+
super
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
355
|
+
load.key?(method_name.to_s) || super
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Usage
|
|
360
|
+
config = ConfigLoader.new('config/app.jcl')
|
|
361
|
+
puts config.version
|
|
362
|
+
puts config.get('app.name')
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### RSpec Integration
|
|
366
|
+
|
|
367
|
+
```ruby
|
|
368
|
+
# spec/support/jcl_helper.rb
|
|
369
|
+
require 'jcl'
|
|
370
|
+
|
|
371
|
+
RSpec.configure do |config|
|
|
372
|
+
config.before(:suite) do
|
|
373
|
+
test_config = JCL.eval_file('spec/fixtures/test_config.jcl')
|
|
374
|
+
ENV['TEST_CONFIG'] = test_config.to_json
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# spec/models/config_spec.rb
|
|
379
|
+
require 'rails_helper'
|
|
380
|
+
|
|
381
|
+
RSpec.describe 'Configuration' do
|
|
382
|
+
let(:jcl_code) do
|
|
383
|
+
<<~JCL
|
|
384
|
+
app = {
|
|
385
|
+
name = "TestApp"
|
|
386
|
+
version = "1.0.0"
|
|
387
|
+
}
|
|
388
|
+
JCL
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it 'parses JCL configuration' do
|
|
392
|
+
config = JCL.eval(jcl_code)
|
|
393
|
+
expect(config['app']['name']).to eq('TestApp')
|
|
394
|
+
expect(config['app']['version']).to eq('1.0.0')
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it 'validates JCL syntax' do
|
|
398
|
+
invalid_jcl = 'invalid syntax here'
|
|
399
|
+
expect { JCL.eval(invalid_jcl) }.to raise_error(RuntimeError)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it 'formats JCL code' do
|
|
403
|
+
unformatted = 'app={name="Test"}'
|
|
404
|
+
formatted = JCL.format(unformatted)
|
|
405
|
+
expect(formatted).to include("app = {")
|
|
406
|
+
expect(formatted).to include('name = "Test"')
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Error Handling
|
|
412
|
+
|
|
413
|
+
All methods raise `RuntimeError` on errors. It's recommended to catch and handle these appropriately:
|
|
414
|
+
|
|
415
|
+
```ruby
|
|
416
|
+
begin
|
|
417
|
+
config = JCL.eval_file('config.jcl')
|
|
418
|
+
rescue RuntimeError => e
|
|
419
|
+
if e.message.include?('Parse error')
|
|
420
|
+
puts "Invalid JCL syntax: #{e.message}"
|
|
421
|
+
elsif e.message.include?('Failed to read file')
|
|
422
|
+
puts "File not found: #{e.message}"
|
|
423
|
+
else
|
|
424
|
+
puts "Evaluation error: #{e.message}"
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Using Rescue Blocks
|
|
430
|
+
|
|
431
|
+
```ruby
|
|
432
|
+
# Inline rescue
|
|
433
|
+
config = JCL.eval_file('config.jcl') rescue {}
|
|
434
|
+
|
|
435
|
+
# Method with rescue
|
|
436
|
+
def load_config(path)
|
|
437
|
+
JCL.eval_file(path)
|
|
438
|
+
rescue RuntimeError => e
|
|
439
|
+
Rails.logger.error("Failed to load config: #{e.message}")
|
|
440
|
+
default_config
|
|
441
|
+
end
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Performance Considerations
|
|
445
|
+
|
|
446
|
+
- The native extension is loaded once per Ruby process
|
|
447
|
+
- Parsing and evaluation are performed in native Rust code for optimal performance
|
|
448
|
+
- For repeated evaluations, consider caching parsed results:
|
|
449
|
+
|
|
450
|
+
```ruby
|
|
451
|
+
class JCLCache
|
|
452
|
+
def initialize
|
|
453
|
+
@cache = {}
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def eval_file(path)
|
|
457
|
+
mtime = File.mtime(path)
|
|
458
|
+
cache_key = "#{path}:#{mtime}"
|
|
459
|
+
|
|
460
|
+
@cache[cache_key] ||= JCL.eval_file(path)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def clear
|
|
464
|
+
@cache.clear
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Thread Safety
|
|
470
|
+
|
|
471
|
+
The JCL Ruby bindings are thread-safe. Multiple threads can safely call JCL methods concurrently:
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
threads = 10.times.map do |i|
|
|
475
|
+
Thread.new do
|
|
476
|
+
config = JCL.eval_file("config/env#{i}.jcl")
|
|
477
|
+
# Process config...
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
threads.each(&:join)
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Development
|
|
485
|
+
|
|
486
|
+
### Running Tests
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# Build the extension
|
|
490
|
+
cargo build --release --features ruby
|
|
491
|
+
|
|
492
|
+
# Run Ruby tests
|
|
493
|
+
ruby test/jcl_test.rb
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Benchmarking
|
|
497
|
+
|
|
498
|
+
```ruby
|
|
499
|
+
require 'benchmark'
|
|
500
|
+
require 'jcl'
|
|
501
|
+
|
|
502
|
+
jcl_code = File.read('large_config.jcl')
|
|
503
|
+
|
|
504
|
+
Benchmark.bm do |x|
|
|
505
|
+
x.report('parse:') { 100.times { JCL.parse(jcl_code) } }
|
|
506
|
+
x.report('eval:') { 100.times { JCL.eval(jcl_code) } }
|
|
507
|
+
x.report('format:') { 100.times { JCL.format(jcl_code) } }
|
|
508
|
+
x.report('lint:') { 100.times { JCL.lint(jcl_code) } }
|
|
509
|
+
end
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
## Contributing
|
|
513
|
+
|
|
514
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
515
|
+
|
|
516
|
+
## License
|
|
517
|
+
|
|
518
|
+
MIT OR Apache-2.0
|
data/ext/jcl/extconf.rb
ADDED
data/lib/jcl.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jcl
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Hemmer IO
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-11-19 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '13.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '13.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake-compiler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.2'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.2'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.12'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.12'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rb_sys
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.9'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.9'
|
|
69
|
+
description: JCL is a general-purpose configuration language with powerful built-in
|
|
70
|
+
functions, static type inference, and multi-language bindings.
|
|
71
|
+
email:
|
|
72
|
+
- info@hemmer.io
|
|
73
|
+
executables: []
|
|
74
|
+
extensions:
|
|
75
|
+
- ext/jcl/extconf.rb
|
|
76
|
+
extra_rdoc_files: []
|
|
77
|
+
files:
|
|
78
|
+
- Cargo.toml
|
|
79
|
+
- README.md
|
|
80
|
+
- ext/jcl/extconf.rb
|
|
81
|
+
- lib/jcl.rb
|
|
82
|
+
homepage: https://hemmer-io.github.io/jcl/
|
|
83
|
+
licenses:
|
|
84
|
+
- MIT OR Apache-2.0
|
|
85
|
+
metadata:
|
|
86
|
+
homepage_uri: https://hemmer-io.github.io/jcl/
|
|
87
|
+
source_code_uri: https://github.com/hemmer-io/jcl
|
|
88
|
+
bug_tracker_uri: https://github.com/hemmer-io/jcl/issues
|
|
89
|
+
documentation_uri: https://hemmer-io.github.io/jcl/
|
|
90
|
+
changelog_uri: https://github.com/hemmer-io/jcl/blob/main/CHANGELOG.md
|
|
91
|
+
post_install_message:
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
require_paths:
|
|
94
|
+
- lib
|
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: 2.7.0
|
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
requirements: []
|
|
106
|
+
rubygems_version: 3.4.19
|
|
107
|
+
signing_key:
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: Ruby bindings for JCL (Jack-of-All Configuration Language)
|
|
110
|
+
test_files: []
|