2019-07-02 03:50:50 +02:00
|
|
|
|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
# 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
|
|
|
|
|
|
2019-08-03 13:01:29 +02:00
|
|
|
|
lines = [] of String
|
|
|
|
|
|
|
|
|
|
lines << "# Generated by `package`."
|
|
|
|
|
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|
|
|
|
|
|
lines << "depends = #{atom.to_s}"
|
|
|
|
|
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"
|
2019-07-03 05:23:48 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-07-03 03:35:35 +02:00
|
|
|
|
class Package::Backend::Packaging
|
|
|
|
|
getter name : String
|
|
|
|
|
|
2019-07-04 02:23:15 +02:00
|
|
|
|
def initialize(@name, &block : Proc(Context, Package, Bool))
|
2019-07-03 03:35:35 +02:00
|
|
|
|
@callback = block
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-04 02:23:15 +02:00
|
|
|
|
def package(context : Context, package : Package)
|
|
|
|
|
@callback.call context, package
|
2019-07-03 03:35:35 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-04 23:18:54 +02:00
|
|
|
|
class Package::Backend::Splitter
|
|
|
|
|
def initialize(&block : Proc(Recipe, Package))
|
|
|
|
|
@callback = block
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def create_split(recipe : Recipe) : Package
|
|
|
|
|
@callback.call recipe
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-02 03:50:50 +02:00
|
|
|
|
class Package::Context
|
|
|
|
|
property working_directory = "/tmp/package"
|
|
|
|
|
property sources_directory = Dir.current
|
|
|
|
|
property packages_directory = Dir.current
|
|
|
|
|
|
2019-07-03 03:48:31 +02:00
|
|
|
|
getter packaging_backends = [] of Backend::Packaging
|
|
|
|
|
getter building_backends = [] of Backend::Building
|
2019-07-04 23:18:54 +02:00
|
|
|
|
getter splitter_backends = [] of Backend::Splitter
|
2019-07-03 03:35:35 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
# Directories where ports can be found.
|
|
|
|
|
getter repositories = [] of String
|
|
|
|
|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
# Well, this will need configuration, auto-detection and conversion,
|
|
|
|
|
# but it’ll be kind of enough for now.
|
|
|
|
|
property architecture = "x86_64"
|
|
|
|
|
|
2019-07-02 03:50:50 +02:00
|
|
|
|
def initialize
|
2019-07-04 02:23:15 +02:00
|
|
|
|
@packaging_backends << Backend::Packaging.new "pkgutils" do |context, package|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
puts "#{package.fake_root_directory} -> #{packages_directory}/#{package.name}##{package.version}-#{package.release}.pkg.tar.xz"
|
2019-07-03 03:35:35 +02:00
|
|
|
|
pp! r = run package.fake_root_directory, "tar", ["cJf", "#{packages_directory}/#{package.name}##{package.version}.pkg.tar.xz", "."]
|
|
|
|
|
|
|
|
|
|
r.exit_status == 0
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-04 02:23:15 +02:00
|
|
|
|
@packaging_backends << Backend::Packaging.new "apk" do |context, package|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
# 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
|
|
|
|
|
|
2019-07-04 02:23:15 +02:00
|
|
|
|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
# Create data.tar.gz here.
|
2019-07-04 02:23:15 +02:00
|
|
|
|
package_target = "#{packages_directory}/#{context.architecture}/#{package.name}-#{package.version}-r#{package.release}.apk"
|
|
|
|
|
Dir.mkdir_p File.dirname package_target
|
|
|
|
|
|
2019-07-03 05:23:48 +02:00
|
|
|
|
# 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
|
|
|
|
|
|
2019-07-03 03:35:35 +02:00
|
|
|
|
@selected_packaging_backend = @packaging_backends[0]
|
2019-07-03 03:48:31 +02:00
|
|
|
|
|
|
|
|
|
@building_backends << Backend::Building.new "configure", "autotools" do |context, recipe|
|
|
|
|
|
Dir.cd recipe.dirname
|
|
|
|
|
|
|
|
|
|
unless File.exists? "configure"
|
|
|
|
|
next BuildStatus::Pass
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-23 16:41:34 +02:00
|
|
|
|
child = context.sh "./configure --prefix=/usr #{recipe.options["configure"]? || ""}"
|
2019-07-03 03:48:31 +02:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2019-07-23 16:41:34 +02:00
|
|
|
|
child = context.sh "make #{recipe.options["make"]? || ""}"
|
2019-07-03 03:48:31 +02:00
|
|
|
|
|
|
|
|
|
if child.exit_status == 0
|
|
|
|
|
BuildStatus::Success
|
|
|
|
|
else
|
|
|
|
|
BuildStatus::Failed
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-07-03 05:23:48 +02:00
|
|
|
|
|
|
|
|
|
@building_backends << Backend::Building.new "install", "make" do |context, recipe|
|
|
|
|
|
Dir.cd recipe.dirname
|
|
|
|
|
|
|
|
|
|
unless File.exists? "Makefile"
|
|
|
|
|
next BuildStatus::Pass
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-23 16:41:34 +02:00
|
|
|
|
child = context.sh "make install 'DESTDIR=#{recipe.fake_root_directory}' #{recipe.options["make install"]? || ""}"
|
2019-07-03 05:23:48 +02:00
|
|
|
|
|
|
|
|
|
if child.exit_status == 0
|
|
|
|
|
BuildStatus::Success
|
|
|
|
|
else
|
|
|
|
|
BuildStatus::Failed
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-07-04 23:18:54 +02:00
|
|
|
|
|
|
|
|
|
@splitter_backends << Backend::Splitter.new do |recipe|
|
|
|
|
|
Package.new(recipe, true).tap do |split|
|
|
|
|
|
split.name = "#{recipe.name}-man"
|
2019-07-23 12:55:14 +02:00
|
|
|
|
split.files = ["/usr/share/man"]
|
2019-07-04 23:18:54 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@splitter_backends << Backend::Splitter.new do |recipe|
|
|
|
|
|
Package.new(recipe, true).tap do |split|
|
|
|
|
|
split.name = "#{recipe.name}-dev"
|
2019-07-23 12:55:14 +02:00
|
|
|
|
split.files = ["/usr/include"]
|
2019-07-23 17:33:38 +02:00
|
|
|
|
split.file_patterns = [
|
|
|
|
|
Regex.new("^/lib/.*\\.a$"),
|
|
|
|
|
Regex.new("^/usr/lib/.*\\.a$")
|
|
|
|
|
]
|
2019-07-04 23:18:54 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2019-07-03 03:35:35 +02:00
|
|
|
|
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
|
2019-07-02 03:50:50 +02:00
|
|
|
|
end
|
2019-07-02 19:45:33 +02:00
|
|
|
|
|
|
|
|
|
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
|
2019-07-03 03:17:01 +02:00
|
|
|
|
|
2019-07-23 16:41:34 +02:00
|
|
|
|
def sh(command)
|
|
|
|
|
run nil, "sh", ["-x", "-e", "-c", command]
|
|
|
|
|
end
|
|
|
|
|
|
2019-07-03 03:17:01 +02:00
|
|
|
|
def package(package : Package) : Bool
|
2019-07-04 02:23:15 +02:00
|
|
|
|
@selected_packaging_backend.package self, package
|
2019-07-03 03:17:01 +02:00
|
|
|
|
end
|
2019-08-02 17:43:09 +02:00
|
|
|
|
|
|
|
|
|
def read_recipe(filename : String)
|
2019-08-02 23:58:42 +02:00
|
|
|
|
Recipe.new self, filename
|
2019-08-02 17:43:09 +02:00
|
|
|
|
end
|
2019-08-03 12:55:47 +02:00
|
|
|
|
|
|
|
|
|
def find_recipe(name : String) : Recipe?
|
|
|
|
|
recipe_file_name = ""
|
|
|
|
|
|
|
|
|
|
repo = @repositories.find do |repo|
|
|
|
|
|
repo_dir_name = "#{repo}/#{name}"
|
|
|
|
|
recipe_file_name = "#{repo_dir_name}/recipe.spec"
|
|
|
|
|
|
|
|
|
|
if Dir.exists?(repo_dir_name) && File.exists?(recipe_file_name)
|
|
|
|
|
next true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
read_recipe recipe_file_name if repo
|
|
|
|
|
end
|
2019-07-02 03:50:50 +02:00
|
|
|
|
end
|
|
|
|
|
|