Class: Cardio::Mod::Dirs

Inherits:
Array
  • Object
show all
Defined in:
lib/cardio/mod/dirs.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mod_paths = []) ⇒ Dirs

Returns a new instance of Dirs.

Parameters:

  • mod_paths (String, Array<String>) (defaults to: [])

    paths to directories that contain mods



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/cardio/mod/dirs.rb', line 51

def initialize mod_paths=[]
  @mods = []
  @mods_by_name = {}
  @loaded_gem_mods = ::Set.new
  mod_paths = Array(mod_paths)
  mod_paths.each do |mp|
    @current_path = mp
    load_from_modfile || load_from_dir
  end
  load_from_gemfile
  super()
  @mods.each do |mod|
    self << mod.path
  end
end

Instance Attribute Details

#modsObject (readonly)

Returns the value of attribute mods.



48
49
50
# File 'lib/cardio/mod/dirs.rb', line 48

def mods
  @mods
end

Instance Method Details

#add_gem_mod(mod_name, mod_path) ⇒ Object



67
68
69
70
71
72
# File 'lib/cardio/mod/dirs.rb', line 67

def add_gem_mod mod_name, mod_path
  return if @loaded_gem_mods.include?(mod_name)

  @loaded_gem_mods << mod_name
  add_mod mod_name, mod_path
end

#add_mod(mod_name, path = nil) ⇒ Object

Add a mod to mod load paths



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/cardio/mod/dirs.rb', line 75

def add_mod mod_name, path=nil
  if @mods_by_name.key? Mod.normalize_name(mod_name)
    raise ::Card::Error,
          "name conflict: mod with name \"#{mod_name}\" already loaded"
  end

  path ||= File.join @current_path, mod_name
  mod = Mod.new mod_name, path, @mods.size
  @mods << mod
  @mods_by_name[mod.name] = mod
end

#delete_mod(mod_name) ⇒ Object



87
88
89
90
91
92
# File 'lib/cardio/mod/dirs.rb', line 87

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) ⇒ Object



121
122
123
# File 'lib/cardio/mod/dirs.rb', line 121

def dirname path, type
  type ? File.join(path, type.to_s) : path
end

#each(type = nil) ⇒ Object

Iterate over each mod directory

Parameters:

  • type (Symbol) (defaults to: nil)

    the type of modification like set, set_pattern, or format. It is attached as subdirectory.



114
115
116
117
118
119
# File 'lib/cardio/mod/dirs.rb', line 114

def each type=nil
  super() do |path|
    dirname = dirname path, type
    yield dirname if Dir.exist? dirname
  end
end

#each_subpath(*subdirs) ⇒ Object



139
140
141
142
143
# File 'lib/cardio/mod/dirs.rb', line 139

def each_subpath *subdirs
  subpaths(*subdirs).each do |mod_name, subpath|
    yield mod_name, subpath
  end
end

#each_tmp(type) ⇒ Object



125
126
127
128
129
130
# File 'lib/cardio/mod/dirs.rb', line 125

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) ⇒ Object



132
133
134
135
136
137
# File 'lib/cardio/mod/dirs.rb', line 132

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) ⇒ Object



107
108
109
# File 'lib/cardio/mod/dirs.rb', line 107

def fetch_mod mod_name
  @mods_by_name[Mod.normalize_name(mod_name)]
end

#load_from_gemfileObject



145
146
147
148
149
# File 'lib/cardio/mod/dirs.rb', line 145

def load_from_gemfile
  Cardio::Mod.gem_specs.each do |mod_name, mod_spec|
    add_gem_mod mod_name, mod_spec.full_gem_path
  end
end

#path(mod_name) ⇒ Object

Returns the path to mod ‘mod_name`.

Parameters:

  • mod_name (String)

    the name of a mod

Returns:

  • the path to mod ‘mod_name`



96
97
98
# File 'lib/cardio/mod/dirs.rb', line 96

def path mod_name
  fetch_mod(mod_name)&.path
end

#subpaths(*subdirs) ⇒ Object



100
101
102
103
104
105
# File 'lib/cardio/mod/dirs.rb', line 100

def subpaths *subdirs
  @mods.each_with_object({}) do |mod, hash|
    path = mod.subpath(*subdirs)
    hash[mod.name] = path if path
  end
end