Environment Variable Utilities#
Version |
Date |
Author |
Purpose |
|---|---|---|---|
1 |
September 2026 |
Nino Tarantino |
Initial version |
Introduction#
The Environment Variable Utilities model provides C++ interfaces to retrieve environment variables with a variety of selectable fallback behaviors if the requested variable is not set.
Requirements#
CML-ENV-UTILS-1: The model shall provide an option to terminate the program if a requested environment variable is not set.
CML-ENV-UTILS-2: The model shall provide an option to return a default value if a requested environment variable is not set.
CML-ENV-UTILS-3: The model shall provide an option to throw an error if a requested environment variable is not set.
CML-ENV-UTILS-4: The model shall provide a method for expanding environment variables in a user-defined string.
Model Specifications#
Architectural Considerations#
Existing External Capabilities#
The C++ standard library has the std::getenv function, which exposes a C-based API. This model wraps
that standard library function with a C++ API and performs error handling and environment variable expansion.
Model Structure#
Functions
-
inline std::string getenv_or_exit(const std::string &var_name, const std::function<void(int)> &exit_fn = std::exit)#
Retrieve the environment variable if it is set, otherwise terminate the program
- Parameters:
var_name -- Environment variable to retrieve
exit_fn -- Function to be called if the variable is not set
- Returns:
The contents of the environment variable
-
inline std::string getenv_or_default(const std::string &var_name, const std::string &default_value)#
Retrieve the environment variable if it is set, otherwise return a user-defined default value
- Parameters:
var_name -- Environment variable to retrieve
default_value -- Value to return if the variable is not set
- Returns:
The contents of the environment variable if set, otherwise the default value
-
inline std::string getenv_or_throw(const std::string &var_name) noexcept(false)#
Retrieve the environment variable if it is set, otherwise throw an error
- Throws:
std::runtime_error -- If the environment variable is not set
- Parameters:
var_name -- Environment variable to retrieve
- Returns:
The contents of the environment variable
-
std::string expand_env_variables(const std::string &input) noexcept(false)#
Expand all environment variables in a given string
Recognizes both
${VAR}and$VARforms. For the braced form, the name is whatever appears between the braces. For the bare form, the name runs until the next delimiter (space, '/', etc.) or the end of the string. Environment variables are assumed to begin with a letter and contain only letters, numbers, and underscores.If the string has neither of the aforementioned forms, it is considered to not contain any environment variables. In this case, calling this function returns exactly what was passed to it.
Note
Nested environment variables are not supported. Variables of the form
${SOME${VAR}}will not expand correctly.- Throws:
std::runtime_error -- If any expanded environment variable is not set
- Parameters:
input -- String containing environment variables
- Returns:
The original string with environment variables expanded
Mathematical Formulation#
No mathematical formulation.
User's Guide#
Retrieving an Environment Variable#
Exit if the Variable is Not Set#
Retrieve an environment variable's value, or else call std::exit(EXIT_FAILURE) if the
requested value is not set:
const std::string var = getenv_or_exit("MY_ENV_VAR");
Alternatively, a user-defined exit function may be provided. This function will be called
with EXIT_FAILURE as its argument.
auto my_exit_function = [](int return_value) -> void {
// Some user-defined logic goes here.
};
const std::string var = getenv_or_exit("MY_ENV_VAR", my_exit_function);
Use a Default Value if the Variable is Not Set#
Define a default value to use if the requested environment variable is not set:
const std::string var = getenv_or_default("MY_ENV_VAR", "fallback-value");
Throw an Error if the Variable is Not Set#
Retrieve an environment variable's value, or else throw a runtime error:
try {
const std::string var = getenv_or_throw("MY_ENV_VAR");
} catch (const std::runtime_error& err) {
// Handle the missing variable.
}
Expanding Environment Variables in a String#
Expand all environment variables in a string:
const std::filesystem::path data_path = expand_env_variables("${DATA_DIR}/${SCENARIO_NAME}/data.csv");
Note that an std::runtime_error is always thrown if any environment variable in the
provided string is not set.
Extension#
As the model is simply a collection of functions, users may augment it with their own environment variable handling functions.
Verification#
Each model requirement has associated unit tests which verify it. The unit tests are described in the Unit-Test Cases section.
Code Coverage#
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
include/env_utils.hh
17 17 100%
src/env_utils.cc
20 20 100%
------------------------------------------------------------------------------
TOTAL 37 37 100%
------------------------------------------------------------------------------
See detailed coverage information here.
Exceptions#
N/A
Unit-Test Cases#
Each requirement is verified by one or more unit tests constructed using the GoogleTest framework.
Requirement |
Test(s) Which Verify It |
|---|---|
CML-ENV-UTILS-1 |
|
CML-ENV-UTILS-2 |
|
CML-ENV-UTILS-3 |
|
CML-ENV-UTILS-4 |
EnvUtils.ExpandBracedEnvironmentVariables EnvUtils.ExpandUnBracedEnvironmentVariables EnvUtils.ExpandEnvironmentVariablesEdgeCases |
EnvUtils.Exit#
Purpose: Demonstrate that the correct environment variable data is returned if the variable exists, or else calls an exit-handling function.
Requirement: Satisfactory conclusion of the test satisfies the verification of requirement CML-ENV-UTILS-1.
Procedure:
Set the contents of an environment variable,
CML_ENVUTILS_TEST_VAR_EXIT_TEST, equal to"test-value".Query the contents of
CML_ENVUTILS_TEST_VAR_EXIT_TESTusing thegetenv_or_exit()function.Clear the contents of an environment variable,
DOES_NOT_EXIST_EXIT_TEST.Query the contents of
DOES_NOT_EXIST_EXIT_TESTusing thegetenv_or_exit()function.
Success Criteria: The contents retrieved from the CML_ENVUTILS_TEST_VAR_EXIT_TEST environment variable
should match what they were set to in the first step of the test. Attempting to query the contents of the
DOES_NOT_EXIST_EXIT_TEST environment variable should result in an exit-handling function being called.
Results:
Test Step |
Expectation |
Result |
|---|---|---|
|
|
Pass |
|
Exit handler called |
Pass |
By showing that:
Attempting to retrieve the value of an environment variable previously set in the test returns that same value
Attempting to retrieve the value of an environment variable which was previously un-set in the test results in an exit-handler function being called
the test EnvUtils.Exit verifies that the model satisfies the requirement CML-ENV-UTILS-1.
EnvUtils.DefaultValue#
Purpose: Demonstrate that the correct environment variable data is returned if the variable exists, or else returns a user-defined default value.
Requirement: Satisfactory conclusion of the test satisfies the verification of requirement CML-ENV-UTILS-2.
Procedure:
Set the contents of an environment variable,
CML_ENVUTILS_TEST_VAR_DEFAULT_VALUE_TEST, equal to"test-value".Query the contents of
CML_ENVUTILS_TEST_VAR_DEFAULT_VALUE_TESTusing thegetenv_or_default()function with a default value of"DEFAULT"Clear the contents of an environment variable,
DOES_NOT_EXIST_DEFAULT_VALUE_TEST.Query the contents of
DOES_NOT_EXIST_DEFAULT_VALUE_TESTusing thegetenv_or_default()function with a default value of"DEFAULT"
Success Criteria: The contents retrieved from the CML_ENVUTILS_TEST_VAR_DEFAULT_VALUE_TEST environment variable
should match what they were set to in the first step of the test. Attempting to query the contents of the
DOES_NOT_EXIST_DEFAULT_VALUE_TEST environment variable should result in the default value of "DEFAULT" being
returned instead.
Results:
Test Step |
Expectation |
Result |
|---|---|---|
|
|
Pass |
|
|
Pass |
By showing that:
Attempting to retrieve the value of an environment variable previously set in the test returns that same value
Attempting to retrieve the value of an environment variable which was previously un-set in the test results in a specified default value being returned instead
the test EnvUtils.DefaultValue verifies that the model satisfies the requirement CML-ENV-UTILS-2.
EnvUtils.Throw#
Purpose: Demonstrate that the correct environment variable data is returned if the variable exists, or else throws an error.
Requirement: Satisfactory conclusion of the test satisfies the verification of requirement CML-ENV-UTILS-3.
Procedure:
Set the contents of an environment variable,
CML_ENVUTILS_TEST_VAR_THROW_TEST, equal to"test-value".Query the contents of
CML_ENVUTILS_TEST_VAR_THROW_TESTusing thegetenv_or_throw()function.Clear the contents of an environment variable,
DOES_NOT_EXIST_THROW_TEST.Query the contents of
DOES_NOT_EXIST_THROW_TESTusing thegetenv_or_throw()function.
Success Criteria: The contents retrieved from the CML_ENVUTILS_TEST_VAR_THROW_TEST environment variable
should match what they were set to in the first step of the test. Attempting to query the contents of the
DOES_NOT_EXIST_THROW_TEST environment variable should result in an error being thrown.
Results:
Test Step |
Expectation |
Result |
|---|---|---|
|
|
Pass |
|
|
Pass |
By showing that:
Attempting to retrieve the value of an environment variable previously set in the test returns that same value
Attempting to retrieve the value of an environment variable which was previously un-set in the test results in an error being throw
the test EnvUtils.Throw verifies that the model satisfies the requirement CML-ENV-UTILS-3.
EnvUtils.ExpandBracedEnvironmentVariables#
Purpose: Demonstrate that environment variables are correctly expanded when specified in braced form.
Requirement: Satisfactory conclusion of the test partially satisfies the verification of requirement CML-ENV-UTILS-4.
Procedure:
Set the contents of an environment variable,
CML_ENVUTILS_TEST_VAR_BRACED1, equal to"blue".Set the contents of an environment variable,
CML_ENVUTILS_TEST_VAR_BRACED2, equal to"mouse".Expand the environment variables in the string
"I have a pet ${CML_ENVUTILS_TEST_VAR_BRACED1} ${CML_ENVUTILS_TEST_VAR_BRACED2}".Attempt to expand the string when one of the environment variables is not set.
Attempt to expand the string when all of the environment variables are not set.
Success Criteria: When both environment variables are defined, the string should expand to "I have a pet blue mouse".
If any of the variables are not set, an error is thrown.
Results:
Test Step |
Expectation |
Result |
|---|---|---|
|
|
Pass |
|
|
Pass |
|
|
Pass |
By showing that:
Both environment variables are expanded correctly when set
An error is thrown if any environment variable in the string is not set
the test EnvUtils.ExpandBracedEnvironmentVariables partially verifies that the model satisfies the requirement
CML-ENV-UTILS-4.
EnvUtils.ExpandUnbracedEnvironmentVariables#
This test is identical to to braced environment variable expansion test, except it uses the
$UNBRACED_VAR form instead of the ${BRACED_VAR_FORM}. The test procedure, inputs, and expected outputs are
otherwise identical.
the test EnvUtils.ExpandUnbracedEnvironmentVariables partially verifies that the model satisfies the requirement
CML-ENV-UTILS-4.
EnvUtils.ExpandEnvironmentVariablesEdgeCases#
Purpose: Demonstrate that environment variables are correctly expanded under certain edge conditions.
Requirement: Satisfactory conclusion of the test partially satisfies the verification of requirement CML-ENV-UTILS-4.
Procedure:
Attempt to expand environment variables in an input which has no environment variables to expand.
Attempt to expand unbraced environment variables with so spaces between them.
Success Criteria:
A string with no environment variables to expand is returned unmodified.
Two unbraced environment variables which are not separated by a space are correctly expanded.
Test Step |
Expectation |
Result |
|---|---|---|
|
|
Pass |
|
Variables are both expanded |
Pass |
By showing that:
A string with no environment variables to expand is returned unmodified
Two unbraced environment variables which are not separated by a space are correctly expanded
the test EnvUtils.ExpandEnvironmentVariablesEdgeCases partially verifies that the model satisfies the requirement
CML-ENV-UTILS-4.