mercenary 0.0.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 467dae27c989bd4d07318b1965e6e28930f90aeb
4
- data.tar.gz: be71811e5f88c21cc07105822a0d77874893617f
3
+ metadata.gz: 3f441ca546550e0899b4f6aa2135994f482d5d29
4
+ data.tar.gz: d5d7fd3ecd26cf8065b78fd51575c0fe197b9557
5
5
  SHA512:
6
- metadata.gz: bf722d831a506ee191a2609b3420e132f50ddd4d00f87cc3686376767321a77af4310c0f71e481c1138d610b0780395e6b73fda297829b9a8ad8d3846e4160cc
7
- data.tar.gz: c9080a9dbcdda0da115f5d22b511bb20d6e7ce1fe08611076c81c007f69dcd72b96c8a2d6fde4b5694c6ee76c9878cba30f23b9507e1528e8a44a48965c4f9e0
6
+ metadata.gz: bd7eaa27cbe85b82a1997eb6b73b429707c5a63c38e1f09b144eed56f04e819e35759e2b3a7d65bb4c977d87998e7d174544f023c2aa4a0e4f32362f5b9dcf9f
7
+ data.tar.gz: dbf6c19a22daf82dffd6ca7007d9fea7e32e18fe170da8c972779db8e2e76826956028d90febc845b75c79f11377817da42683d3db3291d4faf22440c47b27ff
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - 2.0.0
6
+ script: "bundle exec rspec"
7
+ notification:
8
+ recipients:
9
+ - mercenary@jekyllrb.com
10
+ email:
11
+ on_success: change
12
+ on_failure: change
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Mercenary
2
2
 
