class CrossPlane::Builder
Constants
- DELIMITERS
- EXTERNAL_BUILDERS
- NEWLINE
- TAB
Attributes
header[RW]
indent[RW]
padding[RW]
payload[RW]
state[RW]
tabs[RW]
Public Class Methods
new(*args)
click to toggle source
# File lib/crossplane/builder.rb, line 22 def initialize(*args) args = args[0] || {} required = ['payload'] conflicts = [] requires = {} valid = { 'params' => [ 'header', 'indent', 'payload', 'tabs', ] } content = CrossPlane.utils.validate_constructor(client: self, args: args, required: required, conflicts: conflicts, requires: requires, valid: valid) self.header = (content[:header] && content[:header] == true) ? true : false self.indent = content[:indent] ? content[:indent] : 4 self.payload = content[:payload] ? content[:payload] : nil self.tabs = (content[:tabs] && content[:tabs] == true) ? true : false end
Public Instance Methods
build(*args)
click to toggle source
# File lib/crossplane/builder.rb, line 44 def build(*args) self.padding = self.tabs ? TAB : ' ' * self.indent self.state = { 'prev_obj' => nil, 'depth' => -1, } if self.header lines = [ "# This config was built from JSON using NGINX crossplane.\n", "# If you encounter any bugs please report them here:\n", "# https://github.com/gdanko/crossplane/issues\n", "\n" ] else lines = [] end lines += _build_lines(payload) lines.join('') end
Private Instance Methods
_build_lines(objs)
click to toggle source
# File lib/crossplane/builder.rb, line 83 def _build_lines(objs) lines = Enumerator.new do |y| self.state['depth'] = self.state['depth'] + 1 objs.each do |obj| directive = obj['directive'] if EXTERNAL_BUILDERS[directive] #built = external_builder(obj, padding, state) #y.yield(_put_line(built_obj)) #next end if directive == '#' y.yield(_put_line( '#' + obj['comment'], obj )) next end args = obj['args'].map{|arg| _enquote(arg)} if directive == 'if' line = format('if (%s)', args.join(' ')) elsif args and args.length > 0 line = format('%s %s', directive, args.join(' ')) else line = directive end if not obj.key?('block') y.yield(_put_line(line + ';', obj)) else y.yield(_put_line(line + ' {', obj)) # set prev_obj to proper indentation in block self.state['prev_obj'] = obj _build_lines(obj['block']).each do |line| y.yield(line) end y.yield(_put_line('}', obj)) end self.state['prev_obj'] = obj end self.state['depth'] = self.state['depth'] - 1 end lines.to_a end
_enquote(arg)
click to toggle source
# File lib/crossplane/builder.rb, line 132 def _enquote(arg) if _needs_quotes(arg) arg = arg.inspect arg = arg.gsub('\\\\', '\\') end arg end
_escape(string)
click to toggle source
# File lib/crossplane/builder.rb, line 140 def _escape(string) chars = Enumerator.new do |y| prev, char = '', '' string.split('').each do |char| if prev == '\\' or prev + char == '${' prev += char y.yield char next end if prev == '$' y.yield prev end if not ['\\', '$'].include?(char) y.yield char end prev = char end if ['\\', '$'].include?(char) y.yield char end end chars end
_needs_quotes(string)
click to toggle source
# File lib/crossplane/builder.rb, line 167 def _needs_quotes(string) if string == '' return true elsif DELIMITERS.include?(string) return false end # lexer should throw an error when variable expansion syntax # is messed up, but just wrap it in quotes for now I guess chars = _escape(string) char = chars.next if CrossPlane.utils.isspace(char) or ['{', ';', '"', "'", '${'].include?(char) return true end expanding = false begin while char = chars.next if CrossPlane.utils.isspace(char) or ['{', ';', '"', "'"].include?(char) return true elsif char == (expanding ? '${' : '}') return true elsif char == (expanding ? '}' : '${') expanding = !expanding end end return ['\\', '$'].include?(char) ? ['\\', '$'].include?(char) : expanding rescue StopIteration end end
_put_line(line, obj)
click to toggle source
# File lib/crossplane/builder.rb, line 67 def _put_line(line, obj) margin = self.padding * self.state['depth'] # don't need put \n on first line and after comment if self.state['prev_obj'].nil? return margin + line end # trailing comments have to be without \n if obj['directive'] == '#' and obj['line'] == self.state['prev_obj']['line'] return ' ' + line end return NEWLINE + margin + line end