commandant 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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ doc
23
+ .yardoc
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rein Henrichs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = commander
2
+
3
+ The simplest possible command line subcommand tool. It provides about half of
4
+ what you want and none of what you don't. If you don't like it, don't use it.
5
+
6
+ == Example:
7
+
8
+ #!/usr/bin/env ruby -rubygems
9
+ require 'commander'
10
+ include Commander
11
+
12
+ command :hello do
13
+ puts "Hello, World!"
14
+ end
15
+
16
+ command :argprint do |args| # Array of arguments, like ARGV
17
+ puts args
18
+ end
19
+
20
+ run
21
+
22
+ == Note on Patches/Pull Requests
23
+
24
+ * Fork the project.
25
+ * Make your feature addition or bug fix.
26
+ * Add tests for it. This is important so I don't break it in a
27
+ future version unintentionally.
28
+ * Commit, do not mess with rakefile, version, or history.
29
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
30
+ * Send me a pull request. Bonus points for topic branches.
31
+
32
+ == Copyright
33
+
34
+ Copyright (c) 2010 Rein Henrichs. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "commandant"
8
+ gem.summary = %Q{A simple library for writing commands with subcommands (like git)}
9
+ gem.email = "reinh@reinh.com"
10
+ gem.homepage = "http://github.com/reinh/commandant"
11
+ gem.authors = ["Rein Henrichs"]
12
+ gem.add_development_dependency "rspec", ">= 1.2.9"
13
+ gem.add_development_dependency "yard", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ spec.rcov_opts = ['--exclude /Library,spec/'] # not excluding /Library for some reason"
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ begin
39
+ require 'yard'
40
+ YARD::Rake::YardocTask.new
41
+ rescue LoadError
42
+ task :yard do
43
+ abort "YARD is not available. In order to run yard, you must: sudo gem install yard"
44
+ end
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/lib/commandant.rb ADDED
@@ -0,0 +1,76 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require 'commandant/command'
3
+
4
+ module Commandant
5
+ COMMANDS = {}
6
+
7
+ class UnknownCommand < NameError
8
+ def initialize(name); super "Unknown command `#{name}`" end
9
+ end
10
+
11
+ # Call a given command by name
12
+ #
13
+ # @param [Symbol] name the name of the command to be called
14
+ # @param [Array] args the command's arguments
15
+ # @raise [UnknownCommand] attempt to call a command that does not exist
16
+ def self.call(name, args=nil)
17
+ raise UnknownCommand.new(name) unless COMMANDS[name]
18
+ COMMANDS[name].call(args)
19
+ end
20
+
21
+ # Clears out all defined commands. Primarily useful for testing
22
+ def self.clear!
23
+ COMMANDS.clear
24
+ end
25
+
26
+ # Creates an alias for each given command.
27
+ #
28
+ # @param [Hash<Symbol => Symbol>] commands the aliases to create ( new name => old name )
29
+ # @example
30
+ # alias :br => :branch, :co => :checkout
31
+ def add_alias(commands)
32
+ commands.each do |new, old|
33
+ Commandant::COMMANDS[new] = Commandant::COMMANDS[old]
34
+ end
35
+ end
36
+ module_function :add_alias
37
+
38
+ # Create a new command
39
+ #
40
+ # @param [Symbol] name the name of the command that is created
41
+ # @param [String, nil] description the command's description
42
+ # @yield The command that will be run
43
+ # @yieldparam [Array] args optional: arguments to the command (typically from ARGV)
44
+ #
45
+ # @example A Hello World! command
46
+ # Commandant.command :hello do
47
+ # puts "Hello World!"
48
+ # end
49
+ #
50
+ # Commandant.run "hello"
51
+ #
52
+ # @example A command with arguments
53
+ # Commandant.command :argprint do |args|
54
+ # puts args
55
+ # end
56
+ #
57
+ # Commandant.run "argprint foo bizz bazz"
58
+ def command(name, description="", &command)
59
+ Command.new(name, description, &command)
60
+ end
61
+ module_function :command
62
+
63
+ # Runs a given commandline by parsing the command name and arguments. If no
64
+ # command is given, defaults to a command called :main. If that is not
65
+ # present, an UnknownCommand error will be raised.
66
+ #
67
+ # @param [Array] cmdline the command line args to be run
68
+ # @raise [UnknownCommand] command is unknown and no :main command is available
69
+ def run(cmdline=ARGV)
70
+ name, *args = cmdline
71
+ name, args = :main, [name, *args] if name.nil? || COMMANDS[name.to_sym].nil? && COMMANDS[:main]
72
+ Commandant.call name.to_sym, args.compact
73
+ end
74
+ module_function :run
75
+
76
+ end
@@ -0,0 +1,30 @@
1
+ module Commandant
2
+ class Command
3
+ attr_reader :description
4
+
5
+ # Create a new command by name and add it to the commands list.
6
+ #
7
+ # @param [Symbol] name the name of the command
8
+ # @param [String, nil] description the command's description
9
+ # @raise [ArgumentError] if a command block is not provided
10
+ # @raise [ArgumentError] if a command already exists by that name
11
+ def initialize(name, description=nil, &command)
12
+ raise ArgumentError, "Must provide a command block" unless command
13
+ raise ArgumentError, "Command already exists: #{name}" if COMMANDS[name]
14
+
15
+ @name = name
16
+ @description = description
17
+ @command = command
18
+
19
+ COMMANDS[@name] = self
20
+ end
21
+
22
+ # Execute the command
23
+ #
24
+ # @param [Array] args the command's arguments
25
+ def call(args=nil)
26
+ @command.call(args)
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Commandant::Command do
4
+ before { Commandant.clear! }
5
+ subject { Commandant::Command }
6
+
7
+ describe ".new" do
8
+ it "requres a name" do
9
+ lambda { subject.new(){ "this is the command" }
10
+ }.should raise_error(ArgumentError)
11
+ end
12
+
13
+ it "requires a block" do
14
+ lambda { subject.new(:name)
15
+ }.should raise_error(ArgumentError)
16
+ end
17
+
18
+ it "accepts a description" do
19
+ subject.new(:name, "description"){}.description.should == "description"
20
+ end
21
+
22
+ it "adds the command to the list of commands by name" do
23
+ command = subject.new(:name){ "block" }
24
+ Commandant::COMMANDS[:name].should == command
25
+ end
26
+
27
+ describe "when the command already exists" do
28
+ before { Commandant::Command.new(:dup) { "I am a duplicate" } }
29
+
30
+ it do
31
+ lambda {
32
+ Commandant.command(:dup) { "I am a duplicate" }
33
+ }.should raise_error(ArgumentError)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#call" do
39
+ subject { Commandant::Command.new(:name){ "called" } }
40
+
41
+ it "calls the given command" do
42
+ subject.call.should == "called"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Commandant do
4
+ before { Commandant.clear! }
5
+
6
+ describe ".call" do
7
+ it "calls the given command" do
8
+ Commandant.command(:test) { "test" }
9
+ Commandant.call(:test).should == "test"
10
+ end
11
+
12
+ it "passes args if given" do
13
+ Commandant.command(:test) {|args| args }
14
+
15
+ Commandant.call(:test, "args").should == "args"
16
+ end
17
+
18
+ describe "when the command is unavailable" do
19
+ subject { lambda{Commandant.call(:missing)} }
20
+ it { should raise_error(Commandant::UnknownCommand) }
21
+ end
22
+ end
23
+
24
+ describe ".clear!" do
25
+ before { Commandant.command(:main){"main"} }
26
+
27
+ it "should empty the command list" do
28
+ lambda {
29
+ Commandant.clear!
30
+ }.should change{Commandant::COMMANDS.empty?}.from(false).to(true)
31
+ end
32
+ end
33
+
34
+ describe ".add_alias" do
35
+ it "creates an alias for a given command" do
36
+ Commandant.command(:hello) { "hello" }
37
+ Commandant.add_alias :hi => :hello
38
+
39
+ Commandant.run(:hi).should == "hello"
40
+ end
41
+ end
42
+
43
+ describe ".command" do
44
+ subject { Commandant.command(:test) { "this is a test" } }
45
+ it "creates a new Command with the given name and command block" do
46
+ should be_a_kind_of(Commandant::Command)
47
+ end
48
+ end
49
+
50
+ describe ".run" do
51
+ before { Commandant.command(:main) {|args| "main called with #{args.inspect}" } }
52
+
53
+ it "runs the command specified" do
54
+ Commandant::COMMANDS[:main].should_receive(:call)
55
+
56
+ Commandant.run("main")
57
+ end
58
+
59
+ it "runs the command with arguments" do
60
+ Commandant::COMMANDS[:main].should_receive(:call).with(["args"])
61
+
62
+ Commandant.run(%w{main args})
63
+ end
64
+
65
+ it "defaults to the :main command, if available" do
66
+ Commandant.run(%w{ some args }).should == 'main called with ["some", "args"]'
67
+ end
68
+
69
+ it "runs the main command if no arguments are passed" do
70
+ Commandant.run(nil).should == "main called with []"
71
+ end
72
+
73
+ it "raises an errur of no main command is available" do
74
+ Commandant.clear!
75
+
76
+ lambda {
77
+ Commandant.run(%w{ some args })
78
+ }.should raise_error(Commandant::UnknownCommand)
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,12 @@
1
+ require 'lib/commandant'
2
+ include Commandant
3
+
4
+ command :main do
5
+ print "main"
6
+ end
7
+
8
+ command :argprinter do |args|
9
+ print args.inspect
10
+ end
11
+
12
+ run
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Integration:", "Running a command" do
4
+ def running(args, &block)
5
+ IO.popen "ruby spec/fixtures/basic_runner.rb #{args}", &block
6
+ end
7
+ private :running
8
+
9
+ describe "that prints \"main\" to STDOUT" do
10
+ it "should output \"main\" to STDOUT" do
11
+ running :main do |io|
12
+ io.read.should == "main"
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "that prints its arguments to STDOUT" do
18
+ it "should output its arguments to STDOUT" do
19
+ running "argprinter foo biz bazz" do |io|
20
+ io.read.should == %w{foo biz bazz}.inspect
21
+ end
22
+ end
23
+ end
24
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1 @@
1
+ --exclude /Library
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format specdoc
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'commandant'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: commandant
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Rein Henrichs
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-21 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
31
+ version: 1.2.9
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: yard
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ description:
47
+ email: reinh@reinh.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - LICENSE
54
+ - README.rdoc
55
+ files:
56
+ - .document
57
+ - .gitignore
58
+ - LICENSE
59
+ - README.rdoc
60
+ - Rakefile
61
+ - VERSION
62
+ - lib/commandant.rb
63
+ - lib/commandant/command.rb
64
+ - spec/commandant/commands_spec.rb
65
+ - spec/commandant_spec.rb
66
+ - spec/fixtures/basic_runner.rb
67
+ - spec/integration/run_spec.rb
68
+ - spec/rcov.opts
69
+ - spec/spec.opts
70
+ - spec/spec_helper.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/reinh/commandant
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options:
77
+ - --charset=UTF-8
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.3.6
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: A simple library for writing commands with subcommands (like git)
101
+ test_files:
102
+ - spec/commandant/commands_spec.rb
103
+ - spec/commandant_spec.rb
104
+ - spec/fixtures/basic_runner.rb
105
+ - spec/integration/run_spec.rb
106
+ - spec/spec_helper.rb