Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,21 @@ PATH
remote: .
specs:
ruby-skill-bench (1.2.0)
activesupport (>= 6.0)
cgi (~> 0.5.1)
dotenv (~> 3.2.0)
faraday (~> 2.14)
json (~> 2.19)
parallel (~> 1.26)

GEM
remote: https://rubygems.org/
specs:
activesupport (8.1.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
base64 (0.3.0)
bigdecimal (4.1.2)
bundler-audit (0.9.3)
bundler (>= 1.2.0)
Expand All @@ -43,15 +27,12 @@ GEM
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.7)
connection_pool (3.0.2)
crack (1.0.1)
bigdecimal
rexml
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
docile (1.4.1)
dotenv (3.2.0)
drb (2.2.3)
dry-configurable (1.4.0)
dry-core (~> 1.0)
zeitwerk (~> 2.6)
Expand Down Expand Up @@ -98,8 +79,6 @@ GEM
prism (~> 1.7)
sexp_processor (~> 4.8)
hashdiff (1.2.1)
i18n (1.15.2)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
json (2.20.0)
language_server-protocol (3.17.0.5)
Expand Down Expand Up @@ -179,7 +158,6 @@ GEM
simplecov (>= 0.22.0)
tty-which (~> 0.5.0)
virtus (~> 2.0)
securerandom (0.4.1)
sexp_processor (4.17.5)
simplecov (0.22.0)
docile (~> 1.1)
Expand All @@ -195,8 +173,6 @@ GEM
thor (1.5.0)
thread_safe (0.3.6)
tty-which (0.5.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0)
uri (1.1.1)
virtus (2.0.0)
Expand Down Expand Up @@ -233,23 +209,18 @@ DEPENDENCIES
yard (~> 0.9)

CHECKSUMS
activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e
addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
axiom-types (0.1.1) sha256=c1ff113f3de516fa195b2db7e0a9a95fd1b08475a502ff660d04507a09980383
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9
cgi (0.5.2) sha256=61ca30298171190fd4fa0d8018e57ada456eae9b7a2b78526debf7f0a0e6f8bb
childprocess (5.1.0) sha256=9a8d484be2fd4096a0e90a0cd3e449a05bc3aa33f8ac9e4d6dcef6ac1455b6ec
coercible (1.0.0) sha256=5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc
concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e
descendants_tracker (0.0.4) sha256=e9c41dd4cfbb85829a9301ea7e7c48c2a03b26f09319db230e6479ccdc780897
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
dry-configurable (1.4.0) sha256=e35d1b5f3c081753ef361f564919db79000f32cfa6f20ee3a3ba5921b41b73ce
dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1
dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc
Expand All @@ -263,7 +234,6 @@ CHECKSUMS
flay (2.14.4) sha256=a62d96a51d1da185aa41ba95b696966df9f7d1d91a457709277f24515895de77
flog (4.9.4) sha256=12cc054fab7a2cbd2a906514397c4d7788954d530564782d6f14939dc2dfbcbb
hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1
i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5
ice_nine (0.11.2) sha256=5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db
json (2.20.0) sha256=9362bc6e55a952b056abf9167cf053358181c904cb70cd6eee0808ea830fc32b
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
Expand Down Expand Up @@ -295,7 +265,6 @@ CHECKSUMS
ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef
ruby_parser (3.22.0) sha256=1eb4937cd9eb220aa2d194e352a24dba90aef00751e24c8dfffdb14000f15d23
rubycritic (4.12.0) sha256=024fed90fe656fa939f6ea80aab17569699ac3863d0b52fd72cb99892247abc8
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
sexp_processor (4.17.5) sha256=ae2b48ba98353d5d465ce8759836b7a05f2e12c5879fcd14d7815b026de32f0e
simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
Expand All @@ -305,7 +274,6 @@ CHECKSUMS
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
thread_safe (0.3.6) sha256=9ed7072821b51c57e8d6b7011a8e282e25aeea3a4065eab326e43f66f063b05a
tty-which (0.5.0) sha256=5824055f0d6744c97e7c4426544f01d519c40d1806ef2ef47d9854477993f466
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
virtus (2.0.0) sha256=8841dae4eb7fcc097320ba5ea516bf1839e5d056c61ee27138aa4bddd6e3d1c2
Expand Down
3 changes: 0 additions & 3 deletions lib/skill_bench.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@
require_relative 'skill_bench/trend_tracker/persistence'
require_relative 'skill_bench/trend_tracker/trend_calculator'

