baguette backend overflow bugfix, baguette package tool
parent
a1df0745d7
commit
afaf5c2fda
16
shard.yml
16
shard.yml
|
@ -10,14 +10,14 @@ description: |
|
||||||
dependencies:
|
dependencies:
|
||||||
specparser:
|
specparser:
|
||||||
git: https://git.baguette.netlib.re/Baguette/recipes-parser
|
git: https://git.baguette.netlib.re/Baguette/recipes-parser
|
||||||
|
baguette-crystal-base:
|
||||||
|
git: https://git.baguette.netlib.re/Baguette/baguette-crystal-base
|
||||||
|
branch: master
|
||||||
|
|
||||||
# dependencies:
|
targets:
|
||||||
# pg:
|
package-create:
|
||||||
# github: will/crystal-pg
|
main: src/main.cr
|
||||||
# version: "~> 0.5"
|
baguette:
|
||||||
|
main: src/tools/baguette.cr
|
||||||
# development_dependencies:
|
|
||||||
# webmock:
|
|
||||||
# github: manastech/webmock.cr
|
|
||||||
|
|
||||||
license: ISC
|
license: ISC
|
||||||
|
|
|
@ -45,7 +45,7 @@ class BaguetteBackend < Package::Backend::Packaging
|
||||||
|
|
||||||
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_i * 1024
|
size = du.sub(/[ \t].*/, "").to_u64 * 1024_u64
|
||||||
|
|
||||||
file = File.open file_name, "w"
|
file = File.open file_name, "w"
|
||||||
|
|
||||||
|
|
|
@ -11,37 +11,6 @@ require "./backends/apk.cr"
|
||||||
require "./backends/pkgutils.cr"
|
require "./backends/pkgutils.cr"
|
||||||
require "./backends.cr"
|
require "./backends.cr"
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
lines = [] of String
|
|
||||||
|
|
||||||
lines << "# Generated by `packaging`."
|
|
||||||
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 << "depend = #{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") + "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
class Package::Context
|
class Package::Context
|
||||||
property working_directory = "/tmp/packaging"
|
property working_directory = "/tmp/packaging"
|
||||||
property sources_directory = Dir.current
|
property sources_directory = Dir.current
|
||||||
|
@ -161,6 +130,7 @@ class Package::Context
|
||||||
# new name = split name (-man, -src, ...)
|
# new name = split name (-man, -src, ...)
|
||||||
# split files
|
# split files
|
||||||
|
|
||||||
|
# Man-pages and documentation
|
||||||
@splitter_backends << Backend::Splitter.new do |recipe|
|
@splitter_backends << Backend::Splitter.new do |recipe|
|
||||||
Package.new(recipe, true).tap do |split|
|
Package.new(recipe, true).tap do |split|
|
||||||
prefixes = (@prefixes + [recipe.prefix]).uniq
|
prefixes = (@prefixes + [recipe.prefix]).uniq
|
||||||
|
@ -169,9 +139,11 @@ class Package::Context
|
||||||
split.files = prefixes.map do |prefix|
|
split.files = prefixes.map do |prefix|
|
||||||
"#{prefix}/share/man"
|
"#{prefix}/share/man"
|
||||||
end
|
end
|
||||||
|
split.recipe.require_stripping = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Developer's files: headers, pkgconfig files, *.a.
|
||||||
@splitter_backends << Backend::Splitter.new do |recipe|
|
@splitter_backends << Backend::Splitter.new do |recipe|
|
||||||
Package.new(recipe, true).tap do |split|
|
Package.new(recipe, true).tap do |split|
|
||||||
prefixes = (@prefixes + [recipe.prefix]).uniq
|
prefixes = (@prefixes + [recipe.prefix]).uniq
|
||||||
|
@ -186,6 +158,26 @@ class Package::Context
|
||||||
split.file_patterns = prefixes.map do |prefix|
|
split.file_patterns = prefixes.map do |prefix|
|
||||||
Regex.new("^" + prefix + ".*\\.a$")
|
Regex.new("^" + prefix + ".*\\.a$")
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -149,10 +149,6 @@ if CLIOpts.watch_only
|
||||||
exit 0
|
exit 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: verify package-create dependencies:
|
|
||||||
# - rsync
|
|
||||||
# - tar (bsdtar)
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
latest_build_dir = ""
|
latest_build_dir = ""
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ class Package::Package
|
||||||
|
|
||||||
inherit prefix : String
|
inherit prefix : String
|
||||||
|
|
||||||
@fake_root_directory : String?
|
property fake_root_directory : String?
|
||||||
|
|
||||||
def dependencies
|
def dependencies
|
||||||
@dependencies || @recipe.run_dependencies
|
@dependencies || @recipe.run_dependencies
|
||||||
|
|
|
@ -74,7 +74,11 @@ class Package::Recipe
|
||||||
|
|
||||||
property recipe_directory = "."
|
property recipe_directory = "."
|
||||||
|
|
||||||
getter working_uuid : UUID = UUID.random
|
property working_uuid : UUID = UUID.random
|
||||||
|
|
||||||
|
# Does this package requires running `strip` on its content?
|
||||||
|
# Man-page and source packages don't, for example.
|
||||||
|
property require_stripping = true
|
||||||
|
|
||||||
def initialize(@context, @name, @version)
|
def initialize(@context, @name, @version)
|
||||||
end
|
end
|
||||||
|
@ -302,12 +306,11 @@ class Package::Recipe
|
||||||
raise BuildError.new self, "No file was installed in the fake root."
|
raise BuildError.new self, "No file was installed in the fake root."
|
||||||
end
|
end
|
||||||
|
|
||||||
do_strip
|
do_strip if @require_stripping
|
||||||
|
|
||||||
do_splits
|
do_splits
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: do not search within source files.
|
|
||||||
private def do_strip
|
private def do_strip
|
||||||
@context.info "Stripping binaries"
|
@context.info "Stripping binaries"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
require "../context.cr"
|
||||||
|
require "../recipe.cr"
|
||||||
|
require "../package.cr"
|
||||||
|
require "../backends/baguette.cr"
|
||||||
|
|
||||||
|
require "option_parser"
|
||||||
|
|
||||||
|
require "baguette-crystal-base"
|
||||||
|
|
||||||
|
class Context
|
||||||
|
class_property command = "not-implemented"
|
||||||
|
class_property configuration_file = "#{SYSCONF_DIR}/packaging.cfg"
|
||||||
|
class_property args = Array(String).new
|
||||||
|
end
|
||||||
|
|
||||||
|
class Action
|
||||||
|
property the_call = {} of String => Proc(Nil)
|
||||||
|
property context : Package::Context
|
||||||
|
|
||||||
|
def initialize(@context)
|
||||||
|
@the_call["package"] = ->package
|
||||||
|
end
|
||||||
|
|
||||||
|
def package
|
||||||
|
pkg, uuid = Context.args[0..1]
|
||||||
|
Baguette::Log.info "package #{pkg} uuid #{uuid}"
|
||||||
|
|
||||||
|
recipe = context.find_recipe(pkg)
|
||||||
|
unless recipe
|
||||||
|
Baguette::Log.error "Error: no recipes"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
# Change working UUID.
|
||||||
|
old_uuid = recipe.working_uuid
|
||||||
|
new_uuid = UUID.new(uuid)
|
||||||
|
recipe.working_uuid = new_uuid
|
||||||
|
recipe.packages.each do |pkg|
|
||||||
|
if frd = pkg.fake_root_directory
|
||||||
|
pkg.fake_root_directory = frd.gsub old_uuid.to_s, new_uuid.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
latest_build_dir = recipe.building_directory
|
||||||
|
|
||||||
|
context.title recipe.name
|
||||||
|
|
||||||
|
# recipe.download
|
||||||
|
# recipe.extract
|
||||||
|
# recipe.build
|
||||||
|
recipe.package
|
||||||
|
|
||||||
|
# recipe.clean unless Context.do_not_clean
|
||||||
|
rescue e : Package::Exception
|
||||||
|
Baguette::Log.error "#{e.message}"
|
||||||
|
Baguette::Log.error "You may want to inspect the build directory at #{latest_build_dir}"
|
||||||
|
exit 1
|
||||||
|
rescue e
|
||||||
|
Baguette::Log.error "An unexpected error occured:"
|
||||||
|
Baguette::Log.error e
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def main
|
||||||
|
|
||||||
|
opt_help = -> (parser : OptionParser) {
|
||||||
|
parser.on "help", "Prints this help message." do
|
||||||
|
puts parser
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unrecognized parameters are used to create commands with multiple arguments.
|
||||||
|
# Example: user add _login email phone_
|
||||||
|
# Here, login, email and phone are unrecognized arguments.
|
||||||
|
# Still, the "user add" command expect them.
|
||||||
|
unrecognized_args_to_context_args = -> (parser : OptionParser, n_expected_args : Int32) {
|
||||||
|
# With the right args, these will be interpreted as serialized data.
|
||||||
|
parser.unknown_args do |args|
|
||||||
|
if args.size != n_expected_args
|
||||||
|
Baguette::Log.error "expected number of arguments: #{n_expected_args}, received: #{args.size}"
|
||||||
|
Baguette::Log.error "args: #{args}"
|
||||||
|
Baguette::Log.error "#{parser}"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
args.each do |arg|
|
||||||
|
Baguette::Log.debug "Unrecognized argument: #{arg} (adding to Context.args)"
|
||||||
|
Context.args << arg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionParser.parse do |parser|
|
||||||
|
parser.banner = "usage: baguette [options] command [parameters]"
|
||||||
|
|
||||||
|
parser.on "package", "Create a package." do
|
||||||
|
parser.banner = "Usage: baguette [opt] package package-name uuid"
|
||||||
|
Baguette::Log.info "Create a Baguette package."
|
||||||
|
Context.command = "package"
|
||||||
|
opt_help.call parser
|
||||||
|
# package name, uuid
|
||||||
|
unrecognized_args_to_context_args.call parser, 2
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.on "-c configuration-file", "--config configuration-file", "Configuration file." do |f|
|
||||||
|
Baguette::Log.info "configuration file is: #{f}"
|
||||||
|
Context.configuration_file = f
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.on "-h", "--help", "Show this help" do
|
||||||
|
puts parser
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
context = Package::Context.new()
|
||||||
|
context.repositories << "."
|
||||||
|
|
||||||
|
context.read_configuration Context.configuration_file
|
||||||
|
|
||||||
|
actions = Action.new context
|
||||||
|
|
||||||
|
# Now we did read the intent, we should proceed doing what was asked.
|
||||||
|
begin
|
||||||
|
actions.the_call[Context.command].call
|
||||||
|
rescue e
|
||||||
|
Baguette::Log.info "The command is not recognized (or implemented)."
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue e : OptionParser::Exception
|
||||||
|
Baguette::Log.error e.message
|
||||||
|
rescue e
|
||||||
|
Baguette::Log.error "exception raised: #{e.message}"
|
||||||
|
e.backtrace.try &.each do |line|
|
||||||
|
STDERR << " - " << line << '\n'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
main
|
Reference in New Issue