diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..5d736bf --- /dev/null +++ b/shard.yml @@ -0,0 +1,23 @@ +name: package +version: 0.1.0 + +# authors: +# - name + +# description: | +# Short description of package + +dependencies: + spec: + git: https://git.karchnu.fr/JunkOS/recipes-parser + +# dependencies: +# pg: +# github: will/crystal-pg +# version: "~> 0.5" + +# development_dependencies: +# webmock: +# github: manastech/webmock.cr + +# license: MIT diff --git a/src/recipe.cr b/src/recipe.cr index 9ed154b..8656dce 100644 --- a/src/recipe.cr +++ b/src/recipe.cr @@ -37,7 +37,7 @@ class Package::Recipe getter release = 1 property url : String? - property description : String = "" + property description : String? # Informations not specific to individual packages. getter sources : Sources @@ -58,11 +58,12 @@ class Package::Recipe getter instructions = Instructions.new getter options = Hash(String, String).new - def initialize(@context, @name, @version) - @sources = Sources.new - @packages = [] of Package + getter sources = Sources.new + getter packages = Array(Package).new - @working_uuid = UUID.random + @working_uuid : UUID = UUID.random + + def initialize(@context, @name, @version) end def self.new(context, name, version) diff --git a/test.cr b/test.cr new file mode 100644 index 0000000..7fb1e81 --- /dev/null +++ b/test.cr @@ -0,0 +1,152 @@ + +require "spec" +require "./src/context.cr" +require "./src/recipe.cr" + +extend Package + +# FIXME: recipe.clean? context autoclean? +context = Context.new() +context.packaging_backend = "apk" + +recipes = [] of Package::Recipe + +class Specs + def get_string?(id) : String? + entry = self.assignments[id]? + + unless entry.is_a? StringContainer + nil + else + entry.value + end + end + def get_string(id) : String + entry = self.assignments[id]? + + unless entry.is_a? StringContainer + raise Exception.new "`#{id}` was expected to be a string, but was a #{entry.class}." + end + + entry.value + end + + def get_long_string?(id) : String? + entry = self.assignments[id]? + + unless entry.is_a? LongStringContainer + nil + else + entry.value + end + end + + def get_string_any?(id) : String? + get_string?(id) || get_long_string?(id) + end + + def get_list?(id) : Array(String)? + entry = assignments[id]? + + case entry + when Specs::ArrayContainer + entry.value + when Specs::StringContainer + entry.value.split(",") + when Nil + return nil + else + raise Exception.new "`#{id}` was expected to be a list (string), but was a `#{entry.class}`" + end + end +end + +class Package::Recipe + def initialize(@context, specs : Specs) + pp! specs + + @name = specs.get_string "name" + @version = specs.get_string "version" + @release = specs.get_string?("release").try(&.to_i) || 1 + + @url = specs.get_string? "url" + @description = specs.get_string_any? "description" + @packager = specs.get_string? "packager" + @maintainer = specs.get_string? "packager" + + specs.get_string_any?("configure").try do |script| + @instructions.configure << script + end + + specs.get_string_any?("build").try do |script| + @instructions.build << script + end + + specs.get_string_any?("install").try do |script| + @instructions.install << script + end + + specs.get_list?("dependencies").try &.each do |atom| + @dependencies << atom + end + + specs.get_list?("conflicts").try &.each do |atom| + @conflicts << atom + end + + specs.get_list?("provides").try &.each do |atom| + @provides << atom + end + + specs.get_list?("sources").try &.each do |source| + @sources << source + end + + specs.get_list?("options").try &.each do |option| + match = option.match /\(.*\) *= *\(.*\)/ + unless match + puts "WARNING: misformed option: #{option}" + next + end + + name, value = match + + puts "OPTION: #{name} -> #{value}" + + @options[name] = value + end + end +end + +class Package::Context + def read_recipe(filename : String) + specs = Specs.parse filename + + if specs.nil? + raise Exception.new "file could not be parsed" + end + + Recipe.new self, specs + end +end + +pp! context.read_recipe "test.spec" + +if ARGV.size == 0 || ARGV[0]? == "-h" + pp recipes.map &.name + exit 0 +end + + +recipes.each do |recipe| + pp recipe + + raise "oh no, download failed" unless recipe.download + raise "oh no, extraction failed" unless recipe.extract + + raise "oh no, build failed" unless recipe.build + raise "oh no, packaging failed" unless recipe.package + + recipe.clean +end + diff --git a/test.spec b/test.spec new file mode 100644 index 0000000..79d5bb5 --- /dev/null +++ b/test.spec @@ -0,0 +1,20 @@ +name: hello +version: 2.10 +sources: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz + +url: https://www.gnu.org/software/hello/ +description: The GNU Hello program produces a familiar, friendly greeting. + +#dependencies: gettext + +dependencies: + - gettext + - something else + +@configure + cd %{name}-%{version} + ./configure --prefix=/usr + +options: + - configure = --without-nls +