diff --git a/aprsd/aprsd.py b/aprsd/aprsd.py index e1ef9c3..67f00a1 100644 --- a/aprsd/aprsd.py +++ b/aprsd/aprsd.py @@ -34,9 +34,9 @@ import click_completion # local imports here import aprsd +from aprsd import cli_helper from aprsd import config as aprsd_config from aprsd import messaging, packets, stats, threads, utils -from aprsd.cli_helper import AliasedGroup # setup the global logger @@ -56,9 +56,10 @@ def custom_startswith(string, incomplete): click_completion.core.startswith = custom_startswith click_completion.init() +cli_initialized = 0 -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +@click.group(cls=cli_helper.GroupWithCommandOptions, context_settings=CONTEXT_SETTINGS) @click.option( "--loglevel", default="INFO", @@ -87,12 +88,17 @@ click_completion.init() @click.version_option() @click.pass_context def cli(ctx, loglevel, config_file, quiet): + global cli_initialized + # Have to do the global crap because the cli_helper GroupWithCommandOptions + # ends up calling this twice. ctx.ensure_object(dict) ctx.obj["loglevel"] = loglevel ctx.obj["config_file"] = config_file ctx.obj["quiet"] = quiet ctx.obj["config"] = aprsd_config.parse_config(config_file) - setup_logging(ctx.obj["config"], loglevel, quiet) + if not cli_initialized: + setup_logging(ctx.obj["config"], loglevel, quiet) + cli_initialized = 1 def main(): diff --git a/aprsd/cli_helper.py b/aprsd/cli_helper.py index ef83aae..3a911c6 100644 --- a/aprsd/cli_helper.py +++ b/aprsd/cli_helper.py @@ -33,3 +33,42 @@ class AliasedGroup(click.Group): self.add_command(cmd, name=alias) return cmd return decorator + + +class GroupWithCommandOptions(click.Group): + """ Allow application of options to group with multi command """ + + def add_command(self, cmd, name=None): + click.Group.add_command(self, cmd, name=name) + + # add the group parameters to the command + for param in self.params: + cmd.params.append(param) + + # hook the commands invoke with our own + cmd.invoke = self.build_command_invoke(cmd.invoke) + self.invoke_without_command = True + + def build_command_invoke(self, original_invoke): + + def command_invoke(ctx): + """ insert invocation of group function """ + + # separate the group parameters + ctx.obj = dict(_params={}) + for param in self.params: + name = param.name + if name in ctx.params: + ctx.obj["_params"][name] = ctx.params[name] + del ctx.params[name] + + # call the group function with its parameters + params = ctx.params + ctx.params = ctx.obj["_params"] + self.invoke(ctx) + ctx.params = params + + # now call the original invoke(the command) + original_invoke(ctx) + + return command_invoke