Skip to content
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
9 changes: 6 additions & 3 deletions lib/dt_shell/commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,11 @@ def as_dict(self) -> dict:
}

def refresh(self):
from .importer import import_commandset_configuration
# reload command set configuration
self.configuration = import_commandset_configuration(self)
# reload commands
self.commands = self._find_commands()
self.commands = self._find_commands() or {}

def command_path(self, selector: str) -> str:
return os.path.join(self.path, selector.strip(".").replace(".", os.path.sep))
Expand All @@ -421,12 +424,12 @@ def download(self) -> bool:
branch: List[str] = ["--branch", self.repository.branch] if self.repository.branch else []
run_cmd(["git", "clone"] + branch + ["--recurse-submodules", remote_url, self.path])
logger.info("Command set downloaded successfully!")
# refresh commands
self.refresh()
except Exception as e:
# Excepts as InvalidRemote
logger.error(f"Unable to clone the repo at '{remote_url}':\n{str(e)}.")
return False
# refresh commands (outside try/except since clone succeeded)
self.refresh()
return True

def update(self) -> bool:
Expand Down
20 changes: 13 additions & 7 deletions lib/dt_shell/commands/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Maintainer: Andrea F. Daniele
import copy
import importlib
import importlib.util
import os.path
import sys
from os.path import (
Expand All @@ -29,17 +30,20 @@ def import_commandset_configuration(command_set: CommandSet) -> Type[DTCommandSe
if DTShellConstants.VERBOSE:
logger.debug(f"Importing configuration for command set '{command_set.name}' from "
f"'{_configuration_file}'")
_configuration_sel: str = "__command_set__.configuration"
# use a unique module name to avoid caching issues between command sets
_module_name: str = f"__command_set_config_{command_set.name}__"
# we temporarily add the path to the command set to PYTHONPATH
old: List[str] = copy.deepcopy(sys.path)
sys.path.insert(0, os.path.abspath(command_set.path))
try:
# import/refresh the configuration module
configuration = importlib.import_module(_configuration_sel)
if configuration.__file__ != _configuration_file:
importlib.reload(configuration)
# make sure we got the right one
assert configuration.__file__ == _configuration_file
# load the configuration module from the specific file
spec = importlib.util.spec_from_file_location(_module_name, _configuration_file)
if spec is None or spec.loader is None:
msg = f"Cannot load command set configuration module from {_configuration_file}"
raise CommandsLoadingException(msg)
configuration = importlib.util.module_from_spec(spec)
sys.modules[_module_name] = configuration
spec.loader.exec_module(configuration)
finally:
# restore PYTHONPATH
sys.path = old
Expand All @@ -55,6 +59,8 @@ def import_commandset_configuration(command_set: CommandSet) -> Type[DTCommandSe

return DTCommandSetConfiguration
else:
# populate path on default configuration as well
default_commandset_configuration.DTCommandSetConfiguration.path = command_set.path
return default_commandset_configuration.DTCommandSetConfiguration


Expand Down
4 changes: 4 additions & 0 deletions lib/dt_shell/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,10 @@ def load_commands(self, skeleton: bool):
if not skeleton:
cs.init()

# skip command sets with no commands (e.g., failed to load)
if cs.commands is None:
continue

# load commands from disk
for cmd, subcmds in cs.commands.items():
# noinspection PyTypeChecker
Expand Down