rcoli 0.5.0

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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+
3
+ pkg
4
+
5
+ test
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rcoli (0.5.0)
5
+ highline (~> 1.6.11)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ highline (1.6.15)
11
+ rake (10.0.3)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ rake
18
+ rcoli!
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ RCoLi
2
+ =====
3
+
4
+ Library for development of command line applications in Ruby.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => :build
@@ -0,0 +1,12 @@
1
+ def setter(name)
2
+ define_method(name) do |value|
3
+ ivar = "@#{name}"
4
+ instance_variable_set(ivar, value)
5
+ end
6
+
7
+ define_method("value_of_#{name}") do
8
+ ivar = "@#{name}"
9
+ instance_variable_get(ivar).to_s
10
+ end
11
+
12
+ end
data/lib/rcoli/help.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'erb'
2
+
3
+ module RCoLi
4
+
5
+ module Help
6
+
7
+ def help
8
+ puts template 'help'
9
+ end
10
+
11
+ def template(name)
12
+ ERB.new(File.read(File.join(File.dirname(__FILE__), 'templates', "#{name}.erb")), nil, '-').result binding
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,190 @@
1
+ class InvalidCommand < Exception
2
+ end
3
+
4
+ module RCoLi
5
+
6
+ module CommandContainer
7
+
8
+ attr_accessor :parent
9
+
10
+ def action(&block)
11
+ @action = block
12
+ end
13
+
14
+ def get_action
15
+ @action
16
+ end
17
+
18
+ def command(name, &block)
19
+ obj = Command.new(name)
20
+ obj.parent = self
21
+ block.call(obj)
22
+ commands << obj
23
+ end
24
+
25
+ def commands
26
+ (@commands ||= [])
27
+ end
28
+
29
+ def options
30
+ (@options ||= [])
31
+ end
32
+
33
+ def switch(names, &block)
34
+ obj = Switch.new(names)
35
+ block.call(obj) if block_given?
36
+ options << obj
37
+ end
38
+
39
+ def flag(names, &block)
40
+ obj = Flag.new(names)
41
+ block.call(obj) if block_given?
42
+ options << obj
43
+ end
44
+
45
+ def parse_args(args, result)
46
+ return if args.empty?
47
+ arg = args.delete_at(0)
48
+ if (is_option? arg)
49
+ if (option = find_option(arg))
50
+ if (option.is_a? Flag)
51
+ raise InvalidCommand, "Flag #{arg} is missing a value" if args.empty?
52
+ value = args.delete_at(0)
53
+ else
54
+ value = true
55
+ end
56
+ target = self.parent ? :options : :global_options
57
+ option.keys.each{|key| result.send(target)[key] = value}
58
+ else
59
+ raise InvalidCommand, "#'{arg}' is not a valid option"
60
+ end
61
+ else
62
+ if (cmd = find_command(arg))
63
+ result.command = cmd
64
+ cmd.parse_args(args, result)
65
+ elsif (commands.empty?)
66
+ result.arguments << arg
67
+ else
68
+ raise InvalidCommand, "'#{arg}' is not a valid #{@name} command"
69
+ end
70
+ end
71
+ parse_args(args, result)
72
+ end
73
+
74
+ private
75
+
76
+ def find_option(name)
77
+ options.find{|opt| opt.correspond?(name)}
78
+ end
79
+
80
+ def find_command(name)
81
+ commands.find{|command| command.value_of_name.eql? name}
82
+ end
83
+
84
+ def is_option?(value)
85
+ value.start_with?('-')
86
+ end
87
+
88
+ end
89
+
90
+ module Option
91
+
92
+ setter :description
93
+
94
+ def initialize(names)
95
+ @s_name = names[:short]
96
+ @l_name = names[:long]
97
+ end
98
+
99
+ def keys
100
+ [@s_name, @l_name].compact
101
+ end
102
+
103
+ def help_keys
104
+ result = []
105
+ result << "-#{@s_name}" if @s_name
106
+ result << "--#{@l_name}" if @l_name
107
+ result
108
+ end
109
+
110
+ def correspond?(value)
111
+ return (value.sub('-','').eql? @s_name or value.sub('--','').eql? @l_name)
112
+ end
113
+
114
+ end
115
+
116
+ class Switch
117
+
118
+ include Option
119
+
120
+ end
121
+
122
+ class Flag
123
+
124
+ include Option
125
+
126
+ setter :default_value
127
+ setter :arg_name
128
+
129
+ end
130
+
131
+ class Command
132
+
133
+ setter :name
134
+ setter :summary
135
+ setter :description
136
+ setter :syntax
137
+
138
+ def initialize(name)
139
+ @name = name
140
+ end
141
+
142
+ include CommandContainer
143
+
144
+ end
145
+
146
+ class Program
147
+
148
+ setter :name
149
+ setter :author
150
+ setter :version
151
+ setter :description
152
+
153
+ include Help
154
+ include CommandContainer
155
+
156
+ def execute(args, context)
157
+ result = ParsedArgs.new
158
+ parse_args(args, result)
159
+ if result.command
160
+ action = result.command.get_action
161
+ context.instance_exec(result.global_options, result.options, result.arguments, &action)
162
+ else
163
+ say "Display UI"
164
+ end
165
+ end
166
+
167
+ end
168
+
169
+
170
+ class ParsedArgs
171
+
172
+ attr_reader :global_options
173
+ attr_reader :options
174
+ attr_reader :arguments
175
+
176
+ attr_accessor :command
177
+
178
+ def initialize
179
+ @global_options = {}
180
+ @options = {}
181
+ @arguments = []
182
+ end
183
+
184
+ def no_command?
185
+ return @command.nil?
186
+ end
187
+
188
+ end
189
+
190
+ end
@@ -0,0 +1,22 @@
1
+ <%= $terminal.color "NAME", :bold %>:
2
+ <%= @name %>
3
+
4
+ <%= $terminal.color "VERSION", :bold %>:
5
+ <%= @version %>
6
+
7
+ <%= $terminal.color "DESCRIPTION", :bold %>:
8
+ <%= @description %>
9
+
10
+ <%= $terminal.color "COMMANDS", :bold %>:
11
+ <% @commands.sort{|a,b| a.value_of_name <=> b.value_of_name}.each do |c| -%>
12
+ <%= "%-20s %s" % [c.value_of_name, c.value_of_description] %>
13
+ <% end %>
14
+
15
+ <% unless @options.empty? -%>
16
+ <%= $terminal.color "GLOBAL OPTIONS", :bold %>:
17
+ <% for option in @options -%>
18
+
19
+ <%= option.help_keys.join ', ' %>
20
+ <%= option.value_of_description %>
21
+ <% end -%>
22
+ <% end -%>
@@ -0,0 +1,5 @@
1
+ module RCoLi
2
+
3
+ VERSION = '0.5.0'
4
+
5
+ end
data/lib/rcoli.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'highline/import'
2
+ require 'rcoli/extensions'
3
+ require 'rcoli/help'
4
+ require 'rcoli/model'
5
+
6
+
7
+ @program = RCoLi::Program.new
8
+
9
+ def application(id, &block)
10
+ @program.name id
11
+ @program.command(:help) do |c|
12
+ c.description "Display help documentation"
13
+ c.action do |global_opts, opts, args|
14
+ @program.help
15
+ end
16
+ end
17
+ @program.instance_eval &block
18
+ end
19
+
20
+ at_exit {
21
+ begin
22
+ @program.execute(ARGV, self)
23
+ rescue InvalidCommand => e
24
+ say "#{@program.value_of_name}: #{e.message}. See '#{@program.value_of_name} --help'"
25
+ end
26
+
27
+ }
data/rcoli.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rcoli/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rcoli"
7
+ s.version = RCoLi::VERSION
8
+ s.authors = ["Jiri Pisa"]
9
+ s.email = ["jirka.pisa@gmail.com"]
10
+ s.homepage = "http://jiripisa.com"
11
+ s.summary = "The complete solution for commandline application written in ruby."
12
+ s.description = "The complete solution for commandline application written in ruby."
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_runtime_dependency("highline", "~> 1.6.11")
18
+
19
+ s.add_development_dependency("rake")
20
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rcoli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jiri Pisa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: highline
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.11
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.11
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
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
+ description: The complete solution for commandline application written in ruby.
47
+ email:
48
+ - jirka.pisa@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - Gemfile.lock
56
+ - README.md
57
+ - Rakefile
58
+ - lib/rcoli.rb
59
+ - lib/rcoli/extensions.rb
60
+ - lib/rcoli/help.rb
61
+ - lib/rcoli/model.rb
62
+ - lib/rcoli/templates/help.erb
63
+ - lib/rcoli/version.rb
64
+ - rcoli.gemspec
65
+ homepage: http://jiripisa.com
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ segments:
78
+ - 0
79
+ hash: -1633884952265524071
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ segments:
87
+ - 0
88
+ hash: -1633884952265524071
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 1.8.24
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: The complete solution for commandline application written in ruby.
95
+ test_files: []