require 'optparse' options = {} def ensure_key!(m, k) if not m.has_key?(k) ks = m.keys.map { |k| k.to_s }.join(",") raise ArgumentError.new("Required key not set: #{k} (keys: #{ks})") end end OptionParser.new do |opts| opts.on("-c", "--classpath=PATH", "Classpath to pass to clojure.") { |cp| options[:classpath] = cp } opts.on("-t", "--target=TARGET", "Directory at which to perform the build.") { |target| options[:target] = target } opts.on("-p", "--project=PROJECT", "Name of the project being built (eg. org.clojure/build.tools).") { |project| options[:project] = project } opts.on("-v", "--version=VERS", "Version of the project being built (eg. 1.0.2).") { |vers| options[:version] = vers } opts.on("-e", "--build-deps=PATH", "Location of the build deps.edn, for build-specific dependencies.") { |deps| options[:build_deps] = deps } opts.on("-r", "--root=PATH", "Root of the build project, containing deps.edn.") { |path| options[:root] = path } opts.on("-s", "--source-paths=PATHS", "Location of the Clojure project to be built.") { |paths| options[:sources] = paths.split(",") } end.parse! [:classpath, :target, :project, :build_deps, :sources, :root, :version].each { |k| ensure_key!(options, k) } target = options[:target] if not (File::directory?(target) and File::writable?(target)) raise ArgumentError.new("Not a valid build target directory: #{target}") end options[:sources].each { |path| raise ArgumentError.new("Not a valid source path: #{path}") if not (File::directory? path) } if not File::exists? "#{options[:root]}/deps.edn" raise ArgumentError.new("Does not appear to be project root directory: #{options[:root]}") end if not File::exists? "#{options[:build_deps]}" raise ArgumentError.new("Build deps.edn not found: #{options[:build_deps]}") end command = [ "clojure", "-Scp #{options[:classpath]}", "-Sdeps #{options[:build_deps]}", "-T:build", "lib-uberjar", ":project #{options[:project]}", ":target #{options[:target]}", ":version #{options[:version]}", ":srcs #{options[:sources]}" ].join(" ") Dir::chdir(options[:root]) do output = `#{command}` puts output end