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

berserkhmdvhb / charfinder / 15812117954

22 Jun 2025 11:54PM UTC coverage: 93.405% (+0.9%) from 92.472%
15812117954

push

github

berserkhmdvhb
fixing unit tests

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

85 existing lines in 11 files now uncovered.

1388 of 1486 relevant lines covered (93.41%)

7.47 hits per line

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

94.55
/src/charfinder/cli/utils_runner.py
1
"""Utilities for orchestrating the CharFinder CLI runner.
2

3
This module contains reusable utility functions used by the CLI main entry point
4
for tasks like resolving the final query string, managing environment flags,
5
and invoking the main search handler with diagnostics support.
6

7
Functions:
8
    resolve_final_query(): Determine the query string from CLI args.
9
    auto_enable_debug(): Enable debug if CHARFINDER_DEBUG_ENV_LOAD is set.
10
    handle_cli_workflow(): Execute main CLI logic and diagnostics.
11
"""
12

13
# ---------------------------------------------------------------------
14
# Imports
15
# ---------------------------------------------------------------------
16

17
import logging
8✔
18
import os
8✔
19
import sys
8✔
20
import traceback
8✔
21
from argparse import Namespace
8✔
22
from typing import TYPE_CHECKING
8✔
23

24
from charfinder.cli.diagnostics import print_debug_diagnostics
8✔
25
from charfinder.cli.handlers import (
8✔
26
    get_version,
27
    handle_find_chars,
28
)
29
from charfinder.config.constants import (
8✔
30
    EXIT_CANCELLED,
31
    EXIT_ERROR,
32
)
33
from charfinder.config.messages import (
8✔
34
    MSG_ERROR_EXCEPTION_DETAIL,
35
    MSG_ERROR_UNHANDLED_EXCEPTION,
36
    MSG_INFO_CLI_STARTED,
37
    MSG_INFO_ENVIRONMENT,
38
    MSG_INFO_QUERY_FINISHED,
39
    MSG_WARNING_INTERRUPTED,
40
    MSG_WARNING_PROD_ENV,
41
)
42
from charfinder.config.settings import get_environment, is_prod, load_settings
8✔
43
from charfinder.config.types import (
8✔
44
    FuzzyConfig,
45
    MatchResult,
46
)
47
from charfinder.utils.formatter import echo, should_use_color
8✔
48
from charfinder.utils.logger_setup import get_logger, setup_logging, teardown_logger
8✔
49
from charfinder.utils.logger_styles import (
8✔
50
    format_error,
51
    format_info,
52
    format_settings,
53
    format_success,
54
    format_warning,
55
)
56
from charfinder.validators import resolve_effective_color_mode
8✔
57

58
if TYPE_CHECKING:
8✔
UNCOV
59
    from charfinder.config.types import MatchResult
×
60

61

62
__all__ = [
8✔
63
    "auto_enable_debug",
64
    "build_fuzzy_config_from_args",
65
    "handle_cli_workflow",
66
    "resolve_final_query",
67
]
68

69
# ---------------------------------------------------------------------
70
# Query Handling
71
# ---------------------------------------------------------------------
72

73

74
def resolve_final_query(args: Namespace) -> str:
8✔
75
    """
76
    Determine the final query string based on CLI arguments.
77

78
    Prefers --query/-q if provided; otherwise falls back to positional args.
79

80
    Args:
81
        args (Namespace): Parsed CLI arguments.
82

83
    Returns:
84
        str: The final normalized query string to use.
85
    """
86
    query_list = args.option_query if args.option_query else args.positional_query
8✔
87
    return " ".join(query_list).strip()
8✔
88

89

90
# ---------------------------------------------------------------------
91
# Environment and Flags
92
# ---------------------------------------------------------------------
93

94

95
def auto_enable_debug(args: Namespace) -> None:
8✔
96
    """
97
    Enable debug mode if CHARFINDER_DEBUG_ENV_LOAD=1 is set in the environment.
98

99
    Modifies `args.debug` in-place if not already set.
100

101
    Args:
102
        args (Namespace): Parsed CLI arguments.
103
    """
104
    if os.getenv("CHARFINDER_DEBUG_ENV_LOAD") == "1" and not args.debug:
8✔
105
        args.debug = True
8✔
106

107

108
# ---------------------------------------------------------------------
109
# Main Execution Logic
110
# ---------------------------------------------------------------------
111

