Class: XDG::BaseDir

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/xdg/base_dir.rb,
lib/xdg/base_dir/mixin.rb,
lib/xdg/base_dir/legacy.rb,
lib/xdg/base_dir/extended.rb

Overview

Base directory interface class.

Defined Under Namespace

Modules: Legacy, Mixin

Constant Summary collapse

DEFAULTS =

Standard defaults for locations.

{
  'XDG_DATA_HOME'   => ['~/.local/share'],
  'XDG_DATA_DIRS'   => ['/usr/local/share', datadir],
  'XDG_CONFIG_HOME' => ['~/.config'],
  'XDG_CONFIG_DIRS' => [File.join(sysconfdir,'xdg'), sysconfdir],
  'XDG_CACHE_HOME'  => ['~/.cache'],
  'XDG_CACHE_DIRS'  => ['/tmp']
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*env) ⇒ BaseDir

Initialize new instance of BaseDir class.



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/xdg/base_dir.rb', line 31

def initialize(*env)
  @environment_variables = []
  env.each do |v|
    v = v.to_s.upcase
    if v !~ /_/
      @environment_variables << 'XDG_' + v + '_HOME'
      @environment_variables << 'XDG_' + v + '_DIRS'
    else
      @environment_variables << 'XDG_' + v
    end
  end
end

Instance Attribute Details

#subdirectoryObject

The common subdirectory.



138
139
140
# File 'lib/xdg/base_dir.rb', line 138

def subdirectory
  @subdirectory
end

Class Method Details

.[](*env) ⇒ Object

