Dslable
Dslable is generator for simple spec gem.
Summary
- create gem template with DslSettingFile.
- you can get bin-executable gem.
- you can gem creation workflow.
- generated gem has 1-DslSettingFile.
- generated gem has 1-core logic class.
- generated gem has 1-dsl class.
- generated gem has 1-dsl-model class.
- generated gem has 1-core class's RSpec spec.
- generated gem has Gemfile.(already has minimum necessary gem)
Purpose
- to create simple spec gem easier.
Structure
Dsldefine
this is setting file.
set ...
- gem_name: your gem name. set snake case name
- bin_name: your bin name. set snake case name
- field: your dsl field.
generated code: lib/your_gem_name_core.rb
- main logic.
- init method generate DslSettingFile.
- execute method is main logic. you must edit additional logic manually.
generated code: lib/your_gem_name_dsl.rb
- this file keeps values from DslSettingFile.
generated code: lib/your_gem_name_dsl_model.rb
- this file define DslSettingFile's model.
generated code: bin/your_bin_name
- this file has command line interface logic.
generated code: spec/your_gem_name_core_spec.rb
- this file is RSpec spec for 'your_gem_name_core.rb'.
DSL List
Global DSL
dsl | mean |
---|---|
gem_name | set your gem name.(snake_case) |
bin_name | set your bin name.(snake_case) |
field | set your field information by block |
Field DSL
dsl | mean |
---|---|
desc | set your field description |
Args DSL
dsl | mean |
---|---|
desc | set your args description |
klass | set your args data type. you can choose [String, Array, Hash, :Boolean] |
required | if you want to set required, use this. |
default_value | if you want to set default value, use this. |
Installation
Add this line to your application's Gemfile:
gem 'dslable'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dslable
Sample Usage
Sample Spec
- create FizzBuzzGem
- if you execute 'fizzbuzzgem', result is...
1 2 fizz 3 4 buzz 5 fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz
- you can choose output 'fizz/buzz/fizzbuzz' or 'FIZZ/BUZZ/FIZZBUZZ' by setting file.
- you can set fizzbuzz range by setting file.
Steps: 'dslable init'. generate Dsldefine Template.
$ dslable init
$ ls
Dsldefine
Dsldefine Template Contents
# encoding: utf-8
# set your gem name. this is use in rb-filename and class-name
gem_name "TODO: set your gem_name"
# set your bin name
bin_name "TODO: set your bin_name"
# set your dsl filed
field :field_name1 do |f|
# set your field description
f.desc "field1 description"
f.args :args_name do |a|
# set your args description
a.desc "args description"
# you can use String, Array, Hash and :Boolean
a.klass String
# if you want not required, comment out following line
a.required
# if you comment out following line, default => nil
a.default_value "args_value2"
end
end
# field :field_name2 do |f|
# f.desc "field2 description"
# f.args :args_name do |a|
# a.desc "args description"
# a.klass String
# a.required
# a.default_value "args_value2"
# end
# end
Steps: Edit Dsldefine manually.
# encoding: utf-8
gem_name "fizz_buzz_gem"
bin_name "fizzbuzzgem"
field :is_upper_case do |f|
f.desc "is_upper_case"
f.args :is_upper_case do |a|
a.desc "is_upper_case flg."
a.klass String
a.required
a.default_value "false"
end
end
field :range do |f|
f.desc "range"
f.args :range do |a|
a.desc "range."
a.klass Array
a.default_value (1..15).to_a
end
end
Steps: 'dslable generate'. generate template.
dslable generate
FileTree
fizz_buzz_gem
│ .gitignore
│ .rspec
│ fizz_buzz_gem.gemspec
│ Gemfile
│ LICENSE.txt
│ Rakefile
│ README.md
│
├─.git
├─bin
│ fizzbuzzgem
│
├─lib
│ │ fizz_buzz_gem_core.rb
│ │ fizz_buzz_gem_dsl.rb
│ │ fizz_buzz_gem_dsl_model.rb
│ │
│ └─fizz_buzz_gem
│ version.rb
│
├─spec
│ fizz_buzz_gem_core_spec.rb
│ spec_helper.rb
└─tudu
todos
doings
dones
Gemfile Template
source 'https://rubygems.org'
gemspec
gem "rspec", "~> 2.14.1"
gem "thor", "~> 0.18.1"
gem "simplecov", "~> 0.8.2"
gem "activesupport", "~> 4.0.1"
gem "activemodel", "~> 4.0.2"
core source Template fizz_buzz_gem_core.rb
# encoding: utf-8
require 'fizz_buzz_gem_dsl'
module FizzBuzzGem
# FizzBuzzGem Core
class Core
# rubocop:disable LineLength
FIZZ_BUZZ_GEM_FILE = 'Fizzbuzzgemfile'
FIZZ_BUZZ_GEM_TEMPLATE = <<-EOS
# encoding: utf-8
# is_upper_case
# is_upper_case is required
# is_upper_case allow only String
# is_upper_case's default value => "false"
is_upper_case "false"
# range
# range allow only Array
# range's default value => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
range [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
EOS
# rubocop:enable LineLength
# generate Fizzbuzzgemfile to current directory.
def init
File.open(FIZZ_BUZZ_GEM_FILE, 'w') do |f|
f.puts FIZZ_BUZZ_GEM_TEMPLATE
end
end
# TODO: write your gem's specific contents
def execute
src = read_dsl
dsl = FizzBuzzGem::Dsl.new
dsl.instance_eval src
# TODO: implement your gem's specific logic
end
private
def read_dsl
File.open(FIZZ_BUZZ_GEM_FILE) { |f|f.read }
end
end
end
dsl source Template fizz_buzz_gem_dsl.rb
# encoding: utf-8
require 'fizz_buzz_gem_dsl_model'
module FizzBuzzGem
# Dsl
class Dsl
attr_accessor :fizz_buzz_gem
# String Define
[:is_upper_case].each do |f|
define_method f do |value|
@fizz_buzz_gem.send("#{f}=", value)
end
end
# Array/Hash/Boolean Define
[:range].each do |f|
define_method f do |value|
@fizz_buzz_gem.send("#{f}=", value)
end
end
def initialize
@fizz_buzz_gem = FizzBuzzGem::DslModel.new
@fizz_buzz_gem.is_upper_case = 'false'
@fizz_buzz_gem.range = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
end
end
end
dsl model source Template fizz_buzz_gem_dsl_model.rb
# encoding: utf-8
require 'active_model'
# rubocop:disable LineLength
module FizzBuzzGem
# DslModel
class DslModel
include ActiveModel::Model
# is_upper_case
attr_accessor :is_upper_case
validates :is_upper_case, presence: true
# range
attr_accessor :range
end
end
# rubocop:enable LineLength
bin source Template
#!/usr/bin/env ruby
# encoding: utf-8
require "fizz_buzz_gem_core"
require "fizz_buzz_gem/version"
require "thor"
module FizzBuzzGem
#= FizzBuzzGem CLI
class CLI < Thor
class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
class_option :version, type: :boolean, desc: 'version'
desc "execute", "TODO: write your desc"
def execute
FizzBuzzGem::Core.new.execute
end
desc "init", "generate Fizzbuzzgemfile"
def init
FizzBuzzGem::Core.new.init
end
desc "version", "version"
def version
p FizzBuzzGem::VERSION
end
end
end
FizzBuzzGem::CLI.start(ARGV)
spec source Template
# encoding: utf-8
require "spec_helper"
require "fizz_buzz_gem_core"
describe FizzBuzzGem::Core do
context :init do
cases = [
{
case_no: 1,
case_title: "case_title",
expected: "expected",
},
]
cases.each do |c|
it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
begin
case_before c
# -- given --
fizz_buzz_gem_core = FizzBuzzGem::Core.new
# -- when --
# TODO: implement execute code
# actual = fizz_buzz_gem_core.init
# -- then --
# TODO: implement assertion code
# ret = expect(actual).to eq(c[:expected])
ensure
case_after c
end
end
def case_before(c)
# implement each case before
end
def case_after(c)
# implement each case after
end
end
end
context :execute do
cases = [
{
case_no: 1,
case_title: "case_title",
expected: "expected",
},
]
cases.each do |c|
it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
begin
case_before c
# -- given --
fizz_buzz_gem_core = FizzBuzzGem::Core.new
# -- when --
# TODO: implement execute code
# actual = fizz_buzz_gem_core.execute
# -- then --
# TODO: implement assertion code
# ret = expect(actual).to eq(c[:expected])
ensure
case_after c
end
end
def case_before(c)
# implement each case before
end
def case_after(c)
# implement each case after
end
end
end
end
Workflow Template(tudu/todos, tudu/doings, tudu/dones). you can check by tudu gem.
$ tudu tasks -c
========TODOS========
implement 'fizz_buzz_gem_core.rb' your main logic. pass rspec all specs.
implement bin 'bin/your_bin'.
edit 'fizz_buzz_gem.gemspec'.
edit 'README.md'.
edit 'LICENSE.txt'.
git add, commit.
rake install.
check gem(test using).
gem uninstall fizz_buzz_gem.
rake release.
gem install fizz_buzz_gem.
after release check.
========DOINGS========
implement 'fizz_buzz_gem_core_spec.rb'.
========DONES========
Steps: check todo by tudu now
$ tudu now
implement 'fizz_buzz_gem_core_spec.rb'.
Steps: implement 'fizz_buzz_core_spec.rb' manually. (TDD step)
# encoding: utf-8
require "spec_helper"
require "fizz_buzz_gem_core"
describe FizzBuzzGem::Core do
context :init do
cases = [
{
case_no: 1,
case_title: "output template",
expected: FizzBuzzGem::Core::FIZZ_BUZZ_GEM_TEMPLATE
},
]
cases.each do |c|
it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
begin
case_before c
# -- given --
fizz_buzz_core = FizzBuzzGem::Core.new
# -- when --
fizz_buzz_core.init
# -- then --
actual = File.read(FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE)
expect(actual).to eq(c[:expected])
ensure
case_after c
end
end
def case_before(c)
# implement each case before
end
def case_after(c)
# implement each case after
FileUtils.rm_rf(FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE) if File.exists? FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE
end
end
end
context :execute do
FIZZBUZZGEMFILE_CASE1 =<<-EOS
# encoding: utf-8
is_upper_case "false"
EOS
FIZZBUZZGEMFILE_CASE2 =<<-EOS
# encoding: utf-8
is_upper_case "true"
range (1..16).to_a
EOS
cases = [
{
case_no: 1,
case_title: "upper false, range default",
fizzgemfile: FIZZBUZZGEMFILE_CASE1,
expected: "1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz",
},
{
case_no: 2,
case_title: "upper true, range 1..16",
fizzgemfile: FIZZBUZZGEMFILE_CASE2,
expected: "1 2 FIZZ 4 BUZZ FIZZ 7 8 FIZZ BUZZ 11 FIZZ 13 14 FIZZBUZZ 16",
},
]
cases.each do |c|
it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
begin
case_before c
# -- given --
fizz_buzz_gem_core = FizzBuzzGem::Core.new
# -- when --
actual = fizz_buzz_gem_core.execute
# -- then --
ret = expect(actual).to eq(c[:expected])
ensure
case_after c
end
end
def case_before(c)
# implement each case before
File.open(FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE, "w") {|f|f.puts c[:fizzgemfile]}
end
def case_after(c)
# implement each case after
FileUtils.rm_rf(FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE) if File.exists? FizzBuzzGem::Core::FIZZ_BUZZ_GEM_FILE
end
end
end
end
Steps: execute 'rspec' and fail.
$ rspec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
.FF
Failures:
1) FizzBuzzGem::Core execute |case_no=1|case_title=upper false, range default
Failure/Error: ret = expect(actual).to eq(c[:expected])
expected: "1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz"
got: "false"
(compared using ==)
# ./spec/fizz_buzz_gem_core_spec.rb:86:in `block (4 levels) in <top (required)>'
2) FizzBuzzGem::Core execute |case_no=2|case_title=upper true, range 1..16
Failure/Error: ret = expect(actual).to eq(c[:expected])
expected: "1 2 FIZZ 4 BUZZ FIZZ 7 8 FIZZ BUZZ 11 FIZZ 13 14 FIZZBUZZ 16"
got: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
(compared using ==)
# ./spec/fizz_buzz_gem_core_spec.rb:86:in `block (4 levels) in <top (required)>'
Finished in 0.01 seconds
3 examples, 2 failures
Failed examples:
rspec ./spec/fizz_buzz_gem_core_spec.rb:75 # FizzBuzzGem::Core execute |case_no=1|case_title=upper false, range default
rspec ./spec/fizz_buzz_gem_core_spec.rb:75 # FizzBuzzGem::Core execute |case_no=2|case_title=upper true, range 1..16
Randomized with seed 63051
Steps: after implement spec, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
implement 'fizz_buzz_gem_core.rb' your main logic. pass rspec all specs.
Steps: implement 'fizz_buzz_core.rb' manually.
# encoding: utf-8
require 'fizz_buzz_gem_dsl'
module FizzBuzzGem
# FizzBuzzGem Core
class Core
FIZZ_BUZZ_GEM_FILE = "Fizzbuzzgemfile"
FIZZ_BUZZ_GEM_TEMPLATE =<<-EOS
# encoding: utf-8
# is_upper_case
# is_upper_case is required
# is_upper_case allow only String
# is_upper_case's default value => "false"
is_upper_case "false"
# range
# range allow only Array
# range's default value => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
range [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
EOS
#== generate Fizzbuzzgemfile to current directory.
def init
File.open(FIZZ_BUZZ_GEM_FILE, "w") {|f|f.puts FIZZ_BUZZ_GEM_TEMPLATE}
end
#== TODO: write your gem's specific contents
def execute
src = read_dsl
dsl = FizzBuzzGem::Dsl.new
dsl.instance_eval src
output_fizzbuzz(dsl)
end
private
def read_dsl
File.open(FIZZ_BUZZ_GEM_FILE) {|f|f.read}
end
def output_fizzbuzz(dsl)
ret = []
dsl.fizz_buzz_gem.range.each do |i|
if i % 15 == 0
ret << 'fizzbuzz'
elsif i % 3 == 0
ret << 'fizz'
elsif i % 5 == 0
ret << 'buzz'
else
ret << i
end
end
output = ret.join(' ')
dsl.fizz_buzz_gem.is_upper_case == 'true' ? output.upcase : output
end
end
end
Steps: execute rspec
$rspec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
...
Finished in 0.011 seconds
3 examples, 0 failures
Randomized with seed 29906
Steps: after implement core.rb, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
implement bin 'bin/your_bin'.
Steps: Edit bin bin/fizzbuzzgem manually
#!/usr/bin/env ruby
# encoding: utf-8
require "fizz_buzz_gem_core"
require "fizz_buzz_gem/version"
require "thor"
module FizzBuzzGem
#= FizzBuzzGem CLI
class CLI < Thor
class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
class_option :version, type: :boolean, desc: 'version'
desc "execute", "execute fizz buzz"
def execute
puts FizzBuzzGem::Core.new.execute
end
desc "init", "generate Fizzbuzzgemfile"
def init
FizzBuzzGem::Core.new.init
end
desc "version", "version"
def version
p FizzBuzzGem::VERSION
end
end
end
FizzBuzzGem::CLI.start(ARGV)
Steps: after implement bin, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
edit 'fizz_buzz_gem.gemspec'.
Steps: Edit fizz_buzz_gem.gemspec manually
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'fizz_buzz_gem/version'
Gem::Specification.new do |spec|
spec.name = "fizz_buzz_gem"
spec.version = FizzBuzzGem::VERSION
spec.authors = ["yourname"]
spec.email = ["your@mail.address"]
spec.description = %q{fizz buzz gem}
spec.summary = %q{fizz buzz gem}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files`.split($/)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_runtime_dependency "thor", "~> 0.18.1"
spec.add_runtime_dependency "activesupport", "~> 4.0.1"
spec.add_runtime_dependency "activemodel", "~> 4.0.2"
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec", "~> 2.14.1"
spec.add_development_dependency "simplecov", "~> 0.8.2"
end
Steps: after edit gemspec, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
edit 'README.md'.
Steps: Edit README.md manually
# FizzBuzzGem
FizzBuzzApplication summary.
## Installation
Add this line to your application's Gemfile:
gem 'fizz_buzz_gem'
And then execute:
$ bundle
Or install it yourself as:
$ gem install fizz_buzz_gem
## Usage
usage...
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
Steps: after edit README.md, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
edit 'LICENSE.txt'.
Steps: Edit LICENSE.txt
edit.
Steps: after edit LICENSE.txt, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
git add, commit.
Steps: git add, commit
$ git add -A
$ git add -u
$ git commit -m "first commit"
Steps: after git add/commit, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
rake install.
Steps: rake install
$ rake install
fizz_buzz_gem 0.0.1 built to pkg/fizz_buzz_gem-0.0.1.gem.
fizz_buzz_gem (0.0.1) installed.
Steps: after rake install, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
check gem(test using).
Steps: test use fizzbuzzgem
show help
$ fizzbuzzgem
Commands:
fizzbuzzgem execute # TODO: write your desc
fizzbuzzgem help [COMMAND] # Describe available commands or one specific c...
fizzbuzzgem init # generate Fizzbuzzgemfile
fizzbuzzgem version # version
Options:
-h, [--help] # help message.
[--version] # version
fizzbuzzgem init
$ fizzbuzzgem init
$ ls
Fizzbuzzgemfile*
$ cat Fizzbuzzgemfile
# encoding: utf-8
# is_upper_case
# is_upper_case is required
# is_upper_case allow only String
# is_upper_case's default value => "false"
is_upper_case "false"
# range
# range allow only Array
# range's default value => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
range [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
edit Fizzbuzzgemfile manually
# encoding: utf-8
is_upper_case "true"
range (1..16).to_a
execute 'fizzbuzzgem execute'
$ fizzbuzzgem execute
1 2 FIZZ 4 BUZZ FIZZ 7 8 FIZZ BUZZ 11 FIZZ 13 14 FIZZBUZZ 16
re-edit Fizzbuzzgemfile manually
# encoding: utf-8
is_upper_case "false"
execute 'fizzbuzzgem execute'
$ fizzbuzzgem e
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz
Steps: after test using, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
gem uninstall fizz_buzz_gem.
Steps: uninstall test installed gem.
gem uninstall fizz_buzz_gem
Steps: after gem uninstall fizz_buzz_gem, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
rake release.
Steps: if test using is ok, release gem to RubyGems
$ rake release
Steps: after rake release, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
gem install fizz_buzz_gem.
Steps: install gem
$ gem install fizz_buzz_gem
Steps: after gem install fizz_buzz_gem, execute 'tudu done'. and confirm next todo by 'todo now'
$ tudu done
$ tudu now
after release check.
Steps: check your gem.
check.
Steps: after check your gem complete, execute 'tudu done'. all todo complete'
$ tudu done
All Tasks Finish!!
Notes
- this gem uses 'bundle gem' command to create gem template. (bundler gem).
- this gem uses 'rspec --init' command to create RSpec template (rspec gem).
- this gem uses 'piccolo' command to create RSpec spec template (rspec_piccolo gem).
- this gem uses 'tudu' command to create Workflow (tudu gem).
History
- version 0.0.6 : fix generation code.remove rubocop warnings
- version 0.0.5 : update runtime_dependency(version up rspec_piccolo ver0.0.6 to ver0.0.8)
- version 0.0.4 : delete Core#init spec generation
- version 0.0.4 : delete Hash default brace.
- version 0.0.3 : add using class Boolean(true or class).
- version 0.0.2 : add workflow generation by 'tudu gem'.
- version 0.0.1 : first release.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request