This repository has been archived on 2022-01-17. You can view files and clone it, but cannot push or open issues/pull-requests.
packaging/src/context.cr

185 lines
5.4 KiB
Crystal
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

require "colorize"
require "specparser"
require "./exception.cr"
require "./config.cr"
require "./backends.cr"
class Package::Context
property working_directory = "/tmp/packaging"
property sources_directory = Dir.current
property packages_directory = Dir.current
#alias Backends = Backend::Packaging | Backend::Building | Backend::Splitter
property user_instructions = Hash(String, Instructions).new
property configure_backends = Hash(String, Backend::Building).new
property building_backends = Hash(String, Backend::Building).new
property install_backends = Hash(String, Backend::Building).new
getter packaging_backends = Hash(String, Backend::Packaging).new
getter splitter_backends = Hash(String, Backend::Splitter).new
# General options, to add to the recipe before reading it.
getter options = Hash(String, String).new
getter all_phase_names = [
"sources-split",
"pre-configure", "configure",
"pre-build", "build",
"pre-install", "install", "post-install",
]
# Directories where ports can be found.
getter repositories = [] of String
# Well, this will need configuration, auto-detection and conversion,
# but itll be kind of enough for now.
property architecture = "x86_64"
# prefixes for `packaging` running environment and child processes
# = where to search for binaries and libraries for the build
property prefixes = ["/usr/baguette", "/usr", "/"]
# By default, building a package only uses one core
property build_cores = 1
property recipe : Recipe? = nil
def initialize
# Add package backends: baguette (package-tools) and apk.
# They implement the Backend::Packaging abstract class:
# init (@name) + package (context, package) method
@packaging_backends["baguette"] = Backend::Packaging::Baguette.new
@packaging_backends["apk"] = Backend::Packaging::APK.new
@packaging_backends["pkgutils"] = Backend::Packaging::Pkgutils.new
@selected_packaging_backend = @packaging_backends["baguette"]
# Add building backends: configuration, build and install.
@configure_backends["autotools"] = Backend::Configure.autotools
@configure_backends["cmake"] = Backend::Configure.cmake
@building_backends["make"] = Backend::Build.make
@install_backends["make"] = Backend::Install.make
# Split = new package from a recipe, each one with different files being included.
@splitter_backends["man"] = Backend::Splitter.man @prefixes
@splitter_backends["dev"] = Backend::Splitter.dev @prefixes
@splitter_backends["doc"] = Backend::Splitter.doc @prefixes
# src isn't really a split, files already are copied before build.
#@splitter_backends << Backend::Splitter.src @prefixes
end
def packaging_backend=(name : String)
@selected_packaging_backend = @packaging_backends[name].not_nil!
end
def packaging_backend=(backend : Backend::Packaging)
@selected_packaging_backend = backend
end
def package(package : Package) : Bool
@selected_packaging_backend.package @packages_directory, @architecture, package
end
def read_recipe(filename : String)
@recipe = Recipe.new self, filename
@recipe.not_nil!
end
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
def read_configuration(filename : String)
specs = SpecParser.parse(File.read(filename))
specs.assignments.each do |key, value|
case key
when "packages-directory"
@packages_directory = value.as_s
when "sources-directory"
@sources_directory = value.as_s
when "working-directory"
@working_directory = value.as_s
when "prefixes"
# Prefixes during the build process.
@prefixes = value.as_a_or_s
when "build-cores"
# NB of cores used to compile applications.
@build_cores = value.as_s.to_i
when "environment"
# Environment variables during the build process.
value.as_a_or_s.each do |entry|
match = entry.split(':').map(
&.gsub(/^[ \t]*/, "").gsub(/[ \t]*$/, ""))
if match.size != 2
STDERR.puts "WARNING: misformed environment definition: #{entry}"
next
end
key, value = match
Do.environment[key] = value
if Baguette::Context.verbosity > 2
STDOUT.puts "environment: #{key} => #{value}"
end
end
when "options"
value.as_a_or_s.each do |option|
match = option.split(':').map(&.strip)
if match.size != 2
STDERR.puts "WARNING: misformed option: #{option}"
next
end
key, value = match
@options[key] = value
end
# (default) user instructions (for testing).
when /(?<phase>(pre-)?(configure|build|install)|post-install)/
phase = $~["phase"]
@user_instructions[phase] = Instructions.new(phase).<<(value.as_s_or_ls)
when "package-manager"
# Targeted package manager (default: package, for BaguetteOS).
begin
self.packaging_backend = value.as_s
rescue e
STDERR.puts "Error during selecting packaging backend: #{e}"
STDERR.puts "#{value.as_s} seems not to be a valid backend"
STDERR.puts "valid backends:"
@packaging_backends.each do |name, backend|
STDERR.puts "- #{name}"
end
exit 1
end
end
end
end
def install(packages : Array(String))
@selected_packaging_backend.install packages
end
end