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 +4 -4
- data/.rspec +2 -0
- data/.travis.yml +12 -0
- data/README.md +36 -2
- data/lib/mercenary.rb +4 -0
- data/lib/mercenary/command.rb +99 -8
- data/lib/mercenary/program.rb +25 -12
- data/lib/mercenary/version.rb +1 -1
- data/mercenary.gemspec +6 -5
- data/spec/command_spec.rb +55 -0
- data/spec/program_spec.rb +0 -0
- data/spec/spec_helper.rb +15 -0
- metadata +30 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f441ca546550e0899b4f6aa2135994f482d5d29
|
4
|
+
data.tar.gz: d5d7fd3ecd26cf8065b78fd51575c0fe197b9557
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd7eaa27cbe85b82a1997eb6b73b429707c5a63c38e1f09b144eed56f04e819e35759e2b3a7d65bb4c977d87998e7d174544f023c2aa4a0e4f32362f5b9dcf9f
|
7
|
+
data.tar.gz: dbf6c19a22daf82dffd6ca7007d9fea7e32e18fe170da8c972779db8e2e76826956028d90febc845b75c79f11377817da42683d3db3291d4faf22440c47b27ff
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Mercenary
|
2
2
|
|
3
|
-
|
3
|
+
Lightweight and flexible library for writing command-line apps in Ruby.
|
4
|
+
|
5
|
+
[](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
|
-
|
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
data/lib/mercenary/command.rb
CHANGED
@@ -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
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
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
|
-
|
120
|
+
logger.debug "Found subcommand '#{cmd.name}'"
|
53
121
|
argv.shift
|
54
122
|
cmd.go(argv, opts, config)
|
55
123
|
else
|
56
|
-
|
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
|
-
|
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 }
|
data/lib/mercenary/program.rb
CHANGED
@@ -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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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
|
-
|
47
|
+
logger.debug("Parsed config: #{@config.inspect}")
|
35
48
|
|
36
49
|
cmd.actions.each { |a| a.call(argv, @config) }
|
37
50
|
end
|
data/lib/mercenary/version.rb
CHANGED
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 = ["
|
10
|
-
spec.email = ["
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.homepage = "
|
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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
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-
|
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
|
-
|
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
|
-
|
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:
|
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
|