diff --git a/src/backends.cr b/src/backends.cr index 010f439..4944d3d 100644 --- a/src/backends.cr +++ b/src/backends.cr @@ -5,7 +5,7 @@ abstract class Package::Backend::Packaging def initialize(@name) end - abstract def package(context : Context, package : Package) : Bool + abstract def package(pkgdir : String, architecture : String, package : Package) : Bool def self.install(packages : Array(String)) raise "'install' unimplemented for this backend, yet" end @@ -14,13 +14,4 @@ abstract class Package::Backend::Packaging end end -class Package::Backend::Splitter - def initialize(&block : Proc(Recipe, Package)) - @callback = block - end - - def create_split(recipe : Recipe) : Package - @callback.call recipe - end -end - +require "./backends/*" \ No newline at end of file diff --git a/src/backends/apk.cr b/src/backends/apk.cr index d2472c5..3a45b2f 100644 --- a/src/backends/apk.cr +++ b/src/backends/apk.cr @@ -1,23 +1,25 @@ require "../backends.cr" -class ApkBackend < Package::Backend::Packaging +class Package::Backend::Packaging::APK < Package::Backend::Packaging def initialize @name = "apk" end - def package(context : Package::Context, package : Package::Package) : Bool + def package(pkgdir : String, architecture : String, package : ::Package::Package) : Bool # FIXME: This needs to have access to architecture (from Context?) # to work properly. old_cwd = Dir.current - File.write "#{package.fake_root_directory}/.PKGINFO", ApkBackend.pkginfo package + APK.pkginfo package, "#{package.fake_root_directory}/.PKGINFO" # Create data.tar.gz here. - package_target = "#{context.packages_directory}/#{context.architecture}/#{package.name}-#{package.version}-r#{package.release}.apk" + package_target = "#{pkgdir}/" + package_target += "#{architecture}/" + package_target += "#{package.name}-#{package.version}-r#{package.release}.apk" Dir.mkdir_p File.dirname package_target # FIXME: This shouldn’t have to be in users’ PATH. libexec? - r = context.run package.fake_root_directory, "#{OWN_LIBEXEC_DIR}/assemble-apk.sh", [ + r = Do.run package.fake_root_directory, "#{OWN_LIBEXEC_DIR}/assemble-apk.sh", [ package_target ] @@ -25,34 +27,32 @@ class ApkBackend < Package::Backend::Packaging end # This generated file content is specific to the Apk package manager. - def self.pkginfo(package) + def self.pkginfo(package : ::Package::Package, file_name : String) du = `du -sk #{package.fake_root_directory}` - size = du.sub(/[ \t].*/, "").to_i * 1024 + size = du.sub(/[ \t].*/, "").to_u64 * 1024_u64 - lines = [] of String + File.open file_name, "w" do |file| + file.puts "# Generated by `packaging`." + file.puts "pkgname = #{package.name}" + file.puts "pkgver = #{package.version}-r#{package.release}" + file.puts "url = #{package.url || ""} " + file.puts "size = #{size}" + file.puts "origin = #{package.recipe.name}" + file.puts "buildtype = host" # This’ll need to be imported from Context. + file.puts "builddate = #{Time.utc.to_unix}" - lines << "# Generated by `packaging`." - lines << "pkgname = #{package.name}" - lines << "pkgver = #{package.version}-r#{package.release}" - lines << "url = #{package.url || ""} " - lines << "size = #{size}" - lines << "origin = #{package.recipe.name}" - lines << "buildtype = host" # This’ll need to be imported from Context. - lines << "builddate = #{Time.utc.to_unix}" + package.dependencies.each do |atom| + file.puts "depend = #{atom.to_s}" + end - package.dependencies.each do |atom| - lines << "depend = #{atom.to_s}" + package.provides.each do |atom| + file.puts "provides = #{atom.to_s}" + end + + package.conflicts.each do |atom| + file.puts "conflicts = #{atom.to_s}" + end end - - package.provides.each do |atom| - lines << "provides = #{atom.to_s}" - end - - package.conflicts.each do |atom| - lines << "conflicts = #{atom.to_s}" - end - - lines.join("\n") + "\n" end # Install programs. diff --git a/src/backends/baguette.cr b/src/backends/baguette.cr index 23d08bb..6bb31bd 100644 --- a/src/backends/baguette.cr +++ b/src/backends/baguette.cr @@ -3,38 +3,43 @@ require "openssl" require "../backends.cr" -class BaguetteBackend < Package::Backend::Packaging +class Package::Backend::Packaging::Baguette < Package::Backend::Packaging def initialize @name = "package" end # TODO: checksums + security - def package(context : Package::Context, package : Package::Package) : Bool + def package(pkgdir : String, architecture : String, package : ::Package::Package) : Bool # Fake root example: /tmp/packages//root-xz-dev fake_root = package.fake_root_directory - data_archive_path = "#{fake_root}/data.tar" - compressed_data_archive_path = "#{fake_root}/data.tar.zst" - control_spec_file_path = "#{fake_root}/control.spec" - manifest_file_path = "#{fake_root}/manifest" + # Temporary archive, before compression. + data_archive_path = "#{fake_root}/data.tar" # All archive data. + # Content of the final tarball. + compressed_data_archive_path = "#{fake_root}/data.tar.zst" # Compressed version (in final tarball). + control_spec_file_path = "#{fake_root}/control.spec" # Spec file, with package informations. + manifest_file_path = "#{fake_root}/manifest" # List of all the included files. - package_target = "#{context.packages_directory}/#{package.name}-#{package.version}-#{package.release}.baguette" + package_target = "#{pkgdir}/" + package_target += "#{architecture}/" + package_target += "#{package.name}-#{package.version}-#{package.release}.baguette" + Dir.mkdir_p File.dirname package_target - context.detail "Archiving package content" - context.run fake_root, "tar", ["cvf", data_archive_path, "."] + ::Baguette::Log.detail "Archiving package content" + Do.run fake_root, "tar", ["cvf", data_archive_path, "."] - context.detail "Compressing the archive" + ::Baguette::Log.detail "Compressing the archive" # produces data.tar.zst - context.run fake_root, "zstd", ["--ultra", data_archive_path] + Do.run fake_root, "zstd", ["--ultra", data_archive_path] - context.detail "Generating control.spec" + ::Baguette::Log.detail "Generating control.spec" generate_spec package, control_spec_file_path - context.detail "Generating manifest" - generate_manifest context, package, manifest_file_path + ::Baguette::Log.detail "Generating manifest" + generate_manifest package, manifest_file_path - context.detail "Assembling '#{package_target}'" - r = context.run fake_root, "tar", [ + ::Baguette::Log.detail "Assembling '#{package_target}'" + r = Do.run fake_root, "tar", [ "cf", package_target, # WARNING: relative paths are necessary. "control.spec", "manifest", "data.tar.zst" @@ -43,31 +48,29 @@ class BaguetteBackend < Package::Backend::Packaging r.exit_status == 0 end - def generate_spec(package : Package::Package, file_name : String) + def generate_spec(package : ::Package::Package, file_name : String) du = `du -sk #{package.fake_root_directory}` size = du.sub(/[ \t].*/, "").to_u64 * 1024_u64 - file = File.open file_name, "w" - - file.puts "name: #{package.name}" - file.puts "version: #{package.version}" - file.puts "release: #{package.release}" - file.puts - file.puts "size: #{size}" - file.puts "origin: #{package.recipe.name}" - file.puts "slot: #{package.prefix}" - file.puts - file.puts "url: #{package.url}" - file.puts "description: #{package.description}" - file.puts - file.puts "dependencies: #{package.dependencies.join ", "}" - file.puts "conflicts: #{package.conflicts.join ", "}" - file.puts "provides: #{package.provides.join ", "}" - - file.close + File.open file_name, "w" do |file| + file.puts "name: #{package.name}" + file.puts "version: #{package.version}" + file.puts "release: #{package.release}" + file.puts + file.puts "size: #{size}" + file.puts "origin: #{package.recipe.name}" + file.puts "slot: #{package.prefix}" + file.puts + file.puts "url: #{package.url}" + file.puts "description: #{package.description}" + file.puts + file.puts "dependencies: #{package.dependencies.join ", "}" + file.puts "conflicts: #{package.conflicts.join ", "}" + file.puts "provides: #{package.provides.join ", "}" + end end - def generate_manifest(context : Package::Context, package : Package::Package, file_name : String) + def generate_manifest(package : ::Package::Package, file_name : String) old_pwd = Dir.current manifest = File.open(file_name, "w").not_nil! diff --git a/src/backends/build.cr b/src/backends/build.cr new file mode 100644 index 0000000..3242937 --- /dev/null +++ b/src/backends/build.cr @@ -0,0 +1,23 @@ + +class Package::Backend::Build + + def self.make : Backend::Building + Backend::Building.new "build", "make" do |context, recipe| + next BuildStatus::Pass unless Dir.exists? recipe.dirname + Dir.cd recipe.dirname + + unless File.exists? "Makefile" + next BuildStatus::Pass + end + + child = Do.sh "make -j#{context.build_cores} #{recipe.options["make"]? || ""}" + + if child.exit_status == 0 + BuildStatus::Success + else + BuildStatus::Failed + end + end + end + +end diff --git a/src/backends/configure.cr b/src/backends/configure.cr new file mode 100644 index 0000000..99ff575 --- /dev/null +++ b/src/backends/configure.cr @@ -0,0 +1,47 @@ + +class Package::Backend::Configure + + def self.autotools : Backend::Building + Backend::Building.new "configure", "autotools" do |context, recipe| + next BuildStatus::Pass unless Dir.exists? recipe.dirname + + Dir.cd recipe.dirname + + unless File.exists? "configure" + next BuildStatus::Pass + end + + child = Do.sh "./configure --prefix=#{recipe.prefix} #{recipe.options["configure"]? || ""}" + + if child.exit_status == 0 + BuildStatus::Success + else + BuildStatus::Failed + end + end + end + + def self.cmake : Backend::Building + Backend::Building.new "configure", "cmake" do |context, recipe| + next BuildStatus::Pass unless Dir.exists? recipe.dirname + + Dir.cd recipe.dirname + + next BuildStatus::Pass unless File.exists? "CMakeLists.txt" + + options = [ + "-DCMAKE_INSTALL_PREFIX='#{recipe.prefix}'", + "-DCMAKE_BUILD_TYPE=Release #{recipe.options["cmake"]}", + "-- -j#{context.build_cores}" + ] + + child = Do.sh "cmake . #{options.join " "}" + if child.exit_status == 0 + BuildStatus::Success + else + BuildStatus::Failed + end + end + end + +end diff --git a/src/backends/install.cr b/src/backends/install.cr new file mode 100644 index 0000000..4b812e5 --- /dev/null +++ b/src/backends/install.cr @@ -0,0 +1,23 @@ + +class Package::Backend::Install + def self.make : Backend::Building + Backend::Building.new "install", "make" do |context, recipe| + next BuildStatus::Pass unless Dir.exists? recipe.dirname + Dir.cd recipe.dirname + + unless File.exists? "Makefile" + next BuildStatus::Pass + end + + child = Do.sh "make install 'DESTDIR=#{recipe.fake_root_directory}' #{recipe.options["make install"]? || ""}" + + if child.exit_status == 0 + BuildStatus::Success + else + BuildStatus::Failed + end + end + end + +end + diff --git a/src/backends/pkgutils.cr b/src/backends/pkgutils.cr index 65895db..8f3e35d 100644 --- a/src/backends/pkgutils.cr +++ b/src/backends/pkgutils.cr @@ -1,13 +1,21 @@ require "../backends.cr" +require "baguette-crystal-base" -class PkgutilsBackend < Package::Backend::Packaging +# This packaging backend only helps to create a package containing the data. +# This serves as the simplest example of packaging system: +# no extra data nor structure in the final archive. + +class Package::Backend::Packaging::Pkgutils < Package::Backend::Packaging def initialize @name = "pkgutils" end - def package(context : Package::Context, package : Package::Package) : Bool - puts "#{package.fake_root_directory} -> #{context.packages_directory}/#{package.name}##{package.version}-#{package.release}.pkg.tar.xz" - pp! r = context.run package.fake_root_directory, "tar", ["cJf", "#{context.packages_directory}/#{package.name}##{package.version}.pkg.tar.xz", "."] + def package(pkgdir : String, architecture : String, package : ::Package::Package) : Bool + package_file = pkgdir + "/" + architecture + "/" + package_file += "#{package.name}-#{package.version}-#{package.release}.pkg.tar.xz" + + ::Baguette::Log.info "#{package.fake_root_directory} -> #{package_file}" + pp! r = Do.run package.fake_root_directory, "tar", ["cJf", package_file, "."] r.exit_status == 0 end diff --git a/src/backends/splitter.cr b/src/backends/splitter.cr new file mode 100644 index 0000000..dfb32c0 --- /dev/null +++ b/src/backends/splitter.cr @@ -0,0 +1,75 @@ + +class Package::Backend::Splitter + def initialize(&block : Proc(Recipe, Package)) + @callback = block + end + + def create_split(recipe : Recipe) : Package + @callback.call recipe + end + + # Package::Backend::Splitter = create new package + # takes (then stores) the given block + # this block takes a recipe as a parameter and create a new package + # the new package: + # keep prefixes + # new name = split name (-man, -src, ...) + # split files + + # Man-pages and documentation + def self.man(prefixes : Array(String)) : Splitter + Backend::Splitter.new do |recipe| + Package.new(recipe, true).tap do |split| + prefixes = (prefixes + [recipe.prefix]).uniq + + split.name = "#{recipe.name}-man" + split.files = prefixes.map do |prefix| + "#{prefix}/share/man" + end + split.recipe.require_stripping = false + end + end + end + + # Developer's files: headers, pkgconfig files, *.a. + def self.dev(prefixes : Array(String)) : Splitter + Backend::Splitter.new do |recipe| + Package.new(recipe, true).tap do |split| + prefixes = (prefixes + [recipe.prefix]).uniq + + split.name = "#{recipe.name}-dev" + split.files = prefixes.map do |prefix| + [ + "#{prefix}/include", + "#{prefix}/lib/pkgconfig" + ] + end.flatten + split.file_patterns = prefixes.map do |prefix| + Regex.new("^" + prefix + ".*\\.a$") + end + # Any prefix containing "/include/" + split.file_patterns.not_nil! << Regex.new(".*/include/.*.h(pp)?") + end + end + end + + # Source files: prefix containing "src". + def self.src(prefixes : Array(String)) : Splitter + Backend::Splitter.new do |recipe| + Package.new(recipe, true).tap do |split| + prefixes = (prefixes + [recipe.prefix]).uniq + + split.name = "#{recipe.name}-src" + split.files = prefixes.map do |prefix| + [ + "#{prefix}/lib/share/src", + "#{prefix}/src", + "#{prefix}/usr/src", + "#{prefix}/usr/local/src" + ] + end.flatten + split.recipe.require_stripping = false + end + end + end +end diff --git a/src/context.cr b/src/context.cr index f14fe3a..b5e3dd3 100644 --- a/src/context.cr +++ b/src/context.cr @@ -1,14 +1,8 @@ require "colorize" - require "specparser" require "./exception.cr" - require "./config.cr" - -require "./backends/baguette.cr" -require "./backends/apk.cr" -require "./backends/pkgutils.cr" require "./backends.cr" class Package::Context @@ -29,157 +23,37 @@ class Package::Context # prefixes for `packaging` running environment and child processes # = where to search for binaries and libraries for the build - property prefixes = ["/usr", "/", "/usr/baguette"] + property prefixes = ["/usr/baguette", "/usr", "/"] # By default, building a package only uses one core property build_cores = 1 # list of environment variables we want to have when building - property environment = {} of String => String - - property verbosity = 0 + #property environment = {} of String => String property recipe : Recipe? = nil def initialize - @packaging_backends << ApkBackend.new - @packaging_backends << BaguetteBackend.new - @packaging_backends << PkgutilsBackend.new + # Add package backends: baguette (package-tools) and apk. + # They implement the Backend::Packaging abstract class: + # init (@name) + package (context, package) method + @packaging_backends << Backend::Packaging::Baguette.new + @packaging_backends << Backend::Packaging::APK.new + @packaging_backends << Backend::Packaging::Pkgutils.new @selected_packaging_backend = @packaging_backends[0] - @building_backends << Backend::Building.new "configure", "autotools" do |context, recipe| - next BuildStatus::Pass unless Dir.exists? recipe.dirname + # Add building backends: configuration, build and install. + @building_backends << Backend::Configure.autotools + @building_backends << Backend::Configure.cmake + @building_backends << Backend::Build.make + @building_backends << Backend::Install.make - Dir.cd recipe.dirname - - unless File.exists? "configure" - next BuildStatus::Pass - end - - child = context.sh "./configure --prefix=#{recipe.prefix} #{recipe.options["configure"]? || ""}" - - if child.exit_status == 0 - BuildStatus::Success - else - BuildStatus::Failed - end - end - - @building_backends << Backend::Building.new "configure", "cmake" do |context, recipe| - next BuildStatus::Pass unless Dir.exists? recipe.dirname - - Dir.cd recipe.dirname - - next BuildStatus::Pass unless File.exists? "CMakeLists.txt" - - options = [ - "-DCMAKE_INSTALL_PREFIX='#{recipe.prefix}'", - "-DCMAKE_BUILD_TYPE=Release #{recipe.options["cmake"]}", - "-- -j#{context.build_cores}" - ] - - child = context.sh "cmake . #{options.join " "}" - if child.exit_status == 0 - BuildStatus::Success - else - BuildStatus::Failed - end - end - - @building_backends << Backend::Building.new "build", "make" do |context, recipe| - next BuildStatus::Pass unless Dir.exists? recipe.dirname - Dir.cd recipe.dirname - - unless File.exists? "Makefile" - next BuildStatus::Pass - end - - child = context.sh "make -j#{context.build_cores} #{recipe.options["make"]? || ""}" - - if child.exit_status == 0 - BuildStatus::Success - else - BuildStatus::Failed - end - end - - @building_backends << Backend::Building.new "install", "make" do |context, recipe| - next BuildStatus::Pass unless Dir.exists? recipe.dirname - Dir.cd recipe.dirname - - unless File.exists? "Makefile" - next BuildStatus::Pass - end - - child = context.sh "make install 'DESTDIR=#{recipe.fake_root_directory}' #{recipe.options["make install"]? || ""}" - - if child.exit_status == 0 - BuildStatus::Success - else - BuildStatus::Failed - end - end - - # Package::Backend::Splitter = create new package - # takes (then stores) the given block - # this block takes a recipe as a parameter and create a new package - # the new package: - # keep prefixes - # new name = split name (-man, -src, ...) - # split files - - # Man-pages and documentation - @splitter_backends << Backend::Splitter.new do |recipe| - Package.new(recipe, true).tap do |split| - prefixes = (@prefixes + [recipe.prefix]).uniq - - split.name = "#{recipe.name}-man" - split.files = prefixes.map do |prefix| - "#{prefix}/share/man" - end - split.recipe.require_stripping = false - end - end - - # Developer's files: headers, pkgconfig files, *.a. - @splitter_backends << Backend::Splitter.new do |recipe| - Package.new(recipe, true).tap do |split| - prefixes = (@prefixes + [recipe.prefix]).uniq - - split.name = "#{recipe.name}-dev" - split.files = prefixes.map do |prefix| - [ - "#{prefix}/include", - "#{prefix}/lib/pkgconfig" - ] - end.flatten - split.file_patterns = prefixes.map do |prefix| - Regex.new("^" + prefix + ".*\\.a$") - end - # Any prefix containing "/include/" - split.file_patterns.not_nil! << Regex.new(".*/include/.*/") - end - end - - # Source files: prefix containing "src". - @splitter_backends << Backend::Splitter.new do |recipe| - Package.new(recipe, true).tap do |split| - prefixes = (@prefixes + [recipe.prefix]).uniq - - split.name = "#{recipe.name}-src" - split.files = prefixes.map do |prefix| - [ - "#{prefix}/lib/share/src", - "#{prefix}/src", - "#{prefix}/usr/src", - "#{prefix}/usr/local/src" - ] - end.flatten - split.recipe.require_stripping = false - end - end + # Split = new package from a recipe, each one with different files being included. + @splitter_backends << Backend::Splitter.man @prefixes + @splitter_backends << Backend::Splitter.dev @prefixes + @splitter_backends << Backend::Splitter.src @prefixes end def packaging_backend=(name : String) @@ -190,84 +64,8 @@ class Package::Context @selected_packaging_backend = backend end - def run(chdir, command, args) - output = Process::Redirect::Inherit - - if @verbosity < -1 - output = Process::Redirect::Close - else - # log sub-commands outputs - logfile_path = "#{@working_directory}/#{@recipe.not_nil!.working_uuid}.log" - output = File.open logfile_path, "a" - STDOUT.puts "logging command " + - "#{command} #{args}".colorize(:light_magenta).to_s - STDOUT.puts "in " + logfile_path.colorize(:blue).mode(:bright).to_s - - output.puts "" - output.puts "" - output.puts "logging command $ #{command}" - output.puts " parameters $ #{args}" - end - - c = Process.run command, args, chdir: chdir, output: output, error: output, env: @environment - - case output - when File - output.close - end - - c - end - - def run(command, args) - run nil, command, args - end - - def run(command) - run nil, command, nil - end - - def sh(command) - run nil, "sh", ["-x", "-e", "-c", command] - end - - def captured_sh(command) - output = IO::Memory.new - child = Process.run "sh", ["-x", "-e", "-c", command], output: output - - {child, output} - end - - # Log file moves during splits. - def mv(f1 : String, f2 : String) - run "mv", [ f1, f2 ] - end - - # Log directory creations during splits. - def mkdir_p(dir : String) - run "mkdir", [ "-p", dir ] - end - - # Output functions. - def title(s) - return if @verbosity < -3 - puts ">> ".colorize(:green).mode(:bright).to_s + - s.colorize(:white).mode(:bright).to_s - STDOUT.flush - end - def info(s) - return if @verbosity < -2 - puts ":: ".colorize(:green).to_s + s.colorize(:white).to_s - STDOUT.flush - end - def detail(s) - return if @verbosity < -1 - puts ("+ " + s).colorize(:cyan) - STDOUT.flush - end - def package(package : Package) : Bool - @selected_packaging_backend.package self, package + @selected_packaging_backend.package @packages_directory, @architecture, package end def read_recipe(filename : String) @@ -320,8 +118,8 @@ class Package::Context end key, value = match - @environment[key] = value - if @verbosity > 0 + Do.environment[key] = value + if Baguette::Context.verbosity > 2 STDOUT.puts "environment: #{key} => #{value}" end end diff --git a/src/do.cr b/src/do.cr index fddfbb8..7e320e8 100644 --- a/src/do.cr +++ b/src/do.cr @@ -1,9 +1,75 @@ +class Baguette::Context + #class_property logfile_path = "#{@working_directory}/#{@recipe.not_nil!.working_uuid}.log" + class_property logfile_path = "/tmp/package-create.log" + class_property no_logfile = false +end + class Do < Process + class_property environment = {} of String => String + def self.require_cmd(cmd : String) unless Process.run("which", [ cmd ]).success? STDERR.puts "#{cmd} isn't installed" exit 1 end end + + def self.run(chdir, command, args) + output = Process::Redirect::Inherit + + if Baguette::Context.no_logfile + output = Process::Redirect::Close + else + # log sub-commands outputs + STDOUT.puts "logging command " + + "#{command} #{args}".colorize(:light_magenta).to_s + STDOUT.puts "in " + Baguette::Context.logfile_path.colorize(:blue).mode(:bright).to_s + + File.open Baguette::Context.logfile_path, "a" do |file| + file.puts "" + file.puts "" + file.puts "logging command $ #{command}" + file.puts " parameters $ #{args}" + end + end + + c = Process.run command, args, chdir: chdir, output: output, error: output, env: @@environment + + case output + when File + output.close + end + + c + end + + def self.run(command, args) + self.run nil, command, args + end + + def self.run(command) + self.run nil, command, nil + end + + def self.sh(command) + self.run nil, "sh", ["-x", "-e", "-c", command] + end + + def self.captured_sh(command) + output = IO::Memory.new + child = Process.run "sh", ["-x", "-e", "-c", command], output: output + + {child, output} + end + + # Log file moves during splits. + def self.mv(f1 : String, f2 : String) + self.run "mv", [ f1, f2 ] + end + + # Log directory creations during splits. + def self.mkdir_p(dir : String) + self.run "mkdir", [ "-p", dir ] + end end diff --git a/src/instructions.cr b/src/instructions.cr index 08c6e10..4de3ace 100644 --- a/src/instructions.cr +++ b/src/instructions.cr @@ -28,7 +28,7 @@ class Package::Instructions def run(context : Context, recipe : Recipe) : BuildStatus if size > 0 each do |command| - child = context.run recipe.building_directory, "sh", ["-x", "-c", command] + child = Do.run recipe.building_directory, "sh", ["-x", "-c", command] if child.exit_status != 0 return BuildStatus::Failed diff --git a/src/main.cr b/src/main.cr index 8829342..3d84f4e 100644 --- a/src/main.cr +++ b/src/main.cr @@ -1,6 +1,7 @@ require "option_parser" require "file_utils" require "colorize" +require "baguette-crystal-base" require "./context.cr" require "./recipe.cr" @@ -70,11 +71,11 @@ OptionParser.parse do |parser| } parser.on("-v", "--verbose", "Runs more verbosely.") { - context.verbosity += 1 + Baguette::Context.verbosity += 1 } parser.on("-q", "--quiet", "Runs more quietely.") { - context.verbosity -= 1 + Baguette::Context.verbosity -= 1 } parser.on("-n", "--ignore-dependencies", "Do not try to install build-dependencies.") { @@ -172,7 +173,7 @@ begin recipes.each do |recipe| latest_build_dir = recipe.building_directory - context.title recipe.name + Baguette::Log.title recipe.name recipe.download diff --git a/src/recipe.cr b/src/recipe.cr index a465a3f..0bb4f8c 100644 --- a/src/recipe.cr +++ b/src/recipe.cr @@ -216,13 +216,13 @@ class Package::Recipe unless File.exists? filename if url.scheme == "file" - @context.info "Copying '#{url.filename}'" + Baguette::Log.info "Copying '#{url.filename}'" FileUtils.cp "#{recipe_directory}/#{url.filename}", filename else - @context.info "Downloading '#{url.filename}'" + Baguette::Log.info "Downloading '#{url.filename}'" - status = @context.run @context.sources_directory, "wget", [ url.to_s, "-O", filename ] + status = Do.run @context.sources_directory, "wget", [ url.to_s, "-O", filename ] raise DownloadError.new self, url unless status.success? end @@ -231,15 +231,15 @@ class Package::Recipe end def extract - @context.mkdir_p building_directory + Do.mkdir_p building_directory sources.each do |url| basename = url.filename if basename.match /\.(tar\.(gz|xz|bz2|lzma)|tgz)$/ - @context.info "Extracting '#{url.filename}'" + Baguette::Log.info "Extracting '#{url.filename}'" - status = @context.run( + status = Do.run( building_directory, "bsdtar", [ "xf", @@ -249,9 +249,9 @@ class Package::Recipe raise ExtractionError.new self, url unless status.success? elsif basename.match /\.patch$/ - @context.info "Applying '#{url.filename}'" + Baguette::Log.info "Applying '#{url.filename}'" - status = @context.run( + status = Do.run( "#{building_directory}/#{dirname}", "patch", [ "-i", "#{@context.sources_directory}/#{url.filename}" @@ -260,7 +260,7 @@ class Package::Recipe raise ExtractionError.new self, url unless status.success? else - @context.info "Copying '#{url.filename}'" + Baguette::Log.info "Copying '#{url.filename}'" directory = if url.scheme == "file" @recipe_directory @@ -282,7 +282,7 @@ class Package::Recipe # goes somehow wrong. # - Make things thread-safe. (those ENV[]= calls are definitely not) def build - @context.mkdir_p fake_root_directory + Do.mkdir_p fake_root_directory ENV["PKG"] = fake_root_directory @@ -290,7 +290,7 @@ class Package::Recipe old_dir = Dir.current instructions.to_a.each do |instruction| - @context.info "Building ('#{instruction.phase}' phase)" + Baguette::Log.info "Building ('#{instruction.phase}' phase)" if instruction.run(@context, self).failed? raise BuildError.new self, "Building (#{instruction.phase} phase) failed." @@ -312,7 +312,7 @@ class Package::Recipe end private def do_strip - @context.info "Stripping binaries" + Baguette::Log.info "Stripping binaries" FileUtils.find_files(fake_root_directory) do |path| file_output = `file #{path}` @@ -327,7 +327,7 @@ class Package::Recipe end if strip_opt - @context.detail "stripping #{path}" + Baguette::Log.detail "stripping #{path}" Process.run "strip", [strip_opt, path] end @@ -357,7 +357,7 @@ class Package::Recipe end if files_to_split.size > 0 - @context.info "Splitting " + "'#{package.name}'".colorize(:light_red).underline.to_s + Baguette::Log.info "Splitting " + "'#{package.name}'".colorize(:light_red).underline.to_s end # FIXME: What do we do if those are not on the filesystem? @@ -365,11 +365,11 @@ class Package::Recipe origin = "#{fake_root_directory}#{file}" destination = "#{package.fake_root_directory}#{file}" - @context.detail "Moving '#{file}' to split" + Baguette::Log.detail "Moving '#{file}' to split" - @context.mkdir_p File.dirname destination + Do.mkdir_p File.dirname destination - @context.mv( + Do.mv( "#{fake_root_directory}#{file}", "#{package.fake_root_directory}#{file}" ) @@ -394,7 +394,7 @@ class Package::Recipe next end - @context.info "Assembling " + "'#{package.name}'".colorize(:light_red).underline.to_s + Baguette::Log.info "Assembling " + "'#{package.name}'".colorize(:light_red).underline.to_s unless @context.package package raise PackagingError.new self, package @@ -408,7 +408,7 @@ class Package::Recipe def watch if script = @watch_script - status, output = @context.captured_sh script + status, output = Do.captured_sh script output = output.to_s .gsub(/^[ \t\n]*/, "").gsub(/[ \t\n]*$/, "") diff --git a/src/tools/baguette.cr b/src/tools/baguette.cr index 2cff477..f4c0912 100644 --- a/src/tools/baguette.cr +++ b/src/tools/baguette.cr @@ -44,7 +44,7 @@ class Action latest_build_dir = recipe.building_directory - context.title recipe.name + Do.title recipe.name # recipe.download # recipe.extract