• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

python-formate / formate / 4830233253

pending completion
4830233253

push

github

Dominic Davis-Foster
Factor out into _find_from_parents function.

14 of 14 new or added lines in 3 files covered. (100.0%)

699 of 727 relevant lines covered (96.15%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.43
/formate/__main__.py
1
#!/usr/bin/env python3
2
#
3
#  __main__.py
4
"""
1✔
5
CLI entry point.
6
"""
7
#
8
#  Copyright © 2021 Dominic Davis-Foster <dominic@davis-foster.co.uk>
9
#
10
#  Permission is hereby granted, free of charge, to any person obtaining a copy
11
#  of this software and associated documentation files (the "Software"), to deal
12
#  in the Software without restriction, including without limitation the rights
13
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
#  copies of the Software, and to permit persons to whom the Software is
15
#  furnished to do so, subject to the following conditions:
16
#
17
#  The above copyright notice and this permission notice shall be included in all
18
#  copies or substantial portions of the Software.
19
#
20
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
24
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
26
#  OR OTHER DEALINGS IN THE SOFTWARE.
27
#
28

29
# stdlib
30
import sys
1✔
31
from typing import Iterable, List, Optional
1✔
32

33
# 3rd party
34
import click
1✔
35
from consolekit import click_command
1✔
36
from consolekit.options import MultiValueOption, colour_option, flag_option, verbose_option
1✔
37
from consolekit.terminal_colours import ColourTrilean, resolve_color_default
1✔
38
from consolekit.tracebacks import handle_tracebacks, traceback_option
1✔
39
from domdf_python_tools.typing import PathLike
1✔
40

41
# this package
42
from formate import Reformatter
1✔
43
from formate.utils import _find_from_parents
1✔
44

45
__all__ = ("main", )
1✔
46

47

48
@flag_option("--diff", "show_diff", help="Show a diff of changes made")
1✔
49
@traceback_option()
1✔
50
@colour_option()
1✔
51
@verbose_option()
1✔
52
@click.option(
1✔
53
                "-e",
54
                "--exclude",
55
                metavar="PATTERN",
56
                type=click.STRING,
57
                cls=MultiValueOption,
58
                help="Patterns for files to exclude from formatting.",
59
                )
60
@click.option(
1✔
61
                "-c",
62
                "--config-file",
63
                type=click.STRING,
64
                help=
65
                "The path or filename of the TOML configuration file to use. If a filename is given it is searched for in the current and parent directories.",
66
                default="formate.toml",
67
                show_default=True,
68
                )
69
@click.argument("filename", type=click.STRING, nargs=-1)
1✔
70
@click_command()
1✔
71
def main(
1✔
72
                filename: Iterable[PathLike],
73
                config_file: PathLike,
74
                exclude: "Optional[List[str]]",
75
                colour: "ColourTrilean" = None,
76
                verbose: bool = False,
77
                show_traceback: bool = False,
78
                show_diff: bool = False,
79
                ) -> None:
80
        """
81
        Reformat the given Python source files.
82
        """
83

84
        # stdlib
85
        import fnmatch
1✔
86
        import re
1✔
87

88
        # 3rd party
89
        from domdf_python_tools.paths import PathPlus
1✔
90

91
        # this package
92
        from formate.config import load_toml
1✔
93
        from formate.utils import SyntaxTracebackHandler, syntaxerror_for_file
1✔
94

95
        retv = 0
1✔
96

97
        config_file = PathPlus(config_file)
1✔
98

99
        # If `config_file` is a filename (rather than a path), look in CWD and parent directories
100
        config_file = _find_from_parents(config_file)
1✔
101

102
        try:
1✔
103
                config = load_toml(config_file)
1✔
104
        except FileNotFoundError:
1✔
105
                raise click.UsageError(f"Config file '{config_file}' not found")
1✔
106

107
        for path in filename:
1✔
108
                for pattern in exclude or []:
1✔
109
                        if re.match(fnmatch.translate(pattern), str(path)):  # pylint: disable=loop-invariant-statement
×
110
                                continue
×
111

112
                path = PathPlus(path)
1✔
113

114
                if path.suffix not in {".py", ".pyi", ''} or path.is_dir():  # pylint: disable=loop-invariant-statement
1✔
115
                        if verbose >= 2:
1✔
116
                                click.echo(f"Skipping {path} as it doesn't appear to be a Python file")
1✔
117

118
                        continue
1✔
119

120
                r = Reformatter(path, config=config)
1✔
121

122
                with handle_tracebacks(show_traceback, cls=SyntaxTracebackHandler):
1✔
123
                        with syntaxerror_for_file(path):
1✔
124
                                ret_for_file = r.run()
1✔
125

126
                if ret_for_file:
1✔
127
                        if verbose:
1✔
128
                                click.echo(f"Reformatting {path}")
1✔
129
                        if show_diff:
1✔
130
                                click.echo(r.get_diff(), color=resolve_color_default(colour))
1✔
131

132
                        r.to_file()
1✔
133

134
                elif verbose >= 2:
1✔
135
                        click.echo(f"Checking {path}")
1✔
136

137
                retv |= ret_for_file
1✔
138

139
        sys.exit(retv)
1✔
140

141

142
if __name__ == "__main__":
143
        sys.exit(main())
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc