maid-xdg 2.2.1.1 → 2.2.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ #
5
+ def command?(command)
6
+ system("type #{command} > /dev/null 2>&1")
7
+ end
8
+
9
+ #
10
+ # Tests
11
+ #
12
+
13
+ task :default => [:qed, :test]
14
+
15
+ if command? :turn
16
+ desc "Run tests"
17
+ task :test do
18
+ suffix = "-n #{ENV['TEST']}" if ENV['TEST']
19
+ sh "turn -Ilib:. test/*.rb #{suffix}"
20
+ end
21
+ else
22
+ Rake::TestTask.new do |t|
23
+ t.libs << 'lib'
24
+ t.libs << '.'
25
+ t.pattern = 'test/test_*.rb'
26
+ t.verbose = false
27
+ end
28
+ end
29
+
30
+ if command? :qed
31
+ desc "run qed tests"
32
+ task :qed do
33
+ sh "qed -Ilib qed/"
34
+ end
35
+ else
36
+ task :qed do
37
+ $stderr.puts "WARNING: install qed gem to run qed tests"
38
+ end
39
+ end
40
+
@@ -0,0 +1,77 @@
1
+ = XDG Base Directory Standard
2
+
3
+ The 2.0 API is much a great deal more concise than the original
4
+ 0.0+ and 1.0+ APIs. It consists primarily of a single
5
+ interface method `XDG[]`. Yet all the functionality of the older
6
+ API remain and then some.
7
+
8
+ First we need to require the library.
9
+
10
+ require 'xdg'
11
+
12
+ In the applique we have setup a fake root directory with
13
+ coorepsonding environment settings to use as test fixtures.
14
+
15
+ == Data Paths
16
+
17
+ === Home
18
+
19
+ XDG['DATA_HOME'].environment.assert == ENV['XDG_DATA_HOME'].to_s
20
+ XDG['DATA_HOME'].environment_variables.assert == ['XDG_DATA_HOME']
21
+
22
+ Looking at the data home location by default it should be point to
23
+ our joe user's home directory under `.local/share`.
24
+
25
+ XDG['DATA_HOME'].to_a.assert == [$froot + 'home/joe/.local/share']
26
+
27
+ === Dirs
28
+
29
+ XDG['DATA_DIRS'].environment.assert == ENV['XDG_DATA_DIRS'].to_s
30
+ XDG['DATA_DIRS'].environment_variables.assert == ['XDG_DATA_DIRS']
31
+
32
+ Looking at the system data locations
33
+
34
+ XDG['DATA_DIRS'].to_a.assert == [$froot + 'usr/share']
35
+
36
+ === Combined
37
+
38
+ XDG['DATA'].environment_variables.assert == ['XDG_DATA_HOME', 'XDG_DATA_DIRS']
39
+
40
+ Lookking at both data location combined
41
+
42
+ XDG['DATA'].to_a.assert == [$froot + 'home/joe/.local/share', $froot + 'usr/share']
43
+
44
+
45
+ == Config Paths
46
+
47
+ === Home
48
+
49
+ XDG['CONFIG_HOME'].environment.assert == ENV['XDG_CONFIG_HOME'].to_s
50
+ XDG['CONFIG_HOME'].to_a.assert == [$froot + 'home/joe/.config']
51
+
52
+ === Dirs
53
+
54
+ XDG['CONFIG_DIRS'].environment.assert == ENV['XDG_CONFIG_DIRS'].to_s
55
+ XDG['CONFIG_DIRS'].to_a.assert == [$froot + 'etc/xdg', $froot + 'etc']
56
+
57
+ === Combined
58
+
59
+ XDG['CONFIG'].to_a.assert == [$froot + 'home/joe/.config', $froot + 'etc/xdg', $froot + 'etc']
60
+
61
+
62
+ == Cache Paths
63
+
64
+ === Home
65
+
66
+ XDG['CACHE_HOME'].environment.assert == ENV['XDG_CACHE_HOME'].to_s
67
+ XDG['CACHE_HOME'].to_a.assert == [$froot + 'home/joe/.cache']
68
+
69
+ === Dirs
70
+
71
+ XDG['CACHE_DIRS'].environment.assert == ENV['XDG_CACHE_DIRS'].to_s
72
+ XDG['CACHE_DIRS'].to_a.assert == [$froot + 'tmp']
73
+
74
+ === Combined
75
+
76
+ XDG['CACHE'].to_a.assert == [$froot + 'home/joe/.cache', $froot + 'tmp']
77
+
@@ -0,0 +1,47 @@
1
+ = Extended Base Directory Standard
2
+
3
+ The extended base directory standard provides additional locations
4
+ not apart the offical standard. These are somewhat experimental.
5
+
6
+ == Resource
7
+
8
+ XDG['RESOURCE_HOME'].environment.assert == ENV['XDG_RESOURCE_HOME'].to_s
9
+
10
+ XDG['RESOURCE_HOME'].environment_variables.assert == ['XDG_RESOURCE_HOME']
11
+
12
+ Looking at the data home location by default it should be pointing to
13
+ our joe users home directory under `.local`.
14
+
15
+ XDG['RESOURCE_HOME'].list.assert == ['~/.local']
16
+
17
+ XDG['RESOURCE_HOME'].to_a.assert == [$froot + 'home/joe/.local']
18
+
19
+
20
+ == Work
21
+
22
+ The working configuration directory
23
+
24
+ XDG['CONFIG_WORK'].environment.assert == ENV['XDG_CONFIG_WORK'].to_s
25
+
26
+ XDG['CONFIG_WORK'].environment_variables.assert == ['XDG_CONFIG_WORK']
27
+
28
+ Looking at the config work location, by default it should be pointing to
29
+ the current working directorys `.config` or `config` directory.
30
+
31
+ XDG['CONFIG_WORK'].list.assert == ['.config', 'config']
32
+
33
+ XDG['CONFIG_WORK'].to_a.assert == [Dir.pwd + '/.config', Dir.pwd + '/config']
34
+
35
+ The working cache directory
36
+
37
+ XDG['CACHE_WORK'].environment.assert == ENV['XDG_CACHE_WORK'].to_s
38
+
39
+ XDG['CACHE_WORK'].environment_variables.assert == ['XDG_CACHE_WORK']
40
+
41
+ Looking at the cache work location, by default it should be pointing to
42
+ the current working directorys `.tmp` or `tmp` directory.
43
+
44
+ XDG['CACHE_WORK'].list.assert == ['.tmp', 'tmp']
45
+
46
+ XDG['CACHE_WORK'].to_a.assert == [Dir.pwd + '/.tmp', Dir.pwd + '/tmp']
47
+
@@ -0,0 +1,17 @@
1
+ = Base Directory Mixin
2
+
3
+ The base directory mixin is used to easy augment a class for
4
+ access to a named subdirectory of the XDG directories.
5
+
6
+ class MyAppConfig
7
+ include XDG::BaseDir::Mixin
8
+
9
+ def subdirectory
10
+ 'myapp'
11
+ end
12
+ end
13
+
14
+ c = MyAppConfig.new
15
+
16
+ c.config.home.to_a #=> [$froot + 'home/joe/.config/myapp']
17
+
@@ -0,0 +1 @@
1
+ AE.ansi = false
@@ -0,0 +1,17 @@
1
+ require 'fileutils'
2
+
3
+ dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
4
+
5
+ $froot = File.join(dir, 'fixtures/fakeroot/')
6
+
7
+ puts "Fake root at: `#{$froot}'."
8
+
9
+ #
10
+ ENV['HOME'] = $froot + 'home/joe'
11
+ #ENV['XDG_DATA_HOME'] = $froot + '.local/share'
12
+ ENV['XDG_DATA_DIRS'] = $froot + 'usr/share'
13
+ #ENV['XDG_CONFIG_HOME'] = $froot + '.config'
14
+ ENV['XDG_CONFIG_DIRS'] = $froot + 'etc/xdg' + ':' + $froot + 'etc'
15
+ #ENV['XDG_CACHE_HOME'] = $froot + '.cache'
16
+ ENV['XDG_CACHE_DIRS'] = $froot + 'tmp'
17
+
@@ -0,0 +1 @@
1
+ require 'xdg'
@@ -0,0 +1 @@
1
+ Just here to provide a file for github to keep this directory.
@@ -0,0 +1 @@
1
+ BAR.CONFIG
@@ -0,0 +1 @@
1
+ FOO.CACHE
@@ -0,0 +1 @@
1
+ FOO.DAT
@@ -0,0 +1 @@
1
+ FOO TEXT
@@ -0,0 +1 @@
1
+ BAR.DAT
data/lib/xdg.rb ADDED
@@ -0,0 +1,46 @@
1
+ # XDG Base Directory Standard
2
+ #
3
+ # This provides a conveient library for conforming to the
4
+ # XDG Base Directory Standard.
5
+ #
6
+ # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
7
+ #
8
+ # Some important clarifications, not made clear by the above specification.
9
+ #
10
+ # The data directories are for "read-only" files. In other words once
11
+ # something is put there, it should only be read, and never written to
12
+ # by a program. (Generally speaking only users or package managers should
13
+ # be adding, changing or removing files from the data locations.)
14
+ #
15
+ # The config locations are where you store files that may change,
16
+ # and effect your applications depending on their content. This is like
17
+ # etc/ in the FHS, but alterable by end users and end user programs,
18
+ # not just root and sudo admin scripts.
19
+ #
20
+ # The cache locations stores files that could just as well be deleted
21
+ # and everything would still work fine. This is for variable and
22
+ # temporary files. Much like var/ and tmp/ in FHS.
23
+ #
24
+ # The module returns all paths as String.
25
+ #
26
+ module XDG
27
+ if RUBY_VERSION > '1.9'
28
+ require_relative 'xdg/version'
29
+ require_relative 'xdg/base_dir'
30
+ require_relative 'xdg/base_dir/extended'
31
+ require_relative 'xdg/base_dir/mixin'
32
+ else
33
+ require 'xdg/version'
34
+ require 'xdg/base_dir'
35
+ require 'xdg/base_dir/extended'
36
+ require 'xdg/base_dir/mixin'
37
+ end
38
+
39
+ #
40
+ def self.[](*env_path)
41
+ BaseDir.new(*env_path)
42
+ end
43
+ end
44
+
45
+ # Copyright (c) 2008,2011 Thomas Sawyer
46
+ # Distributed under the terms of the APACHE 2.0 license.
@@ -0,0 +1,256 @@
1
+ module XDG
2
+
3
+ # Base Directory Standard
4
+ class BaseDir
5
+
6
+ # Try to get information from Ruby's install configuration.
7
+ require 'rbconfig'
8
+
9
+ sysconfdir = ::RbConfig::CONFIG['sysconfdir'] || '/etc'
10
+ datadir = ::RbConfig::CONFIG['datadir'] || '/usr/share'
11
+
12
+ # Standard defaults for locations.
13
+ DEFAULTS = {
14
+ 'XDG_DATA_HOME' => ['~/.local/share'],
15
+ 'XDG_DATA_DIRS' => ['/usr/local/share', datadir],
16
+ 'XDG_CONFIG_HOME' => ['~/.config'],
17
+ 'XDG_CONFIG_DIRS' => [File.join(sysconfdir,'xdg'), sysconfdir],
18
+ 'XDG_CACHE_HOME' => ['~/.cache'],
19
+ 'XDG_CACHE_DIRS' => ['/tmp']
20
+ }
21
+
22
+ # BaseDir iterates over directory paths.
23
+ include Enumerable
24
+
25
+ # Shortcut for `BaseDir.new`.
26
+ def self.[](*env)
27
+ new(*env)
28
+ end
29
+
30
+ # Initialize new instance of BaseDir class.
31
+ def initialize(*env)
32
+ @environment_variables = []
33
+ env.each do |v|
34
+ v = v.to_s.upcase
35
+ if v !~ /_/
36
+ @environment_variables << 'XDG_' + v + '_HOME'
37
+ @environment_variables << 'XDG_' + v + '_DIRS'
38
+ else
39
+ @environment_variables << 'XDG_' + v
40
+ end
41
+ end
42
+ end
43
+
44
+ # The environment variables being referenced.
45
+ #
46
+ # @return [Array] list of XDG environment variable names
47
+ def environment_variables
48
+ @environment_variables
49
+ end
50
+
51
+ # The environment setting, or it's equivalent when the BaseDir
52
+ # is a combination of environment variables.
53
+ #
54
+ # @return [String] evnironment vsetting
55
+ def environment
56
+ environment_variables.map{ |v| ENV[v] }.join(':')
57
+ end
58
+
59
+ # This is same as #environment, but also includes default values.
60
+ #
61
+ # @return [String] envinronment value.
62
+ def environment_with_defaults
63
+ environment_variables.map{ |v| ENV[v] || DEFAULTS[v] }.join(':')
64
+ end
65
+
66
+ # Shortcut for #environment_with_defaults.
67
+ alias_method :env, :environment_with_defaults
68
+
69
+ # Returns a complete list of expanded directories.
70
+ #
71
+ # @return [Array<String>] expanded directory list
72
+ def to_a
73
+ environment_variables.map do |v|
74
+ if paths = ENV[v]
75
+ dirs = paths.split(/[:;]/)
76
+ else
77
+ dirs = DEFAULTS[v]
78
+ end
79
+ dirs.map{ |path| expand(path) }
80
+ end.flatten
81
+ end
82
+
83
+ # BaseDir is essentially an array.
84
+ alias_method :to_ary, :to_a
85
+
86
+ # Number of directory paths.
87
+ def size
88
+ to_a.size
89
+ end
90
+
91
+ # Iterate of each directory.
92
+ def each(&block)
93
+ to_a.each(&block)
94
+ end
95
+
96
+ # Returns an *unexpanded* list of directories.
97
+ #
98
+ # @return [Array<String>] unexpanded directory list
99
+ def list
100
+ environment_variables.map do |v|
101
+ if paths = ENV[v]
102
+ dirs = paths.split(/[:;]/)
103
+ else
104
+ dirs = DEFAULTS[v]
105
+ end
106
+ if subdirectory
107
+ dirs.map{ |path| File.join(path, subdirectory) }
108
+ else
109
+ dirs
110
+ end
111
+ end.flatten
112
+ end
113
+
114
+ # List of directories as Pathanme objects.
115
+ #
116
+ # @return [Array<Pathname>] list of directories as Pathname objects
117
+ def paths
118
+ map{ |dir| Pathname.new(dir) }
119
+ end
120
+
121
+ # Returns the first directory expanded. Since a environment settings
122
+ # like `*_HOME` will only have one directory entry, this definition
123
+ # of #to_s makes utilizing those more convenient.
124
+ #
125
+ # @return [String] directory
126
+ def to_s
127
+ to_a.first
128
+ end
129
+
130
+ # The first directory converted to a Pathname object.
131
+ #
132
+ # @return [Pathname] pathname of first directory
133
+ def to_path
134
+ Pathname.new(to_a.first)
135
+ end
136
+
137
+ # The common subdirectory.
138
+ attr :subdirectory
139
+
140
+ # Set subdirectory to be applied to all paths.
141
+ def subdirectory=(path)
142
+ @subdirectory = path.to_s
143
+ end
144
+
145
+ # Set subdirectory to be applied to all paths and return `self`.
146
+ #
147
+ # @return [BaseDir] self
148
+ def with_subdirectory(path)
149
+ @subdirectory = path if path
150
+ self
151
+ end
152
+
153
+ # Return array of matching files or directories
154
+ # in any of the resource locations, starting with
155
+ # the home directory and searching outward into
156
+ # system directories.
157
+ #
158
+ # Unlike #select, this doesn't take a block and each
159
+ # additional glob argument is treated as a logical-or.
160
+ #
161
+ # XDG[:DATA].glob("stick/*.rb", "stick/*.yaml")
162
+ #
163
+ def glob(*glob_and_flags)
164
+ glob, flags = *parse_arguments(*glob_and_flags)
165
+ find = []
166
+ to_a.each do |dir|
167
+ glob.each do |pattern|
168
+ find.concat(Dir.glob(File.join(dir, pattern), flags))
169
+ end
170
+ end
171
+ find.uniq
172
+ end
173
+
174
+ # Return array of matching files or directories
175
+ # in any of the resource locations, starting with
176
+ # the home directory and searching outward into
177
+ # system directories.
178
+ #
179
+ # String parameters are joined into a pathname
180
+ # while Integers and Symbols treated as flags.
181
+ #
182
+ # For example, the following are equivalent:
183
+ #
184
+ # XDG::BaseDir[:DATA,:HOME].select('stick/units', File::FNM_CASEFOLD)
185
+ #
186
+ # XDG::BaseDir[:DATA,:HOME].select('stick', 'units', :casefold)
187
+ #
188
+ def select(*glob_and_flags, &block)
189
+ glob, flag = *parse_arguments(*glob_and_flags)
190
+ find = []
191
+ to_a.each do |dir|
192
+ path = File.join(dir, *glob)
193
+ hits = Dir.glob(path, flag)
194
+ hits = hits.select(&block) if block_given?
195
+ find.concat(hits)
196
+ end
197
+ find.uniq
198
+ end
199
+
200
+ # Find a file or directory. This works just like #select
201
+ # except that it returns the first match found.
202
+ #
203
+ # TODO: It would be more efficient to traverse the dirs and use #fnmatch.
204
+ def find(*glob_and_flags, &block)
205
+ glob, flag = *parse_arguments(*glob_and_flags)
206
+ find = nil
207
+ to_a.each do |dir|
208
+ path = File.join(dir, *glob)
209
+ hits = Dir.glob(path, flag)
210
+ hits = hits.select(&block) if block_given?
211
+ find = hits.first
212
+ break if find
213
+ end
214
+ find
215
+ end
216
+
217
+ private
218
+
219
+ def parse_arguments(*glob_and_flags)
220
+ glob, flags = *glob_and_flags.partition{ |e| String===e }
221
+ glob = ['**/*'] if glob.empty?
222
+ flag = flags.inject(0) do |m, f|
223
+ if Symbol === f
224
+ m + File::const_get("FNM_#{f.to_s.upcase}")
225
+ else
226
+ m + f.to_i
227
+ end
228
+ end
229
+ return glob, flag
230
+ end
231
+
232
+ #
233
+ def expand(path)
234
+ if subdirectory
235
+ File.expand_path(File.join(path, subdirectory))
236
+ else
237
+ File.expand_path(path)
238
+ end
239
+ end
240
+
241
+ # If Pathname is referenced the library is automatically loaded.
242
+ def self.const_missing(const)
243
+ if const == :Pathname
244
+ require 'pathname'
245
+ ::Pathname
246
+ else
247
+ super(const)
248
+ end
249
+ end
250
+
251
+ end
252
+
253
+ end
254
+
255
+ # Copyright (c) 2008,2011 Thomas Sawyer
256
+ # Distributed under the terms of the APACHE 2.0 license.