<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mikko Koivunalho</title>
    <description>The latest articles on DEV Community by Mikko Koivunalho (@mikkoi).</description>
    <link>https://dev.to/mikkoi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1073313%2Fe96f5dd9-5c11-4efc-abee-ce362b38708f.jpeg</url>
      <title>DEV Community: Mikko Koivunalho</title>
      <link>https://dev.to/mikkoi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mikkoi"/>
    <language>en</language>
    <item>
      <title>Manage Environment Configs</title>
      <dc:creator>Mikko Koivunalho</dc:creator>
      <pubDate>Tue, 13 Jan 2026 11:05:46 +0000</pubDate>
      <link>https://dev.to/mikkoi/manage-environment-configs-4b3e</link>
      <guid>https://dev.to/mikkoi/manage-environment-configs-4b3e</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc).&lt;br&gt;
&lt;a href="https://12factor.net/config" rel="noopener noreferrer"&gt;The Twelve-Factor App&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Storing the often changing parts of configuration in environment variables is&lt;br&gt;
one of the principles of &lt;a href="https://12factor.net/config" rel="noopener noreferrer"&gt;The Twelve-Factor App&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From this principle follows the need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;ensure that all the required environment variables are set with&lt;br&gt;
appropriate values, and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;store those environment variables and their values in easily accessible ways suitable both for development and for running in production.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both are typical &lt;em&gt;DevOps&lt;/em&gt; problems. To help solve them, use &lt;a href="https://metacpan.org/pod/Env::Assert" rel="noopener noreferrer"&gt;Env::Assert&lt;/a&gt; and &lt;a href="https://metacpan.org/pod/Env::Dot" rel="noopener noreferrer"&gt;Env::Dot&lt;/a&gt;, two programs which, while doing two very different things, are designed to work in unison.&lt;/p&gt;

