1# Copyright 2021 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""This module manages the global plugin registry for pw_cli."""
15
16import argparse
17import os
18from pathlib import Path
19import sys
20from typing import Iterable
21
22from pw_cli import arguments, plugins
23
24_plugin_registry = plugins.Registry(validator=plugins.callable_with_no_args)
25REGISTRY_FILE = 'PW_PLUGINS'
26
27
28def _register_builtin_plugins(registry: plugins.Registry) -> None:
29    """Registers the commands that are included with pw by default."""
30
31    # Register these by name to avoid circular dependencies.
32    registry.register_by_name('doctor', 'pw_doctor.doctor', 'main')
33    registry.register_by_name('format', 'pw_presubmit.format_code', 'main')
34    registry.register_by_name('logdemo', 'pw_cli.log', 'main')
35    registry.register_by_name('module-check', 'pw_module.check', 'main')
36    registry.register_by_name('test', 'pw_unit_test.test_runner', 'main')
37    registry.register_by_name('watch', 'pw_watch.watch', 'main')
38
39    registry.register('help', _help_command)
40
41
42def _help_command():
43    """Display detailed information about pw commands."""
44    parser = argparse.ArgumentParser(description=_help_command.__doc__)
45    parser.add_argument('plugins',
46                        metavar='plugin',
47                        nargs='*',
48                        help='command for which to display detailed info')
49
50    print(arguments.format_help(_plugin_registry), file=sys.stderr)
51
52    for line in _plugin_registry.detailed_help(**vars(parser.parse_args())):
53        print(line, file=sys.stderr)
54
55
56def register(directory: Path) -> None:
57    _register_builtin_plugins(_plugin_registry)
58    _plugin_registry.register_directory(
59        directory, REGISTRY_FILE, Path(os.environ.get('PW_PROJECT_ROOT', '')))
60
61
62def errors() -> dict:
63    return _plugin_registry.errors()
64
65
66def format_help() -> str:
67    return arguments.format_help(_plugin_registry)
68
69
70def run(name: str, args: Iterable[str]) -> int:
71    return _plugin_registry.run_with_argv(name, args)
72