lucie-lib 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/Rakefile +11 -0
- data/lib/lucie/app.rb +125 -0
- data/lib/lucie/command_line_parser.rb +80 -0
- data/lib/lucie/controller/base.rb +59 -0
- data/lib/lucie/controller/exit_request.rb +10 -0
- data/lib/lucie/exceptions.rb +27 -0
- data/lib/lucie/snippets/template.rb +28 -0
- data/lib/lucie/validators/base.rb +25 -0
- data/lib/lucie/validators/mandatory_option.rb +27 -0
- data/lib/lucie/validators/optional.rb +21 -0
- data/lib/lucie/version.rb +3 -0
- data/lib/lucie.rb +28 -0
- data/lucie-lib.gemspec +23 -0
- data/test/fixtures/command_parser_fixtures.rb +55 -0
- data/test/functional/command_parser_test.rb +83 -0
- data/test/functional/template_snippet_test.rb +84 -0
- data/test/helpers/test_app.rb +2 -0
- data/test/test_helper.rb +30 -0
- data/test/unit/command_line_parser_test.rb +69 -0
- metadata +125 -0
data/Gemfile
ADDED
data/Rakefile
ADDED
data/lib/lucie/app.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
module Lucie
|
2
|
+
class App
|
3
|
+
|
4
|
+
attr_reader :command
|
5
|
+
attr_reader :root
|
6
|
+
|
7
|
+
def self.run(command = ARGV, root = nil)
|
8
|
+
obj = self.new(command, root)
|
9
|
+
obj.start
|
10
|
+
obj.exit_value
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(command, root)
|
14
|
+
self.root = root || File.expand_path("..", File.dirname(Kernel.caller[2]))
|
15
|
+
self.command = command
|
16
|
+
@exit_value ||= 0
|
17
|
+
@task = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
help? ? call_help : call_method_invoking_process
|
22
|
+
end
|
23
|
+
|
24
|
+
def exit_value
|
25
|
+
@exit_value
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_accessor :raise_exception
|
30
|
+
attr_accessor :log_level
|
31
|
+
@@raise_exception = false
|
32
|
+
@@log_level = :info
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def call_method_invoking_process
|
38
|
+
apply_validators
|
39
|
+
pair_parameters
|
40
|
+
call_action_on_controller
|
41
|
+
rescue => e
|
42
|
+
self.exception = e
|
43
|
+
give_user_friendly_error_message
|
44
|
+
write_backtrace
|
45
|
+
raise if self.class.raise_exception
|
46
|
+
end
|
47
|
+
|
48
|
+
def command=(value)
|
49
|
+
@command ||= CommandLineParser.new(value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def help?
|
53
|
+
@command.has_option?("-h") || @command.has_option?("--help") || @command.has_arg?("help") || task == "help"
|
54
|
+
end
|
55
|
+
|
56
|
+
def task
|
57
|
+
@task ||= @command.shift
|
58
|
+
end
|
59
|
+
|
60
|
+
def action
|
61
|
+
@action ||= @command.shift
|
62
|
+
@action ? @action.to_sym : "index"
|
63
|
+
end
|
64
|
+
|
65
|
+
def controller
|
66
|
+
@controller ||= controller_class.send(:new, command)
|
67
|
+
end
|
68
|
+
|
69
|
+
def controller_class
|
70
|
+
@controller_class ||= [task.split("_").map{|i| i.capitalize}.join, "Controller"].join
|
71
|
+
Object.const_get(@controller_class.to_sym)
|
72
|
+
rescue NameError
|
73
|
+
include_controller_for(task)
|
74
|
+
Object.const_get(@controller_class.to_sym)
|
75
|
+
end
|
76
|
+
|
77
|
+
def include_controller_for(task)
|
78
|
+
require [root, "app/controllers", "#{task}_controller"].join("/")
|
79
|
+
rescue LoadError
|
80
|
+
self.exit_value = 255
|
81
|
+
raise ControllerNotFound, task
|
82
|
+
end
|
83
|
+
|
84
|
+
def call_action_on_controller
|
85
|
+
self.exit_value = controller.send(action || "index")
|
86
|
+
rescue NameError
|
87
|
+
self.exit_value = 255
|
88
|
+
raise ActionNotFound.new(action, task)
|
89
|
+
rescue Controller::ExitRequest => exit_request
|
90
|
+
self.exit_value = exit_request.code
|
91
|
+
end
|
92
|
+
|
93
|
+
def apply_validators
|
94
|
+
controller.class.apply_validators
|
95
|
+
end
|
96
|
+
|
97
|
+
def pair_parameters
|
98
|
+
controller.class.pair_parameters
|
99
|
+
end
|
100
|
+
|
101
|
+
def root=(value)
|
102
|
+
@root = value
|
103
|
+
end
|
104
|
+
|
105
|
+
def exception=(exception)
|
106
|
+
@exception = exception
|
107
|
+
end
|
108
|
+
|
109
|
+
def give_user_friendly_error_message
|
110
|
+
$stderr << @exception.to_s.strip
|
111
|
+
end
|
112
|
+
|
113
|
+
def write_backtrace
|
114
|
+
$stderr.puts Kernel.caller.join("\n") if App.log_level == :debug
|
115
|
+
end
|
116
|
+
|
117
|
+
def call_help
|
118
|
+
$stdout << controller.help
|
119
|
+
end
|
120
|
+
|
121
|
+
def exit_value=(exit_value)
|
122
|
+
@exit_value = exit_value if exit_value.is_a?(Fixnum)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class CommandLineParser
|
2
|
+
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(parameters)
|
6
|
+
@params_str = parameters.class == Array ? parameters.join(" ") : parameters
|
7
|
+
@options = {}
|
8
|
+
@latest_option = nil
|
9
|
+
|
10
|
+
parse_options()
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](name)
|
14
|
+
@options[name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def shift
|
18
|
+
@options[:args].shift
|
19
|
+
end
|
20
|
+
|
21
|
+
def pair(short, long)
|
22
|
+
short_p = remove_dashes(short).to_sym
|
23
|
+
long_p = remove_dashes(long).to_sym
|
24
|
+
|
25
|
+
if @options[short_p].class == String
|
26
|
+
@options[long_p] = @options[short_p]
|
27
|
+
else
|
28
|
+
@options[short_p] = @options[long_p]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_option?(option)
|
33
|
+
@options[remove_dashes(option).to_sym] || false
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_arg?(option)
|
37
|
+
@options[:args].include?(option)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def parse_options
|
43
|
+
array_of_options.each do |option|
|
44
|
+
if is_option?(option)
|
45
|
+
save_option(option)
|
46
|
+
else
|
47
|
+
save_parameter(option)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_option?(option)
|
53
|
+
option =~ /^-/
|
54
|
+
end
|
55
|
+
|
56
|
+
def remove_dashes(option)
|
57
|
+
option.gsub(/^-+/, "")
|
58
|
+
end
|
59
|
+
|
60
|
+
def save_option(option)
|
61
|
+
without_dashes = remove_dashes(option)
|
62
|
+
@options[without_dashes.to_sym] = true
|
63
|
+
@latest_option = without_dashes.to_sym
|
64
|
+
end
|
65
|
+
|
66
|
+
def save_parameter(option)
|
67
|
+
if @options[@latest_option].class == String
|
68
|
+
@options[@latest_option] += [" ", option].join
|
69
|
+
elsif !@latest_option
|
70
|
+
@options[:args] ||= []
|
71
|
+
@options[:args] << option
|
72
|
+
else
|
73
|
+
@options[@latest_option] = option
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def array_of_options
|
78
|
+
@params_str.strip.split
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Lucie
|
2
|
+
module Controller
|
3
|
+
class Base
|
4
|
+
|
5
|
+
include Validators::MandatoryOption
|
6
|
+
include Validators::Optional
|
7
|
+
|
8
|
+
class << self
|
9
|
+
@validators = []
|
10
|
+
@params = CommandLineParser.new("")
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(command_line_parser)
|
14
|
+
self.class.params = command_line_parser
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.params=(params)
|
18
|
+
@params = params
|
19
|
+
end
|
20
|
+
|
21
|
+
def params
|
22
|
+
self.class.params
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.params
|
26
|
+
@params
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.validators
|
30
|
+
@validators ||= []
|
31
|
+
@validators
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.pair_parameters
|
35
|
+
validators.each do |validator|
|
36
|
+
short = validator.short_option
|
37
|
+
long = validator.long_option
|
38
|
+
|
39
|
+
if short != "" && long != ""
|
40
|
+
params.pair(short, long)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.apply_validators
|
46
|
+
validators.each {|validator| validator.apply(params) } if validators
|
47
|
+
end
|
48
|
+
|
49
|
+
def exit(value)
|
50
|
+
raise ExitRequest, value
|
51
|
+
end
|
52
|
+
|
53
|
+
def help
|
54
|
+
"Help"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Lucie
|
2
|
+
class RequestError < StandardError
|
3
|
+
def initialize(validator)
|
4
|
+
super "#{validator.description} (#{validator.short_option}) is mandatory parameter"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class ControllerNotFound < StandardError
|
9
|
+
def initialize(controller_name)
|
10
|
+
super "Controller is not found for #{controller_name}."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ActionNotFound < StandardError
|
15
|
+
def initialize(action, controller)
|
16
|
+
super "#{action} is not found in #{controller}."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ExitRequest < Exception
|
21
|
+
attr_reader :exit
|
22
|
+
def initialize(exit)
|
23
|
+
@exit = exit
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Lucie
|
4
|
+
module Snippets
|
5
|
+
module Template
|
6
|
+
def create_file(file_path, &block)
|
7
|
+
dir_name = File.dirname(file_path)
|
8
|
+
if !File.directory?(dir_name)
|
9
|
+
FileUtils.mkdir_p(dir_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
if block
|
13
|
+
File.open(file_path, "a") do |f|
|
14
|
+
yield(f)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
File.new(file_path, "a")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def template(template, target)
|
22
|
+
create_file(target) do |f|
|
23
|
+
f.write ERB.new(File.read(template)).result(binding)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Lucie
|
2
|
+
module Validators
|
3
|
+
class Base
|
4
|
+
def initialize(*args)
|
5
|
+
@argname = args.flatten
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply(params)
|
9
|
+
fail NotImplemented
|
10
|
+
end
|
11
|
+
|
12
|
+
def short_option
|
13
|
+
@argname.select{|option| option[0] == "-" && option[1] != "-"}.join.strip
|
14
|
+
end
|
15
|
+
|
16
|
+
def long_option
|
17
|
+
@argname.select{|option| option[0] == "-" && option[1] == "-"}.join.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
@argname.select{|option| option[0] != "-" }.first
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Lucie
|
2
|
+
module Validators
|
3
|
+
module MandatoryOption
|
4
|
+
|
5
|
+
class Validator < Base
|
6
|
+
def apply(params)
|
7
|
+
fail RequestError.new(self) unless params[:"#{short_option.gsub(/^-*/, '')}"]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def mandatory(*args)
|
12
|
+
v = Validator.new(args)
|
13
|
+
v.apply(params)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def mandatory(*args)
|
22
|
+
self.validators << Validator.new(args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Lucie
|
2
|
+
module Validators
|
3
|
+
module Optional
|
4
|
+
|
5
|
+
class Validator < Base
|
6
|
+
def apply(params)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.extend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def optional(*args)
|
16
|
+
self.validators << Validator.new(args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/lucie.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "lucie/version"
|
2
|
+
require "lucie/exceptions"
|
3
|
+
|
4
|
+
module Lucie
|
5
|
+
|
6
|
+
module Controller
|
7
|
+
autoload :ExitRequest, "lucie/controller/exit_request"
|
8
|
+
end
|
9
|
+
|
10
|
+
module Validators
|
11
|
+
autoload :MandatoryOption, "lucie/validators/mandatory_option"
|
12
|
+
autoload :Optional, "lucie/validators/optional"
|
13
|
+
autoload :Base, "lucie/validators/base"
|
14
|
+
end
|
15
|
+
|
16
|
+
module Snippets
|
17
|
+
autoload :Template, "lucie/snippets/template"
|
18
|
+
end
|
19
|
+
|
20
|
+
autoload :CommandLineParser, "lucie/command_line_parser"
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
require "lucie/app"
|
25
|
+
require "lucie/controller/base"
|
26
|
+
|
27
|
+
include Lucie
|
28
|
+
|
data/lucie-lib.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
version = File.read(File.expand_path('../../version', __FILE__)).strip
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "lucie-lib"
|
8
|
+
gem.version = version
|
9
|
+
gem.authors = ["Nucc"]
|
10
|
+
gem.email = ["nucc@bteam.hu"]
|
11
|
+
gem.description = %q{Command line utility framework}
|
12
|
+
gem.summary = %q{}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency "rake"
|
21
|
+
gem.add_development_dependency "minitest"
|
22
|
+
gem.add_development_dependency "mini_shoulda"
|
23
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class CommandParserController < Controller::Base
|
2
|
+
def hello
|
3
|
+
print "Hello World"
|
4
|
+
end
|
5
|
+
|
6
|
+
def hello_2
|
7
|
+
print params[:parameter]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ParameterParser1Controller < Controller::Base
|
12
|
+
mandatory "-s", "Search expression"
|
13
|
+
def search
|
14
|
+
print "Ok"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class OptionalMandatoryController < Controller::Base
|
19
|
+
def search
|
20
|
+
mandatory "-s", "Search expression"
|
21
|
+
print "Ok"
|
22
|
+
end
|
23
|
+
|
24
|
+
def no_mandatory
|
25
|
+
print "Ok"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ParameterPairingController < Controller::Base
|
30
|
+
optional "-e", "--expression", "Search expression"
|
31
|
+
|
32
|
+
def search_short
|
33
|
+
print params[:expression]
|
34
|
+
end
|
35
|
+
|
36
|
+
def search_long
|
37
|
+
print params[:e]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ExitValueController < Controller::Base
|
42
|
+
def method1
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
def no_exit
|
47
|
+
"asdf"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class CallIndexController < Controller::Base
|
52
|
+
def index
|
53
|
+
print "index_method"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "stringio"
|
3
|
+
require "helpers/test_app"
|
4
|
+
require "fixtures/command_parser_fixtures"
|
5
|
+
|
6
|
+
class CommandProcessorTest < MiniTest::Spec
|
7
|
+
|
8
|
+
should "parse commands" do
|
9
|
+
assert_output("Hello World", nil) { TestApp.run("command_parser hello") }
|
10
|
+
end
|
11
|
+
|
12
|
+
should "parse long parameter" do
|
13
|
+
assert_output("Parameter", nil) { TestApp.run("command_parser hello_2 --parameter Parameter") }
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
should "not give error when mandatory parameters are present" do
|
18
|
+
assert_output("Ok", nil) { TestApp.run("parameter_parser1 search -s") }
|
19
|
+
end
|
20
|
+
|
21
|
+
context "raise exception" do
|
22
|
+
setup do
|
23
|
+
TestApp.raise_exception = true
|
24
|
+
end
|
25
|
+
|
26
|
+
should "force mandatory parameters" do
|
27
|
+
assert_raises(Lucie::RequestError){ TestApp.run("parameter_parser1 search") }
|
28
|
+
end
|
29
|
+
|
30
|
+
should "give error, when method has mandatory parameter but another shouldn't throw in this case" do
|
31
|
+
assert_output("Ok", nil) { TestApp.run("optional_mandatory search -s") }
|
32
|
+
assert_raises(Lucie::RequestError){ TestApp.run("optional_mandatory search") }
|
33
|
+
assert_output("Ok", nil) { TestApp.run("optional_mandatory no_mandatory") }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to pair parameters" do
|
38
|
+
assert_output("some_string", nil) { TestApp.run("parameter_pairing search_short -e some_string") }
|
39
|
+
assert_output("some_string", nil) { TestApp.run("parameter_pairing search_long --expression some_string") }
|
40
|
+
end
|
41
|
+
|
42
|
+
should "write to stderr that no controller found when controller is missing" do
|
43
|
+
assert_output "", "Controller is not found for no_controller." do
|
44
|
+
TestApp.run("no_controller")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
should "write to stderr that no action found when action is missing" do
|
49
|
+
assert_output "", "no_action is not found in optional_mandatory." do
|
50
|
+
TestApp.run("optional_mandatory no_action")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
should "write user friendly message when mandatory parmaeter is missing" do
|
55
|
+
assert_output "", "Search expression (-s) is mandatory parameter" do
|
56
|
+
TestApp.run "parameter_parser1 search"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
should "write help message for help command" do
|
61
|
+
assert_output "Help", "" do
|
62
|
+
TestApp.run "parameter_parser1 help"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should "return the exit value" do
|
67
|
+
assert_equal 1, TestApp.run("exit_value method1")
|
68
|
+
end
|
69
|
+
|
70
|
+
should "return 0 if exit value is missing" do
|
71
|
+
assert_equal 0, TestApp.run("exit_value no_exit")
|
72
|
+
end
|
73
|
+
|
74
|
+
should "return 255 when controller or action is missing" do
|
75
|
+
assert_equal 255, TestApp.run("no_controller_with_this_name")
|
76
|
+
end
|
77
|
+
|
78
|
+
should "call index method when only the task present" do
|
79
|
+
assert_output "index_method", "" do
|
80
|
+
TestApp.run("call_index")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
class TemplateSnippetTest < MiniTest::Spec
|
5
|
+
|
6
|
+
include Snippets::Template
|
7
|
+
|
8
|
+
before do
|
9
|
+
@tmp_filename = template_path
|
10
|
+
remove_file(@tmp_filename) # if it exists
|
11
|
+
end
|
12
|
+
|
13
|
+
after do remove_file(@tmp_filename); end
|
14
|
+
|
15
|
+
|
16
|
+
describe "create_file" do
|
17
|
+
|
18
|
+
should "be able to create an empty file" do
|
19
|
+
create_file @tmp_filename
|
20
|
+
assert File.exists?(@tmp_filename)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "be able to generate multi level directory if it doesn't exist" do
|
24
|
+
@tmp_filename = [template_dir, "a", "b", template_file_name].join("/")
|
25
|
+
create_file @tmp_filename
|
26
|
+
assert File.exists?(@tmp_filename)
|
27
|
+
FileUtils.rmtree([template_dir, "a"].join("/"))
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be able to add content to a file using block" do
|
31
|
+
create_file @tmp_filename do |f|
|
32
|
+
f.puts "line_1"
|
33
|
+
f.puts "line_2"
|
34
|
+
end
|
35
|
+
|
36
|
+
lines = File.new(@tmp_filename, "r").read.split("\n")
|
37
|
+
assert_equal "line_1", lines[0]
|
38
|
+
assert_equal "line_2", lines[1]
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be able to append content to a file" do
|
42
|
+
create_file @tmp_filename do |f| f.puts "line_1"; end
|
43
|
+
create_file @tmp_filename do |f| f.puts "line_2"; end
|
44
|
+
|
45
|
+
lines = File.new(@tmp_filename, "r").read.split("\n")
|
46
|
+
assert_equal "line_1", lines[0]
|
47
|
+
assert_equal "line_2", lines[1]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "template" do
|
52
|
+
before do @template_file = Tempfile.new(template_file_name, template_dir); end
|
53
|
+
|
54
|
+
should "generate file from template using absolute directory" do
|
55
|
+
File.open(@template_file, "w+") do |f|
|
56
|
+
f.write "template <%= @variable %>"
|
57
|
+
end
|
58
|
+
@variable = "test_var_for_template"
|
59
|
+
|
60
|
+
template @template_file, @tmp_filename
|
61
|
+
assert_equal "template test_var_for_template", File.open(@tmp_filename, "r").read
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def template_dir
|
68
|
+
File.expand_path("../../../tmp", __FILE__)
|
69
|
+
end
|
70
|
+
|
71
|
+
def template_file_name
|
72
|
+
rand = (Time.now.to_i * rand(10**6)).to_i
|
73
|
+
"template_#{rand}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def template_path
|
77
|
+
[template_dir, template_file_name].join("/")
|
78
|
+
end
|
79
|
+
|
80
|
+
def remove_file(filename)
|
81
|
+
FileUtils.remove_file(filename) if File.exists?(filename)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# MiniTest is integrated to Ruby library and by default the test wants to use that.
|
2
|
+
# Force the Rubygems version
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require "mini_shoulda"
|
5
|
+
#require 'debugger'
|
6
|
+
|
7
|
+
require File.expand_path('../../lib/lucie.rb', __FILE__)
|
8
|
+
|
9
|
+
LUCIE_ROOT = File.expand_path File.dirname(__FILE__)
|
10
|
+
|
11
|
+
class MiniTest::Spec
|
12
|
+
include Lucie
|
13
|
+
|
14
|
+
def setup
|
15
|
+
redirect_stderr
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
reset_stderr_redirection
|
20
|
+
end
|
21
|
+
|
22
|
+
def redirect_stderr
|
23
|
+
@stderr = $stderr
|
24
|
+
$stderr = StringIO.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset_stderr_redirection
|
28
|
+
$stderr = @stderr
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class CommandLineParserTest < MiniTest::Spec
|
4
|
+
|
5
|
+
should "parse empty string" do
|
6
|
+
parser = CommandLineParser.new ""
|
7
|
+
assert_equal Hash.new, parser.options
|
8
|
+
end
|
9
|
+
|
10
|
+
should "parse short boolean value" do
|
11
|
+
parser = CommandLineParser.new "-a"
|
12
|
+
assert parser.options[:a]
|
13
|
+
end
|
14
|
+
|
15
|
+
should "parse more short boolean values" do
|
16
|
+
parser = CommandLineParser.new "-a -b"
|
17
|
+
assert parser.options[:a]
|
18
|
+
assert parser.options[:b]
|
19
|
+
end
|
20
|
+
|
21
|
+
should "parse long boolean value" do
|
22
|
+
parser = CommandLineParser.new "--long-parameter"
|
23
|
+
assert parser.options[:"long-parameter"]
|
24
|
+
end
|
25
|
+
|
26
|
+
should "parse multiple long boolean values" do
|
27
|
+
parser = CommandLineParser.new "--long-parameter --another-long-parameter"
|
28
|
+
assert parser.options[:"long-parameter"]
|
29
|
+
assert parser.options[:"another-long-parameter"]
|
30
|
+
end
|
31
|
+
|
32
|
+
should "parse string parameter" do
|
33
|
+
parser = CommandLineParser.new "--string this_is_a_string"
|
34
|
+
assert_equal "this_is_a_string", parser.options[:string]
|
35
|
+
end
|
36
|
+
|
37
|
+
should "parse more string parameters" do
|
38
|
+
parser = CommandLineParser.new "--string this is a string"
|
39
|
+
assert_equal "this is a string", parser.options[:string]
|
40
|
+
end
|
41
|
+
|
42
|
+
should "parse arguments" do
|
43
|
+
parser = CommandLineParser.new "arg1 arg2 -x -y"
|
44
|
+
assert_equal "arg1", parser.options[:args][0]
|
45
|
+
assert parser.options[:x]
|
46
|
+
end
|
47
|
+
|
48
|
+
should "be able to shift the args array" do
|
49
|
+
parser = CommandLineParser.new "arg1 arg2"
|
50
|
+
arg = parser.shift
|
51
|
+
assert_equal "arg1", arg
|
52
|
+
assert_equal "arg2", parser.options[:args][0]
|
53
|
+
end
|
54
|
+
|
55
|
+
should "be able to answer the an argument is present or not" do
|
56
|
+
parser = CommandLineParser.new "arg1 arg2"
|
57
|
+
assert parser.has_arg?("arg1")
|
58
|
+
assert parser.has_arg?("arg2")
|
59
|
+
assert !parser.has_arg?("arg3")
|
60
|
+
end
|
61
|
+
|
62
|
+
should "be able to answer the parameter is present or not" do
|
63
|
+
parser = CommandLineParser.new "arg1 -h -p"
|
64
|
+
assert parser.has_option?("h")
|
65
|
+
assert parser.has_option?("p")
|
66
|
+
assert !parser.has_option?("print")
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lucie-lib
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nucc
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: minitest
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mini_shoulda
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Command line utility framework
|
63
|
+
email:
|
64
|
+
- nucc@bteam.hu
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- Gemfile
|
70
|
+
- Rakefile
|
71
|
+
- lib/lucie.rb
|
72
|
+
- lib/lucie/app.rb
|
73
|
+
- lib/lucie/command_line_parser.rb
|
74
|
+
- lib/lucie/controller/base.rb
|
75
|
+
- lib/lucie/controller/exit_request.rb
|
76
|
+
- lib/lucie/exceptions.rb
|
77
|
+
- lib/lucie/snippets/template.rb
|
78
|
+
- lib/lucie/validators/base.rb
|
79
|
+
- lib/lucie/validators/mandatory_option.rb
|
80
|
+
- lib/lucie/validators/optional.rb
|
81
|
+
- lib/lucie/version.rb
|
82
|
+
- lucie-lib.gemspec
|
83
|
+
- test/fixtures/command_parser_fixtures.rb
|
84
|
+
- test/functional/command_parser_test.rb
|
85
|
+
- test/functional/template_snippet_test.rb
|
86
|
+
- test/helpers/test_app.rb
|
87
|
+
- test/test_helper.rb
|
88
|
+
- test/unit/command_line_parser_test.rb
|
89
|
+
homepage: ''
|
90
|
+
licenses: []
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
hash: -2466274242132173745
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
hash: -2466274242132173745
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.25
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: ''
|
119
|
+
test_files:
|
120
|
+
- test/fixtures/command_parser_fixtures.rb
|
121
|
+
- test/functional/command_parser_test.rb
|
122
|
+
- test/functional/template_snippet_test.rb
|
123
|
+
- test/helpers/test_app.rb
|
124
|
+
- test/test_helper.rb
|
125
|
+
- test/unit/command_line_parser_test.rb
|