scripting 0.1.2 → 0.2.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/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