scripting 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/examples/command.rb +44 -0
- data/examples/simple.rb +4 -4
- data/lib/scripting/app_defaults.rb +1 -1
- data/lib/scripting/application.rb +39 -0
- data/lib/scripting/commands.rb +69 -0
- data/lib/scripting/options.rb +13 -4
- data/scripting.gemspec +8 -4
- data/spec/commands_spec.rb +67 -0
- data/spec/options_spec.rb +18 -1
- metadata +10 -21
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/examples/command.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path('../../lib/scripting', __FILE__)
|
2
|
+
|
3
|
+
my_app = Scripting::create_application do
|
4
|
+
plugin Scripting::AppDefaults
|
5
|
+
plugin Scripting::Commands
|
6
|
+
|
7
|
+
options do
|
8
|
+
end
|
9
|
+
|
10
|
+
switches do
|
11
|
+
self.banner = "Usage: #{File.basename(__FILE__)} [opts] command [args]"
|
12
|
+
end
|
13
|
+
|
14
|
+
command :echo do
|
15
|
+
description "Echo arguments to stdout"
|
16
|
+
work do |*args|
|
17
|
+
puts args.join(' ')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
command :add do
|
22
|
+
description "Add two arguments"
|
23
|
+
work do |a, b|
|
24
|
+
puts a.to_f + b.to_f
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
command :sum do
|
29
|
+
description "Sum all arguments"
|
30
|
+
work do |*args|
|
31
|
+
puts args.collect(&:to_f).inject(&:+)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
command :avg do
|
36
|
+
description "Average of all arguments"
|
37
|
+
work do |*args|
|
38
|
+
count = args.length
|
39
|
+
puts args.collect(&:to_f).inject(&:+) / count
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
my_app.run! ARGV if $0 == __FILE__
|
data/examples/simple.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path('../../lib/scripting', __FILE__)
|
2
2
|
|
3
|
-
|
3
|
+
my_app = Scripting::create_application do
|
4
4
|
plugin Scripting::AppDefaults
|
5
5
|
|
6
6
|
options do
|
@@ -24,9 +24,9 @@ MyApp = Scripting::create_application do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
work do
|
27
|
-
|
28
|
-
|
27
|
+
$stderr.puts options.message if options.stderr?
|
28
|
+
$stdout.puts options.message if options.stdout?
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
my_app.run! ARGV if $0 == __FILE__
|
@@ -2,6 +2,7 @@ require File.expand_path('../pluggable', __FILE__)
|
|
2
2
|
require File.expand_path('../parser', __FILE__)
|
3
3
|
require File.expand_path('../options', __FILE__)
|
4
4
|
require File.expand_path('../app_defaults', __FILE__)
|
5
|
+
require File.expand_path('../commands', __FILE__)
|
5
6
|
|
6
7
|
module Scripting
|
7
8
|
class Application
|
@@ -11,6 +12,7 @@ module Scripting
|
|
11
12
|
clear_switches!
|
12
13
|
clear_options!
|
13
14
|
clear_work!
|
15
|
+
clear_help!
|
14
16
|
end
|
15
17
|
|
16
18
|
def context
|
@@ -49,6 +51,19 @@ module Scripting
|
|
49
51
|
@work
|
50
52
|
end
|
51
53
|
|
54
|
+
def clear_help!
|
55
|
+
@help = [lambda { $stderr.puts @switches }]
|
56
|
+
end
|
57
|
+
|
58
|
+
def help &blk
|
59
|
+
@help << blk if block_given?
|
60
|
+
@help
|
61
|
+
end
|
62
|
+
|
63
|
+
def help!
|
64
|
+
@help.each(&:call)
|
65
|
+
end
|
66
|
+
|
52
67
|
def parse! args
|
53
68
|
switches.parse! args
|
54
69
|
args
|
@@ -63,6 +78,30 @@ module Scripting
|
|
63
78
|
end
|
64
79
|
end
|
65
80
|
|
81
|
+
# Creates a new Scripting::Application class instance receiving a block
|
82
|
+
# used to describe options, command line switches, and other traits.
|
83
|
+
#
|
84
|
+
# my_app = Scripting::create_application do
|
85
|
+
# plugin Scripting::AppDefaults
|
86
|
+
#
|
87
|
+
# options do
|
88
|
+
# message = "Hello World"
|
89
|
+
# stderr = false
|
90
|
+
# stdout = true
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# switches do
|
94
|
+
# on('--message=TEXT (default: #{options.message})') { |opt| options.message = opt }
|
95
|
+
# on('--[no]-stderr') { |opt| options.stderr = opt }
|
96
|
+
# on('--[no]-stdout') { |opt| options.stdout = opt }
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# work do
|
100
|
+
# $stderr.puts options.message if options.stderr?
|
101
|
+
# $stdout.puts options.message if options.stdout?
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
#
|
66
105
|
def self.create_application &blk
|
67
106
|
app = Class.new(Application).new
|
68
107
|
app.describe &blk
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Scripting
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
class Command
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize name
|
8
|
+
@name = name.to_s.downcase.to_sym
|
9
|
+
@description = nil
|
10
|
+
@work = lambda {} # noop by default
|
11
|
+
end
|
12
|
+
|
13
|
+
def describe &blk
|
14
|
+
instance_eval &blk if block_given?
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def description desc=nil
|
19
|
+
unless desc.nil?
|
20
|
+
@description = desc
|
21
|
+
end
|
22
|
+
@description
|
23
|
+
end
|
24
|
+
|
25
|
+
def work &blk
|
26
|
+
@work = blk if block_given?
|
27
|
+
@work
|
28
|
+
end
|
29
|
+
|
30
|
+
def run! *args
|
31
|
+
@work.call(*args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.instance_init(instance, *args)
|
36
|
+
instance.instance_eval do
|
37
|
+
options do
|
38
|
+
commands Hash.new
|
39
|
+
end
|
40
|
+
|
41
|
+
help do
|
42
|
+
$stderr.puts "\nAvailable commands:"
|
43
|
+
max_width = options.commands.keys.collect(&:length).max
|
44
|
+
options.commands.each do |k,v|
|
45
|
+
$stderr.puts sprintf(" %*s: %s", max_width, k, v.description)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
work do |*args|
|
50
|
+
name = args.shift.downcase.to_sym rescue nil
|
51
|
+
command = options.commands[name]
|
52
|
+
if command.nil?
|
53
|
+
help!
|
54
|
+
puts "\nCommand: #{name} is not known"
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
command.run! *args
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module InstanceMethods
|
64
|
+
def command name, &blk
|
65
|
+
options.commands[name] = Command.new(name).describe(&blk)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/scripting/options.rb
CHANGED
@@ -19,14 +19,23 @@ module Scripting
|
|
19
19
|
instance_variable_set(ivar, value)
|
20
20
|
end
|
21
21
|
|
22
|
-
def method_missing(name,
|
22
|
+
def method_missing(name, *args, &blk)
|
23
23
|
name = name.to_s
|
24
|
-
|
24
|
+
|
25
|
+
# predicate?
|
26
|
+
if name =~/\?$/
|
27
|
+
return !!self[name.chop]
|
28
|
+
end
|
29
|
+
|
30
|
+
# assignment=
|
31
|
+
if name =~ /=$/
|
32
|
+
name.chop!
|
33
|
+
end
|
25
34
|
|
26
35
|
if block_given?
|
27
36
|
self[name] = blk
|
28
|
-
elsif
|
29
|
-
self[name] =
|
37
|
+
elsif args.length > 0
|
38
|
+
self[name] = args.first
|
30
39
|
else
|
31
40
|
self[name]
|
32
41
|
end
|
data/scripting.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{scripting}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["sdeming"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-28}
|
13
13
|
s.description = %q{Simplified command line scripting tool}
|
14
14
|
s.email = %q{sdeming@makefile.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,16 +23,19 @@ Gem::Specification.new do |s|
|
|
23
23
|
"README.rdoc",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
|
+
"examples/command.rb",
|
26
27
|
"examples/simple.rb",
|
27
28
|
"lib/scripting.rb",
|
28
29
|
"lib/scripting/app_defaults.rb",
|
29
30
|
"lib/scripting/application.rb",
|
31
|
+
"lib/scripting/commands.rb",
|
30
32
|
"lib/scripting/options.rb",
|
31
33
|
"lib/scripting/parser.rb",
|
32
34
|
"lib/scripting/pluggable.rb",
|
33
35
|
"scripting.gemspec",
|
34
36
|
"spec/app_defaults_spec.rb",
|
35
37
|
"spec/application_spec.rb",
|
38
|
+
"spec/commands_spec.rb",
|
36
39
|
"spec/options_spec.rb",
|
37
40
|
"spec/pluggable_spec.rb",
|
38
41
|
"spec/spec_helper.rb"
|
@@ -40,19 +43,20 @@ Gem::Specification.new do |s|
|
|
40
43
|
s.homepage = %q{http://github.com/sdeming/scripting}
|
41
44
|
s.licenses = ["MIT"]
|
42
45
|
s.require_paths = ["lib"]
|
43
|
-
s.rubygems_version = %q{1.
|
46
|
+
s.rubygems_version = %q{1.6.1}
|
44
47
|
s.summary = %q{Simplified command line scripting tool}
|
45
48
|
s.test_files = [
|
49
|
+
"examples/command.rb",
|
46
50
|
"examples/simple.rb",
|
47
51
|
"spec/app_defaults_spec.rb",
|
48
52
|
"spec/application_spec.rb",
|
53
|
+
"spec/commands_spec.rb",
|
49
54
|
"spec/options_spec.rb",
|
50
55
|
"spec/pluggable_spec.rb",
|
51
56
|
"spec/spec_helper.rb"
|
52
57
|
]
|
53
58
|
|
54
59
|
if s.respond_to? :specification_version then
|
55
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
56
60
|
s.specification_version = 3
|
57
61
|
|
58
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Scripting::Commands do
|
4
|
+
it "should symbolize and downcase the command name" do
|
5
|
+
Scripting::Commands::Command.new(:testing).name.should == :testing
|
6
|
+
Scripting::Commands::Command.new(:Testing).name.should == :testing
|
7
|
+
Scripting::Commands::Command.new('testing').name.should == :testing
|
8
|
+
Scripting::Commands::Command.new("Testing").name.should == :testing
|
9
|
+
Scripting::Commands::Command.new("TESTING").name.should == :testing
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Scripting::Commands::Command do
|
14
|
+
before :each do
|
15
|
+
@stdout = ''
|
16
|
+
STDOUT.stub(:write) { |*args| @stdout << args.join }
|
17
|
+
|
18
|
+
@stderr = ''
|
19
|
+
STDERR.stub(:write) { |*args| @stderr << args.join }
|
20
|
+
|
21
|
+
@app = Scripting::create_application do
|
22
|
+
plugin Scripting::Commands
|
23
|
+
|
24
|
+
command :answer do
|
25
|
+
description "The answer to life, the universe, and everything"
|
26
|
+
work { puts 42 }
|
27
|
+
end
|
28
|
+
|
29
|
+
command :echo do
|
30
|
+
description "Echo args"
|
31
|
+
work { |*args| puts args.join(" ") }
|
32
|
+
end
|
33
|
+
|
34
|
+
command :add do
|
35
|
+
description "Add two numbers"
|
36
|
+
work { |a,b| puts a.to_f + b.to_f }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should populate the help text with details for each command" do
|
42
|
+
@app.help!
|
43
|
+
@stderr.should include("answer: The answer to life, the universe, and everything")
|
44
|
+
@stderr.should include("echo: Echo args")
|
45
|
+
@stderr.should include("add: Add two numbers")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should run the specified command" do
|
49
|
+
@app.run! 'answer'
|
50
|
+
@stdout.should include("42")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should send arguments to the specified command" do
|
54
|
+
@app.run! %w{add 4 8}
|
55
|
+
@stdout.should include("12")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should run the specified command as well as other work items" do
|
59
|
+
@app.describe do
|
60
|
+
work { puts "Hello world!" }
|
61
|
+
end
|
62
|
+
@app.run! %w{echo to infinity and beyond!}
|
63
|
+
@stdout.should include("to infinity and beyond!")
|
64
|
+
@stdout.should include("Hello world!")
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/spec/options_spec.rb
CHANGED
@@ -35,7 +35,24 @@ describe Scripting::Options do
|
|
35
35
|
opts.fourth.should == "4"
|
36
36
|
end
|
37
37
|
|
38
|
-
it "should
|
38
|
+
it "should treat predicates as truthy" do
|
39
|
+
opts = Scripting::Options.new
|
40
|
+
opts.a_true = true
|
41
|
+
opts.a_false = false
|
42
|
+
opts.a_nil = nil
|
43
|
+
opts.a_forty_two = 42
|
44
|
+
opts.a_hello = "hello"
|
45
|
+
opts.a_colon_hello = :hello
|
46
|
+
|
47
|
+
opts.a_true?.should be_true
|
48
|
+
opts.a_false?.should be_false
|
49
|
+
opts.a_nil?.should be_false
|
50
|
+
opts.a_forty_two?.should be_true
|
51
|
+
opts.a_hello?.should be_true
|
52
|
+
opts.a_colon_hello?.should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should assign blocks and call the block for each visit" do
|
39
56
|
opts = Scripting::Options.new
|
40
57
|
opts.block { true }
|
41
58
|
opts.block.should be_true
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 2
|
9
|
-
version: 0.1.2
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- sdeming
|
@@ -14,7 +10,7 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-28 00:00:00 -04:00
|
18
14
|
default_executable:
|
19
15
|
dependencies:
|
20
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,10 +20,6 @@ dependencies:
|
|
24
20
|
requirements:
|
25
21
|
- - ">="
|
26
22
|
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 2
|
29
|
-
- 5
|
30
|
-
- 0
|
31
23
|
version: 2.5.0
|
32
24
|
type: :development
|
33
25
|
prerelease: false
|
@@ -39,10 +31,6 @@ dependencies:
|
|
39
31
|
requirements:
|
40
32
|
- - ~>
|
41
33
|
- !ruby/object:Gem::Version
|
42
|
-
segments:
|
43
|
-
- 1
|
44
|
-
- 5
|
45
|
-
- 2
|
46
34
|
version: 1.5.2
|
47
35
|
type: :development
|
48
36
|
prerelease: false
|
@@ -54,8 +42,6 @@ dependencies:
|
|
54
42
|
requirements:
|
55
43
|
- - ">="
|
56
44
|
- !ruby/object:Gem::Version
|
57
|
-
segments:
|
58
|
-
- 0
|
59
45
|
version: "0"
|
60
46
|
type: :development
|
61
47
|
prerelease: false
|
@@ -76,16 +62,19 @@ files:
|
|
76
62
|
- README.rdoc
|
77
63
|
- Rakefile
|
78
64
|
- VERSION
|
65
|
+
- examples/command.rb
|
79
66
|
- examples/simple.rb
|
80
67
|
- lib/scripting.rb
|
81
68
|
- lib/scripting/app_defaults.rb
|
82
69
|
- lib/scripting/application.rb
|
70
|
+
- lib/scripting/commands.rb
|
83
71
|
- lib/scripting/options.rb
|
84
72
|
- lib/scripting/parser.rb
|
85
73
|
- lib/scripting/pluggable.rb
|
86
74
|
- scripting.gemspec
|
87
75
|
- spec/app_defaults_spec.rb
|
88
76
|
- spec/application_spec.rb
|
77
|
+
- spec/commands_spec.rb
|
89
78
|
- spec/options_spec.rb
|
90
79
|
- spec/pluggable_spec.rb
|
91
80
|
- spec/spec_helper.rb
|
@@ -103,7 +92,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
92
|
requirements:
|
104
93
|
- - ">="
|
105
94
|
- !ruby/object:Gem::Version
|
106
|
-
hash:
|
95
|
+
hash: 913442681717536161
|
107
96
|
segments:
|
108
97
|
- 0
|
109
98
|
version: "0"
|
@@ -112,20 +101,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
101
|
requirements:
|
113
102
|
- - ">="
|
114
103
|
- !ruby/object:Gem::Version
|
115
|
-
segments:
|
116
|
-
- 0
|
117
104
|
version: "0"
|
118
105
|
requirements: []
|
119
106
|
|
120
107
|
rubyforge_project:
|
121
|
-
rubygems_version: 1.
|
108
|
+
rubygems_version: 1.6.1
|
122
109
|
signing_key:
|
123
110
|
specification_version: 3
|
124
111
|
summary: Simplified command line scripting tool
|
125
112
|
test_files:
|
113
|
+
- examples/command.rb
|
126
114
|
- examples/simple.rb
|
127
115
|
- spec/app_defaults_spec.rb
|
128
116
|
- spec/application_spec.rb
|
117
|
+
- spec/commands_spec.rb
|
129
118
|
- spec/options_spec.rb
|
130
119
|
- spec/pluggable_spec.rb
|
131
120
|
- spec/spec_helper.rb
|