wip-runner 0.3.0 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/wip/runner/cli.rb +12 -1
- data/lib/wip/runner/command.rb +21 -19
- data/lib/wip/runner/errors.rb +52 -5
- data/lib/wip/runner/options.rb +13 -1
- data/lib/wip/runner/parser/option_parser.rb +41 -0
- data/lib/wip/runner/parser.rb +7 -4
- data/lib/wip/runner/renderer/context.rb +24 -0
- data/lib/wip/runner/renderer/handlers/erb.rb +22 -0
- data/lib/wip/runner/renderer/handlers.rb +5 -0
- data/lib/wip/runner/renderer/helper.rb +26 -0
- data/lib/wip/runner/renderer.rb +33 -0
- data/lib/wip/runner/version.rb +1 -1
- data/lib/wip/runner.rb +1 -1
- metadata +8 -4
- data/lib/wip/runner/renderers/erb.rb +0 -34
- data/lib/wip/runner/renderers.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f477879c1c21aefbb14a98a5b81adbec74aa359
|
4
|
+
data.tar.gz: 5476e96fb0f8bd8a7235e7ac22d7e8386ba2cdcd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c5f6158af88078c592cabbdc937287abfb40f5b34f70be01471ec571ef19b37c0b3b71223f1ac331fd74e7f6c589696d188d0a16fdba8bdf3d2cae94b03a25a
|
7
|
+
data.tar.gz: 3a7515d2f1463bff01978b09e40575a97bfecb414a3036d59d7a31df465651e1306b445a08a9c881ebb256d1ad5387dee5efc6c63eb7160c3f96ec96b3dad46f
|
data/lib/wip/runner/cli.rb
CHANGED
@@ -10,6 +10,8 @@ module WIP
|
|
10
10
|
if File.exist?("#{extension}.rb")
|
11
11
|
$:.push(File.join(extension, 'lib'))
|
12
12
|
require extension
|
13
|
+
|
14
|
+
templates(File.join(extension, 'templates'))
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -29,6 +31,14 @@ module WIP
|
|
29
31
|
def namespace
|
30
32
|
@namespace || WIP::Runner
|
31
33
|
end
|
34
|
+
|
35
|
+
def templates(*paths)
|
36
|
+
@templates ||= []
|
37
|
+
unless paths.empty?
|
38
|
+
@templates = (@templates + paths.flatten).uniq
|
39
|
+
end
|
40
|
+
@templates
|
41
|
+
end
|
32
42
|
end
|
33
43
|
|
34
44
|
def initialize(io = HighLine.new)
|
@@ -43,7 +53,8 @@ module WIP
|
|
43
53
|
exit
|
44
54
|
end
|
45
55
|
|
46
|
-
def run(
|
56
|
+
def run(argv = [])
|
57
|
+
args = argv.dup
|
47
58
|
recipient = (command(args) || @parser)
|
48
59
|
recipient.run(args)
|
49
60
|
rescue InvalidCommand => e
|
data/lib/wip/runner/command.rb
CHANGED
@@ -51,21 +51,25 @@ module WIP
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def run(argv = [])
|
54
|
-
|
55
|
-
|
56
|
-
if
|
57
|
-
|
58
|
-
|
54
|
+
begin
|
55
|
+
parser.run(argv) do |command, arguments, options|
|
56
|
+
if command.nil?
|
57
|
+
if options.help
|
58
|
+
parser.help
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
validate!(arguments)
|
63
|
+
execute(arguments, options)
|
64
|
+
else
|
65
|
+
# TODO: add a spec for the help path.
|
66
|
+
command.match(/^-/) ? parser.help : delegate(command, argv)
|
59
67
|
end
|
60
|
-
|
61
|
-
validate!(arguments)
|
62
|
-
execute(arguments, options)
|
63
|
-
else
|
64
|
-
# TODO: add a spec for the help path.
|
65
|
-
command.match(/^-/) ? parser.help : delegate(command, argv)
|
66
68
|
end
|
69
|
+
rescue OptionParser::InvalidOption => e
|
70
|
+
raise InvalidOption, e.args.join(' ')
|
67
71
|
end
|
68
|
-
rescue
|
72
|
+
rescue InvalidArgument, InvalidArguments, InvalidCommand, InvalidOption, InvalidOptions => e
|
69
73
|
print_error(e)
|
70
74
|
end
|
71
75
|
|
@@ -77,13 +81,11 @@ module WIP
|
|
77
81
|
|
78
82
|
def validate!(arguments)
|
79
83
|
unless parser.arguments.empty? || parser.config.no_validate
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
lines << " - #{key} ... (missing)" if value.nil?
|
84
|
-
end
|
85
|
-
raise InvalidArguments, %Q{\n#{lines.join("\n")}}
|
84
|
+
missing = parser.arguments.keys.inject({}) do |memo, key|
|
85
|
+
memo[key] = nil if arguments[key].nil?
|
86
|
+
memo
|
86
87
|
end
|
88
|
+
raise InvalidArguments, missing unless missing.empty?
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
@@ -95,7 +97,7 @@ module WIP
|
|
95
97
|
end
|
96
98
|
|
97
99
|
def print_error(e)
|
98
|
-
@io.say(e.message
|
100
|
+
@io.say(e.message)
|
99
101
|
@io.newline
|
100
102
|
parser.help
|
101
103
|
end
|
data/lib/wip/runner/errors.rb
CHANGED
@@ -10,15 +10,62 @@ module WIP
|
|
10
10
|
# - OptionParser::InvalidOption
|
11
11
|
module Runner
|
12
12
|
class Error < StandardError
|
13
|
+
def initialize(message = nil)
|
14
|
+
super
|
15
|
+
@message = message
|
16
|
+
end
|
17
|
+
|
13
18
|
def message
|
14
|
-
prefix
|
15
|
-
|
19
|
+
"#{prefix.capitalize}: #{format(super)}".sub(/\s\n/, "\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def format(original)
|
25
|
+
if @message.is_a?(Array)
|
26
|
+
values = @message.map(&:to_s)
|
27
|
+
width = values.sort { |a, b| b.size <=> a.size }[0].size
|
28
|
+
lines = []
|
29
|
+
values.each do |value|
|
30
|
+
lines << sprintf(" - %-#{width}s", value)
|
31
|
+
end
|
32
|
+
"\n#{lines.join("\n")}"
|
33
|
+
elsif @message.respond_to?(:each) # e.g., Hash, WIP::Runner::Options
|
34
|
+
keys = @message.keys.map(&:to_s)
|
35
|
+
width = keys.sort { |a, b| b.size <=> a.size }[0].size
|
36
|
+
lines = []
|
37
|
+
@message.each do |key, value|
|
38
|
+
lines << [
|
39
|
+
sprintf(" - %-#{width}s", key.to_s),
|
40
|
+
format_value(value)
|
41
|
+
].join(' ... ')
|
42
|
+
end
|
43
|
+
"\n#{lines.join("\n")}"
|
44
|
+
else
|
45
|
+
format_value(@message)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def format_value(value)
|
50
|
+
case value
|
51
|
+
when nil
|
52
|
+
'(missing)'
|
53
|
+
else
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def prefix
|
59
|
+
self.class.name.split('::').last.gsub(/([A-Z])/, " \\1")
|
16
60
|
.strip
|
17
61
|
.capitalize
|
18
|
-
"#{prefix}: #{super}".sub(/\s\n/, "\n")
|
19
62
|
end
|
20
63
|
end
|
21
|
-
|
22
|
-
class
|
64
|
+
|
65
|
+
class InvalidArgument < Error ; end
|
66
|
+
class InvalidArguments < Error ; end
|
67
|
+
class InvalidCommand < Error ; end
|
68
|
+
class InvalidOption < Error ; end
|
69
|
+
class InvalidOptions < Error ; end
|
23
70
|
end
|
24
71
|
end
|
data/lib/wip/runner/options.rb
CHANGED
@@ -2,6 +2,18 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module WIP
|
4
4
|
module Runner
|
5
|
-
class Options < OpenStruct
|
5
|
+
class Options < OpenStruct
|
6
|
+
def each(&block)
|
7
|
+
self.to_h.each(&block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def keys
|
11
|
+
self.to_h.keys
|
12
|
+
end
|
13
|
+
|
14
|
+
def values
|
15
|
+
self.to_h.values
|
16
|
+
end
|
17
|
+
end
|
6
18
|
end
|
7
19
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner
|
3
|
+
class Parser
|
4
|
+
class OptionParser < ::OptionParser
|
5
|
+
def list(items, mode = :rows, option = nil, pad = true)
|
6
|
+
if (mode == :rows)
|
7
|
+
items = items.map { |item| "#{option} #{item}" } if option
|
8
|
+
items.join("\n#{pad ? padding : nil}")
|
9
|
+
else
|
10
|
+
HighLine.new.list(items, mode, option)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def wrap(text, mode = :description, line_width = 80)
|
15
|
+
indented = false
|
16
|
+
|
17
|
+
if mode == :description
|
18
|
+
line_width -= indentation
|
19
|
+
indented = true
|
20
|
+
end
|
21
|
+
|
22
|
+
wrapped = text.split("\n").collect! do |line|
|
23
|
+
line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
|
24
|
+
end * "\n"
|
25
|
+
|
26
|
+
indented ? wrapped.split("\n").join("\n#{padding}") : wrapped
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def indentation
|
32
|
+
@indentation ||= summary_indent.length + summary_width + 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def padding
|
36
|
+
@padding ||= ' ' * indentation
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/wip/runner/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'wip/runner/parser/option_parser'
|
2
|
+
|
1
3
|
module WIP
|
2
4
|
module Runner
|
3
5
|
class Parser
|
@@ -12,7 +14,7 @@ module WIP
|
|
12
14
|
def run(argv)
|
13
15
|
unless commands.empty?
|
14
16
|
command = argv.shift
|
15
|
-
raise InvalidCommand
|
17
|
+
raise InvalidCommand if command.nil?
|
16
18
|
yield(command, nil, nil)
|
17
19
|
else
|
18
20
|
remaining = options.parse!(argv)
|
@@ -82,9 +84,10 @@ module WIP
|
|
82
84
|
parser.separator ''
|
83
85
|
parser.separator heading
|
84
86
|
|
85
|
-
pairs.each do |name,
|
86
|
-
padding
|
87
|
-
|
87
|
+
pairs.each do |name, definition|
|
88
|
+
padding = ' ' * (parser.summary_width - name.length + 1)
|
89
|
+
overview = definition[:overview]
|
90
|
+
parser.separator [parser.summary_indent, name, padding, overview].join('')
|
88
91
|
end
|
89
92
|
end
|
90
93
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WIP::Runner::Renderer
|
2
|
+
class Context
|
3
|
+
class << self
|
4
|
+
def for(context = {})
|
5
|
+
self.new(context).send(:__binding__)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(context)
|
10
|
+
context.each do |key, value|
|
11
|
+
if value.is_a?(Module)
|
12
|
+
value = Helper.for(self, value)
|
13
|
+
end
|
14
|
+
self.class.send(:define_method, key.intern, Proc.new { value })
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def __binding__
|
21
|
+
binding
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module WIP::Runner::Renderer
|
4
|
+
class Handlers::ERB
|
5
|
+
def initialize(template)
|
6
|
+
@template = clean(template)
|
7
|
+
end
|
8
|
+
|
9
|
+
def render(context)
|
10
|
+
::ERB.new(@template).result(context)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def clean(string)
|
16
|
+
return if string.nil?
|
17
|
+
|
18
|
+
indent = (string.scan(/^[ \t]*(?=\S)/).min || '').size
|
19
|
+
string.gsub(/^[ \t]{#{indent}}/, '').strip
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WIP::Runner::Renderer
|
2
|
+
class Helper
|
3
|
+
def self.for(context, mod)
|
4
|
+
self.instance_eval { include mod }
|
5
|
+
self.new(context)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(context)
|
9
|
+
@context = context
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def method_missing(method_name, *args, &block)
|
15
|
+
if @context.respond_to?(method_name)
|
16
|
+
@context.send(method_name, *args, &block)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to_missing?(method_name, include_private = false)
|
23
|
+
@context.respond_to?(method_name) || super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module WIP
|
2
|
+
module Runner
|
3
|
+
module Renderer
|
4
|
+
# TODO: allow handler configuration/option
|
5
|
+
def render(content, context = {})
|
6
|
+
content = path?(content) ? template(content) : content
|
7
|
+
handler(:ERB, content).render(Context.for(context))
|
8
|
+
end
|
9
|
+
|
10
|
+
def template(path)
|
11
|
+
base_paths = WIP::Runner::CLI.templates
|
12
|
+
base_paths.each do |base|
|
13
|
+
file = File.join("#{base}/#{path}")
|
14
|
+
return File.read(file) if File.exist?(file)
|
15
|
+
end
|
16
|
+
|
17
|
+
raise WIP::Runner::InvalidArgument, "#{path} not found in:\n#{base_paths.map { |base| " - #{base}" }.join("\n")}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def path?(content)
|
23
|
+
File.extname(content).match(/\.[a-z]+$/)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handler(key, content)
|
27
|
+
Handlers::const_get(key).new(content)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Dir[File.expand_path('../renderer/*.rb', __FILE__)].each { |f| require(f) }
|
data/lib/wip/runner/version.rb
CHANGED
data/lib/wip/runner.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wip-runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Corey Innis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -95,8 +95,12 @@ files:
|
|
95
95
|
- lib/wip/runner/errors.rb
|
96
96
|
- lib/wip/runner/options.rb
|
97
97
|
- lib/wip/runner/parser.rb
|
98
|
-
- lib/wip/runner/
|
99
|
-
- lib/wip/runner/
|
98
|
+
- lib/wip/runner/parser/option_parser.rb
|
99
|
+
- lib/wip/runner/renderer.rb
|
100
|
+
- lib/wip/runner/renderer/context.rb
|
101
|
+
- lib/wip/runner/renderer/handlers.rb
|
102
|
+
- lib/wip/runner/renderer/handlers/erb.rb
|
103
|
+
- lib/wip/runner/renderer/helper.rb
|
100
104
|
- lib/wip/runner/shell.rb
|
101
105
|
- lib/wip/runner/shell/handlers.rb
|
102
106
|
- lib/wip/runner/shell/handlers/base.rb
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
module WIP
|
4
|
-
module Runner
|
5
|
-
module Renderers
|
6
|
-
module ERB
|
7
|
-
def self.included(base)
|
8
|
-
base.extend(ClassMethods)
|
9
|
-
end
|
10
|
-
|
11
|
-
def render(template, context)
|
12
|
-
if (file = File.join("#{self.class.templates}/#{template}.erb")) && File.exist?(file)
|
13
|
-
template = File.read(file)
|
14
|
-
end
|
15
|
-
::ERB.new(clean(template)).result(context)
|
16
|
-
end
|
17
|
-
|
18
|
-
def clean(string)
|
19
|
-
return if string.nil?
|
20
|
-
|
21
|
-
indent = (string.scan(/^[ \t]*(?=\S)/).min || '').size
|
22
|
-
string.gsub(/^[ \t]{#{indent}}/, '').strip
|
23
|
-
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
def templates(value = nil)
|
27
|
-
@templates = value unless value.nil?
|
28
|
-
@templates
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|