class Cardio::Mod::Dirs

Dirs objects are used to manage the load paths for card mods. Mods can be loaded as gems and by using directories with mod subdirectories.

  1. Gemfile

A mod gem needs a metadata attribute with { “card-mod” => “the_mod_name” } or the name has to start with “card-mod-”. Then you can just add it to your Gemfile. Otherwise it won’t be recognized as mod.

  1. mod directory

Give a path to a directory with mods. The mods will be loaded in alphabetical order. To change the load order you can add number prefixes to the mod names (like “01_this_first”) or add a Modfile. In the Modfile you list all the mods you want to be loaded from that directory in load order with a preceding “mod” command (similar to a Gemfile). The mods are expected in subdirectories with the mod names.

Mods in Modfiles are always loaded before mods in the Gemfile. If you have to change the order add gem mods to your Modfile using the mod_gem command. You can omit the ‘card-mod’ prefix.

Example for a mod directory:

# my_mod/Modfile
mod "twitter"
gem_mod "logger"
mod "cache"

# directory structure
my_mods/
  Modfile
  cache/
    set/
      all/
        my_cache.rb
  twitter/
    set/
      type/
        basic.rb
    set_pattern/
      my_pattern.rb

Dir checks always for gems. You can initialize an Dirs object with an additional array of paths to card mod directories.

Attributes

mods[R]

Public Class Methods

new(mod_paths=[]) click to toggle source

@param mod_paths [String, Array<String>] paths to directories that contain mods

Calls superclass method
# File lib/cardio/mod/dirs.rb, line 51
def initialize mod_paths=[]
  @mods = []
  @mods_by_name = {}
  @loaded_gem_mods = ::Set.new
  add_core_mods
  add_gem_mods
  Array(mod_paths).each do |mp|
    @current_path = mp
    add_from_modfile || add_from_dir
  end
  super()
  @mods.each { |mod| self << mod.path }
end

Public Instance Methods

add_mod(mod_name, path: nil, group: nil) click to toggle source

Add a mod to mod load paths

# File lib/cardio/mod/dirs.rb, line 66
def add_mod mod_name, path: nil, group: nil
  if @mods_by_name.key? Mod.normalize_name(mod_name)
    raise StandardError,
          "name conflict: mod with name \"#{mod_name}\" already loaded"
  end

  path ||= File.join @current_path, mod_name
  group ||= @current_group

  mod = Mod.new mod_name, path, group, @mods.size
  @mods << mod
  @mods_by_name[mod.name] = mod
end
delete_mod(mod_name) click to toggle source
# File lib/cardio/mod/dirs.rb, line 80
def delete_mod mod_name
  name = Mod.normalize_name mod_name
  mod = @mods_by_name[name]
  @mods.delete mod
  @mods_by_name.delete name
end
dirname(path, type) click to toggle source
# File lib/cardio/mod/dirs.rb, line 114
def dirname path, type
  type ? File.join(path, type.to_s) : path
end
each(type=nil) { |dirname| ... } click to toggle source

Iterate over each mod directory @param type [Symbol] the type of modification like set, set_pattern, or format.

It is attached as subdirectory.
Calls superclass method
# File lib/cardio/mod/dirs.rb, line 107
def each type=nil
  super() do |path|
    dirname = dirname path, type
    yield dirname if Dir.exist? dirname
  end
end
each_subpath(*subdirs) { |mod_name, subpath| ... } click to toggle source
# File lib/cardio/mod/dirs.rb, line 132
def each_subpath *subdirs
  subpaths(*subdirs).each do |mod_name, subpath|
    yield mod_name, subpath
  end
end
each_tmp(type) { |path| ... } click to toggle source
# File lib/cardio/mod/dirs.rb, line 118
def each_tmp type
  @mods.each do |mod|
    path = mod.tmp_dir type
    yield path if Dir.exist? path
  end
end
each_with_tmp(type=nil) { |dirname, tmp_dir| ... } click to toggle source
# File lib/cardio/mod/dirs.rb, line 125
def each_with_tmp type=nil
  @mods.each do |mod|
    dirname = dirname mod.path, type
    yield dirname, mod.tmp_dir(type) if Dir.exist? dirname
  end
end
fetch_mod(mod_name) click to toggle source
# File lib/cardio/mod/dirs.rb, line 100
def fetch_mod mod_name
  @mods_by_name[Mod.normalize_name(mod_name)]
end
path(mod_name) click to toggle source

@param mod_name [String] the name of a mod @return the path to mod ‘mod_name`

# File lib/cardio/mod/dirs.rb, line 89
def path mod_name
  fetch_mod(mod_name)&.path
end
subpaths(*subdirs) click to toggle source
# File lib/cardio/mod/dirs.rb, line 93
def subpaths *subdirs
  @mods.each_with_object({}) do |mod, hash|
    path = mod.subpath(*subdirs)
    hash[mod.name] = path if path
  end
end

Private Instance Methods

add_core_mods() click to toggle source
# File lib/cardio/mod/dirs.rb, line 153
def add_core_mods
  @current_path = File.join Cardio.gem_root, "mod"
  @current_group = "gem-card"
  add_from_dir
  @current_group = nil
end
add_from_dir() click to toggle source
# File lib/cardio/mod/dirs.rb, line 169
def add_from_dir
  Dir.entries(@current_path).sort.each do |filename|
    add_mod filename unless filename.match?(/^\./)
  end
end
add_from_modfile() click to toggle source
# File lib/cardio/mod/dirs.rb, line 160
def add_from_modfile
  modfile_path = File.join @current_path, "Modfile"
  return unless File.exist? modfile_path

  loader = ModfileLoader.new self
  loader.load modfile_path
  true
end
add_gem_mod(mod_name, mod_path, group) click to toggle source
# File lib/cardio/mod/dirs.rb, line 146
def add_gem_mod mod_name, mod_path, group
  return if @loaded_gem_mods.include?(mod_name)

  @loaded_gem_mods << mod_name
  add_mod mod_name, path: mod_path, group: (group || "gem")
end
add_gem_mods() click to toggle source
# File lib/cardio/mod/dirs.rb, line 140
def add_gem_mods
  Cardio::Mod.gem_specs.each do |mod_name, spec|
    add_gem_mod mod_name, spec.full_gem_path, spec.metadata["card-mod-group"]
  end
end