baguette backend overflow bugfix, baguette package tool

master
Philippe Pittoli 2021-03-02 10:33:54 +01:00
parent a1df0745d7
commit afaf5c2fda
7 changed files with 184 additions and 48 deletions

View File

@ -10,14 +10,14 @@ description: |
dependencies:
specparser:
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:
# pg:
# github: will/crystal-pg
# version: "~> 0.5"
# development_dependencies:
# webmock:
# github: manastech/webmock.cr
targets:
package-create:
main: src/main.cr
baguette:
main: src/tools/baguette.cr
license: ISC

View File

@ -45,7 +45,7 @@ class BaguetteBackend < Package::Backend::Packaging
def generate_spec(package : Package::Package, file_name : String)
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"

View File

@ -11,37 +11,6 @@ require "./backends/apk.cr"
require "./backends/pkgutils.cr"
require "./backends.cr"
# FIXME: Where should this go? We cant 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" # Thisll 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
property working_directory = "/tmp/packaging"
property sources_directory = Dir.current
@ -161,6 +130,7 @@ class Package::Context
# new name = split name (-man, -src, ...)
# split files
# Man-pages and documentation
@splitter_backends << Backend::Splitter.new do |recipe|
Package.new(recipe, true).tap do |split|
prefixes = (@prefixes + [recipe.prefix]).uniq
@ -169,9 +139,11 @@ class Package::Context
split.files = prefixes.map do |prefix|
"#{prefix}/share/man"
end
split.recipe.require_stripping = false
end
end
# Developer's files: headers, pkgconfig files, *.a.
@splitter_backends << Backend::Splitter.new do |recipe|
Package.new(recipe, true).tap do |split|
prefixes = (@prefixes + [recipe.prefix]).uniq
@ -186,6 +158,26 @@ class Package::Context
split.file_patterns = prefixes.map do |prefix|
Regex.new("^" + prefix + ".*\\.a$")
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

View File

@ -149,10 +149,6 @@ if CLIOpts.watch_only
exit 0
end
# TODO: verify package-create dependencies:
# - rsync
# - tar (bsdtar)
begin
latest_build_dir = ""

View File

@ -67,7 +67,7 @@ class Package::Package
inherit prefix : String
@fake_root_directory : String?
property fake_root_directory : String?
def dependencies
@dependencies || @recipe.run_dependencies

View File

@ -74,7 +74,11 @@ class Package::Recipe
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)
end
@ -302,12 +306,11 @@ class Package::Recipe
raise BuildError.new self, "No file was installed in the fake root."
end
do_strip
do_strip if @require_stripping
do_splits
end
# TODO: do not search within source files.
private def do_strip
@context.info "Stripping binaries"

145
src/tools/baguette.cr Normal file
View File

@ -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