#!/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
)
).then(&:to_binary)
end
def compile_file(file_path, relative_to: Pathname.new("."))
out = file_path.sub_ext(@extension)
if @output_directory
out = @output_directory + out.relative_path_from(relative_to)
out.dirname.mkpath
end
warn "#{file_path} => #{out}"
compile(file_path.expand_path).then(&out.method(:write))
end
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("-h", "--help", "Show this usage information") do
warn opts
exit
end
end
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