Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default for entry_points_for_group and handle edge case in URI's #72

Merged
merged 2 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions hab/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ def closest_config(self, path, default=False):
"""
if not path.startswith(HabBase.separator):
path = "".join((HabBase.separator, path))
# Anytree<2.9.0 had a bug when resolving URI's that end in a slash like
# `app/` would cause a IndexError. This ensure that older versions work
path = path.rstrip("/")

if default:
node_names = path.split(HabBase.separator)
current = self.configs["default"]
Expand Down
21 changes: 16 additions & 5 deletions hab/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,34 @@ def dump(self, verbosity=0, color=None):
ret = "\n".join(ret)
return utils.dump_title("Dump of Site", f"{site_ret}\n{ret}", color=color)

def entry_points_for_group(self, group):
def entry_points_for_group(self, group, default=None):
"""Returns a list of importlib_metadata.EntryPoint objects enabled by
this site config. To import and resolve the defined object call `ep.load()`.

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"}`
"""
# Delay this import to when required. It's faster than pkg_resources but
# no need to pay the import price for it if you are not using it.
from importlib_metadata import EntryPoint

ret = []
entry_points = self.get("entry_points")
if not entry_points:
return ret
entry_points = self.get("entry_points", {})

# Get the entry point definitions, falling back to default if provided
if group in entry_points:
ep_defs = entry_points[group]
else:
ep_defs = default if default else {}

# Init the EntryPoint objects
# While we are using importlib.metadata to create EntryPoints, we are not
# using it's `entry_points` function. We want the current site configuration
# to define the entry points being loaded not the installed pip packages.
ep_defs = entry_points.get(group, {})
for name, value in ep_defs.items():
ep = EntryPoint(name=name, group=group, value=value)
ret.append(ep)
Expand Down
4 changes: 4 additions & 0 deletions tests/test_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def test_config(resolver):
"default/Sc11",
"More specific default secondary not returned",
),
# Leading/trailing separators
("/app", "app", "Leading slash not ignored"),
("app/", "app", "Trailing slash not sanitized correctly"),
("app/case/", "app", "Trailing slash not sanitized correctly"),
),
)
def test_closest_config(resolver, path, result, reason):
Expand Down
12 changes: 12 additions & 0 deletions tests/test_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,18 @@ def test_empty_site(self, config_root):
entry_points = site.entry_points_for_group("cli")
assert len(entry_points) == 0

def test_default(self, config_root):
"""Test a site not defining any entry points for cli."""
site = Site([config_root / "site_main.json"])
entry_points = site.entry_points_for_group("cli", default={"test": "case:func"})
assert len(entry_points) == 1

# Test that the `test-gui` cli entry point is handled correctly
ep = entry_points[0]
assert ep.name == "test"
assert ep.group == "cli"
assert ep.value == "case:func"

@pytest.mark.parametrize(
"site_files,import_name,fname",
(
Expand Down