Archived
3
0

Massive refactoring. See more in git log.

This refactoring includes:
- the use of baguette-crystal-base (Baguette::Log, Baguette::Context for verbosity and logfile)
- moving configure, build, install and splits backends into dedicated files
- removing a lot of code from Package::Context (it was a mess, still kinda is)
- fix 32-bit integer bug from APK backend
- some API changes in packaging backends to remove the context instance
  it was replaced by two parameters: package directory and architecture
- Baguette, APK and PkgUtils now share (kinda) the same coding style
This commit is contained in:
Philippe Pittoli 2021-03-02 15:42:17 +01:00
parent e0d3c6bf7e
commit 8392363d49
14 changed files with 360 additions and 325 deletions

View File

@ -5,7 +5,7 @@ abstract class Package::Backend::Packaging
def initialize(@name) def initialize(@name)
end 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)) def self.install(packages : Array(String))
raise "'install' unimplemented for this backend, yet" raise "'install' unimplemented for this backend, yet"
end end
@ -14,13 +14,4 @@ abstract class Package::Backend::Packaging
end end
end end
class Package::Backend::Splitter require "./backends/*"
def initialize(&block : Proc(Recipe, Package))
@callback = block
end
def create_split(recipe : Recipe) : Package
@callback.call recipe
end
end

View File

@ -1,23 +1,25 @@
require "../backends.cr" require "../backends.cr"
class ApkBackend < Package::Backend::Packaging class Package::Backend::Packaging::APK < Package::Backend::Packaging
def initialize def initialize
@name = "apk" @name = "apk"
end 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?) # FIXME: This needs to have access to architecture (from Context?)
# to work properly. # to work properly.
old_cwd = Dir.current 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. # 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 Dir.mkdir_p File.dirname package_target
# FIXME: This shouldnt have to be in users PATH. libexec? # FIXME: This shouldnt 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 package_target
] ]
@ -25,34 +27,32 @@ class ApkBackend < Package::Backend::Packaging
end end
# This generated file content is specific to the Apk package manager. # 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}` 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`."
lines << "# Generated by `packaging`." file.puts "pkgname = #{package.name}"
lines << "pkgname = #{package.name}" file.puts "pkgver = #{package.version}-r#{package.release}"
lines << "pkgver = #{package.version}-r#{package.release}" file.puts "url = #{package.url || ""} "
lines << "url = #{package.url || ""} " file.puts "size = #{size}"
lines << "size = #{size}" file.puts "origin = #{package.recipe.name}"
lines << "origin = #{package.recipe.name}" file.puts "buildtype = host" # Thisll need to be imported from Context.
lines << "buildtype = host" # Thisll need to be imported from Context. file.puts "builddate = #{Time.utc.to_unix}"
lines << "builddate = #{Time.utc.to_unix}"
package.dependencies.each do |atom| package.dependencies.each do |atom|
lines << "depend = #{atom.to_s}" file.puts "depend = #{atom.to_s}"
end end
package.provides.each do |atom| package.provides.each do |atom|
lines << "provides = #{atom.to_s}" file.puts "provides = #{atom.to_s}"
end end
package.conflicts.each do |atom| package.conflicts.each do |atom|
lines << "conflicts = #{atom.to_s}" file.puts "conflicts = #{atom.to_s}"
end
end end
lines.join("\n") + "\n"
end end
# Install programs. # Install programs.

View File

