149 lines
3.9 KiB
Crystal
149 lines
3.9 KiB
Crystal
|
||
# FIXME: Where should this go? We can’t just leave it here. :(
|
||
def pkginfo(package)
|
||
du = `du -sk #{package.fake_root_directory}`
|
||
size = du.sub(/[ \t].*/, "").to_i * 1024
|
||
|
||
%{ # Generated by `package`.
|
||
pkgname = #{package.name}
|
||
pkgver = #{package.version}-r#{package.release}
|
||
url = #{package.url || ""}
|
||
size = #{size}
|
||
origin = #{package.recipe.name}
|
||
buildtype = host
|
||
builddate = #{Time.utc.to_unix}
|
||
}.gsub /^ */m, ""
|
||
end
|
||
|
||
class Package::Backend::Packaging
|
||
getter name : String
|
||
|
||
def initialize(@name, &block : Proc(Context, Package, Bool))
|
||
@callback = block
|
||
end
|
||
|
||
def package(context : Context, package : Package)
|
||
@callback.call context, package
|
||
end
|
||
end
|
||
|
||
class Package::Context
|
||
property working_directory = "/tmp/package"
|
||
property sources_directory = Dir.current
|
||
property packages_directory = Dir.current
|
||
|
||
getter packaging_backends = [] of Backend::Packaging
|
||
getter building_backends = [] of Backend::Building
|
||
|
||
# Well, this will need configuration, auto-detection and conversion,
|
||
# but it’ll be kind of enough for now.
|
||
property architecture = "x86_64"
|
||
|
||
def initialize
|
||
@packaging_backends << Backend::Packaging.new "pkgutils" do |context, package|
|
||
puts "#{package.fake_root_directory} -> #{packages_directory}/#{package.name}##{package.version}-#{package.release}.pkg.tar.xz"
|
||
pp! r = run package.fake_root_directory, "tar", ["cJf", "#{packages_directory}/#{package.name}##{package.version}.pkg.tar.xz", "."]
|
||
|
||
r.exit_status == 0
|
||
end
|
||
|
||
@packaging_backends << Backend::Packaging.new "apk" do |context, package|
|
||
# FIXME: This needs to have access to architecture (from Context?)
|
||
# to work properly.
|
||
old_cwd = Dir.current
|
||
|
||
puts "#{package.fake_root_directory} -> #{packages_directory}/#{package.name}-#{package.version}-r#{package.release}.apk"
|
||
|
||
puts pkginfo package
|
||
File.write "#{package.fake_root_directory}/.PKGINFO", pkginfo package
|
||
|
||
|
||
# Create data.tar.gz here.
|
||
package_target = "#{packages_directory}/#{context.architecture}/#{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 = run package.fake_root_directory, "assemble-apk.sh", [
|
||
package_target
|
||
]
|
||
|
||
r.exit_status == 0
|
||
end
|
||
|
||
@selected_packaging_backend = @packaging_backends[0]
|
||
|
||
@building_backends << Backend::Building.new "configure", "autotools" do |context, recipe|
|
||
Dir.cd recipe.dirname
|
||
|
||
unless File.exists? "configure"
|
||
next BuildStatus::Pass
|
||
end
|
||
|
||
child = context.run "./configure", ["--prefix=/package"]
|
||
|
||
if child.exit_status == 0
|
||
BuildStatus::Success
|
||
else
|
||
BuildStatus::Failed
|
||
end
|
||
end
|
||
|
||
@building_backends << Backend::Building.new "build", "make" do |context, recipe|
|
||
Dir.cd recipe.dirname
|
||
|
||
unless File.exists? "Makefile"
|
||
next BuildStatus::Pass
|
||
end
|
||
|
||
child = context.run "make"
|
||
|
||
if child.exit_status == 0
|
||
BuildStatus::Success
|
||
else
|
||
BuildStatus::Failed
|
||
end
|
||
end
|
||
|
||
@building_backends << Backend::Building.new "install", "make" do |context, recipe|
|
||
Dir.cd recipe.dirname
|
||
|
||
unless File.exists? "Makefile"
|
||
next BuildStatus::Pass
|
||
end
|
||
|
||
child = context.run "make", ["install", "DESTDIR=#{recipe.fake_root_directory}"]
|
||
|
||
if child.exit_status == 0
|
||
BuildStatus::Success
|
||
else
|
||
BuildStatus::Failed
|
||
end
|
||
end
|
||
end
|
||
|
||
def packaging_backend=(name : String)
|
||
@selected_packaging_backend = @packaging_backends.find(&.name.==(name)).not_nil!
|
||
end
|
||
|
||
def packaging_backend=(backend : Backend::Packaging)
|
||
@selected_packaging_backend = backend
|
||
end
|
||
|
||
def run(chdir, command, args)
|
||
Process.run command, args, chdir: chdir, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit
|
||
end
|
||
|
||
def run(command, args)
|
||
run nil, command, args
|
||
end
|
||
|
||
def run(command)
|
||
run nil, command, nil
|
||
end
|
||
|
||
def package(package : Package) : Bool
|
||
@selected_packaging_backend.package self, package
|
||
end
|
||
end
|
||
|