fat_config 0.4.1 → 0.6.1

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: e6a9ee861c75317e6c334ccb6639eda669b794a3f7a6e33543e91cf9193d5fd1
4
- data.tar.gz: 760c48576a7d7d2376a3524fc9301f0593261a9e6a9ebd75f431683e9e56b9bf
3
+ metadata.gz: 41cf78034335f9fd05433c7058f26fff973575eb0b6becf4f501a15027905c9c
4
+ data.tar.gz: 6987287fa5d625c0c97c1427add4d7777dea525100d220b8f28241720b85b340
5
5
  SHA512:
6
- metadata.gz: a111ad1acbdda7c5070910a1b78c3c9ab389b4ce45012a97642071d6fa7db21550b7806388b31827db0fbdda62ee16373550f0282daf20d68bfe5180ca9405a9
7
- data.tar.gz: 64ee672822816a6ff7776537817ad2bdaa73c7b446ab86c50954ba38ee408f676006957734996a5ec454ade4c5ebdedd00fd274befb30bf2457751f5397226d9
6
+ metadata.gz: b55c2816b7c7402a751242af54e6e6cf54c4b67965e1b276f743c8a4ae991c6e7752c62ca5ff27a69e64eab2b2eb6bb1c8573c4ec3e3a57d5b4eae072e2813aa
7
+ data.tar.gz: 5d8c20611e05bd4af1745fa00dd1e83295c066fa53d40d3e955df032aa71cf144c5331298f42740d0e26b06f94e5a2a2838a875614a1b8685405d427f269023c
data/.envrc ADDED
@@ -0,0 +1 @@
1
+ PATH_add .bundle/bin
data/.rubocop.yml CHANGED
@@ -1,20 +1,12 @@
1
- inherit_from: ./rubocop-global.yml
2
-
3
- require:
4
- - rubocop-rspec
5
- - rubocop-rake
6
- - rubocop-obsession
1
+ inherit_gem:
2
+ rubocop-ddoherty: 'config/default.yml'
7
3
 
8
4
  AllCops:
9
- TargetRubyVersion: 3.3
10
5
  Include:
11
6
  - 'lib/**/*'
12
- - 'bin/**/*'
13
7
  - 'spec/**/*'
14
- # - 'features/**/*'
15
8
  Exclude:
9
+ - 'test/tmp/**/*'
16
10
  - 'spec/tmp/**/*'