&lt;h2&gt;
  
  
  Env::Assert
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Env::Assert&lt;/strong&gt; was born from frustration. One too many times:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ PLAEC='Stockholm'
$ if [[ "$PLACE" == '' ]]; then echo "Normal OK"; fi
OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;... And the program fails with no errors!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not quite what we want!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another example, from a real life Docker execution script:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;perl -Ilib bin/repos-gh-yaml.pl --verbose         \
    | perl -Ilib bin/repos-yaml-csv.pl --verbose  \
    | az storage blob upload --data @-            \
        --content-type 'text/csv'                 \
        --content-encoding 'UTF-8'                \
        --content-language 'en_US'                \
        --name "$blob_name"                       \
        --container "$CONTAINER_NAME"             \
        --account-name "$AZURE_STORAGE_ACCOUNT"   \
        --sas-token "$AZURE_STORAGE_SAS_TOKEN"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If the environment variables are wrongly set, or not set at all, it won't become evident until after the run has started. It could take hours before the run reaches the point when they are used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Describe The Environment
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Env::Assert&lt;/strong&gt;, or rather the executable &lt;code&gt;envassert&lt;/code&gt;, that comes with it provide an easy way to find out if the environment variables are what we require them to be.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;envassert&lt;/code&gt; is a CLI command to assert that your environment variables match your &lt;strong&gt;Environment Description&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Envdesc&lt;/strong&gt; or &lt;strong&gt;Environment Description&lt;/strong&gt; is a way to describe which environment variables are required by your program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment Description&lt;/strong&gt; is written in a file. Default file name is &lt;code&gt;.envdesc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.envdesc&lt;/code&gt; actually looks a lot like a &lt;code&gt;.env&lt;/code&gt; file, except instead of&lt;br&gt;
defining variables and their content, it defines regular expressions&lt;br&gt;
which control the variables' content. These regexps are Perl's&lt;br&gt;
extended regular expressions (&lt;code&gt;m/&amp;lt;regexp&amp;gt;/msx&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Example &lt;code&gt;.envdesc&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONTAINER_NAME=^[a-z0-9-]{1,}$
AZURE_STORAGE_ACCOUNT=^[a-z0-9]{1,}$
AZURE_STORAGE_SAS_TOKEN=^[?].*$
GITHUB_TOKEN=^[[:word:]]{1,}$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In normal circumstances, &lt;code&gt;envassert&lt;/code&gt; only verifies the variables that you specifically describe. If you want more control over your environment, there is the meta command &lt;code&gt;envassert (opts: exact=1)&lt;/code&gt;&lt;br&gt;
which will make &lt;code&gt;envassert&lt;/code&gt; also assert that the environment doesn't contain any unknown variables.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## envassert (opts: exact=1)
USER=^username$
HOME=^/home/username$
PATH=^/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Running Env::Assert
&lt;/h3&gt;

&lt;p&gt;You can create an airtight environment description to verify environment variables in both test and production. Just run &lt;code&gt;envassert&lt;/code&gt; as the first command during container execution or any script run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;envassert --env-description /home/me/.envdesc \
    || ( echo 'Break execution ...' 1&amp;gt;&amp;amp;2 &amp;amp;&amp;amp; exit 1 )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If it detects problems, &lt;code&gt;envassert&lt;/code&gt; will report errors and exit with an error, e.g.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ envassert
Environment Assert: ERRORS:
    variables:
        FIRST_VAR: Variable FIRST_VAR is missing from environment
        FOURTH_VAR: Variable FOURTH_VAR has invalid content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Running Self-Contained
&lt;/h4&gt;

&lt;p&gt;A &lt;code&gt;.envdesc&lt;/code&gt; file is really convenient for a bigger app which may have many disconnected parts and execution scripts. But if you have only a single script which nevertheless is dependent on having certain predefined environment variables, you can also include the &lt;code&gt;.envdesc&lt;/code&gt; file in the script. An example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env sh
envassert --stdin &amp;lt;&amp;lt;'EOF' # Ensure the required environment.
NUMERIC_VAR=^[[:digit:]]+$
TIME_VAR=^\d{2}:\d{2}:\d{2}$
EOF
echo "${NUMERIC_VAR}: ${TIME_VAR}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Using Env::Assert in a Program
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Env::Assert&lt;/strong&gt; is a Perl language module. If your application is a Perl script or package, you can also call &lt;strong&gt;Env::Assert&lt;/strong&gt; directly in the code.&lt;/p&gt;

&lt;p&gt;If you know you will always have a &lt;code&gt;.envdesc&lt;/code&gt; file in the working directory, call:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Env::Assert 'assert';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But it would probably be better to specify the &lt;strong&gt;Environment Description&lt;/strong&gt; file. Other parameters are also available. &lt;strong&gt;break_at_first_error&lt;/strong&gt; will make &lt;strong&gt;Env::Assert&lt;/strong&gt; to only report the first error it detects:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Env::Assert assert =&amp;gt; {
    envdesc_file =&amp;gt; 'another-envdesc',
    break_at_first_error =&amp;gt; 1,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Inlining the description file is also possible:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Env::Assert assert =&amp;gt; {
    exact =&amp;gt; 1,
    envdesc =&amp;gt; &amp;lt;&amp;lt;'EOF'
NUMERIC_VAR=^[[:digit:]]+$
TIME_VAR=^\d{2}:\d{2}:\d{2}$
EOF
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Env::Dot
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Env::Dot&lt;/strong&gt; is the other piece of the puzzle, the one which will provide the environment repeatably and reliably.&lt;/p&gt;

&lt;p&gt;There is plenty of existing DotEnv solutions. &lt;strong&gt;Env::Dot&lt;/strong&gt;, however, can offer a few unique features. The &lt;code&gt;.env&lt;/code&gt; files are treated more like source files, not as ready shell (Unix standard sh or Bash) files. With &lt;em&gt;meta commands&lt;/em&gt; user can specify if the &lt;code&gt;.env&lt;/code&gt; file is compatible with shell or is written in the more limited format that Docker is using:&lt;/p&gt;

&lt;p&gt;For standard shell:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (file:type=shell)
VAR="value"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For Docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (file:type=plain)
VAR=My var value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can chain &lt;code&gt;.env&lt;/code&gt; files. When seeing &lt;em&gt;meta command&lt;/em&gt; read::from_parent&lt;code&gt;**Env::Dot** will search for another&lt;/code&gt;.env` file in any parent directory. It will load the first .env file it finds from the current directory upwards to root. If you have several applications in different subdirectory which share some environment variables but also have some unique ones, you can place the common ones in the parent directory and refer to it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (read:from_parent)
DIR_VAR="dir"
COMMON_VAR="dir"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Env::Dot&lt;/strong&gt; uses environment variable &lt;code&gt;ENVDOT_FILEPATHS&lt;/code&gt; to read dotenv files located somewhere else than in the current work dir. You can specify several file paths; just separate them by "&lt;strong&gt;:&lt;/strong&gt;". Env::Dot will load the files in the reverse order, starting from the last. This is the same ordering as used in PATH variable: the first overrules the following ones, that is, when reading from the last path to the first path, if same variable is present in more than one file, the later one replaces the one already read.&lt;/p&gt;

&lt;p&gt;If you are using Windows, separate the paths by "&lt;strong&gt;;&lt;/strong&gt;"!&lt;/p&gt;

&lt;p&gt;For example, if you have the following directory structure:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project-root
| .env
+ - sub-project
  | .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and you specify &lt;code&gt;ENVDOT_FILEPATHS=project-root/sub-project/.env:project-root/.env&lt;/code&gt;, then the variables in file &lt;code&gt;project-root/.env&lt;/code&gt; will get replaced by the more specific variables in &lt;code&gt;project-root/sub-project/.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Windows, this would be &lt;code&gt;ENVDOT_FILEPATHS=project-root\sub-project\.env;project-root\.env&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Env::Dot Executable
&lt;/h3&gt;

&lt;p&gt;Use executable &lt;code&gt;envdot&lt;/code&gt; to bring the variables into your shell.&lt;br&gt;
The executable is distributed together with Env::Dot package.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;envdot&lt;/code&gt; supports the following Unix shells: &lt;code&gt;sh&lt;/code&gt; and its derivatives, including &lt;code&gt;bash&lt;/code&gt; and &lt;code&gt;ksh&lt;/code&gt;, &lt;code&gt;csh&lt;/code&gt; and its derivative &lt;code&gt;tcsh', and &lt;/code&gt;fish`.&lt;/p&gt;

&lt;p&gt;Normally the variables are created in a way that also exports them into any subsequent programs which are run in the same shell, i.e. they become environment variables. However, &lt;code&gt;envdot&lt;/code&gt; can also create them as simple variables only for the current process.&lt;/p&gt;

&lt;p&gt;Examples of usage:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval `envdot --no-export --shell csh`
eval `envdot --dotenv subdir/.env`
ENVDOT_FILEPATHS='../.env:subdir/.env:.env' eval `envdot`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Using Env::Dot in a Program
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Env::Dot&lt;/strong&gt; is a Perl language module. If used in code, having the &lt;code&gt;.env&lt;/code&gt; file is not mandatory. By default, &lt;strong&gt;Env::Dot&lt;/strong&gt; will do nothing if there is no &lt;code&gt;.env file&lt;/code&gt;. You can also configure *&lt;em&gt;Env::Dot *&lt;/em&gt; to break execution if there is no &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# If your dotenv file is `.env` or there is no `.env` file:
use Env::Dot;

# If you have a dotenv file in a different filepath:
use Env::Dot read =&amp;gt; {
    dotenv_file =&amp;gt; '/other/path/my_environment.env',
};

# When you absolutely require a `.env` file:
use Env::Dot read =&amp;gt; {
    required =&amp;gt; 1,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Existing environment variables always take precedence to dotenv variables. A dotenv variable (variable from a file) does not overwrite an existing environment variable. This is by design because&lt;br&gt;
a dotenv file is to augment the environment, not to replace it. This means that you can override a variable in &lt;code&gt;.env&lt;/code&gt; file by creating its counterpart in the environment.&lt;/p&gt;

&lt;p&gt;An example of how that works in a normal shell:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env sh
unset VAR
echo "VAR='Good value'" &amp;gt;&amp;gt; .env
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Good value
VAR='Better value'; export VAR
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Better value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If your &lt;code&gt;.env&lt;/code&gt; file(s) contain variables which need interpolating,&lt;br&gt;
for example, to combine their value from other variables or execute a command to produce their value, you have to use the &lt;code&gt;envdot&lt;/code&gt; program. &lt;strong&gt;Env::Dot&lt;/strong&gt; does not do any interpolating. It cannot because that would involve running the variable in the shell context within the calling program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Env::Assert And Env::Dot
&lt;/h2&gt;

&lt;p&gt;If you are in the habit of using &lt;code&gt;.env&lt;/code&gt; files, &lt;code&gt;.envdesc&lt;/code&gt; complements it. Commit your &lt;code&gt;.envdesc&lt;/code&gt; file into your repository and it will act as a template for user or developer to create his/her &lt;code&gt;.env&lt;/code&gt; file which should not be committed into Git anyway.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://metacpan.org/dist/Env-Assert" rel="noopener noreferrer"&gt;Env::Assert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://metacpan.org/dist/Env-Dot" rel="noopener noreferrer"&gt;Env::Dot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://12factor.net/" rel="noopener noreferrer"&gt;The Twelve-Factor App&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotenv</category>
      <category>environment</category>
      <category>perl</category>
      <category>docker</category>
    </item>
    <item>
      <title>Maven Enforcer Rule dependOnAllProjects</title>
      <dc:creator>Mikko Koivunalho</dc:creator>
      <pubDate>Thu, 27 Nov 2025 19:09:25 +0000</pubDate>
      <link>https://dev.to/mikkoi/maven-enforcer-rule-dependonallprojects-16n6</link>
      <guid>https://dev.to/mikkoi/maven-enforcer-rule-dependonallprojects-16n6</guid>
      <description>&lt;p&gt;Maven Enforcer Rule &lt;a href="https://mikkoi.github.io/maven-enforcer-rule-depend-on-all-projects/" rel="noopener noreferrer"&gt;&lt;strong&gt;dependOnAllProjects&lt;/strong&gt;&lt;/a&gt;, &lt;code&gt;com.github.mikkoi:maven-enforcer-rule-depend-on-all-projects&lt;/code&gt; is a user-created custom rule to force any Maven project in a multi module build to have a dependency on all other projects in the same build.&lt;/p&gt;

&lt;p&gt;The rule ensures that when a multi module Maven project is reconfigured by adding or removing subprojects, all projects are listed as dependencies for that subproject in which &lt;strong&gt;maven-enforcer-plugin&lt;/strong&gt; is executed. If used in a CI pipeline or in any similar manner, this Maven Enforcer rule will keep the subproject up to date.&lt;/p&gt;

&lt;p&gt;If there is something that needs to be done after everything else in the build is completed, it can be placed into its own subproject with &lt;strong&gt;maven-enforcer-plugin&lt;/strong&gt; configured with this rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case: JaCoCo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.jacoco.org/jacoco/trunk/doc/maven.html" rel="noopener noreferrer"&gt;JaCoCo&lt;/a&gt; is a free Java code coverage library. When used in a multi module project, after building and running tests for all subprojects that contain source code, the build must execute &lt;code&gt;jacoco:report-aggregate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The aggregated report is generated from all subprojects that the project depends on, and optionally from the subproject itself. The class and source files, as well as JaCoCo execution data files, will be collected from those projects.&lt;/p&gt;

&lt;p&gt;With Maven Enforcer Rule &lt;strong&gt;dependOnAllProjects&lt;/strong&gt;, the subproject can ensure that all other subprojects are indeed listed as its dependencies, or that exceptions are configured properly.&lt;/p&gt;

&lt;p&gt;In big projects, where developers are adding and removing subprojects  all the time, it is easy to forget to update the "report-aggregate" subproject. With Enforcer Rule &lt;strong&gt;dependOnAllProjects&lt;/strong&gt; this won't be an issue any more.&lt;/p&gt;

&lt;p&gt;There are also parameters &lt;em&gt;includes&lt;/em&gt; and &lt;em&gt;excludes&lt;/em&gt; to limit which projects are required. Both parameters support wildcards. If a project is excluded by precise name, and Maven Enforcer notices that there is no such project in the build, the build will fail with an error to prevent configuration from becoming obsolete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Configuration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-enforcer-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;                                               
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.mikkoi&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-enforcer-rule-depend-on-all-projects&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;depend-on-all-projects&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;validate&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;                    
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;enforce&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;        
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;       
                &lt;span class="nt"&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;dependOnAllProjects&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;excludes&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;com.example:shared-proj&lt;span class="nt"&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/excludes&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/dependOnAllProjects&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;          
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>maven</category>
      <category>jacoco</category>
    </item>
    <item>
      <title>Env::Dot</title>
      <dc:creator>Mikko Koivunalho</dc:creator>
      <pubDate>Fri, 28 Apr 2023 08:58:06 +0000</pubDate>
      <link>https://dev.to/mikkoi/envdot-aej</link>
      <guid>https://dev.to/mikkoi/envdot-aej</guid>
      <description>&lt;h1&gt;
  
  
  Env::Dot
&lt;/h1&gt;

&lt;p&gt;In the category of "scratching my itch".&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  In Perl:
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Env::Dot;
print $ENV{'VAR_DEFINED_IN_DOTENV_FILE'};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  On Command Line:
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo 'VAR="Good value"'&amp;gt;&amp;gt; .env
envdot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VAR='Good value'; export VAR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc).&lt;br&gt;
&lt;a href="https://12factor.net/config"&gt;The Twelve-Factor App&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Storing the often changing parts of configuration in environment variables is one of the principles of &lt;a href="https://12factor.net/config"&gt;The Twelve-Factor App&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From this principle follows the need to store those environment variables and their values in an easily accessible way. Hence, every developer maintains his or her own project specific &lt;code&gt;.env&lt;/code&gt; files next to the project files in the same directory where they are used, for instance, when running locally or testing locally.&lt;/p&gt;
&lt;h2&gt;
  
  
  Yet Another Dotenv Solution
&lt;/h2&gt;

&lt;p&gt;As if we didn't have these enough already...&lt;/p&gt;

&lt;p&gt;What is different with this one, except the name &lt;a href="https://metacpan.org/pod/Env::Dot"&gt;Env::Dot&lt;/a&gt;?&lt;/p&gt;
&lt;h3&gt;
  
  
  Flexibility in input
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; files come in two formats: &lt;em&gt;Shell compatible&lt;/em&gt; and
&lt;em&gt;Docker combatible&lt;/em&gt;. &lt;code&gt;Env::Dot&lt;/code&gt; supports both.&lt;/li&gt;
&lt;li&gt;If no &lt;code&gt;.env&lt;/code&gt; file is present, then do nothing.&lt;/li&gt;
&lt;li&gt;If your &lt;code&gt;.env&lt;/code&gt; file is located in another path,
not the current working directory,
you can use the environment variable
&lt;code&gt;DOTENV_FILEPATHS&lt;/code&gt; to tell where your dotenv file is located.
You can specify several file paths; just separate
them by &lt;code&gt;:&lt;/code&gt;. &lt;code&gt;Dot::Env&lt;/code&gt; will load all the files in the order
you specify them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Flexibility in output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Just use &lt;code&gt;Env::Dot&lt;/code&gt; in your program and your &lt;code&gt;%ENV&lt;/code&gt; will grow
with the variables defined in &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;There is also a command line executable, &lt;code&gt;envdot&lt;/code&gt;,
to read the &lt;code&gt;.env&lt;/code&gt; file and write out commands to create
the environment variables.&lt;/li&gt;
&lt;li&gt;Command &lt;code&gt;envdot&lt;/code&gt; can write the env vars in &lt;code&gt;sh&lt;/code&gt; (sh/Bash/Zsh),
&lt;code&gt;csh&lt;/code&gt; (C shell/tcsh) and &lt;code&gt;fish&lt;/code&gt; (Fish) shell formats.&lt;/li&gt;
&lt;li&gt;Command &lt;code&gt;envdot&lt;/code&gt; will by default also export variables but you can prevent this if you don't
want the variables to be present in subshells and programs. This would
make the variables only local to your current shell.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Existing Environment Takes Precedence
&lt;/h3&gt;

&lt;p&gt;Existing environment variables always take precedence to dotenv variables!&lt;/p&gt;

&lt;p&gt;A dotenv variable (variable from a file) does not overwrite an existing environment variable. This is by design because a dotenv file is to augment the environment, not to replace it.&lt;/p&gt;

&lt;p&gt;This means that you can override a variable in &lt;code&gt;.env&lt;/code&gt; file by creating its counterpart in the environment. For instance:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unset VAR
echo "VAR='Good value'" &amp;gt;&amp;gt; .env
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Good value
VAR='Better value'; export VAR
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Better value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  DotEnv File Meta Commands
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;file:&lt;/code&gt; commands affect all rows following its use.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;var:&lt;/code&gt; commands affect only the subsequent variable definition. If there is another &lt;strong&gt;envdot&lt;/strong&gt; command, the second overwrites the first and default values are applied again.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;file:type&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Changes how &lt;code&gt;Env::Dot&lt;/code&gt; reads lines below from this commands. Default is:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (file:type=shell)
VAR="value"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Other possible value of &lt;code&gt;file:type&lt;/code&gt; is &lt;code&gt;plain&lt;/code&gt;. Docker is using these kinds of &lt;code&gt;.env&lt;/code&gt; files. Variable name is followed by &lt;code&gt;=&lt;/code&gt; and value is the rest of the row before linefeed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (file:type=plain)
VAR=My var value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;var:allow_interpolate&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;By default, when writing variable definitions for the shell,&lt;br&gt;
every variable is treated as static and surrounded with single quotation marks (') in Unix shell which means shell will read the variable content as is. By setting this to &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;true&lt;/code&gt;, you allow shell to interpolate. &lt;strong&gt;This meta command is only useful when running &lt;code&gt;envdot&lt;/code&gt; command to create variable definitions for &lt;code&gt;eval&lt;/code&gt; command to read.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# envdot (var:allow_interpolate)
DYNAMIC_VAR="$(pwd)/${ANOTHER_VAR}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;envdot&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;envdot&lt;/code&gt; is a shell command which translates the dotenv files into shell commands. The file &lt;code&gt;.env&lt;/code&gt; is of course the default input.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;envdot
# VAR='Good value'; export VAR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It has the following parameters:&lt;/p&gt;

&lt;h4&gt;
  
  
  --export, --no-export
&lt;/h4&gt;

&lt;p&gt;Write commands to set variables for local shell or for exporting&lt;br&gt;
them. You usually want to export the variables to all subsequent&lt;br&gt;
programs and subshells, i.e. make them into &lt;em&gt;environment&lt;br&gt;
variables&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Default: export&lt;/p&gt;

&lt;h4&gt;
  
  
  -s, --shell
&lt;/h4&gt;

&lt;p&gt;Which shell (family) are you using? Supported: sh, csh, fish.&lt;/p&gt;

&lt;h4&gt;
  
  
  -e, --dotenv
&lt;/h4&gt;

&lt;p&gt;Path to .env file.&lt;/p&gt;

&lt;p&gt;Default: current directory .env&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;If you need to use the &lt;code&gt;envdot&lt;/code&gt; command in a restricted environment, such as a docker image build, there is a &lt;a href="https://metacpan.org/pod/fatpack"&gt;FatPacked&lt;/a&gt; executable ready. Usable when using &lt;a href="https://metacpan.org/pod/Env::Dot"&gt;CPAN&lt;/a&gt; is overkill.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -LSs -o envdot https://raw.githubusercontent.com/mikkoi/envdot/master/envdot.self-contained
chmod +x ./envdot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or you can do this in a &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN curl -LSs -o /usr/local/bin/envdot \
    https://raw.githubusercontent.com/mikkoi/env-dot/master/envdot.self-contained
RUN chmod +x /usr/local/bin/envdot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There is no extra dependencies outside Perl's standard distribution, so &lt;code&gt;envdot&lt;/code&gt; is as lean as it can be. And Perl, of course, is present in every more or less standard Linux distribution.&lt;/p&gt;

</description>
      <category>perl</category>
      <category>dotenv</category>
      <category>cli</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
