MooX::...lename(3pm)

πŸ“¦
version 0.009 Β· 5 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu questing

✨ MooX::...lename πŸ’…

okay bestie, welcome to the manual page for MooX::ConfigFromFile::Role::SortedByFilename, which lives in the User Contributed Perl Documentation section, and yes the page header literally calls it MooX::...lename(3pm) because filenames are long and life is short. πŸŽ€


🌸 NAME 🌸

MooX::ConfigFromFile::Role::SortedByFilename β€” it lets you have a filename-based sort algorithm for when you're loading multiple config files. no cap. πŸ’–


✨ SYNOPSIS ✨

package MyApp::Cmd::TPau;

use DBI;
use Moo;
use MooX::Cmd with_configfromfile => 1;

with "MooX::ConfigFromFile::Role::SortedByFilename";
with "MooX::ConfigFromFile::Role::HashMergeLoaded";

# ensure hashes are merged by top-most scalar wins
around _build_config_merge_behavior => sub { 'RIGHT_PRECEDENT' };

has csv => (is => "ro", required => 1);

sub execute
{
    my $self = shift;
    DBI->connect("DBI::csv:", undef, undef, $self->csv);
}

__END__
$ cat etc/myapp.json
{
  "csv": {
    "f_ext": ".csv/r",
    "f_dir": "data"
    "csv_sep_char": ";",
    "csv_class": "Text::CSV_XS"
  }
}
$cat etc/myapp-tpau.json
{
  "csv": {
    "f_dir": "data/tpau"
  }
}

πŸ¦‹ DESCRIPTION πŸ¦‹

so this is an additional role for MooX::ConfigFromFile, and its whole thing is letting you merge loaded configurations in a way more predictable order: filename > extension > path. 🫢

Read that as: when the filename is identical, the extensions get compared; when the extensions are also identical, then the locations get compared.

Here's the lil plot twist though β€” filename and file extension get compared on a character basis, but the sort order of the file locations (the path) is based on precedence in MooX::File::ConfigDir or File::ConfigDir, respectively. And that order is defined internally in @File::ConfigDir::extensible_bases. iykyk. 🌈


πŸ‘‘ ATTRIBUTES πŸ‘‘

🌟 sorted_loaded_config

This role modifies the builder for sorted_loaded_config by sorting the loaded files from raw_loaded_config by filename, extension and location in the filesystem, respectively. iconic behaviour honestly. πŸ’…

okay so imagine the affected setup has a CLI interface named oper, with sub commands the way git provides them, too. And the company using the application does it right by defining staging environments like DEV (Development), TEST (Testing), INT (Integration) and PROD (Production). For the example, the sub commands shall be deploy and report.

This will give you possible config_prefix_maps of:

# main command
['oper']
['oper', 'dev']
['oper', 'test']
['oper', 'int']
['oper', 'prod']
# deploy sub-command
['oper', 'deploy']
['oper', 'deploy', 'dev']
['oper', 'deploy', 'test']
['oper', 'deploy', 'int']
['oper', 'deploy', 'prod']
# report sub-command
['oper', 'report']
['oper', 'report', 'dev']
['oper', 'report', 'test']
['oper', 'report', 'int']
['oper', 'report', 'prod']

This will result in (and let's further assume developers prefer JSON while operators prefer YAML) the following possible config filenames:

[
  # main command
  'oper.json',
  'oper.yaml',
  'oper-dev.json',
  'oper-dev.yaml',
  'oper-test.json',
  'oper-test.yaml',
  'oper-int.json',
  'oper-int.yaml',
  'oper-prod.json',
  'oper-prod.yaml',
  # deploy sub-command
  'oper-deploy.json',
  'oper-deploy.yaml',
  'oper-deploy-dev.json',
  'oper-deploy-dev.yaml',
  'oper-deploy-test.json',
  'oper-deploy-test.yaml',
  'oper-deploy-int.json',
  'oper-deploy-int.yaml',
  'oper-deploy-prod.json',
  'oper-deploy-prod.yaml',
  # report sub-command
  'oper-report.json',
  'oper-report.yaml',
  'oper-report-dev.json',
  'oper-report-dev.yaml',
  'oper-report-test.json',
  'oper-report-test.yaml',
  'oper-report-int.json',
  'oper-report-int.yaml',
  'oper-report-prod.json',
  'oper-report-prod.yaml',
]

For a particular invoking (oper report in int stage) the following files exist:

[
  '/etc/oper.json',                 # global configuration by developers
  '/etc/oper.yaml',                 # global configuration by operating policy
  '/opt/ctrl/etc/oper.json',        # vendor configuration by developers
  '/opt/ctrl/etc/oper.yaml',        # vendor configuration by operating policy
  '/opt/ctrl/etc/oper-int.yaml',    # vendor configuration by stage operating policy
  '/opt/ctrl/etc/oper-report.yaml', # vendor configuration by report operating team
  '/home/usr4711/oper-report.yaml', # usr4711 individual configuration (e.g. for template adoption)
]

The default sort algorithm will deliver:

[
  "/etc/oper.json",
  "/etc/oper.yaml",
  "/home/usr4711/oper-report.yaml",
  "/opt/ctrl/etc/oper-int.yaml",
  "/opt/ctrl/etc/oper-report.yaml",
  "/opt/ctrl/etc/oper.json",
  "/opt/ctrl/etc/oper.yaml"
]

This role will change the sort algorithm to deliver:

[
  "/etc/oper.json",
  "/opt/ctrl/etc/oper.json",
  "/etc/oper.yaml",
  "/opt/ctrl/etc/oper.yaml",
  "/opt/ctrl/etc/oper-int.yaml",
  "/opt/ctrl/etc/oper-report.yaml",
  "/home/usr4711/oper-report.yaml"
]

Which will cause that all policy configuration will override the developer defaults and user configuration override policy settings. πŸŽ€βœ¨ that's the whole point bestie, the vibes are correct now.


πŸ’œ AUTHOR πŸ’œ

Jens Rehsack, "<rehsack at cpan.org>"


🌸 ACKNOWLEDGEMENTS 🌸

(nothing here, it's giving mysterious silence 🫢)


Copyright 2018 Jens Rehsack.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See <http://dev.perl.org/licenses/> for more information.


and that's the whole page!! πŸ’– this came to you courtesy of perl v5.36.0 and it was dated 2022-12-11, so go forth and sort your config files, bestie β€” filename > extension > path, always. mwah. πŸŽ€πŸ¦‹πŸ’…βœ¨

πŸ“¦ where this page comes from