---
# System prepended metadata

title: Easystack notes

---

# Easystack notes

```yaml
robot: True
software:
  GROMACS:
    parallel: 6
    toolchains:
      foss-2020a:
        versions:
          2020.1:
          2020.3:
            from_pr: 1234
            include_easyblocks_from_pr: 123
            debug: True
            trace: True
```

EasyBuild 4.5.0:
```python=
res = (['GROMACS-foss-2020a-2020.1.eb', 'GROMACS-foss-2020a-2020.3.eb'], {})
```

Target:
```python=
orig_paths = [...]
opts_per_ec = {
    'GROMACS-foss-2020a-2020.1': {
        'parallel': 6,
        'robot': True,
    },
    'GROMACS-foss-2020a-2020.3': {
        'debug': True,
        'trace': True,
        'from_pr': 1234,
        'include_easyblocks_from_pr': 123,
        'parallel': 6,
        'robot': True,
    },
}
```

```python=
orig_paths, opts_per_ec = parse_easystack

det_ec_copy_specs(orig_paths, from_pr_list, opts_per_ec={})

det_easyconfig_paths(categorized_paths['easyconfigs'], opts_per_ec={})
```

```python=
opts_per_ec.get(key, {})
```

Actions

* `det_copy_ec_specs`: only relevant for `--copy-ec` => open issue
* `categorize_files_by_type`: no need to be aware of options => no-op
* `det_easyconfig_paths`:
    * has to be made aware of `opts_per_ec` for `from-pr` per ec
* How to handle conflicting command line args & EasyStack options? => don't solve now, make ticket. For now, implement so that EasyStack always wins.
* per-ec options need to be installed:
    * [ESSENTIAL]  Add feature to `update_build_option(key, value)` function to return the original key/value (so that we can restore later).
    * [ESSENTIAL]  also implement `update_build_options(dict)` utility function to pass `opts_by_ec[ec_filename]` dict + return original values (in a dict, aggregated from the returns of `update_build_option`)
    * [ESSENTIAL] when parsing easyconfigs (see `parse_easyconfigs` in `framework/easyconfig/tools.py`)
        * Add update of build options at https://github.com/easybuilders/easybuild-framework/blob/f1f421b7b126d95afd6fc97d7a650e5fc3b38bfb/easybuild/framework/easyconfig/tools.py#L387
        * Do the parse + store custom options in `EasyConfig` instance (`self.custom_build_opts`)
        * Restore original build options with another call to `update_build_options`
    * [DETAIL] when resolving dependencies (in `resolve_dependencies`, right before `robot_find_easyconfig` is called in while loop, https://github.com/easybuilders/easybuild-framework/blob/f1f421b7b126d95afd6fc97d7a650e5fc3b38bfb/easybuild/tools/robot.py#L403)
        * only relevant to pick up custom `robot_paths` for a specific easyconfig
    * [ESSENTIAL] when installing easyconfigs (see `build_and_install_software` in `main.py`)
        * Update build opts (this time using `ec.custom_build_opts`) at https://github.com/easybuilders/easybuild-framework/blob/f1f421b7b126d95afd6fc97d7a650e5fc3b38bfb/easybuild/main.py#L125
        * Restore original build options at the end of the iteration

special cases

- `--from-pr`: needs to be taken into more places (`det_easyconfig_paths`)
- `--include-easyblocks-from-pr`: included easyblocks are set up *very* early (directly after option parsing)
    - `update_build_option` needs to re-do setup of included easyblocks (from PR)
- `robot-paths` specified for specific easyconfig

issues

* semantics of `--copy-ec` + `--easystack` 
* combining of configuration options from env/eb-arg + easystack file => which wins?
* semantics of using `--try-*` options in easystack file (see `tweak` function)