baguette backend overflow bugfix, baguette package tool
parent
a1df0745d7
commit
afaf5c2fda
16
shard.yml
16
shard.yml
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -11,37 +11,6 @@ require "./backends/apk.cr"
|
|||
require "./backends/pkgutils.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
|
||||
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
|
||||
|
|
|
@ -149,10 +149,6 @@ if CLIOpts.watch_only
|
|||
exit 0
|
||||
end
|
||||
|
||||
# TODO: verify package-create dependencies:
|
||||
# - rsync
|
||||
# - tar (bsdtar)
|
||||
|
||||
begin
|
||||
latest_build_dir = ""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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