Skip to content

Commit 77fa6a9

Browse files
authored
Merge pull request #979 from GitGuardian/agateau/use-ui-verbose
Rework verbose mode
2 parents bc77a6a + db00d97 commit 77fa6a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+359
-461
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Changed
2+
3+
- Adding the `--debug` argument now automatically turns on verbose mode.

Diff for: ggshield/__main__.py

+22-21
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_level, 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_level(ui.Level.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):

Diff for: ggshield/cmd/hmsl/check_secret_manager/hashicorp_vault.py

+1-3
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}")

Diff for: ggshield/cmd/iac/scan/all.py

+3-3
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

Diff for: ggshield/cmd/iac/scan/ci.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ggshield.cmd.utils.common_decorators import display_beta_warning, exception_wrapper
1414
from ggshield.cmd.utils.common_options import directory_argument
1515
from ggshield.cmd.utils.context_obj import ContextObj
16+
from ggshield.core import ui
1617
from ggshield.core.git_hooks.ci.get_scan_ci_parameters import (
1718
NotAMergeRequestError,
1819
get_scan_ci_parameters,
@@ -54,14 +55,9 @@ def scan_ci_cmd(
5455
# we will work with branch names and deep commits, so we run a git fetch to ensure the
5556
# branch names and commit sha are locally available
5657
git(["fetch"], cwd=directory)
57-
params = get_scan_ci_parameters(
58-
ci_mode, wd=directory, verbose=config.user_config.verbose
59-
)
58+
params = get_scan_ci_parameters(ci_mode, wd=directory)
6059
if params is None:
61-
click.echo(
62-
"No commit found in merge request, skipping scan.",
63-
err=True,
64-
)
60+
ui.display_info("No commit found in merge request, skipping scan.")
6561
return 0
6662

6763
current_commit, reference_commit = params
@@ -78,13 +74,10 @@ def scan_ci_cmd(
7874
augment_unignored_issues(config.user_config, result)
7975
return display_iac_scan_diff_result(ctx, directory, result)
8076
except NotAMergeRequestError:
81-
click.echo(
82-
(
83-
"WARNING: scan ci expects to be run in a merge-request pipeline.\n"
84-
"No target branch could be identified, will perform a scan all instead.\n"
85-
"This is a fallback behaviour, that will be removed in a future version."
86-
),
87-
err=True,
77+
ui.display_warning(
78+
"scan ci expects to be run in a merge-request pipeline.\n"
79+
"No target branch could be identified, will perform a scan all instead.\n"
80+
"This is a fallback behaviour, that will be removed in a future version."
8881
)
8982
result = iac_scan_all(
9083
ctx, directory, scan_mode=ScanMode.CI_ALL, ci_mode=ci_mode

Diff for: ggshield/cmd/iac/scan/diff.py

+9-8
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

Diff for: ggshield/cmd/iac/scan/iac_scan_utils.py

+1-1
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:

Diff for: ggshield/cmd/sca/scan/ci.py

+7-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
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
17+
from ggshield.core import ui
1818
from ggshield.core.git_hooks.ci.get_scan_ci_parameters import (
1919
NotAMergeRequestError,
2020
get_scan_ci_parameters,
@@ -63,22 +63,16 @@ def scan_ci_cmd(
6363
ignore_not_fixable,
6464
)
6565

66-
config = ContextObj.get(ctx).config
6766
ci_mode = SupportedCI.from_ci_env()
6867
output_handler = create_output_handler(ctx)
6968

7069
try:
7170
# we will work with branch names and deep commits, so we run a git fetch to ensure the
7271
# branch names and commit sha are locally available
7372
git(["fetch"], cwd=directory)
74-
params = get_scan_ci_parameters(
75-
ci_mode, wd=directory, verbose=config.user_config.verbose
76-
)
73+
params = get_scan_ci_parameters(ci_mode, wd=directory)
7774
if params is None:
78-
click.echo(
79-
"No commit found in merge request, skipping scan.",
80-
err=True,
81-
)
75+
ui.display_info("No commit found in merge request, skipping scan.")
8276
return 0
8377

8478
current_commit, reference_commit = params
@@ -94,13 +88,10 @@ def scan_ci_cmd(
9488
scan = SCAScanDiffVulnerabilityCollection(id=str(directory), result=result)
9589
return output_handler.process_scan_diff_result(scan)
9690
except NotAMergeRequestError:
97-
click.echo(
98-
(
99-
"WARNING: scan ci expects to be run in a merge-request pipeline.\n"
100-
"No target branch could be identified, will perform a scan all instead.\n"
101-
"This is a fallback behaviour, that will be removed in a future version."
102-
),
103-
err=True,
91+
ui.display_warning(
92+
"scan ci expects to be run in a merge-request pipeline.\n"
93+
"No target branch could be identified, will perform a scan all instead.\n"
94+
"This is a fallback behaviour, that will be removed in a future version."
10495
)
10596
result = sca_scan_all(ctx, directory=directory, scan_mode=ScanMode.CI_ALL)
10697
scan = SCAScanAllVulnerabilityCollection(id=str(directory), result=result)

Diff for: ggshield/cmd/sca/scan/sca_scan_utils.py

+8-22
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:

Diff for: ggshield/cmd/secret/scan/archive.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,15 @@ def archive_cmd(
4444

4545
ctx_obj = ContextObj.get(ctx)
4646
config = ctx_obj.config
47-
verbose = config.user_config.verbose
4847
files, binary_paths = create_files_from_paths(
4948
paths=[temp_path],
5049
exclusion_regexes=ctx_obj.exclusion_regexes,
5150
list_files_mode=ListFilesMode.ALL,
5251
)
53-
if verbose:
54-
print_file_list(files, binary_paths)
52+
print_file_list(files, binary_paths)
5553
ui.display_heading("Starting scan")
5654

57-
with ui.create_scanner_ui(len(files), verbose=verbose) as scanner_ui:
55+
with ui.create_scanner_ui(len(files)) as scanner_ui:
5856
scan_context = ScanContext(
5957
scan_mode=ScanMode.ARCHIVE,
6058
command_path=ctx.command_path,

Diff for: ggshield/cmd/secret/scan/changes.py

+3-5
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,
@@ -54,5 +53,4 @@ def changes_cmd(ctx: click.Context, **kwargs: Any) -> int:
5453
exclusion_regexes=ctx_obj.exclusion_regexes,
5554
secret_config=config.user_config.secret,
5655
scan_context=scan_context,
57-
verbose=config.user_config.verbose,
5856
)

Diff for: ggshield/cmd/secret/scan/ci.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
)
1212
from ggshield.cmd.utils.common_decorators import exception_wrapper
1313
from ggshield.cmd.utils.context_obj import ContextObj
14+
from ggshield.core import ui
1415
from ggshield.core.cache import ReadOnlyCache
1516
from ggshield.core.git_hooks.ci import collect_commit_range_from_ci_env
1617
from ggshield.core.scan import ScanContext, ScanMode
@@ -32,11 +33,10 @@ def ci_cmd(ctx: click.Context, **kwargs: Any) -> int:
3233
if not (os.getenv("CI") or os.getenv("JENKINS_HOME") or os.getenv("BUILD_BUILDID")):
3334
raise UsageError("`secret scan ci` should only be used in a CI environment.")
3435

35-
commit_list, ci_mode = collect_commit_range_from_ci_env(config.user_config.verbose)
36+
commit_list, ci_mode = collect_commit_range_from_ci_env()
3637
mode_header = f"{ScanMode.CI.value}/{ci_mode.value}"
3738

38-
if config.user_config.verbose:
39-
click.echo(f"Commits to scan: {len(commit_list)}", err=True)
39+
ui.display_verbose(f"Commits to scan: {len(commit_list)}")
4040

4141
scan_context = ScanContext(
4242
scan_mode=mode_header,

Diff for: ggshield/cmd/secret/scan/docker.py

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ def docker_name_cmd(
5959
cache=ctx_obj.cache,
6060
secret_config=config.user_config.secret,
6161
scan_context=scan_context,
62-
verbose=config.user_config.verbose,
6362
)
6463

6564
return output_handler.process_scan(scan)

0 commit comments

Comments
 (0)