inversion 0.18.0 → 1.0.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +61 -1
- data/History.rdoc +5 -0
- data/Manifest.txt +1 -0
- data/Rakefile +12 -11
- data/bin/inversion +2 -270
- data/lib/inversion.rb +3 -3
- data/lib/inversion/command.rb +277 -0
- data/spec/inversion/mixins_spec.rb +1 -0
- data/spec/inversion/renderstate_spec.rb +2 -2
- metadata +61 -42
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4b8da84f00dd67a57f9f261339c2f8fd0dad397
|
4
|
+
data.tar.gz: 21dbe5879f682b3b5b4a8c955bc48619cd6636ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 586cf26085d8dc43c9034c686428009ba5d55d12c9c8bdeb2ad9a888aa8a8b5b5eefb305a0be3485b74d1d3e7a08d14ec9ac9e0a668ddc412f547883be426ca4
|
7
|
+
data.tar.gz: 7c5995c50244a22c035242a5363901fb110ac84fc541e6feea4ca172a954598e570ca0b75b11a452fe8d448f6330496cd009fcabe42189398720d979b2fd8b9d
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,8 +1,68 @@
|
|
1
|
+
2017-01-16 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* spec/inversion/mixins_spec.rb:
|
4
|
+
Fix a missing require in specs
|
5
|
+
[c9b0de03e1ea] [tip]
|
6
|
+
|
7
|
+
* spec/inversion/renderstate_spec.rb:
|
8
|
+
Fix some RSpec warnings
|
9
|
+
[1170ee8acbda]
|
10
|
+
|
11
|
+
* Rakefile:
|
12
|
+
Update dependencies
|
13
|
+
[7d7eb92c583a]
|
14
|
+
|
15
|
+
* bin/inversion, lib/inversion/command.rb:
|
16
|
+
Pull command class out into a file of its own
|
17
|
+
[f6e97907c0ae]
|
18
|
+
|
19
|
+
* .gems, .ruby-gemset, .ruby-version, .rvm.gems, .rvmrc:
|
20
|
+
Convert to generic version-manager files
|
21
|
+
[cec180dfa0f0]
|
22
|
+
|
23
|
+
2015-10-01 Michael Granger <ged@FaerieMUD.org>
|
24
|
+
|
25
|
+
* .hgtags:
|
26
|
+
Added tag v0.18.0 for changeset 0ec4018edc34
|
27
|
+
[585edc63b697] [github/master]
|
28
|
+
|
29
|
+
* .hgsigs:
|
30
|
+
Added signature for changeset 644316d7a5e8
|
31
|
+
[0ec4018edc34] [v0.18.0]
|
32
|
+
|
33
|
+
* History.rdoc, lib/inversion.rb:
|
34
|
+
Bump the minor version, update history.
|
35
|
+
[644316d7a5e8]
|
36
|
+
|
37
|
+
* lib/inversion/template.rb, spec/inversion/template_spec.rb:
|
38
|
+
Add docs for `strict_attributes` mode.
|
39
|
+
|
40
|
+
Also make the spec a bit more comprehensive.
|
41
|
+
[29e5a7d99f19]
|
42
|
+
|
43
|
+
* lib/inversion/template.rb, spec/inversion/template_spec.rb:
|
44
|
+
Add a `strict_attributes` option for templates.
|
45
|
+
[d826f7b0dd7a]
|
46
|
+
|
47
|
+
2015-07-08 Michael Granger <ged@FaerieMUD.org>
|
48
|
+
|
49
|
+
* .hgtags:
|
50
|
+
Added tag v0.17.4 for changeset 001e10b33bde
|
51
|
+
[4e4ded827c75]
|
52
|
+
|
53
|
+
* .hgsigs:
|
54
|
+
Added signature for changeset 8c35dab89dcc
|
55
|
+
[001e10b33bde] [v0.17.4]
|
56
|
+
|
57
|
+
* History.rdoc, Rakefile, inversion.gemspec, lib/inversion.rb:
|
58
|
+
Bump patch version, update history.
|
59
|
+
[8c35dab89dcc]
|
60
|
+
|
1
61
|
2015-07-08 rgalanakis <rob.galanakis@gmail.com>
|
2
62
|
|
3
63
|
* Tags.rdoc:
|
4
64
|
Update Tags doc with more precise ?default behavior
|
5
|
-
[acea5413919c]
|
65
|
+
[acea5413919c]
|
6
66
|
|
7
67
|
* lib/inversion/template/defaulttag.rb,
|
8
68
|
spec/inversion/template/defaulttag_spec.rb:
|
data/History.rdoc
CHANGED
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -26,19 +26,20 @@ hoespec = Hoe.spec 'inversion' do
|
|
26
26
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
27
27
|
self.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
|
28
28
|
|
29
|
-
self.dependency 'loggability', '~> 0.
|
30
|
-
|
31
|
-
self.dependency 'highline',
|
32
|
-
self.dependency 'hoe-deveiate',
|
33
|
-
self.dependency 'rack-test',
|
34
|
-
self.dependency 'simplecov',
|
35
|
-
self.dependency 'sinatra',
|
36
|
-
self.dependency 'tilt',
|
37
|
-
self.dependency 'sysexits',
|
38
|
-
self.dependency 'trollop',
|
29
|
+
self.dependency 'loggability', '~> 0.12'
|
30
|
+
|
31
|
+
self.dependency 'highline', '~> 1.6', :development
|
32
|
+
self.dependency 'hoe-deveiate', '~> 0.5', :development
|
33
|
+
self.dependency 'rack-test', '~> 0.6', :development
|
34
|
+
self.dependency 'simplecov', '~> 0.8', :development
|
35
|
+
self.dependency 'sinatra', '~> 1.4', :development
|
36
|
+
self.dependency 'tilt', '~> 1.4', :development
|
37
|
+
self.dependency 'sysexits', '~> 1.0', :development
|
38
|
+
self.dependency 'trollop', '~> 2.0', :development
|
39
39
|
self.dependency 'rdoc-generator-fivefish', '~> 0', :development
|
40
|
+
self.dependency 'configurability', '~> 3.1', :development
|
40
41
|
|
41
|
-
self.require_ruby_version( '>=2.
|
42
|
+
self.require_ruby_version( '>=2.2.0' )
|
42
43
|
self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
|
43
44
|
self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
|
44
45
|
self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
data/bin/inversion
CHANGED
@@ -1,278 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'logger'
|
4
3
|
require 'inversion'
|
5
|
-
require '
|
6
|
-
require 'highline'
|
7
|
-
require 'sysexits'
|
8
|
-
require 'shellwords'
|
4
|
+
require 'inversion/command'
|
9
5
|
|
10
|
-
|
11
|
-
class Inversion::Command
|
12
|
-
extend Sysexits
|
13
|
-
|
14
|
-
# The list of valid subcommands
|
15
|
-
SUBCOMMANDS = %w[api tagtokens tree]
|
16
|
-
|
17
|
-
# Class-instance variable for the HighLine prompt object
|
18
|
-
@prompt = nil
|
19
|
-
|
20
|
-
|
21
|
-
### Run the command
|
22
|
-
def self::run( args )
|
23
|
-
opts, args = self.parse_options( args )
|
24
|
-
subcommand = args.shift
|
25
|
-
|
26
|
-
command = self.new( opts )
|
27
|
-
command.run( subcommand, args )
|
28
|
-
rescue => err
|
29
|
-
$stderr.puts "%p: %s" % [ err.class, err.message ]
|
30
|
-
$stderr.puts( err.backtrace.join("\n ") ) if opts && opts.debug
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
### Fetch the HighLine instance for the command, creating it if necessary.
|
35
|
-
def self::prompt
|
36
|
-
unless @prompt
|
37
|
-
@prompt = HighLine.new
|
38
|
-
@prompt.page_at = @prompt.output_rows - 5
|
39
|
-
@prompt.wrap_at = @prompt.output_cols - 2
|
40
|
-
end
|
41
|
-
|
42
|
-
@prompt
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
### Create an option parser for the command and return it
|
47
|
-
def self::create_option_parser
|
48
|
-
pr = self.prompt
|
49
|
-
progname = pr.color( File.basename($0), :bold, :yellow )
|
50
|
-
|
51
|
-
return Trollop::Parser.new do
|
52
|
-
version Inversion.version_string( true )
|
53
|
-
|
54
|
-
banner (<<-END_BANNER).gsub(/^\t+/, '')
|
55
|
-
#{progname} OPTIONS SUBCOMMAND ARGS
|
56
|
-
|
57
|
-
Run the specified SUBCOMMAND with the given ARGS.
|
58
|
-
END_BANNER
|
59
|
-
text ''
|
60
|
-
|
61
|
-
stop_on( *SUBCOMMANDS )
|
62
|
-
text pr.color('Subcommands', :bold, :white)
|
63
|
-
text pr.list( SUBCOMMANDS, :columns_across )
|
64
|
-
text ''
|
65
|
-
|
66
|
-
text pr.color('Inversion Config', :bold, :white)
|
67
|
-
opt :ignore_unknown_tags, "Ignore unknown tags instead of displaying an error"
|
68
|
-
opt :path, "Add one or more directories to the template search path",
|
69
|
-
:type => :string, :multi => true
|
70
|
-
text ''
|
71
|
-
|
72
|
-
|
73
|
-
text pr.color('Other Options', :bold, :white)
|
74
|
-
opt :debug, "Enable debugging output"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
### Parse the given command line +args+, returning a populated options struct
|
80
|
-
### and any remaining arguments.
|
81
|
-
def self::parse_options( args )
|
82
|
-
oparser = self.create_option_parser
|
83
|
-
opts = oparser.parse( args )
|
84
|
-
|
85
|
-
if oparser.leftovers.empty?
|
86
|
-
$stderr.puts "No subcommand given.\nUsage: "
|
87
|
-
oparser.educate( $stderr )
|
88
|
-
exit :usage
|
89
|
-
end
|
90
|
-
args.replace( oparser.leftovers )
|
91
|
-
|
92
|
-
return opts, args
|
93
|
-
rescue Trollop::HelpNeeded
|
94
|
-
oparser.educate( $stderr )
|
95
|
-
exit :ok
|
96
|
-
rescue Trollop::VersionNeeded
|
97
|
-
$stderr.puts( oparser.version )
|
98
|
-
exit :ok
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
### Create a new instance of the command that will use the specified +opts+
|
103
|
-
### to parse and dump info about the given +templates+.
|
104
|
-
def initialize( opts )
|
105
|
-
@opts = opts
|
106
|
-
@prompt = self.class.prompt
|
107
|
-
|
108
|
-
# Configure logging
|
109
|
-
Loggability.level = opts.debug ? :debug : :error
|
110
|
-
Loggability.format_with( :color ) if $stdin.tty?
|
111
|
-
|
112
|
-
# Configure Inversion's strictness
|
113
|
-
Inversion::Template.configure(
|
114
|
-
:ignore_unknown_tags => opts.ignore_unknown_tags,
|
115
|
-
:template_paths => opts.path,
|
116
|
-
)
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
######
|
121
|
-
public
|
122
|
-
######
|
123
|
-
|
124
|
-
# The command-line options
|
125
|
-
attr_reader :opts
|
126
|
-
|
127
|
-
# The command's prompt object (HighLine)
|
128
|
-
attr_reader :prompt
|
129
|
-
|
130
|
-
|
131
|
-
### Run the given +subcommand+ with the specified +args+.
|
132
|
-
def run( subcommand, args )
|
133
|
-
case subcommand.to_sym
|
134
|
-
when :tree
|
135
|
-
self.dump_node_trees( args )
|
136
|
-
when :api
|
137
|
-
self.describe_templates( args )
|
138
|
-
when :tagtokens
|
139
|
-
self.dump_tokens( args )
|
140
|
-
else
|
141
|
-
self.output_error( "No such command #{subcommand.dump}" )
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
### Load the Inversion::Template from the specified +tmplpath+ and return it. If there
|
147
|
-
### is an error loading the template, output the error and return +nil+.
|
148
|
-
def load_template( tmplpath )
|
149
|
-
template = Inversion::Template.load( tmplpath )
|
150
|
-
return template
|
151
|
-
rescue Errno => err
|
152
|
-
self.prompt.say "Failed to load %s: %s" % [ tmplpath, err.message ]
|
153
|
-
rescue Inversion::ParseError => err
|
154
|
-
self.prompt.say "%s: Invalid template: %p: %s" %
|
155
|
-
[ tmplpath, err.class, err.message ]
|
156
|
-
self.prompt.say( err.backtrace.join("\n ") ) if self.opts.debug
|
157
|
-
end
|
158
|
-
|
159
|
-
|
160
|
-
### Dump the node tree of the given +templates+.
|
161
|
-
def dump_node_trees( templates )
|
162
|
-
templates.each do |path|
|
163
|
-
template = self.load_template( path )
|
164
|
-
self.output_blank_line
|
165
|
-
self.output_template_header( template )
|
166
|
-
self.output_template_nodes( template.node_tree )
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
|
171
|
-
### Output the given +tree+ of nodes at the specified +indent+ level.
|
172
|
-
def output_template_nodes( tree, indent=0 )
|
173
|
-
indenttxt = ' ' * indent
|
174
|
-
tree.each do |node|
|
175
|
-
self.prompt.say( indenttxt + node.as_comment_body )
|
176
|
-
self.output_template_nodes( node.subnodes, indent+4 ) if node.is_container?
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
|
181
|
-
### Output a description of the templates.
|
182
|
-
def describe_templates( templates )
|
183
|
-
templates.each do |path|
|
184
|
-
template = self.load_template( path )
|
185
|
-
self.output_blank_line
|
186
|
-
self.output_template_header( template )
|
187
|
-
self.describe_template_api( template )
|
188
|
-
self.describe_publications( template )
|
189
|
-
self.describe_subscriptions( template )
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
|
194
|
-
### Output a header between each template.
|
195
|
-
def output_template_header( template )
|
196
|
-
header_info = "%s (%0.2fK, %s)" %
|
197
|
-
[ template.source_file, template.source.bytesize/1024.0, template.source.encoding ]
|
198
|
-
header_line = "-- %s" % [ header_info ]
|
199
|
-
self.prompt.say( self.prompt.color(header_line, :bold, :white) )
|
200
|
-
end
|
201
|
-
|
202
|
-
|
203
|
-
### Output a description of the +template+'s attributes, subscriptions, etc.
|
204
|
-
def describe_template_api( template )
|
205
|
-
attrs = template.attributes.keys.map( &:to_s )
|
206
|
-
return if attrs.empty?
|
207
|
-
|
208
|
-
self.output_subheader "%d Attribute/s" % [ attrs.length ]
|
209
|
-
self.output_list( attrs.sort )
|
210
|
-
self.output_blank_line
|
211
|
-
end
|
212
|
-
|
213
|
-
|
214
|
-
### Output a list of sections the template publishes.
|
215
|
-
def describe_publications( template )
|
216
|
-
ptags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::PublishTag) }
|
217
|
-
return if ptags.empty?
|
218
|
-
|
219
|
-
pubnames = ptags.map( &:key ).map( &:to_s ).uniq.sort
|
220
|
-
self.output_subheader "%d Publication/s" % [ pubnames.length ]
|
221
|
-
self.output_list( pubnames )
|
222
|
-
self.output_blank_line
|
223
|
-
end
|
224
|
-
|
225
|
-
|
226
|
-
### Output a list of sections the template subscribes to.
|
227
|
-
def describe_subscriptions( template )
|
228
|
-
stags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::SubscribeTag) }
|
229
|
-
return if stags.empty?
|
230
|
-
|
231
|
-
subnames = stags.map( &:key ).map( &:to_s ).uniq.sort
|
232
|
-
self.output_subheader "%d Subscription/s" % [ subnames.length ]
|
233
|
-
self.output_list( subnames )
|
234
|
-
self.output_blank_line
|
235
|
-
end
|
236
|
-
|
237
|
-
|
238
|
-
### Attempt to parse the given +code+ and dump its tokens as a tagpattern.
|
239
|
-
def dump_tokens( args )
|
240
|
-
code = args.join(' ')
|
241
|
-
|
242
|
-
require 'ripper'
|
243
|
-
tokens = Ripper.lex( code ).collect do |(pos, tok, text)|
|
244
|
-
"%s<%p>" % [ tok.to_s.sub(/^on_/,''), text ]
|
245
|
-
end.join(' ')
|
246
|
-
|
247
|
-
self.prompt.say( tokens )
|
248
|
-
end
|
249
|
-
|
250
|
-
|
251
|
-
### Display a columnar list.
|
252
|
-
def output_list( columns )
|
253
|
-
self.prompt.say( self.prompt.list(columns, :columns_down) )
|
254
|
-
end
|
255
|
-
|
256
|
-
|
257
|
-
### Display an error message.
|
258
|
-
def output_error( message )
|
259
|
-
self.prompt.say( self.prompt.color(message, :red) )
|
260
|
-
end
|
261
|
-
|
262
|
-
|
263
|
-
### Output a subheader with the given +caption+.
|
264
|
-
def output_subheader( caption )
|
265
|
-
self.prompt.say( self.prompt.color(caption, :cyan) )
|
266
|
-
end
|
267
|
-
|
268
|
-
|
269
|
-
### Output a blank line
|
270
|
-
def output_blank_line
|
271
|
-
self.prompt.say( "\n" )
|
272
|
-
end
|
6
|
+
Inversion::Command.run( ARGV )
|
273
7
|
|
274
|
-
end # class Inversion::Command
|
275
8
|
|
276
|
-
Inversion::Command.run( ARGV )
|
277
9
|
|
278
10
|
|
data/lib/inversion.rb
CHANGED
@@ -23,13 +23,13 @@ module Inversion
|
|
23
23
|
log_as :inversion
|
24
24
|
|
25
25
|
|
26
|
-
warn ">>> Inversion requires Ruby 2.
|
26
|
+
warn ">>> Inversion requires Ruby 2.2.0 or later. <<<" if RUBY_VERSION < '2.2.0'
|
27
27
|
|
28
28
|
# Library version constant
|
29
|
-
VERSION = '0.
|
29
|
+
VERSION = '1.0.0'
|
30
30
|
|
31
31
|
# Version-control revision constant
|
32
|
-
REVISION = %q$Revision:
|
32
|
+
REVISION = %q$Revision: a4b621e66915 $
|
33
33
|
|
34
34
|
|
35
35
|
### Get the Inversion version.
|
@@ -0,0 +1,277 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
require 'trollop'
|
6
|
+
require 'highline'
|
7
|
+
require 'sysexits'
|
8
|
+
require 'shellwords'
|
9
|
+
|
10
|
+
require 'inversion' unless defined?( Inversion )
|
11
|
+
|
12
|
+
|
13
|
+
# Command class for the 'inversion' command-line tool.
|
14
|
+
class Inversion::Command
|
15
|
+
extend Sysexits
|
16
|
+
|
17
|
+
# The list of valid subcommands
|
18
|
+
SUBCOMMANDS = %w[api tagtokens tree]
|
19
|
+
|
20
|
+
# Class-instance variable for the HighLine prompt object
|
21
|
+
@prompt = nil
|
22
|
+
|
23
|
+
|
24
|
+
### Run the command
|
25
|
+
def self::run( args )
|
26
|
+
opts, args = self.parse_options( args )
|
27
|
+
subcommand = args.shift
|
28
|
+
|
29
|
+
command = self.new( opts )
|
30
|
+
command.run( subcommand, args )
|
31
|
+
rescue => err
|
32
|
+
$stderr.puts "%p: %s" % [ err.class, err.message ]
|
33
|
+
$stderr.puts( err.backtrace.join("\n ") ) if opts && opts.debug
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
### Fetch the HighLine instance for the command, creating it if necessary.
|
38
|
+
def self::prompt
|
39
|
+
unless @prompt
|
40
|
+
@prompt = HighLine.new
|
41
|
+
@prompt.page_at = @prompt.output_rows - 5
|
42
|
+
@prompt.wrap_at = @prompt.output_cols - 2
|
43
|
+
end
|
44
|
+
|
45
|
+
@prompt
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
### Create an option parser for the command and return it
|
50
|
+
def self::create_option_parser
|
51
|
+
pr = self.prompt
|
52
|
+
progname = pr.color( File.basename($0), :bold, :yellow )
|
53
|
+
|
54
|
+
return Trollop::Parser.new do
|
55
|
+
version Inversion.version_string( true )
|
56
|
+
|
57
|
+
banner (<<-END_BANNER).gsub(/^\t+/, '')
|
58
|
+
#{progname} OPTIONS SUBCOMMAND ARGS
|
59
|
+
|
60
|
+
Run the specified SUBCOMMAND with the given ARGS.
|
61
|
+
END_BANNER
|
62
|
+
text ''
|
63
|
+
|
64
|
+
stop_on( *SUBCOMMANDS )
|
65
|
+
text pr.color('Subcommands', :bold, :white)
|
66
|
+
text pr.list( SUBCOMMANDS, :columns_across )
|
67
|
+
text ''
|
68
|
+
|
69
|
+
text pr.color('Inversion Config', :bold, :white)
|
70
|
+
opt :ignore_unknown_tags, "Ignore unknown tags instead of displaying an error"
|
71
|
+
opt :path, "Add one or more directories to the template search path",
|
72
|
+
:type => :string, :multi => true
|
73
|
+
text ''
|
74
|
+
|
75
|
+
|
76
|
+
text pr.color('Other Options', :bold, :white)
|
77
|
+
opt :debug, "Enable debugging output"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
### Parse the given command line +args+, returning a populated options struct
|
83
|
+
### and any remaining arguments.
|
84
|
+
def self::parse_options( args )
|
85
|
+
oparser = self.create_option_parser
|
86
|
+
opts = oparser.parse( args )
|
87
|
+
|
88
|
+
if oparser.leftovers.empty?
|
89
|
+
$stderr.puts "No subcommand given.\nUsage: "
|
90
|
+
oparser.educate( $stderr )
|
91
|
+
exit :usage
|
92
|
+
end
|
93
|
+
args.replace( oparser.leftovers )
|
94
|
+
|
95
|
+
return opts, args
|
96
|
+
rescue Trollop::HelpNeeded
|
97
|
+
oparser.educate( $stderr )
|
98
|
+
exit :ok
|
99
|
+
rescue Trollop::VersionNeeded
|
100
|
+
$stderr.puts( oparser.version )
|
101
|
+
exit :ok
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
### Create a new instance of the command that will use the specified +opts+
|
106
|
+
### to parse and dump info about the given +templates+.
|
107
|
+
def initialize( opts )
|
108
|
+
@opts = opts
|
109
|
+
@prompt = self.class.prompt
|
110
|
+
|
111
|
+
# Configure logging
|
112
|
+
Loggability.level = opts.debug ? :debug : :error
|
113
|
+
Loggability.format_with( :color ) if $stdin.tty?
|
114
|
+
|
115
|
+
# Configure Inversion's strictness
|
116
|
+
Inversion::Template.configure(
|
117
|
+
:ignore_unknown_tags => opts.ignore_unknown_tags,
|
118
|
+
:template_paths => opts.path,
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
######
|
124
|
+
public
|
125
|
+
######
|
126
|
+
|
127
|
+
# The command-line options
|
128
|
+
attr_reader :opts
|
129
|
+
|
130
|
+
# The command's prompt object (HighLine)
|
131
|
+
attr_reader :prompt
|
132
|
+
|
133
|
+
|
134
|
+
### Run the given +subcommand+ with the specified +args+.
|
135
|
+
def run( subcommand, args )
|
136
|
+
case subcommand.to_sym
|
137
|
+
when :tree
|
138
|
+
self.dump_node_trees( args )
|
139
|
+
when :api
|
140
|
+
self.describe_templates( args )
|
141
|
+
when :tagtokens
|
142
|
+
self.dump_tokens( args )
|
143
|
+
else
|
144
|
+
self.output_error( "No such command #{subcommand.dump}" )
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
### Load the Inversion::Template from the specified +tmplpath+ and return it. If there
|
150
|
+
### is an error loading the template, output the error and return +nil+.
|
151
|
+
def load_template( tmplpath )
|
152
|
+
template = Inversion::Template.load( tmplpath )
|
153
|
+
return template
|
154
|
+
rescue Errno => err
|
155
|
+
self.prompt.say "Failed to load %s: %s" % [ tmplpath, err.message ]
|
156
|
+
rescue Inversion::ParseError => err
|
157
|
+
self.prompt.say "%s: Invalid template: %p: %s" %
|
158
|
+
[ tmplpath, err.class, err.message ]
|
159
|
+
self.prompt.say( err.backtrace.join("\n ") ) if self.opts.debug
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
### Dump the node tree of the given +templates+.
|
164
|
+
def dump_node_trees( templates )
|
165
|
+
templates.each do |path|
|
166
|
+
template = self.load_template( path )
|
167
|
+
self.output_blank_line
|
168
|
+
self.output_template_header( template )
|
169
|
+
self.output_template_nodes( template.node_tree )
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
### Output the given +tree+ of nodes at the specified +indent+ level.
|
175
|
+
def output_template_nodes( tree, indent=0 )
|
176
|
+
indenttxt = ' ' * indent
|
177
|
+
tree.each do |node|
|
178
|
+
self.prompt.say( indenttxt + node.as_comment_body )
|
179
|
+
self.output_template_nodes( node.subnodes, indent+4 ) if node.is_container?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
### Output a description of the templates.
|
185
|
+
def describe_templates( templates )
|
186
|
+
templates.each do |path|
|
187
|
+
template = self.load_template( path )
|
188
|
+
self.output_blank_line
|
189
|
+
self.output_template_header( template )
|
190
|
+
self.describe_template_api( template )
|
191
|
+
self.describe_publications( template )
|
192
|
+
self.describe_subscriptions( template )
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
### Output a header between each template.
|
198
|
+
def output_template_header( template )
|
199
|
+
header_info = "%s (%0.2fK, %s)" %
|
200
|
+
[ template.source_file, template.source.bytesize/1024.0, template.source.encoding ]
|
201
|
+
header_line = "-- %s" % [ header_info ]
|
202
|
+
self.prompt.say( self.prompt.color(header_line, :bold, :white) )
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
### Output a description of the +template+'s attributes, subscriptions, etc.
|
207
|
+
def describe_template_api( template )
|
208
|
+
attrs = template.attributes.keys.map( &:to_s )
|
209
|
+
return if attrs.empty?
|
210
|
+
|
211
|
+
self.output_subheader "%d Attribute/s" % [ attrs.length ]
|
212
|
+
self.output_list( attrs.sort )
|
213
|
+
self.output_blank_line
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
### Output a list of sections the template publishes.
|
218
|
+
def describe_publications( template )
|
219
|
+
ptags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::PublishTag) }
|
220
|
+
return if ptags.empty?
|
221
|
+
|
222
|
+
pubnames = ptags.map( &:key ).map( &:to_s ).uniq.sort
|
223
|
+
self.output_subheader "%d Publication/s" % [ pubnames.length ]
|
224
|
+
self.output_list( pubnames )
|
225
|
+
self.output_blank_line
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
### Output a list of sections the template subscribes to.
|
230
|
+
def describe_subscriptions( template )
|
231
|
+
stags = template.node_tree.find_all {|node| node.is_a?(Inversion::Template::SubscribeTag) }
|
232
|
+
return if stags.empty?
|
233
|
+
|
234
|
+
subnames = stags.map( &:key ).map( &:to_s ).uniq.sort
|
235
|
+
self.output_subheader "%d Subscription/s" % [ subnames.length ]
|
236
|
+
self.output_list( subnames )
|
237
|
+
self.output_blank_line
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
### Attempt to parse the given +code+ and dump its tokens as a tagpattern.
|
242
|
+
def dump_tokens( args )
|
243
|
+
code = args.join(' ')
|
244
|
+
|
245
|
+
require 'ripper'
|
246
|
+
tokens = Ripper.lex( code ).collect do |(pos, tok, text)|
|
247
|
+
"%s<%p>" % [ tok.to_s.sub(/^on_/,''), text ]
|
248
|
+
end.join(' ')
|
249
|
+
|
250
|
+
self.prompt.say( tokens )
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
### Display a columnar list.
|
255
|
+
def output_list( columns )
|
256
|
+
self.prompt.say( self.prompt.list(columns, :columns_down) )
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
### Display an error message.
|
261
|
+
def output_error( message )
|
262
|
+
self.prompt.say( self.prompt.color(message, :red) )
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
### Output a subheader with the given +caption+.
|
267
|
+
def output_subheader( caption )
|
268
|
+
self.prompt.say( self.prompt.color(caption, :cyan) )
|
269
|
+
end
|
270
|
+
|
271
|
+
|
272
|
+
### Output a blank line
|
273
|
+
def output_blank_line
|
274
|
+
self.prompt.say( "\n" )
|
275
|
+
end
|
276
|
+
|
277
|
+
end # class Inversion::Command
|
@@ -91,7 +91,7 @@ describe Inversion::RenderState do
|
|
91
91
|
state.with_attributes( {} ) do
|
92
92
|
raise "Charlie dooo!"
|
93
93
|
end
|
94
|
-
}.to raise_error()
|
94
|
+
}.to raise_error( RuntimeError )
|
95
95
|
|
96
96
|
expect( state.scope[:foot] ).to eq( 'in mouth' )
|
97
97
|
end
|
@@ -195,7 +195,7 @@ describe Inversion::RenderState do
|
|
195
195
|
state.with_destination( [] ) do
|
196
196
|
raise "New!"
|
197
197
|
end
|
198
|
-
}.to raise_error()
|
198
|
+
}.to raise_error( RuntimeError )
|
199
199
|
|
200
200
|
expect( state.destination ).to equal( original_dest )
|
201
201
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inversion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -11,27 +11,32 @@ bindir: bin
|
|
11
11
|
cert_chain:
|
12
12
|
- |
|
13
13
|
-----BEGIN CERTIFICATE-----
|
14
|
-
|
14
|
+
MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQsFADA+MQwwCgYDVQQDDANnZWQx
|
15
15
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
16
|
-
|
16
|
+
HhcNMTYwODIwMTgxNzQyWhcNMTcwODIwMTgxNzQyWjA+MQwwCgYDVQQDDANnZWQx
|
17
17
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC/JWGRHO+USzR97vXjkFgt
|
19
|
+
83qeNf2KHkcvrRTSnR64i6um/ziin0I0oX23H7VYrDJC9A/uoUa5nGRJS5Zw/+wW
|
20
|
+
ENcvWVZS4iUzi4dsYJGY6yEOsXh2CcF46+QevV8iE+UmbkU75V7Dy1JCaUOyizEt
|
21
|
+
TH5UHsOtUU7k9TYARt/TgYZKuaoAMZZd5qyVqhF1vV+7/Qzmp89NGflXf2xYP26a
|
22
|
+
4MAX2qqKX/FKXqmFO+AGsbwYTEds1mksBF3fGsFgsQWxftG8GfZQ9+Cyu2+l1eOw
|
23
|
+
cZ+lPcg834G9DrqW2zhqUoLr1MTly4pqxYGb7XoDhoR7dd1kFE2a067+DzWC/ADt
|
24
|
+
+QkcqWUm5oh1fN0eqr7NsZlVJDulFgdiiYPQiIN7UNsii4Wc9aZqBoGcYfBeQNPZ
|
25
|
+
soo/6za/bWajOKUmDhpqvaiRv9EDpVLzuj53uDoukMMwxCMfgb04+ckQ0t2G7wqc
|
26
|
+
/D+K9JW9DDs3Yjgv9k4h7YMhW5gftosd+NkNC/+Y2CkCAwEAAaN1MHMwCQYDVR0T
|
27
|
+
BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFHKN/nkRusdqCJEuq3lgB3fJvyTg
|
28
|
+
MBwGA1UdEQQVMBOBEWdlZEBGYWVyaWVNVUQub3JnMBwGA1UdEgQVMBOBEWdlZEBG
|
29
|
+
YWVyaWVNVUQub3JnMA0GCSqGSIb3DQEBCwUAA4IBgQAPJzKiT0zBU7kpqe0aS2qb
|
30
|
+
FI0PJ4y5I8buU4IZGUD5NEt/N7pZNfOyBxkrZkXhS44Fp+xwBH5ebLbq/WY78Bqd
|
31
|
+
db0z6ZgW4LMYMpWFfbXsRbd9TU2f52L8oMAhxOvF7Of5qJMVWuFQ8FPagk2iHrdH
|
32
|
+
inYLQagqAF6goWTXgAJCdPd6SNeeSNqA6vlY7CV1Jh5kfNJJ6xu/CVij1GzCLu/5
|
33
|
+
DMOr26DBv+qLJRRC/2h34uX71q5QgeOyxvMg+7V3u/Q06DXyQ2VgeeqiwDFFpEH0
|
34
|
+
PFkdPO6ZqbTRcLfNH7mFgCBJjsfSjJrn0sPBlYyOXgCoByfZnZyrIMH/UY+lgQqS
|
35
|
+
6Von1VDsfQm0eJh5zYZD64ZF86phSR7mUX3mXItwH04HrZwkWpvgd871DZVR3i1n
|
36
|
+
w8aNA5re5+Rt/Vvjxj5AcEnZnZiz5x959NaddQocX32Z1unHw44pzRNUur1GInfW
|
37
|
+
p4vpx2kUSFSAGjtCbDGTNV2AH8w9OU4xEmNz8c5lyoA=
|
33
38
|
-----END CERTIFICATE-----
|
34
|
-
date:
|
39
|
+
date: 2017-01-16 00:00:00.000000000 Z
|
35
40
|
dependencies:
|
36
41
|
- !ruby/object:Gem::Dependency
|
37
42
|
name: loggability
|
@@ -39,14 +44,14 @@ dependencies:
|
|
39
44
|
requirements:
|
40
45
|
- - "~>"
|
41
46
|
- !ruby/object:Gem::Version
|
42
|
-
version: '0.
|
47
|
+
version: '0.12'
|
43
48
|
type: :runtime
|
44
49
|
prerelease: false
|
45
50
|
version_requirements: !ruby/object:Gem::Requirement
|
46
51
|
requirements:
|
47
52
|
- - "~>"
|
48
53
|
- !ruby/object:Gem::Version
|
49
|
-
version: '0.
|
54
|
+
version: '0.12'
|
50
55
|
- !ruby/object:Gem::Dependency
|
51
56
|
name: hoe-mercurial
|
52
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,14 +72,14 @@ dependencies:
|
|
67
72
|
requirements:
|
68
73
|
- - "~>"
|
69
74
|
- !ruby/object:Gem::Version
|
70
|
-
version: '0.
|
75
|
+
version: '0.8'
|
71
76
|
type: :development
|
72
77
|
prerelease: false
|
73
78
|
version_requirements: !ruby/object:Gem::Requirement
|
74
79
|
requirements:
|
75
80
|
- - "~>"
|
76
81
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0.
|
82
|
+
version: '0.8'
|
78
83
|
- !ruby/object:Gem::Dependency
|
79
84
|
name: hoe-highline
|
80
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,20 +94,6 @@ dependencies:
|
|
89
94
|
- - "~>"
|
90
95
|
- !ruby/object:Gem::Version
|
91
96
|
version: '0.2'
|
92
|
-
- !ruby/object:Gem::Dependency
|
93
|
-
name: rdoc
|
94
|
-
requirement: !ruby/object:Gem::Requirement
|
95
|
-
requirements:
|
96
|
-
- - "~>"
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version: '4.0'
|
99
|
-
type: :development
|
100
|
-
prerelease: false
|
101
|
-
version_requirements: !ruby/object:Gem::Requirement
|
102
|
-
requirements:
|
103
|
-
- - "~>"
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
version: '4.0'
|
106
97
|
- !ruby/object:Gem::Dependency
|
107
98
|
name: highline
|
108
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -215,20 +206,48 @@ dependencies:
|
|
215
206
|
- - "~>"
|
216
207
|
- !ruby/object:Gem::Version
|
217
208
|
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: configurability
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '3.1'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '3.1'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: rdoc
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '4.0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '4.0'
|
218
237
|
- !ruby/object:Gem::Dependency
|
219
238
|
name: hoe
|
220
239
|
requirement: !ruby/object:Gem::Requirement
|
221
240
|
requirements:
|
222
241
|
- - "~>"
|
223
242
|
- !ruby/object:Gem::Version
|
224
|
-
version: '3.
|
243
|
+
version: '3.16'
|
225
244
|
type: :development
|
226
245
|
prerelease: false
|
227
246
|
version_requirements: !ruby/object:Gem::Requirement
|
228
247
|
requirements:
|
229
248
|
- - "~>"
|
230
249
|
- !ruby/object:Gem::Version
|
231
|
-
version: '3.
|
250
|
+
version: '3.16'
|
232
251
|
description: |-
|
233
252
|
Inversion is a templating system for Ruby. It uses the "Inversion of Control"
|
234
253
|
principle to decouple the contents and structure of templates from the code
|
@@ -249,7 +268,6 @@ extra_rdoc_files:
|
|
249
268
|
- README.rdoc
|
250
269
|
- Tags.rdoc
|
251
270
|
files:
|
252
|
-
- ".gemtest"
|
253
271
|
- ChangeLog
|
254
272
|
- Examples.rdoc
|
255
273
|
- GettingStarted.rdoc
|
@@ -261,6 +279,7 @@ files:
|
|
261
279
|
- Tags.rdoc
|
262
280
|
- bin/inversion
|
263
281
|
- lib/inversion.rb
|
282
|
+
- lib/inversion/command.rb
|
264
283
|
- lib/inversion/exceptions.rb
|
265
284
|
- lib/inversion/mixins.rb
|
266
285
|
- lib/inversion/monkeypatches.rb
|
@@ -350,7 +369,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
350
369
|
requirements:
|
351
370
|
- - ">="
|
352
371
|
- !ruby/object:Gem::Version
|
353
|
-
version: 2.
|
372
|
+
version: 2.2.0
|
354
373
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
355
374
|
requirements:
|
356
375
|
- - ">="
|
@@ -358,7 +377,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
358
377
|
version: '0'
|
359
378
|
requirements: []
|
360
379
|
rubyforge_project:
|
361
|
-
rubygems_version: 2.
|
380
|
+
rubygems_version: 2.6.8
|
362
381
|
signing_key:
|
363
382
|
specification_version: 4
|
364
383
|
summary: Inversion is a templating system for Ruby
|
metadata.gz.sig
CHANGED
Binary file
|
data/.gemtest
DELETED
File without changes
|