class Smith::ACLCompiler
Public Class Methods
new()
click to toggle source
# File lib/smith/acl_compiler.rb, line 11 def initialize @acl_type_cache = AclTypeCache.instance @acl_parser = ACLParser.new end
Public Instance Methods
compile()
click to toggle source
# File lib/smith/acl_compiler.rb, line 16 def compile $LOAD_PATH << Smith.acl_cache_directory Smith.acl_directories.each do |path| $LOAD_PATH << path acl_files = path_glob(path) out_of_date_acls = path_glob(path).select { |p| should_compile?(p) } if out_of_date_acls.size > 0 compile_on_path(path, acl_files, out_of_date_acls) end acl_files.each do |acl_file| acl_class_path = acl_compiled_path(acl_file) load_acl(acl_class_path) add_to_type_cache(acl_class_path) end end end
Private Instance Methods
acl_compiled_path(path)
click to toggle source
# File lib/smith/acl_compiler.rb, line 110 def acl_compiled_path(path) "#{Smith.acl_cache_directory.join(path.basename('.proto'))}.pb.rb" end
add_to_type_cache(path)
click to toggle source
# File lib/smith/acl_compiler.rb, line 98 def add_to_type_cache(path) acl_class = File.read(path) @acl_parser.go(acl_class) @acl_parser.fully_qualified_classes.each do |clazz| @acl_type_cache.add(to_class(clazz)) end end
capture_stderr() { || ... }
click to toggle source
This is not idea but I really don't know how else to do it. I cannot use $stderr = StringIO.new as this only seems to capture STDERR if you explicitly write to STDERR. In my case it's an ffi library call that's writing to STDERR.
# File lib/smith/acl_compiler.rb, line 80 def capture_stderr org_stderr = STDERR.dup begin tmp = Tempfile.new('') tmp.sync = true STDERR.reopen(tmp) yield File.read(tmp.path) ensure STDERR.reopen(org_stderr) end end
compile_on_path(path, acls, out_of_date_acls)
click to toggle source
# File lib/smith/acl_compiler.rb, line 38 def compile_on_path(path, acls, out_of_date_acls) out_of_date_acls.each { |acl| logger.debug("Compiling acl: #{path.join(acl)}") } unless acls.empty? Dir.chdir(path) do cmd = %Q{sh -c 'protoc --ruby_out=#{Smith.acl_cache_directory} -I #{path} #{out_of_date_acls.map(&:to_s).join(' ')} 2>&1'} protoc = IO.popen(cmd) output = protoc.read protoc.close if $?.exitstatus != 0 error = parse_protoc_error(output) logger.fatal { "Cannot compile ACLs: #{error[:file]}" } raise RuntimeError, output end end end end
load_acl(path)
click to toggle source
# File lib/smith/acl_compiler.rb, line 93 def load_acl(path) logger.verbose { "Loading ACL: #{path}" } require path end
parse_protoc_error(s)
click to toggle source
# File lib/smith/acl_compiler.rb, line 57 def parse_protoc_error(s) e = s.split(/:/) {:file => e[0], :line => e[1], :pos => e[2], :error => e[3,-1]} end
path_glob(path)
click to toggle source
# File lib/smith/acl_compiler.rb, line 72 def path_glob(path) Pathname.glob(path.join("*.proto")).map { |acl| acl.realpath } end
should_compile?(file)
click to toggle source
Returns true if the .proto file is newer that the .pb.rb file
# File lib/smith/acl_compiler.rb, line 63 def should_compile?(file) cached_file = Smith.acl_cache_directory.join(file.basename).sub_ext(".pb.rb") if cached_file.exist? file.mtime > cached_file.mtime else true end end
to_class(type_as_array)
click to toggle source
# File lib/smith/acl_compiler.rb, line 106 def to_class(type_as_array) type_as_array.inject(Kernel) { |acc, t| acc.const_get(t) } end