spacepaste

  1.  
  2. import functools
  3. import pathlib
  4. import attr
  5. import click
  6. @attr.s
  7. class CommandSpec:
  8. module = attr.ib()
  9. function = attr.ib()
  10. input_files = attr.ib()
  11. output_files = attr.ib()
  12. class ScriptsCLI(click.MultiCommand):
  13. @functools.lru_cache(None)
  14. def _collect_commands(commands_path):
  15. command_dicts = toml.load(pathlib.Path(commands_path).read_text())["commands"]
  16. command_specs = [CommandSpec(d) for d in command_dicts]
  17. return {spec.name: spec for spec in command_specs}
  18. def list_commands(self, ctx):
  19. specs = self._collect_commands(ctx.obj.config_dir / "commands.toml")
  20. return sorted(specs.keys())
  21. def get_command(self, ctx, name):
  22. specs = self._collect_commands(ctx.obj.config_dir / "commands.toml")
  23. spec = specs[name]
  24. module = importlib.import_module(spec.module)
  25. command = getattr(module, spec.function)
  26. return command
  27. @click.group()
  28. @click.pass_context
  29. def cli(ctx):
  30. ctx.obj.config_dir = 'THE_DIR'
  31. pass
  32. @cli.command(cls=ScriptsCLI)
  33. @click.pass_context
  34. def hello(ctx):
  35. pass
  36. if __name__ == "__main__":
  37. cli()
  38. # File "cli3.py", line 38, in cli
  39. # ctx.obj.config_dir = 'THE_DIR'
  40. # AttributeError: 'NoneType' object has no attribute 'config_dir'
  41.