class Puter::Puterfile
Constants
- BACKSLASH
- BLANK
- COMMANDS
- COMMENT
- CONTINUE
- COPY
- FROM
- RUN
Attributes
executable_ops[RW]
from[RW]
lines[RW]
operations[RW]
raw[RW]
Public Class Methods
executable_operations(operations)
click to toggle source
# File lib/puter/puterfile.rb, line 119 def executable_operations(operations) execs = [] operations.each_with_index do |op, i| case op[:operation] when COPY, RUN, FROM exec = { :operation => op[:operation], :data => op[:data].dup } exec[:start_line] = exec[:end_line] = i execs << exec when CONTINUE execs.last[:data] << op[:data] execs.last[:end_line] = i end end execs.select { |e| e[:operation] == COPY }.each do |e| e[:from], e[:to] = e[:data].strip.split /\s+/, 2 raise SyntaxError.new "COPY operation requires two parameters #{e.inspect}" if e[:from].nil? || e[:to].nil? end execs end
from_path(path)
click to toggle source
# File lib/puter/puterfile.rb, line 42 def from_path(path) parse File.open(path, 'rb') { |f| f.read } end
parse(raw)
click to toggle source
# File lib/puter/puterfile.rb, line 46 def parse(raw) p = Puterfile.new p.raw = raw p.lines = raw.to_s.split "\n" p.operations = parse_operations(p.lines) p.executable_ops = executable_operations(p.operations) p.from = p.operations[0][:data] p end
parse_operation(line, previous_line="")
click to toggle source
# File lib/puter/puterfile.rb, line 75 def parse_operation(line, previous_line="") op = {} line = line.rstrip unless line.nil? case when line.nil? raise SyntaxError.new 'cannot parse nil lines' # blank line when line.strip.empty? op[:operation] = BLANK op[:data] = line op[:continue] = false # commented line when line =~ /\s*\#/ op[:operation] = COMMENT op[:data] = line op[:continue] = line[-1] == BACKSLASH # continuation of a previous line when line =~ /\s/ && previous_line.rstrip[-1] == BACKSLASH op[:operation] = CONTINUE op[:data] = line.lstrip op[:continue] = line[-1] == BACKSLASH # must be an operation (FROM, COPY, RUN, ...) else parts = line.split(/\s+/, 2) cmd = parts[0].downcase.to_sym data = parts[1] raise SyntaxError.new "Unknown operation [#{cmd.to_s.upcase}]" unless COMMANDS.include? cmd raise SyntaxError.new "Operation [#{cmd.to_s.upcase}] has no data" if data.nil? op[:operation] = cmd op[:data] = data op[:continue] = line[-1] == BACKSLASH end op[:data][-1] = " " if op[:continue] op end
parse_operations(lines)
click to toggle source
# File lib/puter/puterfile.rb, line 56 def parse_operations(lines) raise Puter::SyntaxError.new "File is empty. First line must be a FROM command" if lines.length == 0 ops = [] previous_line = "" lines.each_with_index do | line, i | begin ops << parse_operation(line, previous_line) if i == 0 raise Puter::SyntaxError.new "First line must be a FROM command" unless ops[i][:operation] == FROM end rescue Puter::SyntaxError => se raise Puter::SyntaxError.new "On line #{i+1}: #{se.message}" end previous_line = line end ops end
Public Instance Methods
apply(context, backend, ui)
click to toggle source
# File lib/puter/puterfile.rb, line 146 def apply(context, backend, ui) dependency_check(context) ret = { :exit_status => 0, :exit_signal => nil } executable_ops.each_with_index do |op, step| ui.info "Step #{step} : #{op[:operation].to_s.upcase} #{op[:data]}" case op[:operation] when COPY backend.copy path_in_context(op[:from], context), op[:to] when RUN ret = backend.run op[:data] do | type, data | case type when :stderr ui.remote_stderr data when :stdout ui.remote_stdout data end end if ret[:exit_status] != 0 line = "#{op[:start_line]+1}" plural = "" if op[:start_line] != op[:end_line] line << "..#{op[:end_line]+1}" plural = "s" end raise RunError.new "On line#{plural} #{line}: RUN command exited non-zero.", ret end end end ret end
Private Instance Methods
dependency_check(context)
click to toggle source
# File lib/puter/puterfile.rb, line 187 def dependency_check(context) executable_ops.each do |op| case op[:operation] when COPY File.open(path_in_context(op[:from], context), 'r') {} end end end
path_in_context(path, context)
click to toggle source
# File lib/puter/puterfile.rb, line 183 def path_in_context(path, context) File.expand_path(path, context) end