112

113
def build_fuzzy_config_from_args(args: Namespace) -> FuzzyConfig:
8✔
114
    return FuzzyConfig(
8✔
115
        fuzzy_algo=args.fuzzy_algo,
116
        fuzzy_match_mode=args.fuzzy_match_mode,
117
    )
118

119

120
def handle_cli_workflow(args: Namespace, query_str: str, *, use_color: bool) -> int:
8✔
121
    """
122
    Perform the main CLI workflow, including logging setup, environment loading,
123
    diagnostics, and matching dispatch.
124

125
    Args:
126
        args (Namespace): Parsed CLI arguments.
127
        query_str (str): Final query string.
128
        use_color (bool): Whether color output should be used.
129

130
    Returns:
131
        int: Exit code (EXIT_SUCCESS, EXIT_CANCELLED, or EXIT_ERROR).
132
    """
133
    # Logging Setup
134
    setup_logging(reset=True, log_level=None, suppress_echo=True, use_color=use_color)
8✔
135

136
    # Load .env settings
137
    load_settings(verbose=args.verbose, debug=args.debug)
8✔
138

139
    # Resolve settings and color mode
140
    color_mode = resolve_effective_color_mode(args.color)
8✔
141
    use_color = should_use_color(color_mode)
8✔
142

143
    # Finalize logging
144
    log_level = logging.DEBUG if args.debug else None
8✔
145
    setup_logging(
8✔
146
        reset=True,
147
        log_level=log_level,
148
        suppress_echo=not (args.verbose or args.debug),
149
        use_color=use_color,
150
    )
151

152
    logger = get_logger()
8✔
153

154
    try:
8✔
155
        echo(
8✔
156
            msg=MSG_INFO_ENVIRONMENT.format(env=get_environment()),
157
            style=lambda m: format_settings(m, use_color=use_color),
158
            show=args.verbose,
159
            log=True,
160
            log_method="info",
161
        )
162

163
        if is_prod():
8✔
UNCOV
164
            echo(
×
165
                msg=MSG_WARNING_PROD_ENV,
166
                style=lambda m: format_warning(m, use_color=use_color),
167
                stream=sys.stderr,
168
                show=True,
169
                log=True,
170
                log_method="warning",
171
            )
172

173
        echo(
8✔
174
            msg=MSG_INFO_CLI_STARTED.format(version=get_version()),
175
            style=lambda m: format_info(m, use_color=use_color),
176
            show=args.verbose,
177
            log=True,
178
            log_method="info",
179
        )
180

181
        result: MatchResult = handle_find_chars(args, query_str)
8✔
182

183
        if args.debug:
8✔
UNCOV
184
            print_debug_diagnostics(
×
185
                args=args,
186
                match_info=result.match_info,
187
                use_color=use_color,
188
                show=True,
189
            )
190

191
        echo(
8✔
192
            msg=MSG_INFO_QUERY_FINISHED.format(query=query_str),
193
            style=lambda m: format_success(m, use_color=use_color),
194
            show=args.verbose,
195
            log=True,
196
            log_method="info",
197
        )
198

199
    except KeyboardInterrupt:
8✔
200
        echo(
8✔
201
            msg=MSG_WARNING_INTERRUPTED,
202
            style=lambda msg: format_warning(msg, use_color=use_color),
203
            stream=sys.stderr,
204
            show=True,
205
            log=True,
206
            log_method="warning",
207
        )
208
        return EXIT_CANCELLED
8✔
209

210
    except Exception as exc:  # noqa: BLE001
8✔
211
        echo(
8✔
212
            msg=MSG_ERROR_UNHANDLED_EXCEPTION,
213
            style=lambda msg: format_error(msg, use_color=use_color),
214
            stream=sys.stderr,
215
            show=True,
216
            log=True,
217
            log_method="exception",
218
        )
219
        echo(
8✔
220
            msg=MSG_ERROR_EXCEPTION_DETAIL.format(error=exc),
221
            style=lambda msg: format_error(msg, use_color=use_color),
222
            stream=sys.stderr,
223
            show=True,
224
            log=True,
225
            log_method="exception",
226
        )
227

228
        if args.debug:
8✔
229
            traceback.print_exc()
8✔
230

231
        return EXIT_ERROR
8✔
232

233
    else:
234
        return result.exit_code
8✔
235

236
    finally:
237
        teardown_logger(logger)
8✔
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