Skip to content

Commit

Permalink
Add entry_points for modifying a hab config when being flattened
Browse files Browse the repository at this point in the history
- `hab.cfg.reduce.env` is run after the global env is finalized but before aliases.
- `hab.cfg.reduce.aliases` is run after aliases are finalized.

This should allow you to modify global env vars that are then modified
by aliases as well as let you modify aliases after being resolved.
  • Loading branch information
MHendricks committed Nov 30, 2023
1 parent 1a3179d commit a99c8a3
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ for details on each item.
| [Group][tt-group] | Description | [\*\*kwargs][tt-kwargs] | [Return][tt-return] | [Multiple][tt-multi] |
|---|---|---|---|---|
| hab.cli | Used by the hab cli to add extra commands. This is expected to be a `click.command` or `click.group` decorated function. | | | [All][tt-multi-all] |
| hab.cfg.reduce.env | Used to make any modifications to a config after the global env is resolved but before aliases are resolved. | `cfg` | | [All][tt-multi-all] |
| hab.cfg.reduce.finalize | Used to make any modifications to a config after aliases are resolved and just before the the config finishes reducing. | `cfg` | | [All][tt-multi-all] |
| hab.launch_cls | Used as the default `cls` by `hab.parsers.Config.launch()` to launch aliases from inside of python. This should be a subclass of subprocess.Popen. A [complex alias](#complex-aliases) may override this per alias. Defaults to [`hab.launcher.Launcher`](hab/launcher.py). [Example](tests/site/site_entry_point_a.json) | | | [First][tt-multi-first] |
| hab.uri.validate | Used to validate and modify a URI. If the URI is invalid, this should raise an exception. If the URI should be modified, then return the modified URI as a string. | `resolver`, `uri` | Updated URI as string or None. | [All][tt-multi-all] |

Expand Down
8 changes: 8 additions & 0 deletions hab/parsers/flat_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ def _finalize_values(self):
# This call ensures that `self.frozen_data["environment"]` is populated.
self.environment

# Run any configured entry_points before aliases are calculated
self.resolver.site.run_entry_points_for_group("hab.cfg.reduce.env", cfg=self)

# Process version aliases, merging global env vars.
platform_aliases = {}
self.frozen_data["aliases"] = platform_aliases
Expand All @@ -44,6 +47,11 @@ def _finalize_values(self):
):
platform_aliases.setdefault(platform, {})[alias] = data

# Run any configured entry_points before finishing
self.resolver.site.run_entry_points_for_group(
"hab.cfg.reduce.finalize", cfg=self
)

def _process_version(self, version, existing=None):
"""Generator that yields each finalized alias definition dictionary
to be stored in the frozen_data for aliases.
Expand Down
25 changes: 25 additions & 0 deletions hab/site.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import logging
import os
from collections import UserDict
from pathlib import Path, PurePosixPath, PureWindowsPath

from . import utils
from .merge_dict import MergeDict

logger = logging.getLogger(__name__)


class Site(UserDict):
"""Provides site configuration to hab.
Expand Down Expand Up @@ -184,6 +187,28 @@ def platform_path_map(self, path, platform=None):

return str(path)

def run_entry_points_for_group(
self, group, default=None, entry_points=None, **kwargs
):
"""Iterates over `entry_points_for_group` calling the resolved object.
Args:
group (str): The name of the group of entry_points to process.
default (dict, optional): If the entry_point is not defined, return
the entry points defined by this dictionary. This is the contents
of the entry_points group, not the entire entry_points dict. For
example: `{"gui": "hab_gui.cli:gui"}`
entry_points (dict, optional): Use this dictionary instead of the one
defined on this Site object.
**kwargs: Any other kwargs are passed to the loaded entry_point record.
"""
for ep in self.entry_points_for_group(
group, default=default, entry_points=entry_points
):
logger.debug(f"Running {group} entry_point: {ep}")
func = ep.load()
func(**kwargs)

def standardize_platform_path_maps(self):
"""Ensure the mappings defined in platform_path_maps are converted to
the correct PurePath classes."""
Expand Down
16 changes: 16 additions & 0 deletions tests/hab_test_entry_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ def gui_alt():
raise NotImplementedError("hab_test_entry_points.gui_alt called successfully")


def cfg_reduce_env(cfg):
"""Used to test that an entry point is called by raising an exception when
called. See `tests/site/eps/README.md` for details."""
raise NotImplementedError(
"hab_test_entry_points.cfg_reduce_env called successfully"
)


def cfg_reduce_finalize(cfg):
"""Used to test that an entry point is called by raising an exception when
called. See `tests/site/eps/README.md` for details."""
raise NotImplementedError(
"hab_test_entry_points.cfg_reduce_finalize called successfully"
)


def uri_validate_error(resolver, uri):
"""Used to test that an entry point is called by raising an exception when
called. See `tests/site/eps/README.md` for details."""
Expand Down
9 changes: 9 additions & 0 deletions tests/site/eps/cfg_reduce_env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"append": {
"entry_points": {
"hab.cfg.reduce.env": {
"a": "hab_test_entry_points:cfg_reduce_env"
}
}
}
}
9 changes: 9 additions & 0 deletions tests/site/eps/cfg_reduce_finalize.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"append": {
"entry_points": {
"hab.cfg.reduce.finalize": {
"a": "hab_test_entry_points:cfg_reduce_finalize"
}
}
}
}
8 changes: 8 additions & 0 deletions tests/test_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,14 @@ def test_site_cli(self, config_root, site_files, import_name, fname):
@pytest.mark.parametrize(
"site_file,except_match",
(
(
"cfg_reduce_env.json",
"hab_test_entry_points.cfg_reduce_env called successfully",
),
(
"cfg_reduce_finalize.json",
"hab_test_entry_points.cfg_reduce_finalize called successfully",
),
(
"cfg_uri_validate.json",
"hab_test_entry_points.uri_validate_error called successfully",
Expand Down

0 comments on commit a99c8a3

Please sign in to comment.