fat_config 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9402d73a4e16cab2a9088bece9dfa623d406858b5c0ae641df01ee988029e6a1
4
- data.tar.gz: 042c81ad9c917ea1073db02259718a73792dd7e134f8c9c3aa4b60f7d9b756b4
3
+ metadata.gz: 79f4dfb77fd0ccc161c28ad847a93ce649930294a4d444ce5e9f83ac0b49b761
4
+ data.tar.gz: dd9db0f013fdcfb1bb36c84e085b4932d7d6a0a59a53db3b8d6088957701bc12
5
5
  SHA512:
6
- metadata.gz: 9026e4d9b87df9db13e341e5e9af201388335db1a750e7e5d72ddea797787034545bdc03b0358acef9a16ae7fb37e31c7e305f23fc6f1023b5e3acf7fb7f2b72
7
- data.tar.gz: 24b464de194eef9fb81afdcc23afd24dfcf4dcca35b6411d9befed18435dc6c98c3d147c5f6971d586a04e345fdc027be4b34e07fc6f75b6caf47a1ee4da7ccd
6
+ metadata.gz: 147f0b15e9431d4f3d9009eddecb87070c734d1d49858d18fcaabd2a98815c84cd2cb6c3b7d388f162656346e38d8486af211534b11c019a446d14207419ff2b
7
+ data.tar.gz: 7d404f53df4b4e5ae034b62728ec11a4eb155c320f92ccb993fd17d2dfd2721b8bed04e7768ad9f8ef02dc70ca36a15fc06fbc7536dcb2cb1e96ec47afbbacfd
data/CHANGELOG.org CHANGED
@@ -6,6 +6,10 @@
6
6
  user would find useful.
7
7
  5. Give each heading a version number and an inactive date (C-c ! is useful here).
8
8
 
9
+ * Version 0.8.0
10
+ - Allow user to specify an explicit user or system config directory, ignoring
11
+ XDG and classic convention.
12
+
9
13
  * Version 0.7.1 [2026-02-06 Fri]
10
14
  - Improved error diagnostics on ParseError
11
15
 
