Added command line help for the outputs.

--help-list-outputs list supported outputs
--help-outputs list details for the supported outputs
--help-output OUTPUT shows the help for this particular output
This commit is contained in:
Salvador E. Tropea 2020-06-24 11:02:17 -03:00
parent 89fb93d6d7
commit ac4ae89aba
4 changed files with 93 additions and 3 deletions

View File

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Help for the supported outputs (--help-list-outputs, --help-outputs and
--help-output)
- Better YAML validation.
## [0.4.0] - 2020-06-17
### Added

View File

@ -18,7 +18,7 @@ from . import log
log.set_domain('kiplot')
from .kiplot import (GS, generate_outputs)
from .pre_base import (BasePreFlight)
from .config_reader import (CfgYamlReader)
from .config_reader import (CfgYamlReader, print_outputs_help, print_output_help)
from .misc import (NO_PCB_FILE, EXIT_BAD_ARGS)
from .__version__ import __version__
@ -30,8 +30,11 @@ def main():
parser.add_argument('-b', '--board-file', help='The PCB .kicad-pcb board file')
parser.add_argument('-c', '--plot-config', help='The plotting config file to use')
parser.add_argument('-d', '--out-dir', default='.', help='The output directory (cwd if not given)')
parser.add_argument('--help-list-outputs', action='store_true', help='List supported outputs')
parser.add_argument('--help-output', help='Help for this particular output')
parser.add_argument('--help-outputs', action='store_true', help='List supported outputs and details')
parser.add_argument('-i', '--invert-sel', action='store_true', help='Generate the outputs not listed as targets')
parser.add_argument('-l', '--list', action='store_true', help='List available outputs')
parser.add_argument('-l', '--list', action='store_true', help='List available outputs (in the config file)')
group.add_argument('-q', '--quiet', action='store_true', help='remove information logs')
parser.add_argument('-s', '--skip-pre', nargs=1, help='skip pre-flight actions, comma separated list or `all`')
group.add_argument('-v', '--verbose', action='store_true', help='show debugging information')
@ -46,6 +49,13 @@ def main():
# Output dir: relative to CWD (absolute path overrides)
GS.out_dir = os.path.join(os.getcwd(), args.out_dir)
if args.help_outputs or args.help_list_outputs:
print_outputs_help(details=args.help_outputs)
sys.exit(0)
if args.help_output:
print_output_help(args.help_output)
sys.exit(0)
# Determine the PCB file
if args.board_file is None:
board_files = glob('*.kicad_pcb')

View File

@ -9,7 +9,7 @@ import pcbnew
from .error import (KiPlotConfigurationError)
from .kiplot import (Layer, get_layer_id_from_pcb)
from .misc import (NO_YAML_MODULE, EXIT_BAD_CONFIG)
from .misc import (NO_YAML_MODULE, EXIT_BAD_CONFIG, EXIT_BAD_ARGS)
from mcpy import activate # noqa: F401
# Output classes
from .out_base import BaseOutput
@ -268,3 +268,75 @@ class CfgYamlReader(object):
if version is None:
config_error("YAML config needs `kiplot.version`.")
return outputs
def trim(docstring):
""" PEP 257 recommended trim for __doc__ """
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxsize
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxsize:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return trimmed
def print_output_options(name, cl):
obj = cl('', name, '')
print(' * Options:')
num_opts = 0
for k, v in obj.__dict__.items():
if k[0] != '_':
help_attr = '_help_'+k
help = obj.__dict__.get(help_attr)
print(' - {}: {}'.format(k, help if help else 'Undocumented'))
num_opts = num_opts+1
if num_opts == 0:
print(' - No available options')
def print_one_out_help(details, n, o):
lines = trim(o.__doc__)
if len(lines) == 0:
lines = ['Undocumented', 'No description']
if details:
print('* '+lines[0])
print(' * Type: `{}`'.format(n))
print(' * Description: '+lines[1])
for ln in range(2, len(lines)):
print(' '+lines[ln])
print_output_options(n, o)
else:
print('* {} [{}]'.format(lines[0], n))
def print_outputs_help(details=False):
outs = BaseOutput.get_registered()
logger.debug('{} supported outputs'.format(len(outs)))
for n, o in outs.items():
if details:
print()
print_one_out_help(details, n, o)
def print_output_help(name):
if not BaseOutput.is_registered(name):
logger.error('Unknown output type `{}`, try --help-list-outputs'.format(name))
sys.exit(EXIT_BAD_ARGS)
print_one_out_help(True, name, BaseOutput.get_class_for(name))

View File

@ -59,6 +59,10 @@ class BaseOutput(object):
def get_class_for(name):
return BaseOutput._registered[name]
@staticmethod
def get_registered():
return BaseOutput._registered
def __str__(self):
return "'{}' ({}) [{}]".format(self._description, self._name, self._type)