#!/usr/bin/ruby # frozen_string_literal: true require "dhall" require "optparse" @extension = ".dhallb" def compile(source) Dhall.load( source, timeout: Float::INFINITY, resolver: Dhall::Resolvers::Default.new( max_depth: Float::INFINITY ) ) end module FilenameWriter def self.write(_, out, dhall) warn out out.dirname.mkpath out.write(dhall.to_binary) end end module CacheWriter def self.write(output_directory, out, dhall) base = "1220#{dhall.digest.hexdigest}" out = out.dirname + base if output_directory out = output_directory + base out.dirname.mkpath end warn out out.write(dhall.to_cbor) end end def compile_file(file_path, relative_to: Pathname.new(".")) $stderr.print "#{file_path} => " out = file_path.sub_ext(@extension) if @output_directory out = @output_directory + out.relative_path_from(relative_to) end compile(file_path.expand_path).then do |dhall| @writer.write(@output_directory, out, dhall) end end @writer = FilenameWriter # rubocop:disable Metrics/BlockLength opt_parser = OptionParser.new do |opts| opts.banner = "Usage: dhall-compile [options] [-] [files_and_dirs]" opts.on( "-oDIRECTORY", "--output-directory DIRECTORY", "Write output to this directory" ) do |dir| @output_directory = Pathname.new(dir) end opts.on( "-e [EXTENSION]", "--extension [EXTENSION]", "Use this extension for files (default .dhallb)" ) do |ext| @extension = ext ? ".#{ext}" : "" end opts.on( "-c", "--cache", "Write output in standard dhall file cache format" ) do @extension = "" @writer = CacheWriter end opts.on("-h", "--help", "Show this usage information") do warn opts exit end end # rubocop:enable Metrics/BlockLength opt_parser.parse! if ARGV.empty? warn opt_parser exit 0 end ARGV.map(&Pathname.method(:new)).each do |path| if !path.exist? && path.to_s == "-" warn "Compiling STDIN to STDOUT" compile(STDIN.read).then(&STDOUT.method(:write)).sync elsif path.file? compile_file(path, relative_to: path.dirname).sync elsif path.directory? warn "Recursively compiling #{path}" path.find.flat_map do |child| next if !child.file? || child.extname == ".dhallb" compile_file(child, relative_to: path).sync end else warn "#{path} may not exist" exit 1 end end