commandeer 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ test.rb
2
+ Gemfile.lock
3
+ .rvmrc
4
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1 @@
1
+ source "http://rubygems.org"
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/commandeer', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["John E. Vincent"]
6
+ gem.email = ["lusis.org+github.com@gmail.com"]
7
+ gem.description = %q{Class-based CLI utility}
8
+ gem.summary = "Commandeer allows you to make any class a git style command or subcommand"
9
+ gem.homepage = "https://github.com/lusis/commandeer"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "commandeer"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Commandeer::VERSION
17
+ end
data/lib/commandeer.rb ADDED
@@ -0,0 +1,138 @@
1
+ module Commandeer
2
+ VERSION = "0.0.1"
3
+
4
+ @commands = {}
5
+
6
+ def self.commands
7
+ @commands
8
+ end
9
+
10
+ def self.reset!
11
+ @commands = {}
12
+ end
13
+
14
+ def self.add_command(opts)
15
+ command = opts[:command].to_s
16
+ parent = opts[:parent].to_s
17
+ klass = opts[:klass].to_s
18
+ parser = opts[:parser].to_s
19
+ h = {}
20
+ case parent
21
+ when "top"
22
+ h = {:parser => parser, :klass => klass}
23
+ @commands[command] ||= {}
24
+ @commands[command].merge!(h)
25
+ else
26
+ h[command] = {:parser => parser, :klass => klass}
27
+ @commands[parent] ||= {}
28
+ @commands[parent]["subcommands"] ||= {}
29
+ @commands[parent]["subcommands"].merge!(h)
30
+ end
31
+ end
32
+
33
+ def self.parse!(args, script_name=__FILE__)
34
+ @script_name = script_name
35
+ # We haz no commands registered
36
+ if @commands.size == 0
37
+ puts "No known commands!"
38
+ exit(1)
39
+ end
40
+
41
+ # No args. Let's show what we have registered
42
+ if (args.size == 0) || (args[0] =~ /^-/)
43
+ puts "Usage: #{@script_name} [command options] or [command subcommand options]\n\n"
44
+ puts "Registered commands\n"
45
+ @commands.each do |command, options|
46
+ next if (command==:klass || command==:parser)
47
+ puts " #{command}"
48
+ unless options["subcommands"].nil?
49
+ puts " subcommands:"
50
+ options["subcommands"].each do |sub, opts|
51
+ puts " #{sub}"
52
+ end
53
+ end
54
+ end
55
+ exit
56
+ end
57
+
58
+ # Workflow
59
+ # Check if current scope is a valid command
60
+ scope = args.shift
61
+
62
+ # set the current command or return help
63
+ @commands.has_key?(scope) ? command=@commands[scope] : (puts "Unknown command: #{scope}\n"; self.parse!("-h"))
64
+
65
+ subcommands = command["subcommands"]
66
+
67
+ if subcommands
68
+ output = ''
69
+ output << "`#{scope}` has the following registered subcommands:\n"
70
+ subcommands.keys.each {|x| output << "\t#{x}" }
71
+ puts output
72
+ end if args.size == 0
73
+
74
+ if command.has_key?(:parser)
75
+ output = ''
76
+ output << "\n`#{scope}` also takes options"
77
+ output << "\ntry running '#{@script_name} #{scope} --help'"
78
+ puts output
79
+ end if args.size == 0
80
+
81
+ if args.size > 0
82
+ if subcommands.has_key?(args[0])
83
+ # Okay so the next arg is a registered subcommand. Let's shift args
84
+ new_scope = args.shift
85
+ warning =<<-EOF
86
+ Warning! `#{new_scope}` is a registered subcommand for `#{scope}` but `#{scope}` also takes options.
87
+ This can cause unexpected results if `#{scope}` has an option named `#{new_scope}`
88
+ EOF
89
+ puts warning
90
+
91
+ parser = subcommands[new_scope][:parser]
92
+ klass = subcommands[new_scope][:klass]
93
+ else
94
+ parser = command[:parser]
95
+ klass = command[:klass]
96
+ end
97
+ else
98
+ parser = command[:parser]
99
+ klass = command[:klass]
100
+ end
101
+ begin
102
+ handler = constantize(klass)
103
+ handler.send parser.to_sym, args
104
+ rescue NoMethodError
105
+ if command[:parser]
106
+ puts "#{handler}##{parser} method does not exist"
107
+ end
108
+ rescue Exception => e
109
+ puts e.message
110
+ end
111
+ end
112
+
113
+ # Ripped from the ActiveSupport headlines!
114
+ def self.constantize(camel_cased_word)
115
+ names = camel_cased_word.split('::')
116
+ names.shift if names.empty? || names.first.empty?
117
+
118
+ constant = Object
119
+ names.each do |name|
120
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
121
+ end
122
+ constant
123
+ end
124
+
125
+ def self.included(base)
126
+ base.extend ClassMethods
127
+ end
128
+
129
+ module ClassMethods
130
+ def command(command, opts={})
131
+ opts[:command] = command
132
+ opts[:parent] ||= :top
133
+ opts[:klass] ||= self.to_s
134
+ opts[:parser] ||= :parse
135
+ Commandeer.add_command(opts)
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,11 @@
1
+ class Foo
2
+ def self.zing(args)
3
+ puts args
4
+ end
5
+ end
6
+
7
+ class OverRideAll
8
+ include Commandeer
9
+
10
+ command "random", :parent => 'override', :klass => "Foo", :parser => "zing"
11
+ end
@@ -0,0 +1,28 @@
1
+ require 'optparse'
2
+
3
+ class PrimaryCommand
4
+ include Commandeer
5
+
6
+ command "foo"
7
+
8
+ def self.parse(args)
9
+ options = {}
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "foo [options]"
12
+
13
+ opts.on("-f", "--foo FOOTHING", "The option for foo") do |f|
14
+ options[:f] = f
15
+ end
16
+ opts.on_tail("-h", "--help", "foo help") do
17
+ puts opts
18
+ exit(1)
19
+ end
20
+ end
21
+ begin
22
+ opts.parse!(args)
23
+ rescue OptionParser::InvalidOption => e
24
+ puts e
25
+ puts opts
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ module Name
2
+ class Spaced
3
+ include Commandeer
4
+
5
+ command "namespaced"
6
+
7
+ def self.parse(args)
8
+ puts args
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,55 @@
1
+ require 'optparse'
2
+
3
+ class Parent
4
+ include Commandeer
5
+
6
+ command "parent"
7
+
8
+ def self.parse(args)
9
+ options = {}
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "parent [options]"
12
+
13
+ opts.on("-p", "--parent PARENTTHING", "The option for parent") do |f|
14
+ options[:f] = f
15
+ end
16
+ opts.on_tail("-h", "--help", "parent help") do
17
+ puts opts
18
+ exit(1)
19
+ end
20
+ end
21
+ begin
22
+ opts.parse!(args)
23
+ rescue OptionParser::InvalidOption => e
24
+ puts e
25
+ puts opts
26
+ end
27
+ end
28
+ end
29
+
30
+ class Child
31
+ include Commandeer
32
+
33
+ command "child", :parent => 'parent'
34
+
35
+ def self.parse(args)
36
+ options = {}
37
+ opts = OptionParser.new do |opts|
38
+ opts.banner = "child [options]"
39
+
40
+ opts.on("-c", "--child CHILDTHING", "The option for child") do |f|
41
+ options[:f] = f
42
+ end
43
+ opts.on_tail("-h", "--help", "child help") do
44
+ puts opts
45
+ exit(1)
46
+ end
47
+ end
48
+ begin
49
+ opts.parse!(args)
50
+ rescue OptionParser::InvalidOption => e
51
+ puts e
52
+ puts opts
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ require 'optparse'
2
+
3
+ class SubCommand
4
+ include Commandeer
5
+
6
+ command "bar", :parent => 'fakeparent'
7
+
8
+ def self.parse(args)
9
+ options = {}
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "bar [options]"
12
+
13
+ opts.on("-b", "--bar BARTHING", "The option for bar") do |f|
14
+ options[:f] = f
15
+ end
16
+ opts.on_tail("-h", "--help", "bar help") do
17
+ puts opts
18
+ exit(1)
19
+ end
20
+ end
21
+ begin
22
+ opts.parse!(args)
23
+ rescue OptionParser::InvalidOption => e
24
+ puts e
25
+ puts opts
26
+ end
27
+ end
28
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
2
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "test")))
3
+ require 'commandeer'
4
+ require 'minitest/autorun'
File without changes
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: commandeer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - John E. Vincent
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-11-28 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Class-based CLI utility
17
+ email:
18
+ - lusis.org+github.com@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - commandeer.gemspec
29
+ - lib/commandeer.rb
30
+ - test/helpers/all_override.rb
31
+ - test/helpers/command.rb
32
+ - test/helpers/namespaced.rb
33
+ - test/helpers/sub_of_real_command.rb
34
+ - test/helpers/subcommand.rb
35
+ - test/test_commands.rb
36
+ - test/test_helper.rb
37
+ - test/test_output.rb
38
+ homepage: https://github.com/lusis/commandeer
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.6
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Commandeer allows you to make any class a git style command or subcommand
65
+ test_files: []
66
+