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 CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -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
- MyApp = Scripting::create_application do
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
- STDERR.puts options.message if options.stderr
28
- STDOUT.puts options.message if options.stdout
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
- MyApp.run! ARGV
32
+ my_app.run! ARGV if $0 == __FILE__
@@ -18,8 +18,8 @@ module Scripting
18
18
  end
19
19
 
20
20
  on_tail('-h', '--help', "Help text") do
21
- STDERR.puts self
22
21
  context.clear_work!
22
+ context.help!
23
23
  terminate
24
24
  end
25
25
  end
@@ -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
@@ -19,14 +19,23 @@ module Scripting
19
19
  instance_variable_set(ivar, value)
20
20
  end
21
21
 
22
- def method_missing(name, value = nil, &blk)
22
+ def method_missing(name, *args, &blk)
23
23
  name = name.to_s
24
- name.chop! if name =~ /=$/
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 !value.nil?
29
- self[name] = value
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.1.2"
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-09}
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.3.7}
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 assign blocks and call for each visit" do
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: false
5
- segments:
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-09 00:00:00 -05:00
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: -4157022527390188045
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.3.7
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