From 928559f71faa5d4699fbf8774c9fa0ca0bb9a4c9 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Tue, 2 Jul 2019 03:50:50 +0200 Subject: [PATCH] Initial commit. --- src/context.cr | 10 +++++ src/instructions.cr | 18 ++++++++ src/main.cr | 26 ++++++++++++ src/package.cr | 9 ++++ src/recipe.cr | 101 ++++++++++++++++++++++++++++++++++++++++++++ src/sources.cr | 9 ++++ 6 files changed, 173 insertions(+) create mode 100644 src/context.cr create mode 100644 src/instructions.cr create mode 100644 src/main.cr create mode 100644 src/package.cr create mode 100644 src/recipe.cr create mode 100644 src/sources.cr diff --git a/src/context.cr b/src/context.cr new file mode 100644 index 0000000..935de4d --- /dev/null +++ b/src/context.cr @@ -0,0 +1,10 @@ + +class Package::Context + property working_directory = "/tmp/package" + property sources_directory = Dir.current + property packages_directory = Dir.current + + def initialize + end +end + diff --git a/src/instructions.cr b/src/instructions.cr new file mode 100644 index 0000000..93a7c6c --- /dev/null +++ b/src/instructions.cr @@ -0,0 +1,18 @@ + +class Package::Instructions + class Set < Array(String) + # FIXME: def execute + end + + getter configure = Set.new + getter build = Set.new + getter install = Set.new + + def initialize + end + + def map(&block : Proc(String, Nil)) + (configure + build + install).map &block + end +end + diff --git a/src/main.cr b/src/main.cr new file mode 100644 index 0000000..c0e7e27 --- /dev/null +++ b/src/main.cr @@ -0,0 +1,26 @@ + +require "./context.cr" +require "./recipe.cr" + +extend Package + +# FIXME: recipe.clean? context autoclean? +Context.new().tap do |context| + # FIXME: context.new_recipe? context.recipe? + Recipe.new(context, "hello", "2.10").tap do |recipe| + recipe.sources << "https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz" + + recipe.download + recipe.extract + + recipe.instructions.configure << "cd hello-#{recipe.version} && ./configure" + recipe.instructions.build << "cd hello-#{recipe.version} && make" + recipe.instructions.install << "cd hello-#{recipe.version} && make DESTDIR='${PKG}' install" + + recipe.build + recipe.package + + recipe.clean + end +end + diff --git a/src/package.cr b/src/package.cr new file mode 100644 index 0000000..5d97b58 --- /dev/null +++ b/src/package.cr @@ -0,0 +1,9 @@ + +class Package::Package + getter name : String + getter version : String + + def initialize(@name, @version) + end +end + diff --git a/src/recipe.cr b/src/recipe.cr new file mode 100644 index 0000000..40575b5 --- /dev/null +++ b/src/recipe.cr @@ -0,0 +1,101 @@ + +require "uuid" +require "uri" +require "file_utils" + +require "./context.cr" +require "./package.cr" +require "./instructions.cr" +require "./sources.cr" + +# 🤔 +class URI + def basename + File.basename path + end +end + +class Package::Recipe + @context : Context + + getter name : String + getter version : String + + getter sources : Sources + getter packages : Array(Package) + + getter instructions = Instructions.new + + def initialize(@context, @name, @version) + @sources = Sources.new + @packages = [ + Package.new @name, @version + ] + + @working_uuid = UUID.random + end + + def working_directory + @context.working_directory + end + + def building_directory + "#{working_directory}/build" + end + + def fake_root_directory + "#{working_directory}/root" + end + + def download + sources.map do |url| + unless File.exists? url.basename + Process.run "wget", [ url.to_s, "-O", @context.sources_directory + "/" + url.basename ], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit + end + end + end + + def extract + Dir.mkdir_p building_directory + + sources.map do |url| + basename = url.basename + + Process.run "tar", [ "xvf", @context.sources_directory + "/" + url.basename ], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit, chdir: building_directory + end + end + + # TODO: + # - Export packaging directory in $PKG. + # - Add (pre|post)-(configure|build|install) instructions. + # - Have some instructions be non-critical, like the (pre|post] ones. + # - Be careful about return values, flee from everything if something + # goes somehow wrong. + # - Make things thread-safe. (those ENV[]= calls are definitely not) + def build + Dir.mkdir_p fake_root_directory + + ENV["PKG"] = fake_root_directory + + instructions.map do |script| + pp! Process.run "sh", ["-c", script], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit, chdir: building_directory + end + + ENV["PKG"] = nil + end + + def package + puts "#{fake_root_directory} -> #{@context.packages_directory}/#{name}##{version}.pkg.tar.xz" + pp! Process.run "tar", ["cJf", "#{@context.packages_directory}/#{name}##{version}.pkg.tar.xz", "."], output: Process::Redirect::Inherit, error: Process::Redirect::Inherit, chdir: fake_root_directory + end + + def clean + FileUtils.rm_rf building_directory + FileUtils.rm_rf fake_root_directory + end + + def to_s + "#{name}-#{version}" + end +end + diff --git a/src/sources.cr b/src/sources.cr new file mode 100644 index 0000000..23787b6 --- /dev/null +++ b/src/sources.cr @@ -0,0 +1,9 @@ + +require "uri" + +class Package::Sources < Array(URI) + def <<(url : String) + self << URI.parse url + end +end +