require "uuid" require "uri" require "file_utils" require "./context.cr" require "./package.cr" require "./instructions.cr" require "./sources.cr" # 🤔 class URI def basename File.basename path end end class Package::Recipe @context : Context getter name : String getter version : String getter dirname : String? getter sources : Sources getter packages : Array(Package) getter instructions = Instructions.new def initialize(@context, @name, @version) @sources = Sources.new @packages = [] of Package @working_uuid = UUID.random end def self.new(context, name, version) instance = Recipe.allocate.tap &.initialize(context, name, version) instance.packages << Package.new instance instance end def working_directory @context.working_directory end def building_directory "#{working_directory}/build" end def fake_root_directory "#{working_directory}/root" end def dirname @dirname || "#{name}-#{version}" end def download sources.map do |url| unless File.exists? url.basename @context.run @context.sources_directory, "wget", [ url.to_s, "-O", url.basename ] end end end def extract Dir.mkdir_p building_directory sources.map do |url| basename = url.basename @context.run building_directory, "tar", [ "xvf", @context.sources_directory + "/" + url.basename ] end end # TODO: # - Export packaging directory in $PKG. # - Add (pre|post)-(configure|build|install) instructions. # - Have some instructions be non-critical, like the (pre|post] ones. # - Be careful about return values, flee from everything if something # goes somehow wrong. # - Make things thread-safe. (those ENV[]= calls are definitely not) def build success = true Dir.mkdir_p fake_root_directory ENV["PKG"] = fake_root_directory # Safety precautions. old_dir = Dir.current instructions.to_a.each do |instruction| if instruction.run(@context, self).failed? break BuildStatus::Failed end end Dir.cd old_dir ENV["PKG"] = nil success end # TODO: # - Errors management. Stop at first failure? # - Splits. This should be done between #build and #package. def package @packages.find do |package| ! @context.package package end end def clean FileUtils.rm_rf building_directory FileUtils.rm_rf fake_root_directory end def to_s "#{name}-#{version}" end end