diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 027e002..40343da 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.2.1 +current_version = 0.0.1 commit = True message = Bumps version to {new_version} tag = False diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 25453c7..0d42304 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Run test jobs +name: Run salt tests on: pull_request: @@ -7,5 +7,54 @@ concurrency: cancel-in-progress: true jobs: - test: - uses: plus3it/actions-workflows/.github/workflows/test.yml@ce3cef72cf4ac9605a29350d1d4387dfb86cd7a8 + windows: + uses: plus3it/actions-workflows/.github/workflows/test-salt-windows.yml@00ff10246f901f01818db412fa99124dbed4a00c + strategy: + matrix: + os_version: + - windows-2019 + - windows-2022 + - windows-2025 + salt_state: + - notepad-plusplus + salt_pillar_root: + - ./tests/pillar/test-main + with: + salt-os-version: ${{ matrix.os_version }} + salt-state: ${{ matrix.salt_state }} + salt-pillar-root: ${{ matrix.salt_pillar_root }} + + lint_powershell: + name: PowerShell Linting + runs-on: windows-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Run PSScriptAnalyzer + shell: pwsh + run: | + $files = Get-ChildItem -Path ./ -Include *.ps1 -Recurse + Write-Host "--- Starting PowerShell Static Analysis ---" + + $anyErrors = $false + + foreach ($file in $files) { + $relativePath = $file.FullName.Replace($PWD.ProviderPath, ".") + $results = Invoke-ScriptAnalyzer -Path $file.FullName -Severity Warning + + if ($results) { + Write-Host "FAIL: $relativePath" -ForegroundColor Red + $results | Format-Table -AutoSize + $anyErrors = $true + } else { + Write-Host "PASS: $relativePath" -ForegroundColor Green + } + } + + if ($anyErrors) { + Write-Error "Static analysis failed. Please fix the errors above." + exit 1 + } else { + Write-Host "--- All files passed analysis! ---" + } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5caad15..0d55a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,37 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -### [1.2.1] (https://github.com/plus3it/repo-template/releases/tag/1.2.1) +### [0.0.1] (https://github.com/plus3it/repo-template/releases/tag/0.0.1) -**Summary**: - -* Updated README.md to include config settings for github -* Updated LICENSE copyright year - -### [1.2.0] (https://github.com/plus3it/repo-template/releases/tag/1.2.0) +**Released**: 2026.04.14 **Summary**: -* Updated SHA value for Github Actions Workflows -* Updated CHANGELOG.template.md file -* Added Master branch in release workflow logic to make migration to Github Actions more efficient - -### 1.1.0 - -**Commit Delta**: N/A - -**Released**: 2023.01.27 - -**Summary**: +* Adds all necessary, initial install and configuration content for the Notepad++ application to be installed and ready-to-run +* Adds all necessary "clean" content for the Notepad++ application to be fully removed (binaries, config-files and registry-settings +* Activates initial CI content from repo-template repository -* Updated workflow files to be consumable and reusable, and now points to actions-workflows repo -### 1.0.0 -**Commit Delta**: N/A +### [0.0.0] (https://github.com/plus3it/repo-template/releases/tag/0.0.0) -**Released**: 2023.01.10 +**Released**: 2026.04.09 **Summary**: -* Initial release of capability +* "Skeleton" content cloned from [repo-template](https://github.com/plus3it/repo-template) repository diff --git a/CHANGELOG.template.md b/CHANGELOG.template.md deleted file mode 100644 index c61f573..0000000 --- a/CHANGELOG.template.md +++ /dev/null @@ -1,13 +0,0 @@ -## {{ repo-name }} - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). - -### [{{Major.Minor.Patch}}](https://github.com/plus3it/{{RepoName}}/releases/tag/{{Major.Minor.Patch}}) - -**Released**: {{ YYYY.MM.DD }} - -**Summary**: - -* {{ Bulleted descriptions of enhancements, changes, or fixes }} diff --git a/LICENSE b/LICENSE index c2f93d6..adad242 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Maintainers of plus3it/repo-template + Copyright 2026 Maintainers of plus3it/repo-template Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 5de6c40..be18d42 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,40 @@ -# repo-template -Generic repo template for Plus3IT repositories - -To use this template: - -1. Select the green "Use this template" button, or [click here](https://github.com/plus3it/repo-template/generate). -2. Select the repo Owner, give the repo a name, enter a description, select Public or Private, and click "Create repository from template". -3. Clone the repository and create a new branch. -4. Configure the following settings on your new repo. - * `GENERAL` - * `Features` - * Turn off Wikis, Sponsorships, Discussions, and Projects - * `Pull Requests` - * Turn off Squash Merging - * Turn off Rebase Merging - * Turn on Allow Auto-Merge - * Turn on Automatically delete head branches - * `Pushes` - * Limit how many branches can be updated in a single push: 2 - * `COLLABORATORS and TEAMS` - * `Manage Access` - * Add relevant team roles, for example - * `tardigrade-admins` (Admin) - * `terraform` (Write) - * `releasebot` (Write) - * `Branches` - * `Create Branch Protection rule` for `main` - * Turn on Require pull request before merging - * Turn on Require approvals - * Turn on Dismiss stale pull requests... - * `Required Status Checks` - * As relevant to projects, for example - * WIP - * lint/actionlint - * lint/tardigradelint - * test / mockstacktest - * Turn on Do not allow bypassing the above settings -5. Edit the following files to customize them for the new repository: - * `LICENSE` - * Near the end of the file, edit the date and change the repository name - * `CHANGELOG.template.md` - * Rename to `CHANGELOG.md`, replacing the repo-template changelog - * Edit templated items for the new repo - * `.bumpversion.cfg` - * Edit the version number for the new repo, ask team if not sure what to - start with - * `README.md` - * Replace contents for the new repo - * `.github/` - * Inspect dependabot and workflow files in case changes are needed for - the new repo -6. Commit the changes and open a pull request +# notepad-plusplus-formula + +A Saltstack formula designed to install and configure the [Notepad++](https://notepad-plus-plus.org/) text-editor (and to uninstall it later). + +It is primarily expected that this formula will be run via [P3](https://www.plus3it.com/)'s "[watchmaker](https://watchmaker.readthedocs.io/en/stable/)" framework. + +This formula is able to install and configure the Notepad++ text-editor on Windows-based systems. Linux functionality would also have been provided, but there's currently no Linux variant from the same makers. + +## Available states + +- [notepad-plusplus](#notepad-plusplus) +- [notepad-plusplus.clean](#notepad-plusplus.clean) +- [notepad-plusplus.package](#notepad-plusplus.package) +- [notepad-plusplus.package.clean](#notepad-plusplus.package.clean) +- [notepad-plusplus.config](#notepad-plusplus.config) +- [notepad-plusplus.config.clean](#notepad-plusplus.config.clean) + +### notepad-plusplus + +Executes the `package` and `config` states to install and configure the Notepad++ editor. This includes the editor binaries, as well as some Windows Registry settings and user-configuration template files. + +### notepad-plusplus.clean + +Executes the `package` and `config` states' `clean` actions to fully uninstall the Notepad++ editor and associated registry entries + +### notepad-plusplus.package + +Executes _just_ the `package` state to install the Notepad++ package. + +### notepad-plusplus.package.clean + +Executes _just_ the `package` state's `clean` module to uninstall the Notepad++ binaries. + +### notepad-plusplus.config + +Executes _just_ the `config` state to install registry-keys and other configuration-items to support the healthy running of the Notepad++ application + +### notepad-plusplus.config.clean + +Executes _just_ the `config` state's `clean` module to uninstall the Notepad++ application's registry keys and other configuration-items set up during a prior, formula-managed installation. diff --git a/notepad-plusplus/_mapdata/_mapdata.jinja b/notepad-plusplus/_mapdata/_mapdata.jinja new file mode 100644 index 0000000..e356b07 --- /dev/null +++ b/notepad-plusplus/_mapdata/_mapdata.jinja @@ -0,0 +1,13 @@ +# yamllint disable rule:indentation rule:line-length +# {{ grains.get("osfinger", grains.os) }} +--- +{#- use salt.slsutil.serialize to avoid encoding errors on some platforms #} +{{ salt["slsutil.serialize"]( + "yaml", + map, + default_flow_style=False, + allow_unicode=True, + ) + | regex_replace("^\s+'$", "'", multiline=True) + | trim +}} diff --git a/notepad-plusplus/_mapdata/init.sls b/notepad-plusplus/_mapdata/init.sls new file mode 100644 index 0000000..3529a8d --- /dev/null +++ b/notepad-plusplus/_mapdata/init.sls @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls +--- +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split("/")[0] %} +{%- from tplroot ~ "/map.jinja" import mapdata with context %} + +{%- set _mapdata = { + "values": mapdata, + } %} +{%- do salt["log.debug"]("### MAP.JINJA DUMP ###\n" ~ _mapdata | yaml(False)) %} + +{%- set output_dir = "/temp" if grains.os_family == "Windows" else "/tmp" %} +{%- set output_file = output_dir ~ "/salt_mapdata_dump.yaml" %} + +{{ tplroot }}-mapdata-dump: + file.managed: + - name: {{ output_file }} + - source: salt://{{ tplroot }}/_mapdata/_mapdata.jinja + - template: jinja + - context: + map: {{ _mapdata | yaml }} diff --git a/notepad-plusplus/clean.sls b/notepad-plusplus/clean.sls new file mode 100644 index 0000000..477c179 --- /dev/null +++ b/notepad-plusplus/clean.sls @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{%- if grains.os_family == "Windows" %} +include: + - .config.clean + - .package.clean +{%- else %} +Invalid Platform + test.show_notification: + - text: | + ---------------------------------------- + The notepad++ application is not + published for non-Windows platform. + Skipping all further actions. + ---------------------------------------- +{%- endif %} + diff --git a/notepad-plusplus/config/clean.sls b/notepad-plusplus/config/clean.sls new file mode 100644 index 0000000..639a82e --- /dev/null +++ b/notepad-plusplus/config/clean.sls @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import mapdata as notepad_plusplus with context %} +{%- set npp_admins = notepad_plusplus.config.npp_admins or ['Administrator'] %} +{%- set npp_dir = 'C:\\Program Files\\Notepad++' %} + +{# Map descriptive IDs to their respective Registry paths #} +{%- set npp_registry_map = { + 'NPP Application Path': 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\notepad++.exe', + 'NPP Context Menu Entry': 'HKEY_CLASSES_ROOT\\*\\shell\\Open with Notepad++', + 'NPP MuiCache Entry': 'HKEY_CLASSES_ROOT\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache', + 'NPP OpenWithList txt': 'HKEY_CLASSES_ROOT\\.txt\\OpenWithList\\notepad++.exe', + 'NPP System Notepad Replacement': 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Opt +ions\\notepad.exe' + } +%} + +{%- for desc, reg_path in npp_registry_map.items() %} +Remove {{ desc }}: + reg.absent: + - name: '{{ reg_path }}' +{%- endfor %} + +{%- for admin in npp_admins %} +Remove NPP AppData for {{ admin }}: + file.absent: + - name: 'C:\Users\{{ admin }}\AppData\Roaming\Notepad++' +{%- endfor %} + +Remove NPP System Config Files: + file.absent: + - names: + - '{{ npp_dir }}\updater\gup.xml' + - '{{ npp_dir }}\config.model.xml' diff --git a/notepad-plusplus/config/file.sls b/notepad-plusplus/config/file.sls new file mode 100644 index 0000000..ffccac8 --- /dev/null +++ b/notepad-plusplus/config/file.sls @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_package_install = tplroot ~ '.package.install' %} +{%- from tplroot ~ "/map.jinja" import mapdata as notepad_plusplus with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} +{%- set npp_version = notepad_plusplus.pkg.version %} +{%- set npp_url = notepad_plusplus.pkg.installer_uri %} +{%- set npp_admins = notepad_plusplus.config.npp_admins or ['Administrator'] %} +{%- set npp_dir = 'C:\\Program Files\\Notepad++' %} + + +include: + - {{ sls_package_install }} + +Add NPP Icon to Context Menu: + reg.present: + - name: 'HKEY_CLASSES_ROOT\*\shell\Open with Notepad++' + - vname: Icon + - vdata: 'C:\Program Files\Notepad++\notepad++.exe,0' + - vtype: REG_SZ + - require: + - cmd: 'Install NotePad++' + +Add NPP to Context Menu: + reg.present: + - name: 'HKEY_CLASSES_ROOT\*\shell\Open with Notepad++\command' + - vname: '' + - vdata: '"C:\Program Files\Notepad++\notepad++.exe" "%1"' + - vtype: REG_SZ + - require: + - cmd: 'Install NotePad++' + +Auto-updater disablement notice: + test.show_notification: + - text: |- + --------------------------------------------- + Auto-update disabled to prevent users from + being nagged to do something outside their + ability to effect. Administrators can still + login and force an update, if necessary + (typically, system will be re-deployed rather + than updated) + --------------------------------------------- + - require: + - cmd: 'Install NotePad++' + +{% for admin in npp_admins %} +{% set admin_appdata = 'C:\\Users\\' ~ admin ~ '\\AppData\\Roaming\\Notepad++' %} +Create NPP Admin Config File for {{ admin }}: + file.managed: + - name: '{{ admin_appdata }}\config.xml' + - contents: | + + + + - require: + - file: 'Ensure NPP Admin Config Dir for {{ admin }} exists' + +Ensure NPP Admin Config Dir for {{ admin }} exists: + file.directory: + - name: '{{ admin_appdata }}' + - makedirs: True + - onlyif: + - shell: powershell + - cmd: | + if (Get-LocalUser -Name "{{ admin }}" -ErrorAction SilentlyContinue) { + exit 0 + } else { + exit 1 + } +{% endfor %} + +Manage Notepad++ Updater Config: + file.managed: + - context: + npp_version: {{ npp_version}} + - makedirs: True + - name: 'C:\Program Files\Notepad++\updater\gup.xml' + - require: + - test: 'Auto-updater disablement notice' + - source: salt://{{ tplroot }}/files/gup.xml + - template: jinja + +NPP User Template (No nagging for updates): + file.managed: + - name: {{ npp_dir }}\config.model.xml + - contents: | + + + + - require: + - cmd: 'Install NotePad++' + +Replace System Notepad with NPP: + reg.present: + - name: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe' + - vname: Debugger + - vdata: '"C:\Program Files\Notepad++\notepad++.exe" -systemedit' + - vtype: REG_SZ + - require: + - cmd: 'Install NotePad++' + +Set NPP App Path: + reg.present: + - name: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\notepad++.exe' + - vname: '' + - vdata: 'C:\Program Files\Notepad++\notepad++.exe' + - vtype: REG_SZ + - require: + - cmd: 'Install NotePad++' + +Set NPP App Path Default: + reg.present: + - name: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\notepad++.exe' + - vname: Path + - vdata: 'C:\Program Files\Notepad++' + - vtype: REG_SZ + - require: + - cmd: 'Install NotePad++' diff --git a/notepad-plusplus/config/init.sls b/notepad-plusplus/config/init.sls new file mode 100644 index 0000000..465ddfe --- /dev/null +++ b/notepad-plusplus/config/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .file diff --git a/notepad-plusplus/files/default/example.tmpl b/notepad-plusplus/files/default/example.tmpl new file mode 100644 index 0000000..2c9c60f --- /dev/null +++ b/notepad-plusplus/files/default/example.tmpl @@ -0,0 +1,6 @@ +######################################################################## +# File managed by Salt at <{{ source }}>. +# Your changes will be overwritten. +######################################################################## + +This is an example file from SaltStack template-formula. diff --git a/notepad-plusplus/files/default/example.tmpl.jinja b/notepad-plusplus/files/default/example.tmpl.jinja new file mode 100644 index 0000000..26a7ef9 --- /dev/null +++ b/notepad-plusplus/files/default/example.tmpl.jinja @@ -0,0 +1,11 @@ +######################################################################## +# File managed by Salt at <{{ source }}>. +# Your changes will be overwritten. +######################################################################## + +This is another example file from SaltStack template-formula. + +# This is here for testing purposes +{{ notepad_plusplus | json }} + +winner of the merge: {{ notepad_plusplus['winner'] }} diff --git a/notepad-plusplus/files/gup.xml b/notepad-plusplus/files/gup.xml new file mode 100644 index 0000000..5b1e381 --- /dev/null +++ b/notepad-plusplus/files/gup.xml @@ -0,0 +1,10 @@ + + + /S + low + + Notepad++ + {{ npp_version }} + + http://127.0.0.1/checkUpdate.xml + diff --git a/notepad-plusplus/files/npp_install.ps1 b/notepad-plusplus/files/npp_install.ps1 new file mode 100644 index 0000000..4dbcb16 --- /dev/null +++ b/notepad-plusplus/files/npp_install.ps1 @@ -0,0 +1,65 @@ +# Script to install Notepad++ while still keeping saltstack's output not +# completely horrific +# +################################################################################ + +# Force PowerShell to stop on errors so we can catch them and report to Salt +$ErrorActionPreference = 'Stop' + +$target = $args[0].Trim("'") +$tempExe = $args[1].Trim("'") + +# Normalize the exe-installer's path +$tempExe = $tempExe -replace '/', '\' + +# Declare registry-keys to be modified +$paths = @( + "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad++", + "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Notepad++" +) + +$installed = $false + +# Do pre-installation Check of registry-keys +foreach ($path in $paths) { + if (Test-Path $path) { + $val = (Get-ItemProperty $path).DisplayVersion + if ($val -match $target) { $installed = $true; break } + } +} + +# Execute the EXE-based installer +if (-not $installed) { + Write-Output "Version $target not found. Attempting to install from $tempExe..." + try { + # "remote" files may get marked as blocked. Bypass that nonsense + Unblock-File -Path $tempExe -ErrorAction SilentlyContinue + + # Execute the EXE-installer + & $tempExe /S | Out-Null + + # Capture the result of the installer + $exitCode = $LASTEXITCODE + + # Give the Registry a few seconds to flush changes to disk + Start-Sleep -Seconds 5 + + # Make sure we did what we tried to do... + $verified = $false + foreach ($path in $paths) { if (Test-Path $path) { $verified = $true } } + + if ($verified) { + Write-Output "Installation successful (Exit Code: $exitCode)." + exit 0 + } else { + Write-Error "Installer finished (Exit Code: $exitCode) but registry keys not found." + exit 1 + } + } catch { + Write-Error "Installation failed: $($_.Exception.Message)" + exit 1 + } +} else { + Write-Output "Notepad++ $target already installed. Skipping." + exit 0 +} diff --git a/notepad-plusplus/files/npp_uninstall.ps1 b/notepad-plusplus/files/npp_uninstall.ps1 new file mode 100644 index 0000000..1c40d89 --- /dev/null +++ b/notepad-plusplus/files/npp_uninstall.ps1 @@ -0,0 +1,51 @@ +# Setup paths based on standard Notepad++ installation patterns +$NppPath = "${env:ProgramFiles}\Notepad++" +$NppExe = Join-Path $NppPath "notepad++.exe" + +# PRE-CONDITION (State Check) +# Check if the main executable exists. If not, we assume it's already gone. +if (Test-Path $NppExe) { + Write-Output "Found Notepad++ binary at '$NppExe'" +} +else { + # Salt will see this string in 'stdout'; exit 100 identifies "Already Absent" + Write-Output "State: Already Absent" + exit 100 +} + +# EXECUTION +# Notepad++ stores its uninstaller directly in the install directory +$Uninstaller = Join-Path $NppPath "uninstall.exe" + +if (Test-Path $Uninstaller) { + Write-Output "Found uninstaller at '$Uninstaller'" + Write-Output "Executing silent uninstallation..." + + # Start the uninstaller and capture the process object + $Proc = Start-Process -FilePath "$Uninstaller" -ArgumentList "/S" -Wait -PassThru + + # Use the variable to provide meaningful output and logic + Write-Output "Uninstaller exited with code: $($Proc.ExitCode)" + + # Optional: Wait briefly for file system hooks to release + Start-Sleep -Seconds 2 + + # FINAL VERIFICATION: Check both the file system AND the exit code + if (-not (Test-Path $NppExe) -and $Proc.ExitCode -eq 0) { + Write-Output "State: Success" + exit 0 + } elseif ($Proc.ExitCode -ne 0) { + Write-Error "State: Failed. Uninstaller returned non-zero exit code ($($Proc.ExitCode))" + exit 1 + } else { + Write-Error "State: Failed to remove binary" + exit 1 + } +} +else { + # If binary exists but uninstaller is missing, we have a "dirty" state + Write-Error "Binary found but '$Uninstaller' is missing. Manual cleanup required." + exit 1 +} + +exit 100 diff --git a/notepad-plusplus/init.sls b/notepad-plusplus/init.sls new file mode 100644 index 0000000..4029724 --- /dev/null +++ b/notepad-plusplus/init.sls @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{%- if grains.os_family == "Windows" %} +include: + - .package + - .config +{%- else %} +Invalid Platform + test.show_notification: + - text: | + ---------------------------------------- + The notepad++ application is not + published for non-Windows platform. + Skipping all further actions. + ---------------------------------------- +{%- endif %} diff --git a/notepad-plusplus/libmapstack.jinja b/notepad-plusplus/libmapstack.jinja new file mode 100644 index 0000000..8f54ef3 --- /dev/null +++ b/notepad-plusplus/libmapstack.jinja @@ -0,0 +1,315 @@ +{#- -*- coding: utf-8 -*- #} +{#- vim: ft=jinja #} + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split("/")[0] %} +{%- from tplroot ~ "/libmatchers.jinja" import parse_matchers, query_map with context %} + +{%- set _default_config_dirs = [ + "parameters/", + tplroot ~ "/parameters" + ] %} + +{%- macro mapstack( + matchers, + defaults=None, + dirs=_default_config_dirs, + log_prefix="libmapstack: " + ) %} +{#- + Load configuration in the order of `matchers` and merge + successively the values with `defaults`. + + The `matchers` are processed using `libmatchers.jinja` to select + the configuration sources from where the values are loaded. + + Parameters: + + - `matchers`: list of matchers in the form + `[[: