gestopft 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.
@@ -0,0 +1,8 @@
1
+ # vim:set ft=ruby:
2
+
3
+ Autotest.add_hook :initialize do |autotest|
4
+ autotest.add_mapping %r{lib/.*\.rb$} do |f, m|
5
+ Dir.glob "spec/**/*.rb"
6
+ end
7
+ end
8
+
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ --fail-fast
4
+
@@ -0,0 +1,38 @@
1
+ = gestopft
2
+
3
+ == Description
4
+
5
+ Framework for CLI Application (like {App::CLI}[http://search.cpan.org/dist/App-CLI/])
6
+
7
+
8
+ == Installation
9
+
10
+ === Archive
11
+
12
+ rake install
13
+
14
+ === Gem
15
+
16
+ gem install gestopft
17
+
18
+
19
+ == Synopsis
20
+
21
+ require "gestopft"
22
+
23
+ class Echo < Gestopft::App
24
+ option :verbose, "print debug messages."
25
+
26
+ def echo(message)
27
+ puts "Echo#echo is invoked." if @options[:verbose]
28
+ puts message
29
+ end
30
+ end
31
+
32
+
33
+ == Copyright
34
+
35
+ Copyright:: Copyright (c) 2011 AOKI,Hanae
36
+ Author:: AOKI,Hanae (aereal, trasty.loose@gmail.com)
37
+ License:: Ruby's
38
+
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "gestopft/core_ext"
4
+
5
+ module Gestopft
6
+ VERSION = '0.0.1'
7
+
8
+ module Constants
9
+ class Error < ::StandardError; end
10
+ class NotSatisfiedRequirements < Error; end
11
+ end
12
+
13
+ autoload :App, 'gestopft/app'
14
+ autoload :Option, 'gestopft/option'
15
+ end
16
+
@@ -0,0 +1,101 @@
1
+ # -*- encoding: utf-8
2
+
3
+ class Gestopft::App
4
+ include Gestopft::Constants
5
+
6
+ def self.expectation
7
+ @expectation ||= []
8
+ end
9
+
10
+ def self.option(name, *args)
11
+ desc = args.find {|arg| arg.is_a? String }
12
+ params = args.find {|arg| arg.is_a? Array }
13
+ expectation << Gestopft::Option.new(name, {
14
+ :desc => desc,
15
+ :params => params
16
+ })
17
+ end
18
+
19
+ def self.run(argv)
20
+ new(argv).parse_arg.dispatch
21
+ end
22
+
23
+ def self.commands
24
+ public_instance_methods - Gestopft::App.public_instance_methods
25
+ end
26
+
27
+ attr_reader :options
28
+
29
+ def initialize(argv)
30
+ @argv = argv.option_args
31
+ @expectation = self.class.expectation
32
+ @options = {}
33
+ @commands = self.class.commands.map {|cmd| method(cmd) }
34
+ end
35
+
36
+ def parse_arg
37
+ @expectation.each do |opt|
38
+ if opt.require_args?
39
+ if (
40
+ pos = @argv.find_index(opt.option_name) and
41
+ params = @argv[pos + 1, opt.arity] and
42
+ params.none? {|param| param.option? } and
43
+ params.size == opt.arity
44
+ )
45
+ @options[opt.name] = params
46
+ else
47
+ raise NotSatisfiedRequirements
48
+ end
49
+ else
50
+ @options[opt.name] = opt.option_name
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ def dispatch
57
+ argv = @argv.reject {|arg| arg.option? }
58
+ @commands.each do |cmd|
59
+ if pos = argv.find_index(cmd.name.to_s)
60
+ params = argv[pos + 1, cmd.arity.abs]
61
+ return cmd.call(*params)
62
+ end
63
+ end
64
+ self
65
+ end
66
+
67
+ def help_message
68
+ msg = []
69
+ msg << <<-BANNER.strip
70
+ Usage:
71
+ $ #{File.basename($0)} [options] #{"command [args, ...]" unless @commands.empty?}
72
+ BANNER
73
+
74
+ unless @expectation.empty?
75
+ msg << "Options: "
76
+ @expectation.each do |opt|
77
+ line = ["\t", opt.option_name]
78
+ line << opt.params.map {|param|
79
+ param.to_s.upcase
80
+ }.join(' ') unless opt.params.empty?
81
+ line << opt.desc unless opt.desc.empty?
82
+ msg << line.join(" ")
83
+ end
84
+ end
85
+
86
+ unless @commands.empty?
87
+ msg << <<-COMMANDS.strip
88
+ Commands:
89
+ #{@commands.map {|cmd| cmd.name }.join(' ')}
90
+ COMMANDS
91
+ end
92
+
93
+ msg << ""
94
+ msg.join("\n\n")
95
+ end
96
+
97
+ def __default__
98
+ STDIN.puts help_message
99
+ end
100
+ end
101
+
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require "pathname"
4
+
5
+ dir = Pathname.new(__FILE__).expand_path.parent + 'core_ext/'
6
+
7
+ dir.each_child do |entry|
8
+ require entry.to_s
9
+ end
10
+
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ module ArrayExtension
4
+ def option_args
5
+ pos = index('--') ? slice(0...pos) : dup
6
+ end
7
+ end
8
+
9
+ Array.send(:include, ArrayExtension)
10
+
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module StringExtention
4
+ def option?
5
+ /^--[-a-zA-Z0-9]+$/ === self
6
+ end
7
+
8
+ def to_option
9
+ (slice(0..2) == '--' ? '' : '--') + strip.gsub('_', '-')
10
+ end
11
+ end
12
+
13
+ String.send(:include, StringExtention)
14
+
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ module SymbolExtension
4
+ def to_option
5
+ to_s.to_option
6
+ end
7
+ end
8
+
9
+ Symbol.send(:include, SymbolExtension)
10
+
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ class Gestopft::Option
4
+ attr_reader :name, :params, :description
5
+ alias_method :desc, :description
6
+
7
+ def initialize(name, args={})
8
+ @name = name
9
+ @params = args[:params] || []
10
+ @description = args[:desc] || args[:description] || ""
11
+ end
12
+
13
+ def option_name
14
+ @name.to_option
15
+ end
16
+
17
+ def require_args?
18
+ !@params.empty?
19
+ end
20
+
21
+ def arity
22
+ @params.size
23
+ end
24
+ end
25
+
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ # vim:set ft=ruby:
3
+
4
+ require "gestopft"
5
+
6
+ include Gestopft::Constants
7
+
8
+ describe Gestopft::Option do
9
+ subject do
10
+ Gestopft::Option.new(:my_option, :desc => "my description")
11
+ end
12
+
13
+ it "#option_name is option string." do
14
+ subject.option_name.should == '--my-option'
15
+ end
16
+
17
+ context "when given a description." do
18
+ it "#desc[ription] is the description about the option." do
19
+ subject.desc.should == "my description"
20
+ subject.description.should == "my description"
21
+ end
22
+ end
23
+
24
+ context "when does not given a description." do
25
+ subject do
26
+ Gestopft::Option.new(:my_option)
27
+ end
28
+
29
+ it "#desc[ription] is empty." do
30
+ subject.desc.should be_empty
31
+ subject.description.should be_empty
32
+ end
33
+ end
34
+
35
+ context "which requires parameters." do
36
+ subject do
37
+ Gestopft::Option.new(:delay, :params => %w(minute))
38
+ end
39
+
40
+ it "#require_args? is true" do
41
+ subject.require_args?.should be_true
42
+ end
43
+
44
+ it "#arity is the arity of option." do
45
+ subject.arity.should == 1
46
+ end
47
+ end
48
+
49
+ context "which requires no parameter." do
50
+ subject do
51
+ Gestopft::Option.new(:verbose)
52
+ end
53
+
54
+ it "#require_args? is false" do
55
+ subject.require_args?.should be_false
56
+ end
57
+
58
+ it "#arity is 0." do
59
+ subject.arity.should == 0
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,83 @@
1
+ # -*- coding: utf-8 -*-
2
+ # vim: set ft=ruby:
3
+
4
+ require "gestopft"
5
+
6
+ include Gestopft::Constants
7
+
8
+ describe Gestopft::App do
9
+ subject do
10
+ Class.new(Gestopft::App)
11
+ end
12
+
13
+ context "given a option which requires no arguments." do
14
+ before :all do
15
+ subject.module_eval do
16
+ option :with_no_args
17
+ end
18
+ end
19
+
20
+ it "has a option which given." do
21
+ subject.run(%w(--with-no-args)).options.
22
+ should include(:with_no_args)
23
+ end
24
+
25
+ it "does not have a option which does not given." do
26
+ subject.run(%w(--with-no-args)).options.
27
+ should_not include(:does_not_given)
28
+ end
29
+
30
+ it "succeeds when given a option which requires no arguments." do
31
+ expect { subject.run(%w(--with-no-args)) }.
32
+ should_not raise_error(Error)
33
+ end
34
+
35
+ it "succeeds when not given a option which is required." do
36
+ expect { subject.run([]) }.
37
+ should_not raise_error(NotSatisfiedRequirements)
38
+ end
39
+ end
40
+
41
+ context "a option which require a argument." do
42
+ before :all do
43
+ subject.module_eval do
44
+ option :delay, [:minute]
45
+ end
46
+ end
47
+
48
+ it "has a option which given with taken parameter." do
49
+ subject.run(%w(--delay 5)).options.
50
+ should include(:delay => ['5'])
51
+ end
52
+
53
+ it "does not have a option which given without any arguments." do
54
+ expect { subject.run(%w(--delay)) }.
55
+ should raise_error(NotSatisfiedRequirements)
56
+ end
57
+ end
58
+
59
+ context "when defined sub-commands" do
60
+ before do
61
+ subject.module_eval do
62
+ def update
63
+ :update
64
+ end
65
+ end
66
+ end
67
+
68
+ it ".commands is a array of available commands." do
69
+ subject.commands.should == [:update]
70
+ end
71
+
72
+ it "#dispatch return value which of sub-command's" do
73
+ subject.new(%w(update)).dispatch.should == subject.new([]).update
74
+ end
75
+ end
76
+
77
+ context "when not defined sub-commands" do
78
+ it ".commands is empty array." do
79
+ subject.commands.should be_empty
80
+ end
81
+ end
82
+ end
83
+
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gestopft
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors: []
8
+
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-18 00:00:00 +09:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description:
18
+ email: trasty.loose@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - README.rdoc
27
+ - .autotest
28
+ - .rspec
29
+ - lib/gestopft/core_ext/array.rb
30
+ - lib/gestopft/core_ext/symbol.rb
31
+ - lib/gestopft/core_ext/string.rb
32
+ - lib/gestopft/app.rb
33
+ - lib/gestopft/option.rb
34
+ - lib/gestopft/core_ext.rb
35
+ - lib/gestopft.rb
36
+ - spec/gestopft/option_spec.rb
37
+ - spec/gestopft_spec.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/aereal/gestopft
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.6.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Framework for CLI Application
66
+ test_files: []
67
+