data/README.org CHANGED
@@ -30,6 +30,7 @@ the files in the proper priority. It can be set to read ~YAML~, ~TOML~,
30
30
  - [[#usage][Usage:]]
31
31
  - [[#following-xdg-standards][Following XDG Standards]]
32
32
  - [[#following-classic-unix-standards][Following Classic UNIX Standards]]
33
+ - [[#explicitly-providing-config-directories][Explicitly Providing Config Directories]]
33
34
  - [[#available-config-file-styles][Available Config File Styles]]
34
35
  - [[#hash-keys][Hash Keys]]
35
36
  - [[#hash-values][Hash Values]]
@@ -164,6 +165,11 @@ hypothetical application called ~myapp~:
164
165
  ~Hash~, it is used directly and merged into the hash returned from the
165
166
  prior methods.
166
167
 
168
+ ** Explicitly Providing Config Directories
169
+ When the =Reader= is created, the user can give an explicit =user_dir:=,
170
+ =sys_dir:= parameter or both. If given, the XDG or classic conventions for
171
+ locating config files are ignored regardless of the setting of the =xdg:=
172
+ parameter.
167
173
  ** Available Config File Styles
168
174
  ~FatConfig::Reader.new~ takes the optional keyword argument, ~:style~, to
169
175
  indicate what style to use for config files. It can be one of:
@@ -253,11 +259,19 @@ sought. It also takes a few optional keyword arguments:
253
259
  files, or ~false~, to follow classic UNIX conventions.
254
260
  - ~root_prefix:~, to locate the root of the file system somewhere other than
255
261
  ~/~. This is probably only useful in testing ~FatConfig~.
262
+ - =user_dir:=, to explicitly set the name of the user directory in which to
263
+ look for the app's config files, thus ignoring the setting of =xdg:= for the
264
+ user-level settings.
265
+ - =sys_dir:=, to explicitly set the name of the system directory in which to
266
+ look for the app's config files, thus ignoring the setting of =xdg:= for the
267
+ system-level settings.
256
268
 
257
269
  #+begin_src ruby :eval no
258
270
  reader1 = FatConfig.new('labrat') # Use XDG and YAML
259
271
  reader2 = FatConfig.new('labrat', style: 'toml') # Use XDG and TOML
260
272
  reader3 = FatConfig.new('labrat', style: 'ini', xdg: false) # Use classic UNIX and INI style
273
+ reader4 = FatConfig.new('labrat', user_dir: '~/labrat') # Look in ~/labrat for user settings
274
+ reader5 = FatConfig.new('labrat', sys_dir: '/etc/labrat') # Look in /etc/labrat for system settings
261
275
  #+end_src
262
276
 
263
277
  ** Calling the ~read~ method on a ~Reader~
@@ -12,8 +12,9 @@ module FatConfig
12
12
  # - ~xdg~ :: whether follow XDG desktop conventions, by default true; if
13
13
  # false, use "classic" UNIX config practices with /etc/ and ~/.baserc.
14
14
  # - ~root_prefix~ :: an alternate root of the assumed file system, by
15
- # default ''. This facilitated testing.
15
+ # default ''. This facilitates testing.
16
16
  attr_reader :app_name, :style, :root_prefix, :xdg
17
+ attr_reader :user_dir, :sys_dir
17
18
 
18
19
  # Config file may be located in either the xdg locations (containing any
19
20
  # variant of base: base, base.yml, or base.yaml) or in the classic
@@ -38,7 +39,7 @@ module FatConfig
38
39
  # b. Then, either:
39
40
  # A. The file pointed to by the environment variable APPNAME_SYS_CONFIG or
40
41
  # B. System classic config files,
41
- def initialize(app_name, style: :yaml, xdg: true, root_prefix: '')
42
+ def initialize(app_name, style: :yaml, xdg: true, root_prefix: '', user_dir: nil, sys_dir: nil)
42
43
  @app_name = app_name.strip.downcase
43
44
  raise ArgumentError, "reader app name may not be blank" if @app_name.blank?
44
45
 
@@ -63,6 +64,10 @@ module FatConfig
63
64
  msg = "config style must be one of #{VALID_CONFIG_STYLES.join(', ')}"
64
65
  raise ArgumentError, msg
65
66
  end
67
+ # Optional override of directories instead of locating them by XDG or
68
+ # classical conventions.
69
+ @user_dir = user_dir
70
+ @sys_dir = sys_dir
66
71
  end
67
72
 
68
73
  # Return a Hash of the config files for app_name directories. For
@@ -102,6 +107,50 @@ module FatConfig
102
107
  merge_command_line(result, command_line, verbose: verbose)
103
108
  end
104
109
 
110
+ # Return a Hash of Arrays with the outer Hash having the key system:
111
+ # pointing to an Array of system paths and the key :user pointing to an
112
+ # Array of user paths.
113
+ #
114
+ # @param base [String] base name to use for finding config paths
115
+ # @param user_dir [String] optional override of directory with user config files
116
+ # @param sys_dir [String] optional override of directory with system config files
117
+ def config_paths(base = app_name)
118
+ sys_configs = []
119
+ sys_env_name = "#{app_name.upcase}_SYS_CONFIG"
120
+ if sys_dir
121
+ sys_configs = find_config_files_in_dir(base, sys_dir)
122
+ elsif ENV[sys_env_name]
123
+ sys_fname = File.join(root_prefix, File.expand_path(ENV[sys_env_name]))
124
+ sys_configs << sys_fname if File.readable?(sys_fname)
125
+ else
126
+ sys_configs +=
127
+ if xdg
128
+ find_xdg_sys_config_files(base)
129
+ else
130
+ find_classic_sys_config_files(base)
131
+ end
132
+ end
133
+
134
+ usr_configs = []
135
+ usr_env_name = "#{app_name.upcase}_CONFIG"
136
+ if user_dir
137
+ usr_configs = find_config_files_in_dir(base, user_dir)
138
+ elsif ENV[usr_env_name]
139
+ usr_fname = File.join(root_prefix, File.expand_path(ENV[usr_env_name]))
140
+ usr_configs << usr_fname if File.readable?(usr_fname)
141
+ else
142
+ usr_configs <<
143
+ if xdg
144
+ find_xdg_user_config_file(base)
145
+ else
146
+ find_classic_user_config_file(base)
147
+ end
148
+ end
149
+ { system: sys_configs.compact, user: usr_configs.compact }
150
+ end
151
+
152
+ private
153
+
105
154
  def merge_environment(start_hash, verbose: false)
106
155
  return start_hash if ENV[env_name].blank?
107
156
 
@@ -138,35 +187,25 @@ module FatConfig
138
187
  "#{app_name.upcase}_OPTIONS"
139
188
  end
140
189
 
141
- def config_paths(base = app_name)
142
- sys_configs = []
143
- sys_env_name = "#{app_name.upcase}_SYS_CONFIG"
144
- if ENV[sys_env_name]
145
- sys_fname = File.join(root_prefix, File.expand_path(ENV[sys_env_name]))
146
- sys_configs << sys_fname if File.readable?(sys_fname)
147
- else
148
- sys_configs +=
149
- if xdg
150
- find_xdg_sys_config_files(base)
151
- else
152
- find_classic_sys_config_files(base)
153
- end
154
- end
190
+ ########################################################################
191
+ # Explicit config files
192
+ ########################################################################
155
193
 
156
- usr_configs = []
157
- usr_env_name = "#{app_name.upcase}_CONFIG"
158
- if ENV[usr_env_name]
159
- usr_fname = File.join(root_prefix, File.expand_path(ENV[usr_env_name]))
160
- usr_configs << usr_fname if File.readable?(usr_fname)
161
- else
162
- usr_configs <<
163
- if xdg
164
- find_xdg_user_config_file(base)
165
- else
166
- find_classic_user_config_file(base)
167
- end
194
+ # Return a list of readable config files with basename base for the
195
+ # current style in directory dir.
196
+ #
197
+ # @param base [String] base name of config file
198
+ # @param dir [String] directory to search for config giles
199
+ def find_config_files_in_dir(base, dir)
200
+ configs = []
201
+ dir = File.expand_path(dir)
202
+ base_candidates = style.dir_constrained_base_names(base)
203
+ base_candidates.each do |f|
204
+ if File.readable?(File.join(dir, f))
205
+ configs << File.join(dir, f)
206
+ end
168
207
  end
169
- { system: sys_configs.compact, user: usr_configs.compact }
208
+ configs
170
209
  end
171
210
 
172
211
  ########################################################################
@@ -181,9 +220,9 @@ module FatConfig
181
220
  # $XDG_CONFIG_DIRS (default: "/etc/xdg"): precedence-ordered set of system configuration directories.
182
221
 
183
222
  # Return the absolute path names of all XDG system config files for
184
- # app_name with the basename variants of base. Return the lowest priority
185
- # files first, highest last. Prefix the search locations with dir_prefix
186
- # if given.
223
+ # app_name in the current style with the basename variants of base. Return
224
+ # the lowest priority files first, highest last. Prefix the search
225
+ # locations with dir_prefix if given.
187
226
  def find_xdg_sys_config_files(base = app_name)
188
227
  configs = []
189
228
  xdg_search_dirs = ENV['XDG_CONFIG_DIRS']&.split(':')&.reverse || ['/etc/xdg']
@@ -198,16 +237,16 @@ module FatConfig
198
237
  end
199
238
 
200
239
  # Return the absolute path name of any XDG user config files for app_name
201
- # with the basename variants of base. The XDG_CONFIG_HOME environment
202
- # variable for the user configs is intended to be the name of a single xdg
203
- # config directory, not a list of colon-separated directories as for the
204
- # system config. Return the name of a config file for this app in
205
- # XDG_CONFIG_HOME (or ~/.config by default). Prefix the search location
206
- # with dir_prefix if given.
240
+ # in the current style with the basename variants of base. The
241
+ # XDG_CONFIG_HOME environment variable for the user configs is intended to
242
+ # be the name of a single xdg config directory, not a list of
243
+ # colon-separated directories as for the system config. Return the name of
244
+ # a config file for this app in XDG_CONFIG_HOME (or ~/.config by default).
245
+ # Prefix the search location with dir_prefix if given.
207
246
  def find_xdg_user_config_file(base = app_name)
208
247
  xdg_search_dir = ENV['XDG_CONFIG_HOME'] || ['~/.config']
209
248
  dir = File.expand_path(File.join(xdg_search_dir, app_name))
210
- dir = File.join(root_prefix, dir) unless root_prefix.strip.empty?
249
+ dir = File.join(root_prefix, dir) unless root_prefix.to_s.strip.empty?
211
250
  return unless Dir.exist?(dir)
212
251
 
213
252
  base_candidates = style.dir_constrained_base_names(base)
@@ -222,9 +261,9 @@ module FatConfig
222
261
  ########################################################################
223
262
 
224
263
  # Return the absolute path names of all "classic" system config files for
225
- # app_name with the basename variants of base. Return the lowest priority
226
- # files first, highest last. Prefix the search locations with dir_prefix
227
- # if given.
264
+ # app_name in the current style with the basename variants of base. Return
265
+ # the lowest priority files first, highest last. Prefix the search
266
+ # locations with dir_prefix if given.
228
267
  def find_classic_sys_config_files(base = app_name)
229
268
  configs = []
230
269
  env_config = ENV["#{app_name.upcase}_SYS_CONFIG"]
@@ -246,9 +285,9 @@ module FatConfig
246
285
  end
247
286
 
248
287
  # Return the absolute path names of all "classic" system config files for
249
- # app_name with the basename variants of base. Return the lowest priority
250
- # files first, highest last. Prefix the search locations with dir_prefix if
251
- # given.
288
+ # app_name in the current style with the basename variants of base. Return
289
+ # the lowest priority files first, highest last. Prefix the search
290
+ # locations with dir_prefix if given.
252
291
  def find_classic_user_config_file(base = app_name)
253
292
  env_config = ENV["#{app_name.upcase}_CONFIG"]
254
293
  if env_config && File.readable?(config = File.join(root_prefix, File.expand_path(env_config)))
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FatConfig
4
- VERSION = "0.7.1"
4
+ VERSION = "0.8.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-06 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.6.2
128
+ rubygems_version: 4.0.0
129
129
  specification_version: 4
130
130
  summary: Library to read config from standard XDG or classic locations.
131
131
  test_files: []