diff --git a/.coveragerc b/.coveragerc index 57fb4e8..27a2fff 100644 --- a/.coveragerc +++ b/.coveragerc @@ -4,7 +4,7 @@ skip_covered = true skip_empty = true [run] -# Ensure all python modules in hab have their coverage reported, +# Ensure all python modules in hab_gui have their coverage reported, # not just files that pytest touches. source = hab_gui omit = diff --git a/hab_gui/cli.py b/hab_gui/cli.py new file mode 100644 index 0000000..c53fe1e --- /dev/null +++ b/hab_gui/cli.py @@ -0,0 +1,86 @@ +import click +from hab.cli import UriArgument, UriHelpClass + + +def get_application(): + """Returns the QApplication instance, creating it if required.""" + from Qt.QtWidgets import QApplication + + global app + app = QApplication.instance() + if not app: + app = QApplication([]) + + return app + + +@click.group() +@click.pass_context +def gui(ctx): + """Run hab commands using gui mode""" + + +@gui.command(cls=UriHelpClass) +@click.option( + "-v", + "--verbose", + "verbosity", + count=True, + help="Show increasingly detailed output. Can be used up to 3 times.", +) +@click.argument("uri", cls=UriArgument, required=False) +@click.pass_obj +def launch(settings, verbosity, uri): + """Show a gui letting the user launch applications.""" + from .windows.alias_launch_window import AliasLaunchWindow + + if isinstance(uri, click.UsageError): + # Launch doesn't require a URI, but if its not passed a UsageError + # is returned by UriArgument. Convert that to None. + uri = None + + app = get_application() + settings.resolver._verbosity_target = "hab-gui" + window = AliasLaunchWindow(settings.resolver, uri=uri, verbosity=verbosity) + window.show() + app.exec_() + + +@gui.command() +@click.argument("uri", required=False) +@click.pass_obj +def set_uri(settings, uri): + """Allows for saving a local URI default by passing + a URI argument. If no argument is passed uri-set + will prompt you to enter and argument.""" + + settings.log_context(uri) + + from Qt.QtWidgets import QInputDialog, QMessageBox + + # Create the QApplication, app.exec_ currently does not need called due + # to this only using QInputDialog and QMessageBox. + app = get_application() # noqa: F841 + + if uri is not None: + # If the uri was passed, no need to ask the user + settings.resolver.user_prefs().uri = uri + QMessageBox.information( + None, "Hab URI default set", f"The hab URI default was set to {uri}" + ) + return + + # Otherwise ask the user what uri to use. + # TODO: Use fancy hab-gui widgets configured by site + current_uri = settings.resolver.user_prefs().uri + uris = list(settings.resolver.dump_forest(settings.resolver.configs, indent="")) + if current_uri not in uris: + uris.append(current_uri) + uris.sort() + current = uris.index(current_uri) + + uri, ok = QInputDialog.getItem( + None, "Set hab URI", "Set default hab URI to:", uris, current=current + ) + if ok: + settings.resolver.user_prefs().uri = uri diff --git a/hab_gui/widgets/alias_button.py b/hab_gui/widgets/alias_button.py index 3d0f198..f990f69 100644 --- a/hab_gui/widgets/alias_button.py +++ b/hab_gui/widgets/alias_button.py @@ -32,9 +32,8 @@ def __init__(self, cfg, alias_name, parent=None): self.refresh() def _button_action(self): - print(f"cmd {self.alias_dict[self.alias_name]['cmd']}") - # TODO Need to enable the launch command once the Hab code is ready - # cmd = cfg.launch(alias_name) + """Launch the alias in a subprocess.""" + self.cfg.launch(self.alias_name) def refresh(self): alias = self.alias_dict[self.alias_name] diff --git a/hab_gui/windows/alias_launch_window.py b/hab_gui/windows/alias_launch_window.py index bf55bd0..e18bfd5 100644 --- a/hab_gui/windows/alias_launch_window.py +++ b/hab_gui/windows/alias_launch_window.py @@ -14,6 +14,8 @@ class AliasLaunchWindow(QtWidgets.QMainWindow): Args: resolver (hab.Resolver): The resolver to change verbosity settings on. + uri (str, optional): If passed, use this as the current uri. Otherwise + the value stored in the users prefs is used. verbosity (int): Change the verbosity setting to this value. If None is passed, all results are be shown without any filtering. button_wrap_length (int) Indicates the number of buttons per column/row. @@ -23,7 +25,13 @@ class AliasLaunchWindow(QtWidgets.QMainWindow): """ def __init__( - self, resolver, verbosity=0, button_wrap_length=3, button_layout=0, parent=None + self, + resolver, + uri=None, + verbosity=0, + button_wrap_length=3, + button_layout=0, + parent=None, ): super(AliasLaunchWindow, self).__init__(parent) self.resolver = resolver @@ -31,14 +39,14 @@ def __init__( self.button_wrap_length = button_wrap_length self.button_layout = button_layout - self.init_gui() + self.init_gui(uri) # Window properties self.setWindowTitle("Hab Launch Aliases") self.setFixedWidth(400) self.center_window_position() - def init_gui(self): + def init_gui(self, uri=None): self.window = QtWidgets.QWidget() self.hlayout = QtWidgets.QVBoxLayout() self.uri_widget = URIComboBox( @@ -59,10 +67,11 @@ def init_gui(self): self.window.setLayout(self.hlayout) # Check for stored URI and apply it as the current text - local_stored_uri = str(self.resolver.user_prefs().uri_check()) - if local_stored_uri: - self.uri_widget.set_uri(local_stored_uri) - self.uri_changed(local_stored_uri) + if uri is None: + uri = str(self.resolver.user_prefs().uri_check()) + if uri: + self.uri_widget.set_uri(uri) + self.uri_changed(uri) def uri_changed(self, uri): self.alias_button_grid.uri = uri diff --git a/pyproject.toml b/pyproject.toml index b816647..cb87504 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ classifiers = [ ] requires-python = ">=3.6" dependencies = [ - "hab>=0.20.0", + "hab>=0.21.0", "Qt.py", ] @@ -64,8 +64,8 @@ json5 = [ "pyjson5" ] -[project.scripts] -hg1 = "hab_gui.windows.alias_launch_window:main" +[project.gui-scripts] +habw = "hab.cli:cli" [tool.setuptools] include-package-data = true diff --git a/requirements.txt b/requirements.txt index e853493..f19a340 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ click>=7.1.2 +hab>=0.21.0