class DGD::Manifest::AppFile

This class parses the DGD manifest

Attributes

dgd_config[R]
path[R]
repo[R]
shared_dir[R]
specs[R]

Public Class Methods

new(repo, path, shared_dir:) click to toggle source
# File lib/dgd-tools/manifest.rb, line 247
def initialize(repo, path, shared_dir:)
    @path = path
    @repo = repo
    @shared_dir = shared_dir
    raise("No such dgd.manifest file as #{path.inspect}!") unless File.exist?(path)
    contents = AppFile.parse_manifest_file(path)

    read_manifest_file(contents)

    output_paths = @specs.flat_map { |s| s.paths.values }
    unless output_paths == output_paths.uniq
        repeated_paths = output_paths.select { |p| output_paths.count(p) > 1 }
        raise "Repeated (conflicting?) paths in dgd.manifest! #{repeated_paths.inspect}"
    end

    ## Make sure the dgd.manifest file overrides either no kernel paths or both/all
    #if KERNEL_PATHS.any? { |kp| output_paths.include?(kp) }
    #    unless KERNEL_PATHS.all? { |kp| output_paths.include?(kp) }
    #        raise "dgd.manifest file #{path.inspect} includes some Kernel Library paths but not all! All needed: #{KERNEL_PATHS}!"
    #    end
    #    puts "This dgd.manifest file overrides the Kernel Library with its own."
    #else
    #    puts "This dgd.manifest needs the default Kernel Library."
    #    # This app has specified no kernellib paths -- add them
    #    spec_git_repo = @repo.git_repo(DEFAULT_KERNELLIB_URL)
    #    klib_spec = GoodsSpec.new @repo, name: "default Kernel Library",
    #        source: spec_git_repo, paths: KERNEL_PATH_MAP
    #    specs.unshift klib_spec
    #end

    nil
end
parse_manifest_file(path) click to toggle source

Load the JSON and then remove comments

# File lib/dgd-tools/manifest.rb, line 281
def self.parse_manifest_file(path)
    contents = JSON.parse(File.read path)
    remove_comments!(contents)
    contents
end
remove_comments!(items) click to toggle source
# File lib/dgd-tools/manifest.rb, line 287
def self.remove_comments!(items)
    if items.is_a?(Hash)
        items.delete_if { |k, v| k[0] == "#" }
        items.values.each { |v| remove_comments!(v) }
    elsif items.is_a?(Array)
        items.delete_if { |i| i.is_a?(String) && i[0] == "#" }
        items.each { |i| remove_comments!(i) }
    end
end

Public Instance Methods

app_root() click to toggle source
# File lib/dgd-tools/manifest.rb, line 332
def app_root
    @dgd_config.app_root
end
ordered_specs() click to toggle source
# File lib/dgd-tools/manifest.rb, line 381
def ordered_specs
    @specs.flat_map do |s|
        deps = [s]
        deps_to_add = s.dependencies
        while(deps_to_add.size > 0)
            next_deps = deps_to_add.flat_map { |dep| dep.dependencies }
            deps = deps_to_add + deps
            deps_to_add = next_deps
        end
        deps
    end
end
read_manifest_file(contents) click to toggle source
# File lib/dgd-tools/manifest.rb, line 297
def read_manifest_file(contents)
    raise "Expected a top-level JSON object in dgd.manifest!" unless contents.is_a?(Hash)

    @specs = []

    @dgd_config = DGDRuntimeConfig.new (contents["config"] || {})

    if contents["app_root"]
        raise "App_root must now be inside config block!"
    end

    if contents["unbundled_goods"]
        raise "Unbundled_goods must be an array!" unless contents["unbundled_goods"].is_a?(Array)

        @specs += contents["unbundled_goods"].map { |item| unbundled_json_to_spec(item) }
    end

    if contents["goods"]
        raise "Goods must be an array!" unless contents["goods"].is_a?(Array)

        @specs += contents["goods"].map do |goods_url|
            begin
                text_contents = URI.open(goods_url).read
                local_path = shared_dir + "/goods/" + goods_url.tr("/\\ ", "_")
                File.open(local_path, "wb") { |f| f.write(text_contents) }
                json_contents = JSON.parse text_contents
            rescue
                STDERR.puts "Error reading or parsing by URL: #{goods_url.inspect}"
                raise
            end
            unbundled_json_to_spec(json_contents)
        end
    end
end
unbundled_json_to_spec(fields) click to toggle source
# File lib/dgd-tools/manifest.rb, line 336
def unbundled_json_to_spec(fields)
    source = nil
    source_details = nil
    dependencies = []

    if fields["git"]
        raise "A git source requires a git url: #{fields.inspect}!" unless fields["git"]["url"]
        source = @repo.git_repo(fields["git"]["url"])
        source_details = fields["git"]  # May contain branch info, etc.
    else
        raise "DGD Manifest currently requires a Git-based source!"
    end

    unless fields["paths"].all? { |k, v| k.is_a?(String) && v.is_a?(String) }
        raise "Paths in Goods files must map strings to strings! #{fields["paths"].inspect}"
    end

    if fields["dependencies"]
        # For now, permit a single string as a dependency.
        fields["dependencies"] = [ fields["dependencies"] ] if fields["dependencies"].is_a?(String)

        goods_url = nil
        fields["dependencies"].each do |dep|
            if dep.is_a?(String)
                goods_url = dep
            elsif dep.is_a?(Hash)
                raise "Currently only URL-based dependencies on Goods files are supported!" unless dep["url"]
                goods_url = dep["url"]
            else
                raise "Unexpected dependency type #{dep.class} when parsing DGD Manifest specs, item: #{dep.inspect}"
            end

            text_contents = URI.open(goods_url).read
            local_path = shared_dir + "/goods/" + goods_url.tr("/\\ ", "_")
            File.open(local_path, "wb") { |f| f.write(text_contents) }
            dep_fields = JSON.parse text_contents

            dependencies.push unbundled_json_to_spec(dep_fields)
        end
    end

    spec = GoodsSpec.new(@repo, name: fields["name"], source: source, source_details: source_details, paths: fields["paths"], dependencies: dependencies)
    return spec
end