From e0ce1ddd2a3796b3fbe5814dd8b1b55421982efe Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Fri, 2 Aug 2019 17:43:09 +0200 Subject: [PATCH] Improved recipe.spec reader. --- src/context.cr | 10 ++++ src/recipe.cr | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/context.cr b/src/context.cr index 1fded7d..975ecd5 100644 --- a/src/context.cr +++ b/src/context.cr @@ -177,5 +177,15 @@ class Package::Context def package(package : Package) : Bool @selected_packaging_backend.package self, package end + + 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 diff --git a/src/recipe.cr b/src/recipe.cr index 8656dce..6583c8b 100644 --- a/src/recipe.cr +++ b/src/recipe.cr @@ -3,6 +3,8 @@ require "uuid" require "uri" require "file_utils" +require "spec" + require "./context.cr" require "./package.cr" require "./instructions.cr" @@ -28,6 +30,56 @@ module FileUtils end end +# FIXME: This could probably be shorter and less stupid with a macro or two. +class Specs::StringContainer + def as_s : String + value + end + def as_a_or_s : Array(String) + # FIXME: We should probably be splitting the string around comas. + [value] + end + def as_s_or_ls : String + value + end +end + +class Specs::LongStringContainer + def as_s : String + raise "short string expected, got multiline text section" + end + def as_a_or_s : Array(String) + raise "list or string expected, got multiline text section" + end + def as_s_or_ls : String + value + end +end + +class Specs::ArrayContainer + def as_s : String + raise "string expected, got list" + end + def as_a_or_s : Array(String) + value + end + def as_s_or_ls : String + raise "string or multiline text section expected, got list" + end +end + +class Specs::SectionContainer + def as_s : String + raise "string expected, got section" + end + def as_a_or_s : Array(String) + raise "list or string expected, got section" + end + def as_s_or_ls : String + raise "string or multiline text section expected, got section" + end +end + class Package::Recipe @context : Context @@ -74,6 +126,80 @@ class Package::Recipe instance end + def initialize(@context, specs : Specs) + name : String? = nil + version : String? = nil + + specs.assignments.each do |key, value| + case key + when "name" + name = value.as_s + when "version" + version = value.as_s + when "release" + @release = value.as_s.to_i + when "url" + @url = value.as_s + when "description" + @description = value.as_s_or_ls + when "packager" + @packager = value.as_s + when "maintainer" + @maintainer = value.as_s + when "sources" + value.as_a_or_s.each do |source| + @sources << source + end + when "configurue" + @instructions.configure << value.as_s_or_ls + when "build" + @instructions.build << value.as_s_or_ls + when "install" + @instructions.install << value.as_s_or_ls + when "dependencies" + value.as_a_or_s.each do |atom| + @dependencies << atom + end + when "conflicts" + value.as_a_or_s.each do |atom| + @conflicts << atom + end + when "provides" + value.as_a_or_s.each do |atom| + @provides << atom + end + when "options" + value.as_a_or_s.each do |option| + match = option.split(':').map( + &.gsub(/^[ \t]*/, "").gsub(/[ \t]*$/, "")) + + if match.size != 2 + puts "WARNING: misformed option: #{option}" + next + end + + name, value = match + + @options[name] = value + end + end + end + + raise "`name` was not provided" unless name + raise "`version` was not provided" unless version + + @name = name + @version = version + end + + def self.new(context, specs : Specs) + instance = Recipe.allocate.tap &.initialize(context, specs) + + instance.packages << Package.new instance + + instance + end + def working_directory "#{@context.working_directory}/#{@working_uuid}" end