lucie-lib 0.0.1
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.
- 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
|