Skip to content

Commit 6c3560b

Browse files
committed
refactor: rework verbose handling
Use ui.display_verbose() everywhere. Remove many `verbose: bool` arguments. Check if verbose is enabled using `ui.is_verbose()` instead of using `config.user_config.verbose`. This avoids the need to update `config.user_config.verbose` when called with `--verbose`, which is bad because if the command rewrites the configuration file, it's going to write `verbose: true` (this is still the case for `--allow-self-signed`).
1 parent c0f15cb commit 6c3560b

37 files changed

+245
-330
lines changed

ggshield/__main__.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from ggshield.core.config import Config
2929
from ggshield.core.env_utils import load_dot_env
3030
from ggshield.core.errors import ExitCode
31-
from ggshield.core.ui import log_utils
31+
from ggshield.core.ui import ensure_verbose, log_utils
3232
from ggshield.core.ui.rich import RichGGShieldUI
3333
from ggshield.utils.click import RealPath
3434
from ggshield.utils.os import getenv_bool
@@ -57,19 +57,6 @@ def exit_code(ctx: click.Context, exit_code: int, **kwargs: Any) -> int:
5757
return exit_code
5858

5959

60-
def config_path_callback(
61-
ctx: click.Context, param: click.Parameter, value: Optional[Path]
62-
) -> Optional[Path]:
63-
# The --config option is marked as "is_eager" to ensure it's called before all the
64-
# others. This makes it the right place to create the configuration object.
65-
if not ctx.obj:
66-
ctx.obj = ContextObj()
67-
ctx.obj.cache = Cache()
68-
69-
ctx.obj.config = Config(value)
70-
return value
71-
72-
7360
@click.group(
7461
context_settings={"help_option_names": ["-h", "--help"]},
7562
commands={
@@ -91,24 +78,38 @@ def config_path_callback(
9178
type=RealPath(exists=True, resolve_path=True, file_okay=True, dir_okay=False),
9279
is_eager=True,
9380
help="Set a custom config file. Ignores local and global config files.",
94-
callback=config_path_callback,
9581
)
9682
@add_common_options()
9783
@click.version_option(version=__version__)
9884
@click.pass_context
9985
def cli(
10086
ctx: click.Context,
87+
*,
88+
allow_self_signed: Optional[bool],
89+
config_path: Optional[Path],
10190
**kwargs: Any,
10291
) -> None:
103-
load_dot_env()
92+
# Create ContextObj, load config
93+
ctx.obj = ctx_obj = ContextObj()
94+
ctx_obj.cache = Cache()
95+
ctx_obj.config = Config(config_path)
96+
user_config = ctx_obj.config.user_config
97+
98+
# If the config wants a higher UI level, set it now
99+
if user_config.debug and ui.get_level() < ui.Level.DEBUG:
100+
setup_debug_mode()
101+
elif user_config.verbose and ui.get_level() < ui.Level.VERBOSE:
102+
ensure_verbose()
104103

105-
config = ContextObj.get(ctx).config
104+
# Update allow_self_signed in the config
105+
# TODO: this should be reworked: if a command which writes the config is called with
106+
# --allow-self-signed, the config will contain `allow_self_signed: true`.
107+
if allow_self_signed:
108+
user_config.allow_self_signed = allow_self_signed
106109

107-
_set_color(ctx)
110+
load_dot_env()
108111

109-
if config.user_config.debug:
110-
# if `debug` is set in the configuration file, then setup debug mode now.
111-
setup_debug_mode()
112+
_set_color(ctx)
112113

113114

114115
def _set_color(ctx: click.Context):

ggshield/cmd/hmsl/check_secret_manager/hashicorp_vault.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
json_option,
1414
text_json_format_option,
1515
)
16-
from ggshield.cmd.utils.context_obj import ContextObj
1716
from ggshield.core import ui
1817
from ggshield.core.errors import UnexpectedError
1918
from ggshield.core.text_utils import pluralize
@@ -156,8 +155,7 @@ def check_hashicorp_vault_cmd(
156155
f"Could not fetch {len(result.not_fetched_paths)} paths. "
157156
"Make sure your token has access to all the secrets in your vault."
158157
)
159-
config = ContextObj.get(ctx).config
160-
if config.user_config.verbose:
158+
if ui.is_verbose():
161159
ui.display_error("> The following paths could not be fetched:")
162160
for path in result.not_fetched_paths:
163161
ui.display_error(f"- {path}")

ggshield/cmd/iac/scan/all.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ def iac_scan_all(
8484
root = get_project_root_dir(directory)
8585
relative_paths = [str(x.resolve().relative_to(root)) for x in paths]
8686

87-
if config.user_config.verbose:
88-
ui.display_info("> Scanned files")
87+
if ui.is_verbose():
88+
ui.display_verbose("> Scanned files")
8989
for filepath in relative_paths:
90-
ui.display_info(f"- {click.format_filename(filepath)}")
90+
ui.display_verbose(f"- {click.format_filename(filepath)}")
9191

9292
client = ctx_obj.client
9393

ggshield/cmd/iac/scan/ci.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ def scan_ci_cmd(
5555
# we will work with branch names and deep commits, so we run a git fetch to ensure the
5656
# branch names and commit sha are locally available
5757
git(["fetch"], cwd=directory)
58-
params = get_scan_ci_parameters(
59-
ci_mode, wd=directory, verbose=config.user_config.verbose
60-
)
58+
params = get_scan_ci_parameters(ci_mode, wd=directory)
6159
if params is None:
6260
ui.display_info("No commit found in merge request, skipping scan.")
6361
return 0

ggshield/cmd/iac/scan/diff.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,31 +115,32 @@ def iac_scan_diff(
115115

116116
check_directory_not_ignored(directory, exclusion_regexes)
117117

118-
verbose = config.user_config.verbose if config and config.user_config else False
118+
verbose = ui.is_verbose()
119+
119120
if verbose:
120121
if previous_ref is None:
121-
ui.display_info("> No file to scan in reference.")
122+
ui.display_verbose("> No file to scan in reference.")
122123
else:
123-
ui.display_info(f"> Scanned files in reference {previous_ref}")
124+
ui.display_verbose(f"> Scanned files in reference {previous_ref}")
124125
filepaths = filter_iac_filepaths(
125126
directory, get_git_filepaths(directory, previous_ref)
126127
)
127128
for filepath in filepaths:
128-
ui.display_info(f"- {click.format_filename(filepath)}")
129-
ui.display_info("")
129+
ui.display_verbose(f"- {click.format_filename(filepath)}")
130+
ui.display_verbose("")
130131

131132
if current_ref is None:
132133
current_ref = INDEX_REF if include_staged else "HEAD"
133134
if verbose:
134135
if include_staged:
135-
ui.display_info("> Scanned files in current state (staged)")
136+
ui.display_verbose("> Scanned files in current state (staged)")
136137
else:
137-
ui.display_info("> Scanned files in current state")
138+
ui.display_verbose("> Scanned files in current state")
138139
filepaths = filter_iac_filepaths(
139140
directory, get_git_filepaths(directory=directory, ref=current_ref)
140141
)
141142
for filepath in filepaths:
142-
ui.display_info(f"- {click.format_filename(filepath)}")
143+
ui.display_verbose(f"- {click.format_filename(filepath)}")
143144

144145
modified_iac_files = []
145146

ggshield/cmd/iac/scan/iac_scan_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def create_output_handler(ctx: click.Context) -> IaCOutputHandler:
3838
output_handler_cls = IaCJSONOutputHandler
3939
else:
4040
output_handler_cls = IaCTextOutputHandler
41-
return output_handler_cls(verbose=ctx_obj.config.user_config.verbose)
41+
return output_handler_cls(verbose=ui.is_verbose())
4242

4343

4444
def handle_scan_error(client: GGClient, detail: Detail) -> None:

ggshield/cmd/sca/scan/ci.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
)
1515
from ggshield.cmd.utils.common_decorators import exception_wrapper
1616
from ggshield.cmd.utils.common_options import directory_argument
17-
from ggshield.cmd.utils.context_obj import ContextObj
1817
from ggshield.core import ui
1918
from ggshield.core.git_hooks.ci.get_scan_ci_parameters import (
2019
NotAMergeRequestError,
@@ -64,17 +63,14 @@ def scan_ci_cmd(
6463
ignore_not_fixable,
6564
)
6665

67-
config = ContextObj.get(ctx).config
6866
ci_mode = SupportedCI.from_ci_env()
6967
output_handler = create_output_handler(ctx)
7068

7169
try:
7270
# we will work with branch names and deep commits, so we run a git fetch to ensure the
7371
# branch names and commit sha are locally available
7472
git(["fetch"], cwd=directory)
75-
params = get_scan_ci_parameters(
76-
ci_mode, wd=directory, verbose=config.user_config.verbose
77-
)
73+
params = get_scan_ci_parameters(ci_mode, wd=directory)
7874
if params is None:
7975
ui.display_info("No commit found in merge request, skipping scan.")
8076
return 0

ggshield/cmd/sca/scan/sca_scan_utils.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@ def sca_scan_all(
6464
check_directory_not_ignored(directory, exclusion_regexes)
6565

6666
sca_filepaths, sca_filter_status_code = get_sca_scan_all_filepaths(
67-
directory=directory,
68-
exclusion_regexes=exclusion_regexes,
69-
verbose=config.user_config.verbose,
70-
client=client,
67+
directory=directory, exclusion_regexes=exclusion_regexes, client=client
7168
)
7269

7370
if len(sca_filepaths) == 0:
@@ -109,10 +106,7 @@ def sca_scan_all(
109106

110107

111108
def get_sca_scan_all_filepaths(
112-
directory: Path,
113-
exclusion_regexes: Set[Pattern[str]],
114-
verbose: bool,
115-
client: GGClient,
109+
directory: Path, exclusion_regexes: Set[Pattern[str]], client: GGClient
116110
) -> Tuple[List[str], int]:
117111
"""
118112
Retrieve SCA related files of a directory.
@@ -140,10 +134,10 @@ def get_sca_scan_all_filepaths(
140134
# Only sca_files field is useful in the case of a full_scan,
141135
# all the potential files already exist in `all_filepaths`
142136
sca_files = response.sca_files
143-
if verbose:
144-
ui.display_info("> Scanned files:")
137+
if ui.is_verbose():
138+
ui.display_verbose("> Scanned files:")
145139
for filename in sca_files:
146-
ui.display_info(f"- {click.format_filename(filename)}")
140+
ui.display_verbose(f"- {click.format_filename(filename)}")
147141

148142
return sca_files, response.status_code
149143

@@ -159,7 +153,7 @@ def create_output_handler(ctx: click.Context) -> SCAOutputHandler:
159153
output_handler_cls = SCATextOutputHandler
160154
config = ctx_obj.config
161155
return output_handler_cls(
162-
verbose=config.user_config.verbose, exit_zero=config.user_config.exit_zero
156+
verbose=ui.is_verbose(), exit_zero=config.user_config.exit_zero
163157
)
164158

165159

@@ -204,19 +198,11 @@ def sca_scan_diff(
204198
previous_files = []
205199
else:
206200
previous_files = sca_files_from_git_repo(
207-
directory,
208-
previous_ref,
209-
client,
210-
exclusion_regexes=exclusion_regexes,
211-
verbose=config.user_config.verbose,
201+
directory, previous_ref, client, exclusion_regexes=exclusion_regexes
212202
)
213203

214204
current_files = sca_files_from_git_repo(
215-
directory,
216-
current_ref,
217-
client,
218-
exclusion_regexes=exclusion_regexes,
219-
verbose=config.user_config.verbose,
205+
directory, current_ref, client, exclusion_regexes=exclusion_regexes
220206
)
221207

222208
if len(previous_files) == 0 and len(current_files) == 0:

ggshield/cmd/secret/scan/archive.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,13 @@ def archive_cmd(
4444

4545
ctx_obj = ContextObj.get(ctx)
4646
config = ctx_obj.config
47-
verbose = config.user_config.verbose
47+
verbose = ui.is_verbose()
4848
files, binary_paths = create_files_from_paths(
4949
paths=[temp_path],
5050
exclusion_regexes=ctx_obj.exclusion_regexes,
5151
list_files_mode=ListFilesMode.ALL,
5252
)
53-
if verbose:
54-
print_file_list(files, binary_paths)
53+
print_file_list(files, binary_paths)
5554
ui.display_heading("Starting scan")
5655

5756
with ui.create_scanner_ui(len(files), verbose=verbose) as scanner_ui:

ggshield/cmd/secret/scan/changes.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ def changes_cmd(ctx: click.Context, **kwargs: Any) -> int:
3535
default_branch = get_default_branch()
3636
commit_list = get_list_commit_SHA(f"{default_branch}..HEAD")
3737

38-
if config.user_config.verbose:
39-
ui.display_info(
40-
f"Scan staged changes and {len(commit_list)} new {pluralize('commit', len(commit_list))}"
41-
)
38+
ui.display_verbose(
39+
f"Scan staged changes and {len(commit_list)} new {pluralize('commit', len(commit_list))}"
40+
)
4241

4342
scan_context = ScanContext(
4443
scan_mode=ScanMode.CHANGE,
@@ -55,6 +54,5 @@ def changes_cmd(ctx: click.Context, **kwargs: Any) -> int:
5554
matches_ignore=config.user_config.secret.ignored_matches,
5655
scan_context=scan_context,
5756
ignored_detectors=config.user_config.secret.ignored_detectors,
58-
verbose=config.user_config.verbose,
5957
include_staged=True,
6058
)

0 commit comments

Comments
 (0)