# Rails integrations
require_relative 'skill_bench/rails/skill_templates'

# Migration utilities
require_relative 'skill_bench/migration/provider_migrator'

Expand Down
4 changes: 3 additions & 1 deletion lib/skill_bench/commands/skill_new.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require 'fileutils'
require_relative '../rails/skill_templates'

module SkillBench
module Commands
Expand Down Expand Up @@ -107,6 +106,9 @@ def self.create_rails_skill(path, name, template)
file_name = RAILS_TEMPLATES[template]
raise ArgumentError, "Invalid template: #{template}. Use one of: #{RAILS_TEMPLATES.keys.join(', ')}." unless file_name

# Lazily load the scaffold generator so a normal `skill-bench run` does
# not pull it (and its dependencies) in at boot.
require_relative '../rails/skill_templates'
content = Rails::SkillTemplates.public_send(template.to_sym, name)
File.write(File.join(path, file_name), content)
end
Expand Down
24 changes: 19 additions & 5 deletions lib/skill_bench/rails/skill_templates.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
# frozen_string_literal: true

require 'active_support/inflector'

module SkillBench
module Rails
# Generates Rails-specific skill templates
class SkillTemplates
# Convert a snake_case or kebab-case name to CamelCase.
#
# Replaces ActiveSupport's +String#camelize+ for the scaffold inputs used
# here: it splits on +_+ and +-+ separators, upcases the first letter of
# each segment, and preserves any segment that is already CamelCase.
#
# @example
# SkillTemplates.camelize('user_creator') # => "UserCreator"
# SkillTemplates.camelize('order-service') # => "OrderService"
# SkillTemplates.camelize('UserCreator') # => "UserCreator"
# @param name [String] snake_case, kebab-case, or already-CamelCase name
# @return [String] CamelCase name
def self.camelize(name)
name.split(/[-_]/).map { |segment| segment.empty? ? segment : segment[0].upcase + segment[1..] }.join
end

# Generate a service object template
# @param name [String] Service name (e.g., 'my_service' or 'my-service')
# @return [String] Service object Ruby class
def self.service_object(name)
class_name = name.split(/[-_]/).map(&:capitalize).join
class_name = camelize(name)
<<~RUBY
# frozen_string_literal: true

Expand Down Expand Up @@ -43,7 +57,7 @@ def call
# @param name [String] Concern name (e.g., 'my_concern')
# @return [String] Concern module
def self.concern(name)
module_name = name.camelize
module_name = camelize(name)
<<~RUBY
# frozen_string_literal: true

Expand All @@ -67,7 +81,7 @@ module #{module_name}
# @param name [String] Model name (e.g., 'my_model')
# @return [String] ActiveRecord model class
def self.active_record_model(name)
class_name = name.camelize
class_name = camelize(name)
<<~RUBY
# frozen_string_literal: true

Expand Down
4 changes: 1 addition & 3 deletions ruby-skill-bench.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']

# Runtime dependencies
spec.add_dependency 'activesupport', '>= 6.0'
spec.add_dependency 'cgi', '~> 0.5.1'
spec.add_dependency 'dotenv', '~> 3.2.0'
spec.add_dependency 'cgi', '~> 0.5.1'
spec.add_dependency 'faraday', '~> 2.14'
spec.add_dependency 'json', '~> 2.19'
spec.add_dependency 'parallel', '~> 1.26'
Expand Down
17 changes: 17 additions & 0 deletions test/agent_eval/rails/skill_templates_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'test_helper'
require 'skill_bench/rails/skill_templates'

module SkillBench
module Rails
Expand Down Expand Up @@ -33,6 +34,22 @@ def test_active_record_model_generates_valid_ruby
assert_includes code, 'class UserProfile < ApplicationRecord'
assert_includes code, 'validates :name, presence: true'
end

def test_camelize_snake_case
assert_equal 'UserCreator', SkillTemplates.camelize('user_creator')
end

def test_camelize_kebab_case
assert_equal 'OrderService', SkillTemplates.camelize('order-service')
end

def test_camelize_already_camel_case
assert_equal 'UserCreator', SkillTemplates.camelize('UserCreator')
end

def test_camelize_mixed_separators
assert_equal 'MyCoolSkill', SkillTemplates.camelize('my-cool_skill')
end
end
end
end
Loading