Improved recipe.spec reader.

master
Luka Vandervelden 2019-08-02 17:43:09 +02:00
parent bf8a5bbcbb
commit e0ce1ddd2a
2 changed files with 136 additions and 0 deletions

View File

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

View File

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