Libdot provides a bunch of helper tools and we try to have consistent behavior. Lets lay out expectations of them.
When a tool exists to provide a wrapper for how it's executed, we have to balance direct execution by a user with a useful API for other scripts.
For example, libdot/bin/pylint finds the right installed version of pylint and makes sure we use our default pylintrc settings. But we also make it easy for other projects (e.g. ssh_client/bin/pylint) to re-use code with minimal overhead itself. And we make it easy for other tools (e.g. libdot/bin/lint) to build general drivers for the project & integrate well with the our CI (kokoro).
Users should be able to invoke the script with largely the same default behavior as if they had executed the tool directly themselves. The -- marker can always be used to clearly delineate options too. Running ./bin/eslint --help shows our help, but ./bin/eslint -- --help will show the underlying tool's help.
Use the same name as the tool that's being wrapped, and place it under bin/. For example, we wrap pylint via libdot/bin/pylint.
Generic names like libdot/bin/lint are high-level drivers and not specific to any underlying tool.
For the wrapper script itself:
setup: Run any tool-specific logic required to initialize it. This is usually downloading+caching+installing the right programs.main: A thin wrapper to initialize the common libdot API & run the tool.argv as the first argument.get_parser to get the CLI parser.parser.parse_known_args to extract our options while retaining any underlying arguments for the tool.perform and pass parsed CLI options down as makes sense.0 or 1 to indicate pass/fail (respectively).get_parser: Define a command line parser while avoiding conflicts with the underlying wrapped tool.libdot.ArgumentParser with short_options=False.run: A thin wrapper to run the tool.setup to make sure the tool is available.argv=() as the first argument.**kwargs as the last argument.libdot.run directly for the caller.perform: A high level wrapper around the tool. This is where all our custom tool-specific logic lives, and uses run to get it done.argv=() as the first argument.**kwargs as the last argument.Once that's been implemented, add a shortcut to libdot.py using the HelperProgram API. This allows other programs to access the tool directly without going through a fork+exec cycle; while this is a minor speed-up, it helps with OS portability, and provides a more readable API.