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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39e86e1e9f455dde60d2b962de255981046f23c7
4
- data.tar.gz: 1c043e470b3a221fd196fd671d7791987039f1f4
3
+ metadata.gz: f4b8da84f00dd67a57f9f261339c2f8fd0dad397
4
+ data.tar.gz: 21dbe5879f682b3b5b4a8c955bc48619cd6636ab
5
5
  SHA512:
6
- metadata.gz: e56eddccd69b4d0078c6355344ed85f02eb6665928f32facf52b2417c17b4fe774517fe358d2460b8b15674d811aea1ebd2e45e8e00e89a496be2ef87735238d
7
- data.tar.gz: fc8c6f9dafbdd0eb44bb440e1a2ce1e9fdffdde1179d842eb81802e3c2023254c08d4f663ad6d78026b829922f35f036fe37e5394d3854ab6bd64716870fadf2
6
+ metadata.gz: 586cf26085d8dc43c9034c686428009ba5d55d12c9c8bdeb2ad9a888aa8a8b5b5eefb305a0be3485b74d1d3e7a08d14ec9ac9e0a668ddc412f547883be426ca4
7
+ data.tar.gz: 7c5995c50244a22c035242a5363901fb110ac84fc541e6feea4ca172a954598e570ca0b75b11a452fe8d448f6330496cd009fcabe42189398720d979b2fd8b9d
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] [github/master, tip]
65
+ [acea5413919c]
6
66
 
7
67
  * lib/inversion/template/defaulttag.rb,
8
68
  spec/inversion/template/defaulttag_spec.rb:
@@ -1,3 +1,8 @@
1
+ == v1.0.0 [2017-01-16] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Mark as stable, update dependencies.
4
+
5
+
1
6
  == v0.18.0 [2015-10-01] Michael Granger <ged@FaerieMUD.org>
2
7
 
3
8
  Add a `strict_attributes` option for templates.
@@ -9,6 +9,7 @@ Rakefile
9
9
  Tags.rdoc
10
10
  bin/inversion
11
11
  lib/inversion.rb
12
+ lib/inversion/command.rb
12
13
  lib/inversion/exceptions.rb
13
14
  lib/inversion/mixins.rb
14
15
  lib/inversion/monkeypatches.rb
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.11'
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
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.0.0' )
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}"
@@ -1,278 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'logger'
4
3
  require 'inversion'
5
- require 'trollop'
6
- require 'highline'
7
- require 'sysexits'
8
- require 'shellwords'
4
+ require 'inversion/command'
9
5
 
10
- # Command class for the 'inversion' command-line tool.
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
 
@@ -23,13 +23,13 @@ module Inversion
23
23
  log_as :inversion
24
24
 
25
25
 
26
- warn ">>> Inversion requires Ruby 2.0.0 or later. <<<" if RUBY_VERSION < '2.0.0'
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.18.0'
29
+ VERSION = '1.0.0'
30
30
 
31
31
  # Version-control revision constant
32
- REVISION = %q$Revision: 644316d7a5e8 $
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
@@ -3,6 +3,7 @@
3
3
 
4
4
  require_relative '../helpers'
5
5
 
6
+ require 'set'
6
7
  require 'inversion/mixins'
7
8
 
8
9
 
@@ -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.18.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
- MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
14
+ MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQsFADA+MQwwCgYDVQQDDANnZWQx
15
15
  GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
16
- HhcNMTUwNDAxMjEyNDEzWhcNMTYwMzMxMjEyNDEzWjA+MQwwCgYDVQQDDANnZWQx
16
+ HhcNMTYwODIwMTgxNzQyWhcNMTcwODIwMTgxNzQyWjA+MQwwCgYDVQQDDANnZWQx
17
17
  GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
18
- ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb92mkyYwuGBg1oRxt2tkH
19
- +Uo3LAsaL/APBfSLzy8o3+B3AUHKCjMUaVeBoZdWtMHB75X3VQlvXfZMyBxj59Vo
20
- cDthr3zdao4HnyrzAIQf7BO5Y8KBwVD+yyXCD/N65TTwqsQnO3ie7U5/9ut1rnNr
21
- OkOzAscMwkfQxBkXDzjvAWa6UF4c5c9kR/T79iA21kDx9+bUMentU59aCJtUcbxa
22
- 7kcKJhPEYsk4OdxR9q2dphNMFDQsIdRO8rywX5FRHvcb+qnXC17RvxLHtOjysPtp
23
- EWsYoZMxyCDJpUqbwoeiM+tAHoz2ABMv3Ahie3Qeb6+MZNAtMmaWfBx3dg2u+/WN
24
- AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSZ0hCV
25
- qoHr122fGKelqffzEQBhszAcBgNVHREEFTATgRFnZWRARmFlcmllTVVELm9yZzAc
26
- BgNVHRIEFTATgRFnZWRARmFlcmllTVVELm9yZzANBgkqhkiG9w0BAQUFAAOCAQEA
27
- lUKo3NXePpuvN3QGsOLJ6QhNd4+Q9Rz75GipuMrCl296V8QFkd2gg9EG44Pqtk+9
28
- Zac8TkKc9bCSR0snakp+cCPplVvZF0/gMzkSTUJkDBHlNV16z73CyWpbQQa+iLJ4
29
- uisI6gF2ZXK919MYLn2bFJfb7OsCvVfyTPqq8afPY+rq9vlf9ZPwU49AlD8bPRic
30
- 0LX0gO5ykvETIOv+WgGcqp96ceNi9XVuJMh20uWuw6pmv/Ub2RqAf82jQSbpz09G
31
- G8LHR7EjtPPmqCCunfyecJ6MmCNaiJCBxq2NYzyNmluPyHT8+0fuB5kccUVZm6CD
32
- xn3DzOkDE6NYbk8gC9rTsA==
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: 2015-10-01 00:00:00.000000000 Z
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.11'
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.11'
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.7'
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.7'
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.13'
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.13'
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.0.0
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.4.7
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