class DGD::Manifest::Repo

This is a repo of everything DGD Manifest saves between runs. It includes downloaded Git repos, Goods files and more.

Attributes

shared_dir[R]

Public Class Methods

new() click to toggle source
# File lib/dgd-tools/manifest.rb, line 34
def initialize
    @no_manifest_file = true
    @home = ENV["HOME"]
    @shared_dir = "#{@home}/.dgd-tools"
    Dir.mkdir(@shared_dir) unless File.directory?(@shared_dir)

    ["git", "goods"].each do |subdir|
        full_subdir = "#{@shared_dir}/#{subdir}"
        Dir.mkdir(full_subdir) unless File.directory?(full_subdir)
    end

    unless File.exist?("#{@shared_dir}/dgd/bin/dgd")
        dgd_dir = "#{@shared_dir}/dgd"
        if File.directory?(dgd_dir)
            # Not clear to me what to do here...
        else
            DGD::Manifest.system_call("git clone https://github.com/ChatTheatre/dgd.git #{dgd_dir}")
            Dir.chdir("#{@shared_dir}/dgd/src") do
                DGD::Manifest.system_call(DGD_BUILD_COMMAND)
            end
        end
    end
end

Public Instance Methods

assemble_app(location, verbose:) click to toggle source
# File lib/dgd-tools/manifest.rb, line 129
def assemble_app(location, verbose:)
    Dir[File.join(dgd_root(location), "*")].each { |dir| FileUtils.rm_rf dir }
    Dir[File.join(dgd_root(location), "state", "*")].each { |dir| FileUtils.rm_rf dir }

    write_app_files(location, verbose: verbose)
end
dgd_root(location) click to toggle source
# File lib/dgd-tools/manifest.rb, line 125
def dgd_root(location)
    "#{File.expand_path(location)}/#{GENERATED_ROOT}"
end
git_repo(git_url) click to toggle source
# File lib/dgd-tools/manifest.rb, line 58
def git_repo(git_url)
    @git_repos ||= {}
    @git_repos[git_url] ||= GitRepo.new(self, git_url)
end
manifest_file(path) click to toggle source
# File lib/dgd-tools/manifest.rb, line 63
def manifest_file(path)
    raise "Already have a dgd.manifest file!" unless @no_manifest_file

    @no_manifest_file = false
    @manifest_file ||= AppFile.new(self, path, shared_dir: shared_dir)
end
precheck(location, verbose:) click to toggle source
# File lib/dgd-tools/manifest.rb, line 185
def precheck(location, verbose:)
    all_files = assembly_operations(location, verbose: verbose).flat_map { |sd| sd[:non_dirs] }

    if all_files.size != all_files.uniq.size
        repeated = all_files.uniq.select { |f| all_files.count(f) > 1 }
        raise "Error in dgd.manifest! Repeated files: #{repeated.inspect} / #{all_files.inspect}"
    end
end
update_app(location, verbose:) click to toggle source
# File lib/dgd-tools/manifest.rb, line 136
def update_app(location, verbose:)
    Dir[File.join(dgd_root(location), ".repos", "*")].each { |dir| FileUtils.rm_f dir }
    write_app_files(location, verbose: verbose)
end
write_config_file(path) click to toggle source
# File lib/dgd-tools/manifest.rb, line 194
def write_config_file(path)
    File.open(path, "wb") do |f|
        f.write @manifest_file.dgd_config.as_file
    end
end

Protected Instance Methods

assembly_operations(location, verbose:) click to toggle source

This includes files to assemble… But also subdirectories and commands. This format is unstable and ugly, and should not be exposed to outside parties who might later depend on it.

# File lib/dgd-tools/manifest.rb, line 74
def assembly_operations(location, verbose:)
    operations = []

    raise("No manifest file!") if @no_manifest_file

    # For each spec, put its dependencies before itself in order
    @manifest_file.ordered_specs.each do |spec|
        spec_git_repo = spec.source
        spec_git_repo.use_details(spec.source_details)  # This sets things like checked-out branch

        spec.paths.each do |from, to|
            # Note: spec_git_repo.local_dir is an absolute path.
            from_path = "#{spec_git_repo.local_dir}/#{from}"
            if File.directory?(from_path)
                files = Dir["#{from_path}/**/*"].to_a + Dir["#{from_path}/**/.*"].to_a
                dirs = files.select { |file| File.directory?(file) }
                non_dirs = files - dirs
                operations << { cmd: "cp", from: from_path, to: to, dirs: dirs, non_dirs: non_dirs, comment: :single_dir }
            elsif from_path["*"]  # If from_path contains at least one asterisk
                components = from.split("/")
                first_wild_idx = components.index { |item| item["*"] }
                no_wild_from_path = components[0..(first_wild_idx-1)].join("/")
                wild_path = components[first_wild_idx..-1].join("/")

                files = Dir["#{spec_git_repo.local_dir}/#{no_wild_from_path}/#{wild_path}"].to_a
                dirs = files.select { |file| File.directory?(file) }
                dirs += files.map { |f| File.dirname(f) }
                dirs.uniq!

                non_dirs = files - dirs
                operations << { cmd: "cp", from: "#{spec_git_repo.local_dir}/#{no_wild_from_path}", to: to, dirs: dirs, non_dirs: non_dirs, comment: :path_wildcard }
            else
                # A single file
                operations << { cmd: "cp", from: from_path, to: to, dirs: [], non_dirs: [from_path], comment: :single_file }
            end
        end
    end

    app_path = "#{File.expand_path(location)}/#{@manifest_file.app_root}"
    app_files = Dir["#{app_path}/**/*"].to_a
    app_dirs = app_files.select { |f| File.directory?(f) }
    app_non_dirs = app_files - app_dirs
    unless app_dirs.empty? && app_non_dirs.empty?
        operations << { cmd: "cp", from: app_path, to: ".", dirs: app_dirs, non_dirs: app_non_dirs, comment: :app_files }  # No source
    end

    operations
end
write_app_files(location, verbose:) click to toggle source
# File lib/dgd-tools/manifest.rb, line 143
def write_app_files(location, verbose:)
    Dir.chdir(location) do
        write_config_file("#{location}/dgd.config")
        FileUtils.mkdir_p("#{location}/state") # Statedir for statedumps, editor files, etc.
        repos_dir = "#{location}/.repos"
        FileUtils.mkdir_p(repos_dir) # Links to repos in manifest

        @manifest_file.ordered_specs.each do |spec|
            # force:true prevents getting an exception if the file exists
            FileUtils.ln_s(spec.source.local_dir, File.join(".repos", spec.name), force: true)
        end

        assembly_operations(location, verbose: verbose).each do |sd_hash|
            to_path = "#{dgd_root(location)}/#{sd_hash[:to]}"

            if verbose
                puts "  Copy #{sd_hash[:from]} -> #{sd_hash[:to]}, files #{sd_hash[:non_dirs].join(", ")}"
            end

            # Make appropriate dirs, including empty ones
            sd_hash[:dirs].each do |dir|
                FileUtils.mkdir_p dir.sub(sd_hash[:from], to_path)
            end

            # Copy all files
            sd_hash[:non_dirs].each do |from_file|
                to_file = from_file.sub(sd_hash[:from], "#{dgd_root(location)}/#{sd_hash[:to]}")
                to_dir = File.dirname(to_file)
                begin
                    FileUtils.mkdir_p to_dir
                    FileUtils.cp from_file, to_file
                rescue
                    puts "Error when copying: #{from_file} -> #{to_file} in #{sd_hash.inspect}"
                    raise
                end
            end
        end
    end
end