Shortcut for ‘BaseDir.new`.



26
27
28
# File 'lib/xdg/base_dir.rb', line 26

def self.[](*env)
  new(*env)
end

.const_missing(const) ⇒ Object (private)

If Pathname is referenced the library is automatically loaded.



242
243
244
245
246
247
248
249
# File 'lib/xdg/base_dir.rb', line 242

def self.const_missing(const)
  if const == :Pathname
    require 'pathname'
    ::Pathname
  else
    super(const)
  end
end

Instance Method Details

#each(&block) ⇒ Object

Iterate of each directory.



92
93
94
# File 'lib/xdg/base_dir.rb', line 92

def each(&block)
  to_a.each(&block)
end

#environmentString

The environment setting, or it’s equivalent when the BaseDir is a combination of environment variables.

Returns:

  • (String)

    evnironment vsetting



55
56
57
# File 'lib/xdg/base_dir.rb', line 55

def environment
  environment_variables.map{ |v| ENV[v] }.join(':')
end

#environment_variablesArray

The environment variables being referenced.

Returns:

  • (Array)

    list of XDG environment variable names



47
48
49
# File 'lib/xdg/base_dir.rb', line 47

def environment_variables
  @environment_variables
end

#environment_with_defaultsString Also known as: env

This is same as #environment, but also includes default values.

Returns:

  • (String)

    envinronment value.



62
63
64
# File 'lib/xdg/base_dir.rb', line 62

def environment_with_defaults
  environment_variables.map{ |v| ENV[v] || DEFAULTS[v] }.join(':')
end

#expand(path) ⇒ Object (private)



233
234
235
236
237
238
239
# File 'lib/xdg/base_dir.rb', line 233

def expand(path)
  if subdirectory
    File.expand_path(File.join(path, subdirectory))
  else
    File.expand_path(path)
  end
end

#find(*glob_and_flags, &block) ⇒ Object

Find a file or directory. This works just like #select except that it returns the first match found.

TODO: It would be more efficient to traverse the dirs and use #fnmatch.



204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/xdg/base_dir.rb', line 204

def find(*glob_and_flags, &block)
  glob, flag = *parse_arguments(*glob_and_flags)
  find = nil
  to_a.each do |dir|
    path = File.join(dir, *glob)
    hits = Dir.glob(path, flag)
    hits = hits.select(&block) if block_given?
    find = hits.first
    break if find
  end
  find
end

#glob(*glob_and_flags) ⇒ Object

Return array of matching files or directories in any of the resource locations, starting with the home directory and searching outward into system directories.

Unlike #select, this doesn’t take a block and each additional glob argument is treated as a logical-or.

XDG[:DATA].glob("stick/*.rb", "stick/*.yaml")


163
164
165
166
167
168
169
170
171
172
# File 'lib/xdg/base_dir.rb', line 163

def glob(*glob_and_flags)
  glob, flags = *parse_arguments(*glob_and_flags)
  find = []
  to_a.each do |dir|
    glob.each do |pattern|
      find.concat(Dir.glob(File.join(dir, pattern), flags))
    end
  end
  find.uniq
end

#listArray<String>

Returns an unexpanded list of directories.

Returns:

  • (Array<String>)

    unexpanded directory list



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/xdg/base_dir.rb', line 99

def list
  environment_variables.map do |v|
    if paths = ENV[v]
      dirs = paths.split(/[:;]/)
    else
      dirs = DEFAULTS[v]
    end
    if subdirectory
      dirs.map{ |path| File.join(path, subdirectory) }
    else
      dirs
    end
  end.flatten
end

#parse_arguments(*glob_and_flags) ⇒ Object (private)



219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/xdg/base_dir.rb', line 219

def parse_arguments(*glob_and_flags)
  glob, flags = *glob_and_flags.partition{ |e| String===e }
  glob = ['**/*'] if glob.empty?
  flag = flags.inject(0) do |m, f|
    if Symbol === f
      m + File::const_get("FNM_#{f.to_s.upcase}")
    else
      m + f.to_i
    end
  end
  return glob, flag
end

#pathsArray<Pathname>

List of directories as Pathanme objects.

Returns:

  • (Array<Pathname>)

    list of directories as Pathname objects



117
118
119
# File 'lib/xdg/base_dir.rb', line 117

def paths
  map{ |dir| Pathname.new(dir) }
end

#select(*glob_and_flags, &block) ⇒ Object

Return array of matching files or directories in any of the resource locations, starting with the home directory and searching outward into system directories.

String parameters are joined into a pathname while Integers and Symbols treated as flags.

For example, the following are equivalent:

XDG::BaseDir[:DATA,:HOME].select('stick/units', File::FNM_CASEFOLD)

XDG::BaseDir[:DATA,:HOME].select('stick', 'units', :casefold)


188
189
190
191
192
193
194
195
196
197
198
# File 'lib/xdg/base_dir.rb', line 188

def select(*glob_and_flags, &block)
  glob, flag = *parse_arguments(*glob_and_flags)
  find = []
  to_a.each do |dir|
    path = File.join(dir, *glob)
    hits = Dir.glob(path, flag)
    hits = hits.select(&block) if block_given?
    find.concat(hits)
  end
  find.uniq
end

#sizeObject

Number of directory paths.



87
88
89
# File 'lib/xdg/base_dir.rb', line 87

def size
  to_a.size
end

#to_aArray<String> Also known as: to_ary

Returns a complete list of expanded directories.

Returns:

  • (Array<String>)

    expanded directory list



72
73
74
75
76
77
78
79
80
81
# File 'lib/xdg/base_dir.rb', line 72

def to_a
  environment_variables.map do |v|
    if paths = ENV[v]
      dirs = paths.split(/[:;]/)
    else
      dirs = DEFAULTS[v]
    end
    dirs.map{ |path| expand(path) }
  end.flatten
end

#to_pathPathname

The first directory converted to a Pathname object.

Returns:

  • (Pathname)

    pathname of first directory



133
134
135
# File 'lib/xdg/base_dir.rb', line 133

def to_path
  Pathname.new(to_a.first)
end

#to_sString

Returns the first directory expanded. Since a environment settings like ‘*_HOME` will only have one directory entry, this definition of #to_s makes utilizing those more convenient.

Returns:

  • (String)

    directory



126
127
128
# File 'lib/xdg/base_dir.rb', line 126

def to_s
  to_a.first
end

#with_subdirectory(path) ⇒ BaseDir

Set subdirectory to be applied to all paths and return ‘self`.

Returns:



148
149
150
151
# File 'lib/xdg/base_dir.rb', line 148

def with_subdirectory(path)
  @subdirectory = path if path
  self
end