Skip to content

Commit a322780

Browse files
authored
fix: make installation relocatable (#215)
1 parent 9a74add commit a322780

File tree

9 files changed

+103
-4
lines changed

9 files changed

+103
-4
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,13 @@ jobs:
342342
echo '' >> $GITHUB_STEP_SUMMARY
343343
echo '- for details, see the `coverage-report` artifact' >> $GITHUB_STEP_SUMMARY
344344
echo '- to compare to the report from the `main` branch, see <https://jeffersonlab.github.io/iguana/coverage-report>' >> $GITHUB_STEP_SUMMARY
345+
### test relocatability
346+
- name: test relocatability
347+
run: |
348+
mv iguana relocated
349+
source relocated/bin/this_iguana.sh --verbose # do not use --githubCI option, since we want this environment to be for only this step
350+
relocated/bin/iguana-example-basic test_data.hipo ${{ env.num_events }}
351+
mv relocated iguana
345352
### set iguana environment, since the next steps will check the iguana installation
346353
- name: set iguana environment
347354
run: source iguana/bin/this_iguana.sh --verbose --githubCI

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Iguana is not a framework for _reading_ data, rather it is a set of algorithms t
1616
### For Users
1717
1. [Setup Guide](doc/setup.md)
1818
1. [Examples](examples/README.md)
19+
1. [Configuring the Algorithms](doc/configuration.md)
1920
1. [Troubleshooting](doc/troubleshooting.md)
2021
1. [API documentation](https://jeffersonlab.github.io/iguana/doxygen)
2122

doc/configuration.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Configuring the Algorithms
2+
3+
Most of the algorithms are configurable using a YAML configuration file. If you are using Iguana for your analysis, you likely want to customize the algorithm configurations.
4+
5+
The default configuration is installed in the `etc/` subdirectory of the Iguana installation. If you have set the Iguana environment variables using, _e.g._ `source this_iguana.sh`, or if you are using the version of Iguana installed on `ifarm`, you will have the environment variable `$IGUANA_CONFIG_PATH` set to include this `etc/` directory.
6+
7+
There are a few ways to configure the algorithms; see the sections below for the options
8+
9+
> [!IMPORTANT]
10+
> While algorithm developers are encouraged _not_ to make breaking changes to their algorithms or configuration, in some cases certain changes cannot be prevented. Thus if you have your own algorithm configurations, you may want to keep up-to-date on any changes of the algorithm. We will try to announce all breaking changes in the Iguana release notes.
11+
12+
> [!NOTE]
13+
> If the Iguana installation is relocated, the environment variable `$IGUANA_CONFIG_PATH` _must_ be used at runtime.
14+
15+
## Option 1: Copy the default directory, and modify
16+
17+
First, copy the default configuration directory to your work area, or to your analysis code source tree; we'll call the copied directory `my_iguana_config`, as an example. If `$IGUANA_CONFIG_PATH` is the default configuration directory (_i.e._ you have not set or modified this variable yourself), you may run:
18+
```bash
19+
cp -r $IGUANA_CONFIG_PATH my_iguana_config
20+
```
21+
22+
You may then freely modify any configuration file within `my_iguana_config/`. To use this directory in your algorithms, you may do any one of the following:
23+
24+
1. Since `$IGUANA_CONFIG_PATH` allows multiple paths, delimited by colons (`:`), prepend `my_iguana_config/` to `$IGUANA_CONFIG_PATH`; the safest way is to use an absolute path:
25+
```bash
26+
export IGUANA_CONFIG_PATH=`pwd`/my_iguana_config:$IGUANA_CONFIG_PATH # bash or zsh
27+
setenv IGUANA_CONFIG_PATH `pwd`/my_iguana_config:$IGUANA_CONFIG_PATH # tcsh or csh
28+
```
29+
The algorithms will then search `my_iguana_config` for the configuration before searching the default paths. You may add multiple paths, if needed.
30+
Paths which appear first in `$IGUANA_CONFIG_PATH` will be prioritized when the algorithm searches for configuration parameters; this behavior is similar to that of `$PATH` or `$LD_LIBRARY_PATH`.
31+
32+
2. Use `Algorithm::SetConfigDirectory` instead of prepending `$IGUANA_CONFIG_PATH`.
33+
34+
## Option 2: Write your own YAML file
35+
36+
Make a new YAML file, containing just the options you want to override; use `Algorithm::SetConfigFile` to use this file for each algorithm.
37+
See existing algorithms' configuration, and just copy what you need into your own YAML file; be mindful of the indentation, and that the top-level set of YAML nodes are the algorithm names. For example:
38+
39+
Algorithm default configuration files:
40+
```yaml
41+
### default configuration file 1
42+
physics::AlgorithmA
43+
cuts: [-1, 1]
44+
```
45+
```yaml
46+
### default configuration file 2
47+
physics::AlgorithmB
48+
value: 3
49+
```
50+
Custom YAML file, widening `AlgorithmA`'s `cuts` and increasing `AlgorithmB`'s `value`:
51+
```yaml
52+
### custom YAML file
53+
physics::AlgorithmA
54+
cuts: [-2, 2]
55+
56+
physics::AlgorithmB
57+
value: 5
58+
```

doc/setup.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,5 @@ The following environment variables are set or modified; not all of them are nee
162162
| `LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (macOS) | adds paths to dependency and Iguana libraries |
163163
| `PYTHONPATH` | adds paths to dependency and Iguana Python packages, if Python bindings are installed |
164164
| `ROOT_INCLUDE_PATH` | adds paths to dependency and Iguana header files, for usage in ROOT |
165+
| `IGUANA_CONFIG_PATH` | path to iguana algorithm configuration files (`.yaml`); users may override this with their own path; multiple paths may be specified, delimited by colons (`:`), where paths listed first will override paths listed later (similar behavior as `$PATH`); this variable is _only_ necessary if the Iguana installation has been relocated |
165166
| `IGUANA` | the path to the Iguana installation prefix, equivalent to `pkg-config iguana --variable prefix`; this is only for consumers that do not use `pkg-config` or the other standard environment variables, however usage of this variable is _discouraged_ since the installation layout may vary |

examples/iguana-example-basic.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int main(int argc, char** argv)
5757
seq.SetOption("clas12::EventBuilderFilter", "log", "debug");
5858
seq.SetOption("clas12::MomentumCorrection", "log", "debug");
5959

60-
// set algorithm options
60+
// set algorithm options (overrides configuration files)
6161
seq.SetOption<std::vector<int>>("clas12::EventBuilderFilter", "pids", {11, 211, -211});
6262

6363
// start the algorithms

meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ project_test_env.set(
171171

172172
# set preprocessor macros
173173
add_project_arguments(
174-
'-DIGUANA_ETC="' + get_option('prefix') / project_etc + '"',
174+
'-DIGUANA_ETCDIR="' + get_option('prefix') / project_etc + '"',
175175
language: ['cpp'],
176176
)
177177

@@ -218,6 +218,7 @@ if get_option('z_install_envfile')
218218
'python': get_option('bind_python') ? 'true' : 'false',
219219
'libdir': get_option('libdir'),
220220
'root': ROOT_dep.found() ? 'true' : 'false',
221+
'etcdir': project_etc,
221222
},
222223
)
223224
foreach shell : ['csh', 'tcsh']

meson/this_iguana.sh.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ if @root@; then
8282
unset var
8383
fi
8484

85+
# set config file path; append, rather than prepend, in case the user already has their own
86+
export IGUANA_CONFIG_PATH=${IGUANA_CONFIG_PATH:+${IGUANA_CONFIG_PATH}:}$IGUANA/@etcdir@
87+
8588
# print environment variables
8689
if $arg_verbose; then
8790
print_var() { echo "$@" | sed 's/:/\n /g'; }
@@ -107,6 +110,9 @@ ROOT_INCLUDE_PATH -- $(if @root@; then echo 'ADDED iguana and dependency include
107110
PYTHONPATH -- $(if @python@; then echo 'ADDED iguana python bindings:'; else echo 'has NOT been changed'; fi)
108111
$(print_var ${PYTHONPATH-})
109112
113+
IGUANA_CONFIG_PATH -- ADDED iguana algorithms' default configuration directory
114+
$(print_var ${IGUANA_CONFIG_PATH-})
115+
110116
----------------------------
111117
"""
112118
unset -f print_var
@@ -117,6 +123,7 @@ if $arg_githubCI; then
117123
echo PKG_CONFIG_PATH=$PKG_CONFIG_PATH >> $GITHUB_ENV
118124
echo PATH=$PATH >> $GITHUB_ENV
119125
echo @ld_path@=$@ld_path@ >> $GITHUB_ENV
126+
echo IGUANA_CONFIG_PATH=$IGUANA_CONFIG_PATH >> $GITHUB_ENV
120127
if @python@; then
121128
echo PYTHONPATH=$PYTHONPATH >> $GITHUB_ENV
122129
fi

src/iguana/services/ConfigFileReader.cc

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
#include "ConfigFileReader.h"
22
#include <filesystem>
3+
#include <cstdlib>
4+
#include <sstream>
35

46
namespace iguana {
57

68
ConfigFileReader::ConfigFileReader(std::string_view name)
79
: Object(name)
810
{
9-
// add config files from installation prefix
11+
// the algorithms need to know where the config files are;
12+
// first, add config files from installation prefix; since this
13+
// is added first, it's the lowest priority in the configuration
14+
// search path
1015
AddDirectory(GetConfigInstallationPrefix());
16+
// next, add `IGUANA_CONFIG_PATH` paths, which provides:
17+
// - user override of the configuration path(s)
18+
// - a fallback, if `GetConfigInstallationPrefix` is wrong, which happens
19+
// if the Iguana installation is relocated
20+
auto user_paths_env_var = std::getenv("IGUANA_CONFIG_PATH");
21+
if(user_paths_env_var != nullptr) {
22+
std::istringstream user_paths_stream(user_paths_env_var);
23+
std::string user_path_token;
24+
decltype(m_directories) user_paths;
25+
while(getline(user_paths_stream, user_path_token, ':')) // tokenize `IGUANA_CONFIG_PATH`
26+
user_paths.push_front(user_path_token);
27+
for(auto const& user_path : user_paths) // add the paths in the correct order
28+
AddDirectory(user_path);
29+
// after these default paths have been added, the user
30+
// may still override by calling `AddDirectory` etc. themselves
31+
}
1132
}
1233

1334
std::string ConfigFileReader::GetConfigInstallationPrefix()
1435
{
15-
return IGUANA_ETC;
36+
return IGUANA_ETCDIR;
1637
}
1738

1839
void ConfigFileReader::AddDirectory(std::string const& dir)

src/iguana/services/ConfigFileReader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ namespace iguana {
1515
ConfigFileReader(std::string_view name = "config");
1616

1717
/// Get the config files' _fixed_ installation prefix
18+
/// @warning if the Iguana installation is _relocated_, this directory will **not** be correct,
19+
/// since it is compiled in the shared library; as a fallback, you may use the environment variable
20+
/// `$IGUANA_CONFIG_PATH`.
1821
/// @return the absolute path to the installed configuration file directory
1922
static std::string GetConfigInstallationPrefix();
2023

0 commit comments

Comments
 (0)