@ -3,38 +3,43 @@ require "openssl"
require "../backends.cr" require "../backends.cr"
class BaguetteBackend < Package::Backend::Packaging class Package::Backend::Packaging::Baguette < Package::Backend::Packaging
def initialize def initialize
@name = "package" @name = "package"
end end
# TODO: checksums + security # 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/<uuid>/root-xz-dev # Fake root example: /tmp/packages/<uuid>/root-xz-dev
fake_root = package.fake_root_directory fake_root = package.fake_root_directory
data_archive_path = "#{fake_root}/data.tar" # Temporary archive, before compression.
compressed_data_archive_path = "#{fake_root}/data.tar.zst" data_archive_path = "#{fake_root}/data.tar" # All archive data.
control_spec_file_path = "#{fake_root}/control.spec" # Content of the final tarball.
manifest_file_path = "#{fake_root}/manifest" 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" ::Baguette::Log.detail "Archiving package content"
context.run fake_root, "tar", ["cvf", data_archive_path, "."] Do.run fake_root, "tar", ["cvf", data_archive_path, "."]
context.detail "Compressing the archive" ::Baguette::Log.detail "Compressing the archive"
# produces data.tar.zst # 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 generate_spec package, control_spec_file_path
context.detail "Generating manifest" ::Baguette::Log.detail "Generating manifest"
generate_manifest context, package, manifest_file_path generate_manifest package, manifest_file_path
context.detail "Assembling '#{package_target}'" ::Baguette::Log.detail "Assembling '#{package_target}'"
r = context.run fake_root, "tar", [ r = Do.run fake_root, "tar", [
"cf", package_target, "cf", package_target,
# WARNING: relative paths are necessary. # WARNING: relative paths are necessary.
"control.spec", "manifest", "data.tar.zst" "control.spec", "manifest", "data.tar.zst"
@ -43,12 +48,11 @@ class BaguetteBackend < Package::Backend::Packaging
r.exit_status == 0 r.exit_status == 0
end 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}` du = `du -sk #{package.fake_root_directory}`
size = du.sub(/[ \t].*/, "").to_u64 * 1024_u64 size = du.sub(/[ \t].*/, "").to_u64 * 1024_u64
file = File.open file_name, "w" File.open file_name, "w" do |file|
file.puts "name: #{package.name}" file.puts "name: #{package.name}"
file.puts "version: #{package.version}" file.puts "version: #{package.version}"
file.puts "release: #{package.release}" file.puts "release: #{package.release}"
@ -63,11 +67,10 @@ class BaguetteBackend < Package::Backend::Packaging
file.puts "dependencies: #{package.dependencies.join ", "}" file.puts "dependencies: #{package.dependencies.join ", "}"
file.puts "conflicts: #{package.conflicts.join ", "}" file.puts "conflicts: #{package.conflicts.join ", "}"
file.puts "provides: #{package.provides.join ", "}" file.puts "provides: #{package.provides.join ", "}"
end
file.close
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 old_pwd = Dir.current
manifest = File.open(file_name, "w").not_nil! manifest = File.open(file_name, "w").not_nil!

23
src/backends/build.cr Normal file
View File

@ -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

47
src/backends/configure.cr Normal file
View File

@ -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

23
src/backends/install.cr Normal file
View File

@ -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

View File

@ -1,13 +1,21 @@
require "../backends.cr" 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 def initialize
@name = "pkgutils" @name = "pkgutils"
end end
def package(context : Package::Context, package : Package::Package) : Bool def package(pkgdir : String, architecture : String, package : ::Package::Package) : Bool
puts "#{package.fake_root_directory} -> #{context.packages_directory}/#{package.name}##{package.version}-#{package.release}.pkg.tar.xz" package_file = pkgdir + "/" + architecture + "/"
pp! r = context.run package.fake_root_directory, "tar", ["cJf", "#{context.packages_directory}/#{package.name}##{package.version}.pkg.tar.xz", "."] 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 r.exit_status == 0
end end

75
src/backends/splitter.cr Normal file
View File

@ -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

View File

@ -1,14 +1,8 @@
require "colorize" require "colorize"
require "specparser" require "specparser"
require "./exception.cr" require "./exception.cr"
require "./config.cr" require "./config.cr"
require "./backends/baguette.cr"
require "./backends/apk.cr"
require "./backends/pkgutils.cr"
require "./backends.cr" require "./backends.cr"
class Package::Context class Package::Context
@ -29,157 +23,37 @@ class Package::Context
# prefixes for `packaging` running environment and child processes # prefixes for `packaging` running environment and child processes
# = where to search for binaries and libraries for the build # = 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 # By default, building a package only uses one core
property build_cores = 1 property build_cores = 1
# list of environment variables we want to have when building # list of environment variables we want to have when building
property environment = {} of String => String #property environment = {} of String => String
property verbosity = 0
property recipe : Recipe? = nil property recipe : Recipe? = nil
def initialize def initialize
@packaging_backends << ApkBackend.new # Add package backends: baguette (package-tools) and apk.
@packaging_backends << BaguetteBackend.new # They implement the Backend::Packaging abstract class:
@packaging_backends << PkgutilsBackend.new # 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] @selected_packaging_backend = @packaging_backends[0]
@building_backends << Backend::Building.new "configure", "autotools" do |context, recipe| # Add building backends: configuration, build and install.
next BuildStatus::Pass unless Dir.exists? recipe.dirname @building_backends << Backend::Configure.autotools
@building_backends << Backend::Configure.cmake
@building_backends << Backend::Build.make
@building_backends << Backend::Install.make
Dir.cd recipe.dirname # Split = new package from a recipe, each one with different files being included.
@splitter_backends << Backend::Splitter.man @prefixes
unless File.exists? "configure" @splitter_backends << Backend::Splitter.dev @prefixes
next BuildStatus::Pass @splitter_backends << Backend::Splitter.src @prefixes
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
end end
def packaging_backend=(name : String) def packaging_backend=(name : String)
@ -190,84 +64,8 @@ class Package::Context
@selected_packaging_backend = backend @selected_packaging_backend = backend
end 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 def package(package : Package) : Bool
@selected_packaging_backend.package self, package @selected_packaging_backend.package @packages_directory, @architecture, package
end end
def read_recipe(filename : String) def read_recipe(filename : String)
@ -320,8 +118,8 @@ class Package::Context
end end
key, value = match key, value = match
@environment[key] = value Do.environment[key] = value
if @verbosity > 0 if Baguette::Context.verbosity > 2
STDOUT.puts "environment: #{key} => #{value}" STDOUT.puts "environment: #{key} => #{value}"
end end
end end

View File

@ -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 Do < Process
class_property environment = {} of String => String
def self.require_cmd(cmd : String) def self.require_cmd(cmd : String)
unless Process.run("which", [ cmd ]).success? unless Process.run("which", [ cmd ]).success?
STDERR.puts "#{cmd} isn't installed" STDERR.puts "#{cmd} isn't installed"
exit 1 exit 1
end end
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 end

View File

@ -28,7 +28,7 @@ class Package::Instructions
def run(context : Context, recipe : Recipe) : BuildStatus def run(context : Context, recipe : Recipe) : BuildStatus
if size > 0 if size > 0
each do |command| 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 if child.exit_status != 0
return BuildStatus::Failed return BuildStatus::Failed

View File

@ -1,6 +1,7 @@
require "option_parser" require "option_parser"
require "file_utils" require "file_utils"
require "colorize" require "colorize"
require "baguette-crystal-base"
require "./context.cr" require "./context.cr"
require "./recipe.cr" require "./recipe.cr"
@ -70,11 +71,11 @@ OptionParser.parse do |parser|
} }
parser.on("-v", "--verbose", "Runs more verbosely.") { parser.on("-v", "--verbose", "Runs more verbosely.") {
context.verbosity += 1 Baguette::Context.verbosity += 1
} }
parser.on("-q", "--quiet", "Runs more quietely.") { 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.") { parser.on("-n", "--ignore-dependencies", "Do not try to install build-dependencies.") {
@ -172,7 +173,7 @@ begin
recipes.each do |recipe| recipes.each do |recipe|
latest_build_dir = recipe.building_directory latest_build_dir = recipe.building_directory
context.title recipe.name Baguette::Log.title recipe.name
recipe.download recipe.download

View File

@ -216,13 +216,13 @@ class Package::Recipe
unless File.exists? filename unless File.exists? filename
if url.scheme == "file" if url.scheme == "file"
@context.info "Copying '#{url.filename}'" Baguette::Log.info "Copying '#{url.filename}'"
FileUtils.cp "#{recipe_directory}/#{url.filename}", filename FileUtils.cp "#{recipe_directory}/#{url.filename}", filename
else 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? raise DownloadError.new self, url unless status.success?
end end
@ -231,15 +231,15 @@ class Package::Recipe
end end
def extract def extract
@context.mkdir_p building_directory Do.mkdir_p building_directory
sources.each do |url| sources.each do |url|
basename = url.filename basename = url.filename
if basename.match /\.(tar\.(gz|xz|bz2|lzma)|tgz)$/ 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, building_directory,
"bsdtar", [ "bsdtar", [
"xf", "xf",
@ -249,9 +249,9 @@ class Package::Recipe
raise ExtractionError.new self, url unless status.success? raise ExtractionError.new self, url unless status.success?
elsif basename.match /\.patch$/ elsif basename.match /\.patch$/
@context.info "Applying '#{url.filename}'" Baguette::Log.info "Applying '#{url.filename}'"
status = @context.run( status = Do.run(
"#{building_directory}/#{dirname}", "#{building_directory}/#{dirname}",
"patch", [ "patch", [
"-i", "#{@context.sources_directory}/#{url.filename}" "-i", "#{@context.sources_directory}/#{url.filename}"
@ -260,7 +260,7 @@ class Package::Recipe
raise ExtractionError.new self, url unless status.success? raise ExtractionError.new self, url unless status.success?
else else
@context.info "Copying '#{url.filename}'" Baguette::Log.info "Copying '#{url.filename}'"
directory = if url.scheme == "file" directory = if url.scheme == "file"
@recipe_directory @recipe_directory
@ -282,7 +282,7 @@ class Package::Recipe
# goes somehow wrong. # goes somehow wrong.
# - Make things thread-safe. (those ENV[]= calls are definitely not) # - Make things thread-safe. (those ENV[]= calls are definitely not)
def build def build
@context.mkdir_p fake_root_directory Do.mkdir_p fake_root_directory
ENV["PKG"] = fake_root_directory ENV["PKG"] = fake_root_directory
@ -290,7 +290,7 @@ class Package::Recipe
old_dir = Dir.current old_dir = Dir.current
instructions.to_a.each do |instruction| 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? if instruction.run(@context, self).failed?
raise BuildError.new self, "Building (#{instruction.phase} phase) failed." raise BuildError.new self, "Building (#{instruction.phase} phase) failed."
@ -312,7 +312,7 @@ class Package::Recipe
end end
private def do_strip private def do_strip
@context.info "Stripping binaries" Baguette::Log.info "Stripping binaries"
FileUtils.find_files(fake_root_directory) do |path| FileUtils.find_files(fake_root_directory) do |path|
file_output = `file #{path}` file_output = `file #{path}`
@ -327,7 +327,7 @@ class Package::Recipe
end end
if strip_opt if strip_opt
@context.detail "stripping #{path}" Baguette::Log.detail "stripping #{path}"
Process.run "strip", [strip_opt, path] Process.run "strip", [strip_opt, path]
end end
@ -357,7 +357,7 @@ class Package::Recipe
end end
if files_to_split.size > 0 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 end
# FIXME: What do we do if those are not on the filesystem? # FIXME: What do we do if those are not on the filesystem?
@ -365,11 +365,11 @@ class Package::Recipe
origin = "#{fake_root_directory}#{file}" origin = "#{fake_root_directory}#{file}"
destination = "#{package.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}", "#{fake_root_directory}#{file}",
"#{package.fake_root_directory}#{file}" "#{package.fake_root_directory}#{file}"
) )
@ -394,7 +394,7 @@ class Package::Recipe
next next
end 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 unless @context.package package
raise PackagingError.new self, package raise PackagingError.new self, package
@ -408,7 +408,7 @@ class Package::Recipe
def watch def watch
if script = @watch_script if script = @watch_script
status, output = @context.captured_sh script status, output = Do.captured_sh script
output = output.to_s output = output.to_s
.gsub(/^[ \t\n]*/, "").gsub(/[ \t\n]*$/, "") .gsub(/^[ \t\n]*/, "").gsub(/[ \t\n]*$/, "")

View File

@ -44,7 +44,7 @@ class Action
latest_build_dir = recipe.building_directory latest_build_dir = recipe.building_directory
context.title recipe.name Do.title recipe.name
# recipe.download # recipe.download
# recipe.extract # recipe.extract