17
- - 'spec/.examples.txt'
18
- - 'bin/setup'
19
- - '.simplecov'
20
- - 'features/**/*'
11
+ - 'spec/.examples*'
12
+ - 'vendor/bundle/**/*'
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --markup markdown
2
+ --output-dir doc
3
+ --readme README.md
4
+ lib/**/*.rb
data/README.md ADDED
@@ -0,0 +1,289 @@
1
+ - [Introduction](#org1f0d9bd)
2
+ - [Installation](#org3f8a5fd)
3
+ - [Usage:](#org5c5fe0f)
4
+ - [Following XDG Standards](#org7e6640a)
5
+ - [Following Classic UNIX Standards](#orgbc610e8)
6
+ - [Available Config File Styles](#orgacf5ac1)
7
+ - [Hash Keys](#orgf87b1a5)
8
+ - [Hash Values](#org451482b)
9
+ - [YAML](#orgef8563a)
10
+ - [TOML](#orgcf8804e)
11
+ - [JSON](#org549e838)
12
+ - [INI](#org12513cc)
13
+ - [Creating a Reader](#org7a0f2a9)
14
+ - [Calling the `read` method on a `Reader`](#org7e439f9)
15
+ - [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings)
16
+ - [Development](#org1fdfa48)
17
+ - [Contributing](#org4454a76)
18
+ - [License](#org8a2eaa6)
19
+
20
+ [![img](https://github.com/ddoherty03/fat_config/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/ddoherty03/fat_config/actions/workflows/main.yml)
21
+
22
+
23
+ <a id="org1f0d9bd"></a>
24
+
25
+ # Introduction
26
+
27
+ Allowing a user to configure an application to change its behavior at runtime can be seen as constructing a ruby `Hash` that merges settings from a variety of sources in a hierarchical fashion: first from system-wide file settings, merged with user-level file settings, merged with environment variable settings, merged with command-line parameters. Constructing this Hash, while needed by nearly any command-line app, can be a tedious chore, especially when there are standards, such as the XDG standards and Unix tradition, that may or may not be followed.
28
+
29
+ `FatConfig` eliminates the tedium of reading configuration files and the environment to populate a Hash of configuration settings. You need only define a `FatConfig::Reader` and call its `#read` method to look for, read, translate, and merge any config files into a single Hash that encapsulates all the files in the proper priority. It can be set to read `YAML`, `TOML`, `JSON`, or `INI` config files.
30
+
31
+
32
+ <a id="org3f8a5fd"></a>
33
+
34
+ # Installation
35
+
36
+ Install the gem and add to the application's Gemfile by executing:
37
+
38
+ ```sh
39
+ bundle add fat_config
40
+ ```
41
+
42
+ If bundler is not being used to manage dependencies, install the gem by executing:
43
+
44
+ ```sh
45
+ gem install fat_config
46
+ ```
47
+
48
+
49
+ <a id="org5c5fe0f"></a>
50
+
51
+ # Usage:
52
+
53
+ ```ruby
54
+ require 'fat_config'
55
+
56
+ reader = FatConfig::Reader.new('myapp')
57
+ config = reader.read
58
+ ```
59
+
60
+ ```
61
+
62
+ ```
63
+
64
+ The `reader.read` method will parse the config files (by default assumed to be YAML files), config environment variable, and optional command-line parameters and return the composite config as a Hash.
65
+
66
+
67
+ <a id="org7e6640a"></a>
68
+
69
+ ## Following XDG Standards
70
+
71
+ By default, `FatConfig::Reader#read` follows the [XDG Desktop Standards](https://specifications.freedesktop.org/basedir-spec/latest/), reading configuration settings for a hypothetical application called `myapp` from the following locations, from lowest priority to highest:
72
+
73
+ 1. If the environment variable `MYAPP_SYS_CONFIG` is set to the name of a file, it will look in that file for any system-level config file.
74
+ 2. If the environment variable `MYAPP_SYS_CONFIG` is NOT set, it will read any system-level config file from `/etc/xdg/myapp` or, if the `XDG_CONFIG_DIRS` environment variable is set to a list of colon-separated directories, it will look in each of those instead of `/etc/xdg` for config directories called `myapp`. If more than one `XDG_CONFIG_DIRS` is given, they are treated as listed in order of precedence, so the first-listed directory will be given priority over later ones. All such directories will be read, and any config file found will be merged into the resulting Hash, but they will be visited in reverse order so that the earlier-named directories override the earlier ones.
75
+ 3. If the environment variable `MYAPP_CONFIG` is set to a file name, it will look in that file any user-level config file.
76
+ 4. If the environment variable `MYAPP_CONFIG` is NOT set, it will read any user-level config file from `$HOME/.config/myapp` or, if the `XDG_CONFIG_HOME` environment variable is set to an alternative directory, it will look in `XDG_CONFIG_HOME/.config` for a config directory called 'myapp'. Note that in this case, `XDG_CONFIG_HOME` is intended to contain the name of a single directory, not a list of directories as with the system-level config files.
77
+ 5. It will then merge in any options set in the environment variable `MYAPP_OPTIONS`, overriding any conflicting settings gotten from reading the system- and user-level files. It will interpret the String from the environment variable as discussed below in [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings).
78
+ 6. Finally, it will merge in any options given in the optional `command_line:` named parameter to the `#read` method. That parameter can either be a `Hash` or a `String`. If it is a `String`, it is interpreted the same way as the environment variable `MYAPP_OPTIONS` as explained below in [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings); if it is a `Hash`, it is used directly and merged into the hash returned from the prior methods.
79
+
80
+
81
+ <a id="orgbc610e8"></a>
82
+
83
+ ## Following Classic UNIX Standards
84
+
85
+ With the optional `:xdg` keyword parameter to `FatConfig::Reader#read` set to `false`, it will follow "classic" UNIX config file conventions. There is no "standard" here, but there are some conventions, and the closest thing I can find to describe the conventions is this from the [UNIX File Hierarchy Standard](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s08.html#homeReferences) website:
86
+
87
+ > User specific configuration files for applications are stored in the user's home directory in a file that starts with the '.' character (a "dot file"). If an application needs to create more than one dot file then they should be placed in a subdirectory with a name starting with a '.' character, (a "dot directory"). In this case the configuration files should not start with the '.' character.
88
+
89
+ `FatConfig`'s implementation of this suggestion are as follows for a hypothetical application called `myapp`:
90
+
91
+ 1. If the environment variable `MYAPP_SYS_CONFIG` is set to a file name, it will look in that file for any system-level config file.
92
+ 2. If the environment variable `MYAPP_SYS_CONFIG` is NOT set, then either
93
+ - if the file `/etc/my_app` exists and is readable, it is considered the system-wide config file for `my_app`, or
94
+ - if the file `/etc/my_apprc` exists and is readable, it is considered the system-wide config file for `my_app`, or
95
+ - if the *directory* `/etc/my_app` exists, the first file named `config`, `config.yml`, `config.yaml` (this assumes the default YAML style, the extensions looked for will be adjusted for other styles) , `myapp.config`, or `myapp.cfg` that is readable will be considered the system-wide config file for `my_app`
96
+ 3. If the environment variable `MYAPP_CONFIG` is set to a file name, it will look in that file for any user-level config file.
97
+ 4. If the environment variable `MYAPP_CONFIG` is NOT set, then either,
98
+ - if the file, `~/.my_app` or `~/.my_apprc~` exist and are readable, that file is used as the user-level config file,
99
+ - otherwise, if the directory `~/.my_app/` exists, the first file in that directory named `config`, `config.yml`, `config.yaml`, `myapp.config`, or `myapp.cfg` that is readable will be considered the user-level config file for `my_app`
100
+ 5. It will then merge in any options set in the environment variable `MYAPP_OPTIONS`, overriding any conflicting settings gotten from reading the system- and user-level file. It will interpret the environment setting as explained below in [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings).
101
+ 6. Finally, it will merge in any options given in the optional `command_line:` named parameter to the `#read` method. That parameter can either be a `Hash` or a `String`. If it is a `String`, it will interpret the string as explained below in [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings); if it is a `Hash`, it is used directly and merged into the hash returned from the prior methods.
102
+
103
+
104
+ <a id="orgacf5ac1"></a>
105
+
106
+ ## Available Config File Styles
107
+
108
+ `FatConfig::Reader.new` takes the optional keyword argument, `:style`, to indicate what style to use for config files. It can be one of:
109
+
110
+ - **`yaml`:** See [YAML Specs](https://yaml.org/spec/1.2.2/),
111
+ - **`toml`:** See [TOML Specs](https://toml.io/en/),
112
+ - **`json`:** See [JSON Specs](https://datatracker.ietf.org/doc/html/rfc8259), or
113
+ - **`ini`:** See [INI File on Wikipedia](https://en.wikipedia.org/wiki/INI_file)
114
+
115
+ By default, the style is `yaml`. Note that the style only pertains to the syntax of on-disk configuration files. Configuration can also be set by an environment variable, `MYAPP_OPTIONS` and by a command-line string optionally provided to the `#read` method. Those are simple parsers that parse strings of option settings as explained below. See, [Parsing Environment and Command Line Strings](#parsing-environment-and-command-line-strings).
116
+
117
+
118
+ <a id="orgf87b1a5"></a>
119
+
120
+ ## Hash Keys
121
+
122
+ The returned Hash will have symbols as keys, using the names given in the config files, except that they will have any hyphens converted to the underscore. Thus the config setting "page-width: 6.5in" in a config file will result in a Hash entry of `{ page_width: '6.5in' }`.
123
+
124
+
125
+ <a id="org451482b"></a>
126
+
127
+ ## Hash Values
128
+
129
+ Whether the values of the returned Hash will be 'deserialized' into a Ruby object is controlled by the style of the configuration files. For example, the `:yaml` style deserializes the following types:
130
+
131
+
132
+ <a id="orgef8563a"></a>
133
+
134
+ ### YAML
135
+
136
+ - TrueClass (the string 'true' of whatever case)
137
+ - FalseClass (the string 'false' of whatever case)
138
+ - NilClass (when no value given)
139
+ - Integer (when it looks like an whole number)
140
+ - Float (when it looks like an decimal number)
141
+ - String (if not one of the other classes or if enclosed in single- or double-quotes)
142
+ - Array (when sub-elements introduced with '-', each typed by these rules)
143
+ - Hash, (when sub-elements introduced with 'key:', each typed by these rules) and,
144
+ - Date, DateTime, and Time, which FatConfig adds to the foregoing default types deserialized by the default YAML library.
145
+
146
+
147
+ <a id="orgcf8804e"></a>
148
+
149
+ ### TOML
150
+
151
+ - TrueClass (exactly the string 'true')
152
+ - FalseClass (exactly the string 'false')
153
+ - Integer (when it looks like an whole number or 0x&#x2026; or 0o&#x2026; hex or octal)
154
+ - Float (when it looks like an decimal number)
155
+ - String (only if enclosed in single- or double-quotes)
156
+ - Array (when sub-elements enclosed in [&#x2026;], each typed by these rules)
157
+ - Hash, ([hash-key] followed by sub-elements, each typed by these rules) and,
158
+ - Date and Time, when given in ISO form YYYY-MM-DD or YYYY-MM-DDThh:mm:ss
159
+
160
+
161
+ <a id="org549e838"></a>
162
+
163
+ ### JSON
164
+
165
+ - TrueClass (exactly the string 'true')
166
+ - FalseClass (exactly the string 'false')
167
+ - Integer (when it looks like an decimal whole number, but NO provision hex or octal)
168
+ - Float (when it looks like an decimal number)
169
+ - String (only if enclosed in single- or double-quotes)
170
+ - Array (when sub-elements enclosed in [&#x2026;], each typed by these rules)
171
+ - Hash, (when sub-elements enclosed in {&#x2026;}, each typed by these rules) and,
172
+ - Date and Time, NOT deserialized, returns a parse error
173
+
174
+
175
+ <a id="org12513cc"></a>
176
+
177
+ ### INI
178
+
179
+ - TrueClass (exactly the string 'true')
180
+ - FalseClass (exactly the string 'false')
181
+ - Integer (when it looks like an whole number or 0x&#x2026; or 0o&#x2026; hex or octal)
182
+ - Float (when it looks like an decimal number)
183
+ - String (anything else)
184
+ - Array NOT deserialized, returned as a String
185
+ - Hash, NOT deserialized, returned as a String
186
+ - Date and Time, NOT deserialized, returned as a String
187
+
188
+
189
+ <a id="org7a0f2a9"></a>
190
+
191
+ ## Creating a Reader
192
+
193
+ When creating a `Reader`, the `#new` method takes a mandatory argument that specifies the name of the application for which configuration files are to be sought. It also takes a few optional keyword arguments:
194
+
195
+ - `style:` specify a style for the config files other than YAML, the choices are `yaml`, `toml`, `json`, and `ini`. This can be given either as a String or Symbol in upper or lower case.
196
+ - `xdg:` either `true`, to follow the XDG standard for where to find config files, or `false`, to follow classic UNIX conventions.
197
+ - `root_prefix:`, to locate the root of the file system somewhere other than `/`. This is probably only useful in testing `FatConfig`.
198
+
199
+ ```ruby
200
+ reader1 = FatConfig.new('labrat') # Use XDG and YAML
201
+ reader2 = FatConfig.new('labrat', style: 'toml') # Use XDG and TOML
202
+ reader3 = FatConfig.new('labrat', style: 'ini', xdg: false) # Use classic UNIX and INI style
203
+ ```
204
+
205
+
206
+ <a id="org7e439f9"></a>
207
+
208
+ ## Calling the `read` method on a `Reader`
209
+
210
+ Once a `Reader` is created, you can get the completely merged configuration as a Hash by calling `Reader#read`. The `read` method can take several parameters:
211
+
212
+ - **`alternative base`:** as the first positional parameter, you can give an alternative base name to use for the config files other than the app\_name given in the `Reader.new` constructor. This is useful for applications that may want to have more than one set of configuration files. If given, this name only affects the base names of the config files, not the directory in which they are to be sought: those always use the app name.
213
+ - **`command_line:`:** if you want a command-line to override config values, you can supply one as either a String or a Hash to the `command_line:` keyword parameter. See below for how a String is parsed.
214
+ - **`verbose:`:** if you set `verbose:` true as a keyword argument, the `read` method will report details of how the configuration was built on `$stderr`.
215
+
216
+ ```ruby
217
+ reader = FatConfig::Reader.new('labrat')
218
+ reader.read # YAML configs with basename 'labrat'; XDG conventions
219
+
220
+ # Now read another config set in directories named 'labrat' but with base
221
+ # names of 'labeldb'. Overrride any setting named fog_psi with command-line
222
+ # value, and report config build on $stderr.
223
+ reader.read('labeldb', command_line: "--fog-psi=3.41mm", verbose: true)
224
+
225
+ # Similar with a Hash for the command-line
226
+ cl = { fog_psi: '3.41mm' }
227
+ reader.read('labeldb', command_line: cl, verbose: true)
228
+ ```
229
+
230
+
231
+ <a id="parsing-environment-and-command-line-strings"></a>
232
+
233
+ ## Parsing Environment and Command Line Strings
234
+
235
+ The highest priority configs are those contained in the environment variable or in any `command-line:` key-word parameter given to the `#read` method. In the case of the environment variable, the setting is always a String read from the environment.
236
+
237
+ The `command_line:` key-word parameter can be set to either a String or a Hash. When a Hash is provided, it is used unaltered as a config hash. When a String is provided (and in the case of the environment variable), the string should be something like this:
238
+
239
+ ```
240
+ --hello-thing='hello, world' --gb=goodbye world --doit --the_num=3.14159 --the-date=2024-11-27 --no-bueno --~junk
241
+ ```
242
+
243
+ And it is parsed into this Hash:
244
+
245
+ ```ruby
246
+ {
247
+ :hello_thing=>"hello, world",
248
+ :gb=>"goodbye",
249
+ :doit=>true,
250
+ :the_num=>"3.14159",
251
+ :the_date=>"2024-11-27",
252
+ :bueno=>false,
253
+ :junk=>false
254
+ }
255
+ ```
256
+
257
+ Here are the parsing rules:
258
+
259
+ 1. A config element is either of the following, everything else is ignored:
260
+ 1. an "option," of the form "`--<option-name>=<value>`" or
261
+
262
+ 2. a "flag" of the form "`--<flag-name>`"
263
+
264
+ 2. All option values are returned as String's and are not deserialized into Ruby objects,
265
+ 3. All flags are returned as a boolean `true` or `false`. If the flag name starts with 'no', 'no-', 'no\_', '!', or '~', it is set to `false` and the option name has the negating prefix stripped; otherwise, it is set to `true`.
266
+ 4. These rules apply regardless of style being used for config files.
267
+
268
+
269
+ <a id="org1fdfa48"></a>
270
+
271
+ # Development
272
+
273
+ After checking out the repo, run \`bin/setup\` to install dependencies. Then, run \`rake spec\` to run the tests. You can also run \`bin/console\` for an interactive prompt that will allow you to experiment.
274
+
275
+ To install this gem onto your local machine, run \`bundle exec rake install\`. To release a new version, update the version number in \`version.rb\`, and then run \`bundle exec rake release\`, which will create a git tag for the version, push git commits and the created tag, and push the \`.gem\` file to [rubygems.org](https://rubygems.org).
276
+
277
+
278
+ <a id="org4454a76"></a>
279
+
280
+ # Contributing
281
+
282
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/ddoherty03/fat_config>.
283
+
284
+
285
+ <a id="org8a2eaa6"></a>
286
+
287
+ # License
288
+
289
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/README.org CHANGED
@@ -1,11 +1,48 @@
1
- # FatConfig
1
+ #+TITLE: FatConfig
2
+ #+PROPERTY: header-args:ruby :results value :colnames no :hlines yes :exports both :dir "./"
3
+ #+PROPERTY: header-args:ruby+ :wrap example :session fat_config_session :eval yes
4
+ #+PROPERTY: header-args:ruby+ :prologue "$:.unshift('./lib') unless $:.first == './lib'; require 'fat_config'"
5
+ #+PROPERTY: header-args:sh :exports code :eval no
6
+ #+PROPERTY: header-args:bash :exports code :eval no
7
+
8
+ [[https://github.com/ddoherty03/fat_config/actions/workflows/main.yml][https://github.com/ddoherty03/fat_config/actions/workflows/main.yml/badge.svg?branch=master]]
9
+
10
+ * Introduction
11
+ Allowing a user to configure an application to change its behavior at runtime
12
+ can be seen as constructing a ruby ~Hash~ that merges settings from a variety
13
+ of sources in a hierarchical fashion: first from system-wide file settings,
14
+ merged with user-level file settings, merged with environment variable
15
+ settings, merged with command-line parameters. Constructing this Hash, while
16
+ needed by nearly any command-line app, can be a tedious chore, especially when
17
+ there are standards, such as the XDG standards and Unix tradition, that may or
18
+ may not be followed.
2
19
 
3
20
  ~FatConfig~ eliminates the tedium of reading configuration files and the
4
21
  environment to populate a Hash of configuration settings. You need only
5
- define a ~FatConfig::Reader~ and you can call its ~#read~ method to look for,
6
- read, translate, and merge any config files into a single Hash that
7
- encapsulates all the files in the proper priority. It can be set to read
8
- ~YAML~, ~TOML~, ~JSON~, or ~INI~ config files.
22
+ define a ~FatConfig::Reader~ and call its ~#read~ method to look for, read,
23
+ translate, and merge any config files into a single Hash that encapsulates all
24
+ the files in the proper priority. It can be set to read ~YAML~, ~TOML~,
25
+ ~JSON~, or ~INI~ config files.
26
+
27
+ * Table of Contents :toc:noexport:
28
+ - [[#introduction][Introduction]]
29
+ - [[#installation][Installation]]
30
+ - [[#usage][Usage:]]
31
+ - [[#following-xdg-standards][Following XDG Standards]]
32
+ - [[#following-classic-unix-standards][Following Classic UNIX Standards]]
33
+ - [[#available-config-file-styles][Available Config File Styles]]
34
+ - [[#hash-keys][Hash Keys]]
35
+ - [[#hash-values][Hash Values]]
36
+ - [[#yaml][YAML]]
37
+ - [[#toml][TOML]]
38
+ - [[#json][JSON]]
39
+ - [[#ini][INI]]
40
+ - [[#creating-a-reader][Creating a Reader]]
41
+ - [[#calling-the-read-method-on-a-reader][Calling the ~read~ method on a ~Reader~]]
42
+ - [[#parsing-environment-and-command-line-strings][Parsing Environment and Command Line Strings]]
43
+ - [[#development][Development]]
44
+ - [[#contributing][Contributing]]
45
+ - [[#license][License]]
9
46
 
10
47
  * Installation
11
48
 
@@ -30,6 +67,10 @@ If bundler is not being used to manage dependencies, install the gem by executin
30
67
  config = reader.read
31
68
  #+end_src
32
69
 
70
+ #+RESULTS:
71
+ #+begin_example
72
+ #+end_example
73
+
33
74
  The ~reader.read~ method will parse the config files (by default assumed to be
34
75
  YAML files), config environment variable, and optional command-line parameters
35
76
  and return the composite config as a Hash.
@@ -49,26 +90,26 @@ from the following locations, from lowest priority to highest:
49
90
  treated as listed in order of precedence, so the first-listed directory
50
91
  will be given priority over later ones. All such directories will be read,
51
92
  and any config file found will be merged into the resulting Hash, but they
52
- will be visited in reverse order so that the first-named directories
93
+ will be visited in reverse order so that the earlier-named directories
53
94
  override the earlier ones.
54
95
  3. If the environment variable ~MYAPP_CONFIG~ is set to a file name, it will
55
96
  look in that file any user-level config file.
56
97
  4. If the environment variable ~MYAPP_CONFIG~ is NOT set, it will read any
57
98
  user-level config file from ~$HOME/.config/myapp~ or, if the
58
99
  ~XDG_CONFIG_HOME~ environment variable is set to an alternative directory,
59
- it will look ~XDG_CONFIG_HOME/.config~ for a config directory called
100
+ it will look in ~XDG_CONFIG_HOME/.config~ for a config directory called
60
101
  'myapp'. Note that in this case, ~XDG_CONFIG_HOME~ is intended to contain
61
102
  the name of a single directory, not a list of directories as with the
62
103
  system-level config files.
63
104
  5. It will then merge in any options set in the environment variable
64
105
  ~MYAPP_OPTIONS~, overriding any conflicting settings gotten from reading
65
- the system- and user-level file. It will interpret the String from the
66
- environment variable as discussed below in [[*Parsing Environment and Command Line Strings][Parsing Environment and Command
106
+ the system- and user-level files. It will interpret the String from the
107
+ environment variable as discussed below in [[#parsing-environment-and-command-line-strings][Parsing Environment and Command
67
108
  Line Strings]].
68
109
  6. Finally, it will merge in any options given in the optional ~command_line:~
69
110
  named parameter to the ~#read~ method. That parameter can either be a
70
111
  ~Hash~ or a ~String~. If it is a ~String~, it is interpreted the same way
71
- as the environment variable ~MYAPP_OPTIONS~ as explained below in [[*Parsing Environment and Command Line Strings][Parsing
112
+ as the environment variable ~MYAPP_OPTIONS~ as explained below in [[#parsing-environment-and-command-line-strings][Parsing
72
113
  Environment and Command Line Strings]]; if it is a ~Hash~, it is used
73
114
  directly and merged into the hash returned from the prior methods.
74
115
 
@@ -140,18 +181,21 @@ of option settings as explained below. See, [[*Parsing Environment and Command
140
181
  Line Strings]].
141
182
 
142
183
  ** Hash Keys
143
- The returned Hash will have symbols as keys, using the names given in the
144
- config files, except that they will have any hyphens converted to the
145
- underscore. Thus the config setting "page-width: 6.5in" in a config file will
146
- result in a Hash entry of ~{ page_width: '6.5in' }~.
184
+ Any keys that are Strings will be converted to a symbol, using the names given
185
+ in the config files, except that they will have any hyphens converted to the
186
+ underscore so they are suitable for use as a method call. Thus the config
187
+ setting "page-width: 6.5in" in a config file will result in a Hash entry of ~{
188
+ page_width: '6.5in' }~.
189
+
190
+ Keys that are not Strings will be left alone, so that, for example, you might
191
+ have Integer keys, which may be useful below the top level.
147
192
 
148
193
  ** Hash Values
149
194
  Whether the values of the returned Hash will be 'deserialized' into a Ruby
150
- object is controlled by the style of the configuration files. For example,
151
- the ~:yaml~ style deserializes the following types:
195
+ object is controlled by the style of the configuration files.
152
196
 
153
197
  *** YAML
154
-
198
+ The ~:yaml~ style deserializes the following types:
155
199
  - TrueClass (the string 'true' of whatever case)
156
200
  - FalseClass (the string 'false' of whatever case)
157
201
  - NilClass (when no value given)
@@ -164,7 +208,7 @@ the ~:yaml~ style deserializes the following types:
164
208
  types deserialized by the default YAML library.
165
209
 
166
210
  *** TOML
167
-
211
+ The ~:toml~ style deserializes the following types:
168
212
  - TrueClass (exactly the string 'true')
169
213
  - FalseClass (exactly the string 'false')
170
214
  - Integer (when it looks like an whole number or 0x... or 0o... hex or octal)
@@ -175,7 +219,7 @@ the ~:yaml~ style deserializes the following types:
175
219
  - Date and Time, when given in ISO form YYYY-MM-DD or YYYY-MM-DDThh:mm:ss
176
220
 
177
221
  *** JSON
178
-
222
+ The ~:json~ style deserializes the following types:
179
223
  - TrueClass (exactly the string 'true')
180
224
  - FalseClass (exactly the string 'false')
181
225
  - Integer (when it looks like an decimal whole number, but NO provision hex
@@ -187,7 +231,7 @@ the ~:yaml~ style deserializes the following types:
187
231
  - Date and Time, NOT deserialized, returns a parse error
188
232
 
189
233
  *** INI
190
-
234
+ The ~:ini~ style deserializes the following types:
191
235
  - TrueClass (exactly the string 'true')
192
236
  - FalseClass (exactly the string 'false')
193
237
  - Integer (when it looks like an whole number or 0x... or 0o... hex or octal)
@@ -210,18 +254,16 @@ sought. It also takes a few optional keyword arguments:
210
254
  - ~root_prefix:~, to locate the root of the file system somewhere other than
211
255
  ~/~. This is probably only useful in testing ~FatConfig~.
212
256
 
213
- #+begin_src ruby
214
- require 'fat_config'
215
-
257
+ #+begin_src ruby :eval no
216
258
  reader1 = FatConfig.new('labrat') # Use XDG and YAML
217
259
  reader2 = FatConfig.new('labrat', style: 'toml') # Use XDG and TOML
218
260
  reader3 = FatConfig.new('labrat', style: 'ini', xdg: false) # Use classic UNIX and INI style
219
261
  #+end_src
220
262
 
221
- ** Calling the ~#read~ method on a ~Reader~
263
+ ** Calling the ~read~ method on a ~Reader~
222
264
  Once a ~Reader~ is created, you can get the completely merged configuration as
223
265
  a Hash by calling ~Reader#read~. The ~read~ method can take several
224
- parameter:
266
+ parameters:
225
267
 
226
268
  - ~alternative base~ :: as the first positional parameter, you can give an
227
269
  alternative base name to use for the config files other than the app_name
@@ -235,9 +277,7 @@ parameter:
235
277
  - ~verbose:~ :: if you set ~verbose:~ true as a keyword argument, the ~read~
236
278
  method will report details of how the configuration was built on ~$stderr~.
237
279
 
238
- #+begin_src ruby
239
- require 'fat_config'
240
-
280
+ #+begin_src ruby :eval no
241
281
  reader = FatConfig::Reader.new('labrat')
242
282
  reader.read # YAML configs with basename 'labrat'; XDG conventions
243
283
 
@@ -252,6 +292,10 @@ parameter:
252
292
  #+end_src
253
293
 
254
294
  ** Parsing Environment and Command Line Strings
295
+ :PROPERTIES:
296
+ :CUSTOM_ID: parsing-environment-and-command-line-strings
297
+ :END:
298
+
255
299
  The highest priority configs are those contained in the environment variable
256
300
  or in any ~command-line:~ key-word parameter given to the ~#read~ method. In
257
301
  the case of the environment variable, the setting is always a String read from
@@ -268,9 +312,9 @@ should be something like this:
268
312
 
269
313
  And it is parsed into this Hash:
270
314
 
271
- #+begin_src ruby
315
+ #+begin_src ruby :eval no
272
316
  {
273
- :hello_thing=>"hello, world",
317
+ :hello_thing=>"hello, world",
274
318
  :gb=>"goodbye",
275
319
  :doit=>true,
276
320
  :the_num=>"3.14159",
@@ -282,9 +326,12 @@ And it is parsed into this Hash:
282
326
 
283
327
  Here are the parsing rules:
284
328
 
285
- 1. A config element is either an "option," of the form
286
- "--<option-name>=<value>" or a "flag" of the form "--<flag-name>",
287
- everything else is ignored.
329
+ 1. A config element is either of the following, everything else is ignored:
330
+
331
+ a. an "option," of the form "~--<option-name>=<value>~" or
332
+
333
+ b. a "flag" of the form "~--<flag-name>~"
334
+
288
335
  2. All option values are returned as String's and are not deserialized into
289
336
  Ruby objects,
290
337
  3. All flags are returned as a boolean ~true~ or ~false~. If the flag name
data/Rakefile CHANGED
@@ -5,8 +5,12 @@ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
+ require 'gem_docs'
9
+ GemDocs.install
10
+
8
11
  require "rubocop/rake_task"
9
12
 
10
13
  RuboCop::RakeTask.new
14
+ RSpec::Core::RakeTask.new(:spec)
11
15
 
12
16
  task default: %i[spec rubocop]
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Transform String hash keys to symbols suitable for calling as methods,
5
+ # i.e., translate any hyphens to underscores. This is the form we want to
6
+ # keep config hashes in Labrat. Leave non-String keys alone, so, e.g., an
7
+ # Integer can be a key below the top-level
8
+ def methodize
9
+ new_arr = []
10
+ each do |v|
11
+ new_arr <<
12
+ case v
13
+ when Hash, Array
14
+ v.methodize
15
+ when Symbol, String
16
+ # In case the key is a Symbol like :"a key-for-me", convert it back to
17
+ # a String, then let #as_sym convert it to a proper Symbol that can be
18
+ # used as a method call.
19
+ v.as_sym
20
+ else
21
+ v
22
+ end
23
+ end
24
+ new_arr
25
+ end
26
+ end
@@ -1,19 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Hash
4
- # Transform hash keys to symbols suitable for calling as methods, i.e.,
5
- # translate any hyphens to underscores. This is the form we want to keep
6
- # config hashes in Labrat.
4
+ # Transform String hash keys to symbols suitable for calling as methods,
5
+ # i.e., translate any hyphens to underscores. This is the form we want to
6
+ # keep config hashes in Labrat. Leave non-String keys alone, so, e.g., an
7
+ # Integer can be a key below the top-level
7
8
  def methodize
8
9
  new_hash = {}
9
10
  each_pair do |k, v|
10
- new_val =
11
- if v.is_a?(Hash)
12
- v.methodize
13
- else
14
- v
15
- end
16
- new_hash[k.to_s.tr('-', '_').to_sym] = new_val
11
+ case k
12
+ when String
13
+ new_hash[k.as_sym] = v.kind_of?(Hash) ? v.methodize : v
14
+ when Symbol
15
+ # In case the key is a Symbol like :"a key-for-me", convert it back to
16
+ # a String, then let #as_sym convert it to a proper Symbol that can be
17
+ # used as a method call.
18
+ new_hash[k.to_s.as_sym] = v.kind_of?(Hash) ? v.methodize : v
19
+ else
20
+ new_hash[k] = v.kind_of?(Hash) ? v.methodize : v
21
+ end
17
22
  end
18
23
  new_hash
19
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatConfig
2
4
  class ParseError < StandardError; end
3
5
  end
@@ -228,7 +228,7 @@ module FatConfig
228
228
  def find_classic_sys_config_files(base = app_name)
229
229
  configs = []
230
230
  env_config = ENV["#{app_name.upcase}_SYS_CONFIG"]
231
- if env_config && File.readable?((config = File.join(root_prefix, File.expand_path(env_config))))
231
+ if env_config && File.readable?(config = File.join(root_prefix, File.expand_path(env_config)))
232
232
  configs = [config]
233
233
  elsif File.readable?(config = File.join(root_prefix, "/etc/#{base}"))
234
234
  configs = [config]
@@ -251,7 +251,7 @@ module FatConfig
251
251
  # given.
252
252
  def find_classic_user_config_file(base = app_name)
253
253
  env_config = ENV["#{app_name.upcase}_CONFIG"]
254
- if env_config && File.readable?((config = File.join(root_prefix, File.expand_path(env_config))))
254
+ if env_config && File.readable?(config = File.join(root_prefix, File.expand_path(env_config)))
255
255
  config
256
256
  else
257
257
  config_dir = File.join(root_prefix, File.expand_path("~/"))
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatConfig
2
4
  # This class acts as a super class for specific styles of config files. The
3
5
  # subclass must provide a load_file method that takes a file name, reads it
@@ -29,11 +31,10 @@ module FatConfig
29
31
  file_hash = load_file(f)
30
32
  next unless file_hash
31
33
 
32
- if file_hash.is_a?(Hash)
33
- file_hash = file_hash.methodize
34
- else
35
- raise "Error loading file #{f}:\n#{File.read(f)[0..500]}"
34
+ unless file_hash.is_a?(Hash)
35
+ raise FatConfig::ParseError, "Error loading file #{f}:\n#{File.read(f)[0..500]}"
36
36
  end
37
+
37
38
  if verbose
38
39
  warn "Merging system config from file '#{f}':" if sys_files.include?(f)
39
40
  warn "Merging user config from file '#{f}':" if usr_files.include?(f)
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatConfig
2
4
  class INIStyle < Style
3
5
  def load_string(str)
4
6
  # Since INIFile does not have a method for parsing strings, we have to
5
7
  # create a file with the string as content.
6
- tmp_path = File.join("/tmp", "fat_config/ini#{$PID}")
8
+ tmp_path = Tempfile.create
7
9
  File.write(tmp_path, str)
8
10
  load_file(tmp_path)
9
11
  rescue IniFile::Error => ex
@@ -11,7 +13,17 @@ module FatConfig
11
13
  end
12
14
 
13
15
  def load_file(file_name)
14
- IniFile.load(file_name).to_h.methodize
16
+ ini = IniFile.load(file_name)
17
+ config = {}
18
+ ini.each_section do |sec|
19
+ case ini[sec]
20
+ when Hash
21
+ config[sec.to_sym] = ini[sec].methodize
22
+ else
23
+ config[sec.to_sym] = ini[sec]
24
+ end
25
+ end
26
+ config
15
27
  rescue IniFile::Error => ex
16
28
  raise FatConfig::ParseError, ex.to_s
17
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatConfig
2
4
  class JSONStyle < Style
3
5
  def load_string(str)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatConfig
2
4
  class TOMLStyle < Style
3
5
  def load_string(str)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module FatConfig
@@ -17,29 +19,46 @@ module FatConfig
17
19
  # - Array
18
20
  # - Hash
19
21
  #
20
- # Recursive data structures are not allowed by default. Arbitrary classes
21
- # can be allowed by adding those classes to the permitted_classes
22
+ # Recursive data structures are not allowed by Psych by default. Arbitrary
23
+ # classes can be allowed by adding those classes to the permitted_classes
22
24
  # keyword argument. They are additive. For example, to allow Date
23
25
  # deserialization:
24
26
  #
25
27
  # Config.read adds Date, etc., to permitted classes, but provides for no others.
26
28
  class YAMLStyle < Style
27
- def load_string(str)
28
- Psych.safe_load(
29
+ def load_string(str, top_sym: :config)
30
+ data = Psych.safe_load(
29
31
  str,
30
- symbolize_names: true,
32
+ symbolize_names: false,
31
33
  permitted_classes: [Date, DateTime, Time],
32
- )&.methodize || {}
34
+ )
35
+ case data
36
+ when Hash
37
+ data.methodize
38
+ when Array
39
+ { top_sym => data.methodize }
40
+ when NilClass
41
+ {}
42
+ end
33
43
  rescue Psych::SyntaxError => ex
34
44
  raise FatConfig::ParseError, ex.to_s
35
45
  end
36
46
 
37
47
  def load_file(file_name)
38
- Psych.safe_load_file(
48
+ top_sym = File.basename(file_name).sub(/\.[^\.]*$/, '').as_sym
49
+ data = Psych.safe_load_file(
39
50
  file_name,
40
- symbolize_names: true,
51
+ symbolize_names: false,
41
52
  permitted_classes: [Date, DateTime, Time],
42
- )&.methodize || {}
53
+ )
54
+ case data
55
+ when Hash
56
+ data.methodize
57
+ when Array
58
+ { top_sym => data.methodize }
59
+ when NilClass
60
+ {}
61
+ end
43
62
  rescue Psych::SyntaxError => ex
44
63
  raise FatConfig::ParseError, ex.to_s
45
64
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FatConfig
4
- VERSION = "0.4.1"
4
+ VERSION = "0.6.1"
5
5
  end
data/lib/fat_config.rb CHANGED
@@ -1,19 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/hash'
4
+ require 'fat_core/all'
4
5
  require 'fileutils'
5
6
  require 'psych'
6
7
  require 'tomlib'
7
8
  require 'inifile'
8
9
  require 'json'
9
10
 
10
- require_relative "fat_config/version"
11
- require_relative "fat_config/errors"
12
- require_relative "fat_config/core_ext/hash_ext"
13
- require_relative "fat_config/reader"
14
- require_relative "fat_config/style"
15
-
11
+ # Gem Overview (extracted from README.org by gem_docs)
12
+ #
13
+ # * Introduction
14
+ # Allowing a user to configure an application to change its behavior at runtime
15
+ # can be seen as constructing a ruby ~Hash~ that merges settings from a variety
16
+ # of sources in a hierarchical fashion: first from system-wide file settings,
17
+ # merged with user-level file settings, merged with environment variable
18
+ # settings, merged with command-line parameters. Constructing this Hash, while
19
+ # needed by nearly any command-line app, can be a tedious chore, especially when
20
+ # there are standards, such as the XDG standards and Unix tradition, that may or
21
+ # may not be followed.
22
+ #
23
+ # ~FatConfig~ eliminates the tedium of reading configuration files and the
24
+ # environment to populate a Hash of configuration settings. You need only
25
+ # define a ~FatConfig::Reader~ and call its ~#read~ method to look for, read,
26
+ # translate, and merge any config files into a single Hash that encapsulates all
27
+ # the files in the proper priority. It can be set to read ~YAML~, ~TOML~,
28
+ # ~JSON~, or ~INI~ config files.
16
29
  module FatConfig
17
30
  class Error < StandardError; end
18
- # Your code goes here...
31
+ require_relative "fat_config/version"
32
+ require_relative "fat_config/errors"
33
+ require_relative "fat_config/core_ext/hash_ext"
34
+ require_relative "fat_config/core_ext/array_ext"
35
+ require_relative "fat_config/reader"
36
+ require_relative "fat_config/style"
19
37
  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.4.1
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-12-31 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
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
32
+ version: 5.6.1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0'
39
+ version: 5.6.1
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: inifile
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -81,13 +81,17 @@ executables: []
81
81
  extensions: []
82
82
  extra_rdoc_files: []
83
83
  files:
84
+ - ".envrc"
84
85
  - ".rspec"
85
86
  - ".rubocop.yml"
87
+ - ".yardopts"
86
88
  - LICENSE.txt
89
+ - README.md
87
90
  - README.org
88
91
  - Rakefile
89
92
  - TODO.org
90
93
  - lib/fat_config.rb
94
+ - lib/fat_config/core_ext/array_ext.rb
91
95
  - lib/fat_config/core_ext/hash_ext.rb
92
96
  - lib/fat_config/errors.rb
93
97
  - lib/fat_config/reader.rb
@@ -97,15 +101,14 @@ files:
97
101
  - lib/fat_config/styles/toml_style.rb
98
102
  - lib/fat_config/styles/yaml_style.rb
99
103
  - lib/fat_config/version.rb
100
- - rubocop-global.yml
101
104
  - sig/fat_config.rbs
102
- homepage: https://git.ddoherty.net/fat_config
105
+ homepage: https://github.com/ddoherty.net/fat_config
103
106
  licenses:
104
107
  - MIT
105
108
  metadata:
106
109
  allowed_push_host: https://rubygems.org
107
- homepage_uri: https://git.ddoherty.net/fat_config
108
- source_code_uri: https://git.ddoherty.net/fat_config
110
+ homepage_uri: https://github.com/ddoherty.net/fat_config
111
+ source_code_uri: https://github.com/ddoherty.net/fat_config
109
112
  rdoc_options: []
110
113
  require_paths:
111
114
  - lib
@@ -120,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
123
  - !ruby/object:Gem::Version
121
124
  version: '0'
122
125
  requirements: []
123
- rubygems_version: 3.6.2
126
+ rubygems_version: 4.0.0
124
127
  specification_version: 4
125
128
  summary: Library to read config from standard XDG or classic locations.
126
129
  test_files: []
data/rubocop-global.yml DELETED
@@ -1,178 +0,0 @@
1
- require:
2
- - rubocop-rspec
3
- - rubocop-performance
4
- - rubocop-rake
5
-
6
- inherit_gem:
7
- rubocop-shopify: rubocop.yml
8
-
9
- AllCops:
10
- NewCops: enable
11
- # TargetRubyVersion: 3.0
12
-
13
- Style/DateTime:
14
- Enabled: false
15
-
16
- Style/StringLiteralsInInterpolation:
17
- Enabled: true
18
- EnforcedStyle: single_quotes
19
-
20
- Style/MethodCallWithArgsParentheses:
21
- Enabled: false
22
-
23
- Style/StringLiterals:
24
- Enabled: false
25
-
26
- Style/WordArray:
27
- Enabled: false
28
-
29
- Style/SymbolArray:
30
- Enabled: false
31
-
32
- Style/TrailingCommaInHashLiteral:
33
- Enabled: false
34
-
35
- Style/TrailingCommaInArrayLiteral:
36
- Enabled: false
37
-
38
- Style/HashSyntax:
39
- Enabled: false
40
-
41
- Style/ClassMethodsDefinitions:
42
- Enabled: true
43
- EnforcedStyle: def_self
44
-
45
- Layout/LineLength:
46
- Enabled: true
47
- Max: 120
48
- # To make it possible to copy or click on URIs in the code, we allow lines
49
- # containing a URI to be longer than Max.
50
- AllowHeredoc: true
51
- AllowURI: true
52
- URISchemes:
53
- - http
54
- - https
55
-
56
- Layout/ArgumentAlignment:
57
- Enabled: true
58
- EnforcedStyle: with_first_argument
59
-
60
- Naming/InclusiveLanguage:
61
- Enabled: false
62
-
63
- Metrics/AbcSize:
64
- # The ABC size is a calculated magnitude, so this number can be a Fixnum or
65
- # a Float.
66
- Enabled: false
67
- Max: 50
68
-
69
- Metrics/BlockNesting:
70
- Enabled: false
71
- Max: 3
72
-
73
- Metrics/BlockLength:
74
- Enabled: false
75
- Max: 25
76
-
77
- Metrics/ClassLength:
78
- Enabled: false
79
- CountComments: false # count full line comments?
80
- Max: 100
81
-
82
- Metrics/ModuleLength:
83
- Enabled: false
84
- CountComments: false # count full line comments?
85
- Max: 100
86
-
87
- Metrics/MethodLength:
88
- Enabled: false
89
- CountComments: false # count full line comments?
90
- Max: 10
91
-
92
- # Avoid complex methods.
93
- Metrics/CyclomaticComplexity:
94
- Enabled: false
95
- Max: 20
96
-
97
- Metrics/ParameterLists:
98
- Max: 5
99
- CountKeywordArgs: false
100
-
101
- Metrics/PerceivedComplexity:
102
- Enabled: false
103
- Max: 8
104
-
105
- Layout/MultilineOperationIndentation:
106
- EnforcedStyle: aligned
107
-
108
- Layout/MultilineMethodCallIndentation:
109
- EnforcedStyle: indented_relative_to_receiver
110
- SupportedStyles:
111
- - aligned
112
- - indented
113
- - indented_relative_to_receiver
114
- # By default, the indentation width from Style/IndentationWidth is used
115
- # But it can be overridden by setting this parameter
116
- IndentationWidth: ~
117
-
118
- # Though the style guides recommend against them, I like perl back references.
119
- # They are much more concise than the recommended: $2 vs. Regexp.last_match(2).
120
- # Two characters versus 18!
121
- # Cop supports --auto-correct.
122
- Style/PerlBackrefs:
123
- Enabled: false
124
-
125
- # Cop supports --auto-correct.
126
- # Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
127
- # SupportedStyles: line_count_based, semantic, braces_for_chaining
128
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
129
- # FunctionalMethods: let, let!, subject, watch
130
- # IgnoredMethods: lambda, proc, it
131
- Style/BlockDelimiters:
132
- EnforcedStyle: braces_for_chaining
133
- ProceduralMethods: expect
134
-
135
- # Cop supports --auto-correct.
136
- # Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
137
- Layout/ExtraSpacing:
138
- AllowForAlignment: true
139
-
140
- # Configuration parameters: EnforcedStyle, SupportedStyles.
141
- # SupportedStyles: format, sprintf, percent
142
- Style/FormatString:
143
- Enabled: false
144
-
145
- # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
146
- # NamePrefix: is_, has_, have_
147
- # NamePrefixBlacklist: is_, has_, have_
148
- # NameWhitelist: is_a?
149
- Naming/PredicateName:
150
- AllowedMethods: has_overlaps_within?
151
- Exclude:
152
- - 'spec/**/*'
153
-
154
- # Cop supports --auto-correct.
155
- # Configuration parameters: EnforcedStyle, SupportedStyles.
156
- # SupportedStyles: always, never
157
- Style/FrozenStringLiteralComment:
158
- Enabled: false
159
- EnforcedStyle: always
160
-
161
- # I like using !! to convert a value to boolean.
162
- Style/DoubleNegation:
163
- Enabled: false
164
-
165
- RSpec/MultipleExpectations:
166
- Enabled: false
167
-
168
- RSpec/ExampleLength:
169
- Enabled: false
170
-
171
- RSpec/DescribedClass:
172
- Enabled: false
173
-
174
- RSpec/MultipleMemoizedHelpers:
175
- Max: 10
176
-
177
- RSpec/NestedGroups:
178
- Max: 5