Skip to content

Instantly share code, notes, and snippets.

@shaggyrogers
Created December 8, 2018 12:04
Show Gist options
  • Save shaggyrogers/8e697e5a00042f0cebae815b48c1178e to your computer and use it in GitHub Desktop.
Save shaggyrogers/8e697e5a00042f0cebae815b48c1178e to your computer and use it in GitHub Desktop.
python3 script runner, for use with click.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
run_script.py
=============
Description: Runs scripts in the scripts folder.
Author: Michael De Pasquale <shaggyrogers>
Creation Date: 2018-12-08
Modification Date: 2018-12-08
Notes
-----
Adapted from this example in the click documentation:
https://click.palletsprojects.com/en/7.x/commands/#custom-multi-commands
"""
import importlib
from pathlib import Path
from typing import List
import click
# Configuration{{{
# Scrips path. Must be relative, and must be a python package.
SCRIPTS_PATH = Path('scripts')
# Command object/function name
COMMAND_NAME = 'main'
# If True, finds scripts recursively in SCRIPTS_PATH.
RECURSIVE = False # }}}
class RunScriptCommand(click.MultiCommand):
""" Runs commands from python scripts in a given directory. """
__glob = ('**/' if RECURSIVE else '') + '[!_]*.py'
def list_commands(self, ctx: object) -> List[str]: # {{{
""" Returns a list of command names. """
return sorted([
'.'.join(s.relative_to(SCRIPTS_PATH).parts)[:-3]
for s in SCRIPTS_PATH.glob(self.__glob)
]) # }}}
def get_command(self, ctx: object, name: str) -> click.Command: # {{{
""" Returns a Command object for a given command name. """
if SCRIPTS_PATH.parts:
name = f'{".".join(SCRIPTS_PATH.parts)}.{name}'
return getattr(importlib.import_module(name), COMMAND_NAME) # }}}
if __name__ == '__main__':
RunScriptCommand()()
# vim: set ts=4 sw=4 tw=79 fdm=marker et :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment