lucie 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +83 -0
- data/Rakefile +10 -0
- data/bin/lucie +7 -0
- data/lib/lucie.rb +25 -0
- data/lib/lucie/app.rb +60 -0
- data/lib/lucie/buffer.rb +14 -0
- data/lib/lucie/command_line_parser.rb +68 -0
- data/lib/lucie/controller/base.rb +56 -0
- data/lib/lucie/exceptions.rb +4 -0
- data/lib/lucie/snippets/template.rb +28 -0
- data/lib/lucie/validators/base.rb +21 -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/lucie.gemspec +23 -0
- data/test/fixtures/command_parser_fixtures.rb +39 -0
- data/test/functional/command_parser_test.rb +34 -0
- data/test/functional/template_snippet_test.rb +84 -0
- data/test/helpers/test_app.rb +2 -0
- data/test/test_helper.rb +12 -0
- data/test/unit/command_line_parser_test.rb +48 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 10ef9f0d6a4569ca18cce0855f3a06a5f5d7d882
|
4
|
+
data.tar.gz: edb938079f4913b150e71d170f269ad2205ce672
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: de139e2b7d224bf25976b9af0fe64c005610f0ad6fc402471249136b6c840c6ce8a50d76fcf932bd6a8bff5a53aa4fbbfb721dfa5c071831003439caacbfd1e2
|
7
|
+
data.tar.gz: 14b3d6c99db863433ff0d82e723a0844d16b65a24f8d223fce4c69df182fdd16e95bee05d1ef734f03248eb7c2893b1d57c75cbc5e772e1e1a41156e9a5af1d6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Nucc
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Lucie
|
2
|
+
|
3
|
+
The plan of this project is to create a framework for console applications. It would be a bit different to Thor, Rake, Getopt based command line frameworks, because it would based on MVC design pattern, where appears the controller layer to handle the command, the view to define templates for configuration files and the model to store data in XML or NoSQL database.
|
4
|
+
|
5
|
+
Currently it's under hard developing.
|
6
|
+
|
7
|
+
Here is an example of dataflow:
|
8
|
+
|
9
|
+
We have an application to manage nginx webserver configuration. We want to create a new host in the next process. The name of the application is WorkSpace, so we use the ws shortened name for the command.
|
10
|
+
|
11
|
+
`$ ws host create --domain luc.ie --server web1`
|
12
|
+
|
13
|
+
The `HostController`'s create action will handle the request, gets the parameters in params hash. Domain is mandatory parameter for the host command and server is mandatory only for create sub-command.
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
# /app/controllers/host_controller.rb:
|
17
|
+
class HostController < Controller::Base
|
18
|
+
mandatory "-d", "--domain", "Domain name of the host"
|
19
|
+
|
20
|
+
def create
|
21
|
+
mandatory "-s", "--server", "Hosting server"
|
22
|
+
|
23
|
+
@domain = params[:domain]
|
24
|
+
@server = ip_address(find_host(params[:server]))
|
25
|
+
|
26
|
+
Host.create!(:domain => {:_value => @domain, :server => @server)
|
27
|
+
|
28
|
+
template "nginx/vhost", :ssh, @server, "/etc/nginx/vhosts/#{domain}"
|
29
|
+
run "nginx -s reload", :on => @server
|
30
|
+
end
|
31
|
+
end
|
32
|
+
</pre>
|
33
|
+
|
34
|
+
Controller stores the new domain and its base host is in Host model. It uses the `nginx/vhost` template to generate a new configuration file on `@server` at `/etc/nginx/vhosts/#{domain}`. After configuration is generated it reloads nginx.
|
35
|
+
|
36
|
+
The host model is an XML configuration that looks like this:
|
37
|
+
|
38
|
+
<pre>
|
39
|
+
# /app/models/host.rb
|
40
|
+
class Host < XmlModel
|
41
|
+
root :configuration
|
42
|
+
|
43
|
+
Element :domain do
|
44
|
+
Attribute :server
|
45
|
+
end
|
46
|
+
end
|
47
|
+
</pre>
|
48
|
+
|
49
|
+
The root of `Host` is `:configuration`, so it will be under the `<configuration>` node. Domain is an xml element, server is its attribute, so the result will be this:
|
50
|
+
|
51
|
+
<pre>
|
52
|
+
<configuration>
|
53
|
+
<hosts>
|
54
|
+
<domain server='web1'>luc.ie</domain>
|
55
|
+
</hosts>
|
56
|
+
</configuration>
|
57
|
+
</pre>
|
58
|
+
|
59
|
+
The template defines an Nginx configuration. `HostController#create` applies this template and render its content on `@server` to `/etc/nginx/vhosts/luc.ie`.
|
60
|
+
|
61
|
+
<pre>
|
62
|
+
# /app/templates/nginx/vhost:
|
63
|
+
server {
|
64
|
+
listen 80;
|
65
|
+
server_name <%= @domain %>
|
66
|
+
|
67
|
+
location / {
|
68
|
+
root /var/www/<%= @domain %>
|
69
|
+
}
|
70
|
+
}
|
71
|
+
</pre>
|
72
|
+
|
73
|
+
So this would be a simple process in Lucie, if you're interested, let me know!
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
If you want to join to the project, first drop me a mail to nucc@bteam.hu about your ideas. After just
|
78
|
+
|
79
|
+
1. Fork it
|
80
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
82
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
83
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/lucie
ADDED
data/lib/lucie.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "lucie/version"
|
2
|
+
require "lucie/exceptions"
|
3
|
+
|
4
|
+
module Lucie
|
5
|
+
module Controller
|
6
|
+
autoload :Base, "lucie/controller/base"
|
7
|
+
end
|
8
|
+
|
9
|
+
module Validators
|
10
|
+
autoload :MandatoryOption, "lucie/validators/mandatory_option"
|
11
|
+
autoload :Optional, "lucie/validators/optional"
|
12
|
+
autoload :Base, "lucie/validators/base"
|
13
|
+
end
|
14
|
+
|
15
|
+
module Snippets
|
16
|
+
autoload :Template, "lucie/snippets/template"
|
17
|
+
end
|
18
|
+
|
19
|
+
autoload :App, "lucie/app"
|
20
|
+
autoload :Buffer, "lucie/buffer"
|
21
|
+
autoload :CommandLineParser, "lucie/command_line_parser"
|
22
|
+
end
|
23
|
+
|
24
|
+
include Lucie
|
25
|
+
|
data/lib/lucie/app.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Lucie
|
2
|
+
class App
|
3
|
+
|
4
|
+
attr_reader :command
|
5
|
+
|
6
|
+
def self.run(command = ARGV, root = nil)
|
7
|
+
self.new(command, root)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(command, root)
|
11
|
+
self.root = root || File.expand_path("..", File.dirname(Kernel.caller[2]))
|
12
|
+
self.command = command
|
13
|
+
|
14
|
+
controller.class.apply_validators
|
15
|
+
controller.class.pair_parameters
|
16
|
+
controller.send(action)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def root
|
21
|
+
@root
|
22
|
+
end
|
23
|
+
|
24
|
+
def output
|
25
|
+
controller.out.output
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def command=(value)
|
31
|
+
@command ||= value
|
32
|
+
@command = @command.split(" ") if @command.is_a? String
|
33
|
+
end
|
34
|
+
|
35
|
+
def task
|
36
|
+
@task ||= @command.shift
|
37
|
+
end
|
38
|
+
|
39
|
+
def action
|
40
|
+
@action ||= @command.shift.to_sym
|
41
|
+
end
|
42
|
+
|
43
|
+
def controller
|
44
|
+
@controller ||= controller_class.send(:new, command)
|
45
|
+
end
|
46
|
+
|
47
|
+
def controller_class
|
48
|
+
@controller_class ||= [task.split("_").map{|i| i.capitalize}.join, "Controller"].join
|
49
|
+
Object.const_get(@controller_class.to_sym)
|
50
|
+
rescue NameError
|
51
|
+
require [root, "app/controllers", "#{task}_controller"].join("/")
|
52
|
+
Object.const_get(@controller_class.to_sym)
|
53
|
+
end
|
54
|
+
|
55
|
+
def root=(value)
|
56
|
+
@root = value
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/lucie/buffer.rb
ADDED
@@ -0,0 +1,68 @@
|
|
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 pair(short, long)
|
18
|
+
short_p = remove_dashes(short).to_sym
|
19
|
+
long_p = remove_dashes(long).to_sym
|
20
|
+
|
21
|
+
if @options[short_p].class == String
|
22
|
+
@options[long_p] = @options[short_p]
|
23
|
+
else
|
24
|
+
@options[short_p] = @options[long_p]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def parse_options
|
31
|
+
array_of_options.each do |option|
|
32
|
+
if is_option?(option)
|
33
|
+
save_option(option)
|
34
|
+
else
|
35
|
+
save_parameter(option)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_option?(option)
|
41
|
+
option =~ /^-/
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_dashes(option)
|
45
|
+
option.gsub!(/^-+/, "")
|
46
|
+
end
|
47
|
+
|
48
|
+
def save_option(option)
|
49
|
+
remove_dashes(option)
|
50
|
+
@options[option.to_sym] = true
|
51
|
+
@latest_option = option.to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
def save_parameter(option)
|
55
|
+
if @options[@latest_option].class == String
|
56
|
+
@options[@latest_option] += [" ", option].join
|
57
|
+
elsif !@latest_option
|
58
|
+
@options[:args] ||= []
|
59
|
+
@options[:args] << option
|
60
|
+
else
|
61
|
+
@options[@latest_option] = option
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def array_of_options
|
66
|
+
@params_str.strip.split
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,56 @@
|
|
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(params)
|
14
|
+
self.class.params = CommandLineParser.new(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def out
|
18
|
+
@buffer ||= Buffer.new
|
19
|
+
@buffer
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.params=(params)
|
23
|
+
@params = params
|
24
|
+
end
|
25
|
+
|
26
|
+
def params
|
27
|
+
self.class.params
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.params
|
31
|
+
@params
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.validators
|
35
|
+
@validators ||= []
|
36
|
+
@validators
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.pair_parameters
|
40
|
+
validators.each do |validator|
|
41
|
+
short = validator.short_option
|
42
|
+
long = validator.long_option
|
43
|
+
|
44
|
+
if short != "" && long != ""
|
45
|
+
params.pair(short, long)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.apply_validators
|
51
|
+
validators.each {|validator| validator.apply(params) } if validators
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
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,21 @@
|
|
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
|
+
end
|
20
|
+
end
|
21
|
+
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 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/lucie.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'lucie/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "lucie"
|
8
|
+
gem.version = Lucie::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,39 @@
|
|
1
|
+
class CommandParserController < Controller::Base
|
2
|
+
def hello
|
3
|
+
out << "Hello World"
|
4
|
+
end
|
5
|
+
|
6
|
+
def hello_2
|
7
|
+
out << params[:parameter]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ParameterParser1Controller < Controller::Base
|
12
|
+
mandatory "-s", "Search expression"
|
13
|
+
def search
|
14
|
+
out << "Ok"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class OptionalMandatoryController < Controller::Base
|
19
|
+
def search
|
20
|
+
mandatory "-s", "Search expression"
|
21
|
+
out << "Ok"
|
22
|
+
end
|
23
|
+
|
24
|
+
def no_mandatory
|
25
|
+
out << "Ok"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ParameterPairingController < Controller::Base
|
30
|
+
optional "-e", "--expression", "Search expression"
|
31
|
+
|
32
|
+
def search_short
|
33
|
+
out << params[:expression]
|
34
|
+
end
|
35
|
+
|
36
|
+
def search_long
|
37
|
+
out << params[:e]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "test_helper.rb"
|
2
|
+
require "helpers/test_app"
|
3
|
+
require "fixtures/command_parser_fixtures"
|
4
|
+
|
5
|
+
class CommandProcessorTest < MiniTest::Spec
|
6
|
+
|
7
|
+
should "parse commands" do
|
8
|
+
assert_equal "Hello World", TestApp.run("command_parser hello").output
|
9
|
+
end
|
10
|
+
|
11
|
+
should "parse long parameter" do
|
12
|
+
assert_equal "Parameter", TestApp.run("command_parser hello_2 --parameter Parameter").output
|
13
|
+
end
|
14
|
+
|
15
|
+
should "force mandatory parameters" do
|
16
|
+
assert_raises(Lucie::RequestError){ TestApp.run("parameter_parser1 search") }
|
17
|
+
end
|
18
|
+
|
19
|
+
should "not give error when mandatory parameters are present" do
|
20
|
+
assert_equal "Ok", TestApp.run("parameter_parser1 search -s").output
|
21
|
+
end
|
22
|
+
|
23
|
+
should "give error, when method has mandatory parameter but another shouldn't throw in this case" do
|
24
|
+
assert_equal "Ok", TestApp.run("optional_mandatory search -s").output
|
25
|
+
assert_raises(Lucie::RequestError){ TestApp.run("optional_mandatory search") }
|
26
|
+
assert_equal "Ok", TestApp.run("optional_mandatory no_mandatory").output
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be able to pair parameters" do
|
30
|
+
assert_equal "some_string", TestApp.run("parameter_pairing search_short -e some_string").output
|
31
|
+
assert_equal "some_string", TestApp.run("parameter_pairing search_long --expression some_string").output
|
32
|
+
end
|
33
|
+
|
34
|
+
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,12 @@
|
|
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
|
+
|
6
|
+
require File.expand_path('../../lib/lucie.rb', __FILE__)
|
7
|
+
|
8
|
+
LUCIE_ROOT = File.expand_path File.dirname(__FILE__)
|
9
|
+
|
10
|
+
class MiniTest::Spec
|
11
|
+
include Lucie
|
12
|
+
end
|
@@ -0,0 +1,48 @@
|
|
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
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lucie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nucc
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-18 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: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mini_shoulda
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Command line utility framework
|
56
|
+
email:
|
57
|
+
- nucc@bteam.hu
|
58
|
+
executables:
|
59
|
+
- lucie
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/lucie
|
69
|
+
- lib/lucie.rb
|
70
|
+
- lib/lucie/app.rb
|
71
|
+
- lib/lucie/buffer.rb
|
72
|
+
- lib/lucie/command_line_parser.rb
|
73
|
+
- lib/lucie/controller/base.rb
|
74
|
+
- lib/lucie/exceptions.rb
|
75
|
+
- lib/lucie/snippets/template.rb
|
76
|
+
- lib/lucie/validators/base.rb
|
77
|
+
- lib/lucie/validators/mandatory_option.rb
|
78
|
+
- lib/lucie/validators/optional.rb
|
79
|
+
- lib/lucie/version.rb
|
80
|
+
- lucie.gemspec
|
81
|
+
- test/fixtures/command_parser_fixtures.rb
|
82
|
+
- test/functional/command_parser_test.rb
|
83
|
+
- test/functional/template_snippet_test.rb
|
84
|
+
- test/helpers/test_app.rb
|
85
|
+
- test/test_helper.rb
|
86
|
+
- test/unit/command_line_parser_test.rb
|
87
|
+
homepage: ''
|
88
|
+
licenses: []
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.0.0
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: ''
|
110
|
+
test_files:
|
111
|
+
- test/fixtures/command_parser_fixtures.rb
|
112
|
+
- test/functional/command_parser_test.rb
|
113
|
+
- test/functional/template_snippet_test.rb
|
114
|
+
- test/helpers/test_app.rb
|
115
|
+
- test/test_helper.rb
|
116
|
+
- test/unit/command_line_parser_test.rb
|