2019-08-03 12:55:47 +02:00
|
|
|
|
require "option_parser"
|
|
|
|
|
require "file_utils"
|
|
|
|
|
require "colorize"
|
2019-07-02 03:50:50 +02:00
|
|
|
|
|
|
|
|
|
require "./context.cr"
|
|
|
|
|
require "./recipe.cr"
|
|
|
|
|
|
|
|
|
|
extend Package
|
|
|
|
|
|
2019-07-20 13:30:09 +02:00
|
|
|
|
context = Context.new()
|
|
|
|
|
context.packaging_backend = "apk"
|
2019-08-03 12:55:47 +02:00
|
|
|
|
context.repositories << "."
|
2019-07-03 03:35:35 +02:00
|
|
|
|
|
2019-08-29 00:20:15 +02:00
|
|
|
|
configuration_file = "#{SYSCONF_DIR}/package.cfg"
|
|
|
|
|
configuration_file_requested = false
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
requested_recipes = [] of String
|
|
|
|
|
download_only = false
|
|
|
|
|
do_not_clean = false
|
2019-08-29 16:05:39 +02:00
|
|
|
|
watch_only = false
|
2019-09-03 13:15:07 +02:00
|
|
|
|
skip_build_dependencies = false
|
2019-07-02 03:50:50 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
used_X = false
|
|
|
|
|
OptionParser.parse! do |parser|
|
|
|
|
|
parser.banner = "Usage: package [options] <port <port <…>>>"
|
2019-07-02 03:50:50 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
parser.on("-X DIR", "--repository DIR", "Sets a ports repository for finding dependencies (default=.).") { |dir|
|
|
|
|
|
unless used_X
|
|
|
|
|
while context.repositories.pop?
|
|
|
|
|
end
|
|
|
|
|
used_X = true
|
|
|
|
|
end
|
2019-08-01 17:46:37 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
context.repositories << dir
|
2019-08-01 17:46:37 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 00:20:15 +02:00
|
|
|
|
parser.on("-c FILE", "--conf FILE", "Use a configuration file other than the default one.") { |file|
|
|
|
|
|
configuration_file = file
|
|
|
|
|
configuration_file_requested = true
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
parser.on("-D", "--download-only", "Only download sources, do not build.") {
|
|
|
|
|
download_only = true
|
2019-08-01 17:46:37 +02:00
|
|
|
|
}
|
2019-07-21 20:06:46 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
parser.on("-k", "--keep-work-dir", "Do not clean after building.") {
|
|
|
|
|
do_not_clean = true
|
|
|
|
|
}
|
2019-07-28 18:51:27 +02:00
|
|
|
|
|
2019-08-13 13:23:57 +02:00
|
|
|
|
parser.on("-h", "--help", "Prints this help message.") {
|
|
|
|
|
puts parser
|
|
|
|
|
exit 0
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-28 20:25:59 +02:00
|
|
|
|
parser.on("-V", "--version", "Prints package's version and exits.") {
|
|
|
|
|
puts Package::Version
|
|
|
|
|
exit 0
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 16:05:39 +02:00
|
|
|
|
parser.on("-w", "--watch", "Checks if the recipe is up to date and exits.") {
|
|
|
|
|
watch_only = true
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-03 13:03:04 +02:00
|
|
|
|
parser.on("-v", "--verbose", "Runs more verbosely.") {
|
|
|
|
|
context.verbosity += 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parser.on("-q", "--quiet", "Runs more quietely.") {
|
|
|
|
|
context.verbosity -= 1
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-03 13:15:07 +02:00
|
|
|
|
parser.on("-n", "--ignore-dependencies", "Do not try to install build-dependencies.") {
|
|
|
|
|
skip_build_dependencies = true
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
parser.invalid_option do |flag|
|
|
|
|
|
STDERR.puts "ERROR: #{flag} is not a valid option."
|
|
|
|
|
STDERR.puts parser
|
|
|
|
|
exit(1)
|
2019-07-28 18:51:27 +02:00
|
|
|
|
end
|
2019-07-21 20:06:46 +02:00
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
parser.unknown_args do |arg|
|
|
|
|
|
requested_recipes = arg
|
|
|
|
|
end
|
2019-07-28 18:51:27 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-08-29 00:20:15 +02:00
|
|
|
|
if File.exists? configuration_file
|
|
|
|
|
context.read_configuration configuration_file
|
|
|
|
|
elsif configuration_file_requested
|
|
|
|
|
STDERR.puts "ERROR: configuration file '#{configuration_file}' does not exist"
|
|
|
|
|
exit 1
|
|
|
|
|
end
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
found_recipes = requested_recipes.map do |name|
|
|
|
|
|
context.find_recipe(name) || name
|
2019-07-28 18:51:27 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
invalid_recipes = found_recipes.select &.is_a?(String)
|
|
|
|
|
if invalid_recipes.size > 0
|
|
|
|
|
STDERR.puts "ERROR: some of the requested recipes could not be found:"
|
|
|
|
|
invalid_recipes.each do |name|
|
|
|
|
|
STDERR.puts " - #{name}"
|
|
|
|
|
end
|
|
|
|
|
STDERR.puts " (try using -X?)"
|
2019-07-28 18:51:27 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
recipes = found_recipes.compact_map do |recipe_or_string|
|
|
|
|
|
recipe_or_string unless recipe_or_string.is_a?(String)
|
2019-07-20 13:30:09 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-08-03 12:55:47 +02:00
|
|
|
|
# FIXME: Now we need to build their respective deptrees and to deduplicate
|
|
|
|
|
# the list of recipes.
|
2019-07-20 13:30:09 +02:00
|
|
|
|
|
2019-08-29 16:05:39 +02:00
|
|
|
|
if watch_only
|
|
|
|
|
if recipes.size == 0
|
|
|
|
|
context.repositories.each do |repo|
|
|
|
|
|
Dir.children(repo).each do |i|
|
|
|
|
|
recipe_file_name = "#{repo}/#{i}/recipe.spec"
|
|
|
|
|
if File.exists? recipe_file_name
|
|
|
|
|
recipes << context.read_recipe recipe_file_name
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
recipes.each &.watch
|
|
|
|
|
exit 0
|
|
|
|
|
end
|
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
begin
|
|
|
|
|
latest_build_dir = ""
|
2019-08-24 14:02:30 +02:00
|
|
|
|
|
|
|
|
|
dependencies = [] of String
|
|
|
|
|
recipes.each do |recipe|
|
|
|
|
|
recipe.build_dependencies.each do |dep|
|
|
|
|
|
dependencies << dep unless dependencies.any? &.==(dep)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-09-03 13:15:07 +02:00
|
|
|
|
if dependencies.size > 0 && ! skip_build_dependencies
|
2019-08-24 14:02:30 +02:00
|
|
|
|
# FIXME: We’ll probably want to have backends other than apk at some point.
|
2019-09-02 16:40:33 +02:00
|
|
|
|
opts = ["add"] + (ENV["APK_FLAGS"]? || "-i").split(/[ \t]+/) + dependencies
|
|
|
|
|
puts "+ apk #{opts.join " "}"
|
|
|
|
|
r = Process.run "apk", opts,
|
|
|
|
|
output: Process::Redirect::Inherit,
|
|
|
|
|
input: Process::Redirect::Inherit,
|
|
|
|
|
error: Process::Redirect::Inherit
|
2019-08-24 14:02:30 +02:00
|
|
|
|
if r.exit_status != 0
|
|
|
|
|
STDERR.puts "!! Running apk failed!"
|
|
|
|
|
exit 8
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
recipes.each do |recipe|
|
|
|
|
|
latest_build_dir = recipe.building_directory
|
2019-07-03 03:17:01 +02:00
|
|
|
|
|
2019-09-03 13:03:04 +02:00
|
|
|
|
context.title recipe.name
|
2019-07-02 03:50:50 +02:00
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
recipe.download
|
2019-07-02 03:50:50 +02:00
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
next if download_only
|
2019-07-20 13:30:09 +02:00
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
recipe.extract
|
2019-07-20 13:30:09 +02:00
|
|
|
|
|
2019-08-16 14:55:25 +02:00
|
|
|
|
recipe.build
|
|
|
|
|
recipe.package
|
|
|
|
|
|
|
|
|
|
recipe.clean unless do_not_clean
|
|
|
|
|
end
|
|
|
|
|
rescue e : Package::Exception
|
|
|
|
|
STDERR.puts "!! #{e.message}".colorize(:red).bright
|
|
|
|
|
STDERR.puts "!! You may want to inspect the build directory at #{latest_build_dir}"
|
|
|
|
|
exit 1
|
|
|
|
|
rescue e
|
|
|
|
|
STDERR.puts "!! An unexpected error occured:".colorize(:red).bright
|
|
|
|
|
STDERR.puts e
|
|
|
|
|
exit 1
|
2019-08-03 12:55:47 +02:00
|
|
|
|
end
|
2019-07-20 13:30:09 +02:00
|
|
|
|
|