3
- TODO: Write a gem description
3
+ Lightweight and flexible library for writing command-line apps in Ruby.
4
+
5
+ [![Build Status](https://secure.travis-ci.org/jekyll/mercenary.png)](https://travis-ci.org/jekyll/mercenary)
4
6
 
5
7
  ## Installation
6
8
 
@@ -18,7 +20,39 @@ Or install it yourself as:
18
20
 
19
21
  ## Usage
20
22
 
21
- TODO: Write usage instructions here
23
+ ```ruby
24
+ Mercenary.program(:jekyll) do |p|
25
+ p.version Jekyll::VERSION
26
+ p.description 'Jekyll is a blog-aware, static site generator in Ruby'
27
+
28
+ p.command(:new) do |c|
29
+ c.syntax "jekyll new PATH"
30
+ c.description "Creates a new Jekyll site scaffold in PATH"
31
+
32
+ c.action do |args, options|
33
+ Jekyll::Commands::New.process(args)
34
+ end
35
+ end
36
+
37
+ p.command(:import) do |c|
38
+ c.syntax "jekyll import <platform> [options]"
39
+ c.description "Import your old blog to Jekyll"
40
+
41
+ c.action do |args, options|
42
+ begin
43
+ require "jekyll-import"
44
+ rescue
45
+ msg = "You must install the 'jekyll-import' gem before continuing.\n"
46
+ msg += "* Do this by running `gem install jekyll-import`.\n"
47
+ msg += "* Or if you need root privileges, run `sudo gem install jekyll-import`."
48
+ abort msg
49
+ end
50
+
51
+ Jekyll::Commands::Import.process(args.first, options)
52
+ end
53
+ end
54
+ end
55
+ ```
22
56
 
23
57
  ## Contributing
24
58
 
data/lib/mercenary.rb CHANGED
@@ -1,5 +1,9 @@
1
+ lib = File.expand_path('../', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
1
4
  require "mercenary/version"
2
5
  require "optparse"
6
+ require "logger"
3
7
 
4
8
  module Mercenary
5
9
  autoload :Command, "mercenary/command"
@@ -9,6 +9,13 @@ module Mercenary
9
9
  attr_reader :map
10
10
  attr_accessor :parent
11
11
 
12
+ # Public: Creates a new Command
13
+ #
14
+ # name - the name of the command
15
+ # parent - (optional) the instancce of Mercenary::Command which you wish to
16
+ # be the parent of this command
17
+ #
18
+ # Returns nothing
12
19
  def initialize(name, parent = nil)
13
20
  @name = name
14
21
  @options = []
@@ -18,46 +25,114 @@ module Mercenary
18
25
  @parent = parent
19
26
  end
20
27
 
21
- def syntax(syntax)
22
- @syntax = syntax
28
+ # Public: Sets or gets the syntax string
29
+ #
30
+ # syntax - the string which describes this command's usage syntax (optional)
31
+ #
32
+ # Returns the syntax string and sets it if an argument is present
33
+ def syntax(syntax = nil)
34
+ @syntax = syntax if syntax
35
+ @syntax
23
36
  end
24
37
 
25
- def description(desc)
26
- @description = desc
38
+ # Public: Sets or gets the command description
39
+ #
40
+ # description - the description of what the command does (optional)
41
+ #
42
+ # Returns the description and sets it if an argument is present
43
+ def description(desc = nil)
44
+ @description = desc if desc
45
+ @description
27
46
  end
28
47
 
48
+ # Public: Adds an option switch
49
+ #
50
+ # sym - the variable key which is used to identify the value of the switch
51
+ # at runtime in the options hash
52
+ #
53
+ # Returns nothing
29
54
  def option(sym, *options)
30
55
  @options << options
31
56
  @map[options[0]] = sym
32
57
  end
33
58
 
59
+ # Public: Adds a subcommand
60
+ #
61
+ # cmd_name - the name of the command
62
+ # block - a block accepting the new instance of Mercenary::Command to be
63
+ # modified (optional)
64
+ #
65
+ # Returns nothing
34
66
  def command(cmd_name)
35
67
  cmd = Command.new(cmd_name, self)
36
68
  yield cmd
37
69
  @commands[cmd_name] = cmd
38
70
  end
39
71
 
72
+ # Public: Add an alias for this command's name to be attached to the parent
73
+ #
74
+ # cmd_name - the name of the alias
75
+ #
76
+ # Returns nothing
40
77
  def alias(cmd_name)
78
+ logger.debug "adding alias to parent for self: '#{cmd_name}'"
41
79
  @parent.commands[cmd_name] = self
42
80
  end
43
81
 
82
+ # Public: Add an action Proc to be executed at runtime
83
+ #
84
+ # block - the Proc to be executed at runtime
85
+ #
86
+ # Returns nothing
44
87
  def action(&block)
45
88
  @actions << block
46
89
  end
47
90
 
91
+ # Public: Fetch a Logger (stdlib)
92
+ #
93
+ # level - the logger level (a Logger constant, see docs for more info)
94
+ #
95
+ # Returns the instance of Logger
96
+ def logger(level = Logger::INFO)
97
+ unless @logger
98
+ @logger = Logger.new(STDOUT)
99
+ @logger.formatter = proc do |severity, datetime, progname, msg|
100
+ "#{ident} (#{severity}): #{msg}\n"
101
+ end
102
+ end
103
+
104
+ @logger.level = level
105
+ @logger
106
+ end
107
+
108
+ # Public: Run the command
109
+ #
110
+ # argv - an array of string args
111
+ # opts - the instance of OptionParser
112
+ # config - the output config hash
113
+ #
114
+ # Returns the command to be executed
48
115
  def go(argv, opts, config)
116
+ opts.banner = "Usage: #{syntax}"
49
117
  process_options(opts, config)
50
118
 
51
119
  if argv[0] && cmd = commands[argv[0].to_sym]
52
- puts "Found #{cmd.name}"
120
+ logger.debug "Found subcommand '#{cmd.name}'"
53
121
  argv.shift
54
122
  cmd.go(argv, opts, config)
55
123
  else
56
- puts "No additional command found, time to exec"
124
+ logger.debug "No additional command found, time to exec"
57
125
  self
58
126
  end
59
127
  end
60
128
 
129
+ # Public: Add this command's options to OptionParser and set a default
130
+ # action of setting the value of the option to the inputted hash
131
+ #
132
+ # opts - instance of OptionParser
133
+ # config - the Hash in which the option values should be placed
134
+ #
135
+ # Returns nothing
61
136
  def process_options(opts, config)
62
137
  options.each do |o|
63
138
  opts.on(*o) do |x|
@@ -66,13 +141,29 @@ module Mercenary
66
141
  end
67
142
  end
68
143
 
144
+ # Public: Check if this command has a subcommand
145
+ #
146
+ # sub_command - the name of the subcommand
147
+ #
148
+ # Returns true if this command is the parent of a command of name
149
+ # 'sub_command' and false otherwise
150
+ def has_command?(sub_command)
151
+ commands.keys.include?(sub_command)
152
+ end
153
+
154
+ # Public: Identify this command
155
+ #
156
+ # Returns a string which identifies this command
69
157
  def ident
70
158
  "<Command name=#{name}>"
71
159
  end
72
160
 
73
- def inspect
161
+ # Public: Build a string containing the command name, options and any subcommands
162
+ #
163
+ # Returns the string identifying this command, its options and its subcommands
164
+ def to_s
74
165
  msg = ''
75
- msg += "Command #{name}\n"
166
+ msg += "Command: #{name}\n"
76
167
  options.each { |o| msg += " " + o.inspect + "\n"}
77
168
  msg += "\n"
78
169
  commands.each { |k, v| msg += commands[k].inspect }
@@ -1,37 +1,50 @@
1
1
  module Mercenary
2
2
  class Program < Command
3
- attr_reader :version
4
- attr_reader :description
5
3
  attr_reader :optparse
6
4
  attr_reader :config
7
5
 
6
+ # Public: Creates a new Program
7
+ #
8
+ # name - the name of the program
9
+ #
10
+ # Returns nothing
8
11
  def initialize(name)
9
12
  @config = {}
10
13
  super(name)
11
14
  end
12
15
 
13
- def version(version)
14
- @version = version
15
- end
16
-
17
- def description(description)
18
- @description = description
16
+ # Public: Sets or gets the program version
17
+ #
18
+ # version - the program version (optional)
19
+ #
20
+ # Returns the version and sets it if an argument is present
21
+ def version(version = nil)
22
+ @version = version if version
23
+ @version
19
24
  end
20
25
 
26
+ # Public: Run the program
27
+ #
28
+ # argv - an array of string args (usually ARGV)
29
+ #
30
+ # Returns nothing
21
31
  def go(argv)
22
- p argv
23
- puts
24
- p self
32
+ logger.debug("Using args passed in: #{argv.inspect}")
25
33
 
26
34
  cmd = nil
27
35
 
28
36
  @optparse = OptionParser.new do |opts|
29
37
  cmd = super(argv, opts, @config)
38
+
39
+ opts.on('-v' '--version', 'Print the version') do
40
+ puts "#{name} #{version}"
41
+ abort
42
+ end
30
43
  end
31
44
 
32
45
  @optparse.parse!(argv)
33
46
 
34
- p @config
47
+ logger.debug("Parsed config: #{@config.inspect}")
35
48
 
36
49
  cmd.actions.each { |a| a.call(argv, @config) }
37
50
  end
@@ -1,3 +1,3 @@
1
1
  module Mercenary
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/mercenary.gemspec CHANGED
@@ -6,11 +6,11 @@ require 'mercenary/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "mercenary"
8
8
  spec.version = Mercenary::VERSION
9
- spec.authors = ["Parker Moore", "Tom Preston-Werner"]
10
- spec.email = ["parkrmoore@gmail.com", "tom@mojombo.com"]
11
- spec.description = %q{Write better command-line apps.}
12
- spec.summary = %q{Write better command-line apps.}
13
- spec.homepage = "http://github.com/jekyll/mercenary"
9
+ spec.authors = ["Tom Preston-Werner", "Parker Moore"]
10
+ spec.email = ["tom@mojombo.com", "parkrmoore@gmail.com"]
11
+ spec.description = %q{Lightweight and flexible library for writing command-line apps in Ruby.}
12
+ spec.summary = %q{Lightweight and flexible library for writing command-line apps in Ruby.}
13
+ spec.homepage = "https://github.com/jekyll/mercenary"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -20,4 +20,5 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.14"
23
24
  end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe(Mercenary::Command) do
4
+
5
+ context "a basic command" do
6
+ let(:command) { Mercenary::Command.new(:my_name) }
7
+ let(:command_with_parent) do
8
+ Mercenary::Command.new(
9
+ :i_have_parent,
10
+ parent
11
+ )
12
+ end
13
+ let(:parent) { Mercenary::Command.new(:my_parent) }
14
+ let(:add_sub) do
15
+ Proc.new do |c|
16
+ c.command(:sub_command) { |p| }
17
+ end
18
+ end
19
+
20
+ it "can be created with just a name" do
21
+ expect(command.name).to eql(:my_name)
22
+ end
23
+
24
+ it "can hold a parent command" do
25
+ expect(command_with_parent.parent).to eql(parent)
26
+ end
27
+
28
+ it "can create subcommands" do
29
+ expect(add_sub.call(command)).to be_a(Mercenary::Command)
30
+ expect(add_sub.call(command).parent).to eq(command)
31
+ end
32
+
33
+ it "can set its syntax" do
34
+ syntax_string = "my_name [options]"
35
+ cmd = described_class.new(:my_name)
36
+ cmd.syntax syntax_string
37
+ expect(cmd.syntax).to eq(syntax_string)
38
+ end
39
+
40
+ it "can set its description" do
41
+ desc = "run all the things"
42
+ command.description desc
43
+ expect(command.description).to eq(desc)
44
+ end
45
+
46
+ it "can set its options" do
47
+ name = "show_drafts"
48
+ opt = ['--drafts', 'Render posts in the _drafts folder']
49
+ command.option name, *opt
50
+ expect(command.options).to eq([opt])
51
+ expect(command.map).to include({opt.first => name})
52
+ end
53
+ end
54
+
55
+ end
File without changes
@@ -0,0 +1,15 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'mercenary'
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+
10
+ # Run specs in random order to surface order dependencies. If you find an
11
+ # order dependency and want to debug it, you can fix the order by providing
12
+ # the seed, which is printed after each run.
13
+ # --seed 1234
14
+ config.order = 'random'
15
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mercenary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Parker Moore
8
7
  - Tom Preston-Werner
8
+ - Parker Moore
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-06 00:00:00.000000000 Z
12
+ date: 2013-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -39,15 +39,31 @@ dependencies:
39
39
  - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
- description: Write better command-line apps.
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '2.14'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2.14'
56
+ description: Lightweight and flexible library for writing command-line apps in Ruby.
43
57
  email:
44
- - parkrmoore@gmail.com
45
58
  - tom@mojombo.com
59
+ - parkrmoore@gmail.com
46
60
  executables: []
47
61
  extensions: []
48
62
  extra_rdoc_files: []
49
63
  files:
50
64
  - .gitignore
65
+ - .rspec
66
+ - .travis.yml
51
67
  - Gemfile
52
68
  - LICENSE.txt
53
69
  - README.md
@@ -57,7 +73,10 @@ files:
57
73
  - lib/mercenary/program.rb
58
74
  - lib/mercenary/version.rb
59
75
  - mercenary.gemspec
60
- homepage: http://github.com/jekyll/mercenary
76
+ - spec/command_spec.rb
77
+ - spec/program_spec.rb
78
+ - spec/spec_helper.rb
79
+ homepage: https://github.com/jekyll/mercenary
61
80
  licenses:
62
81
  - MIT
63
82
  metadata: {}
@@ -80,5 +99,8 @@ rubyforge_project:
80
99
  rubygems_version: 2.0.3
81
100
  signing_key:
82
101
  specification_version: 4
83
- summary: Write better command-line apps.
84
- test_files: []
102
+ summary: Lightweight and flexible library for writing command-line apps in Ruby.
103
+ test_files:
104
+ - spec/command_spec.rb
105
+ - spec/program_spec.rb
106
+ - spec/spec_helper.rb