Skip to content

Commit

Permalink
Merge pull request #429 from GitGuardian/agateau/verbose-everywhere_3…
Browse files Browse the repository at this point in the history
…_output

Allow using --show-secrets, --json, --output and --banlist-detector anywhere on the command line
  • Loading branch information
agateau-gg authored Nov 24, 2022
2 parents 76b47ba + 43101eb commit 2d70f87
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 124 deletions.
15 changes: 15 additions & 0 deletions ggshield/cmd/common_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ def get_config_from_context(ctx: click.Context) -> UserConfig:
return cast(UserConfig, ctx.obj["config"].user_config)


def create_ctx_callback(name: str) -> ClickCallback:
"""Helper function to define a Click option callback for simple cases where we only
have to set a value on Click context object if the option is defined.
"""

def callback(
ctx: click.Context, param: click.Parameter, value: Optional[ArgT]
) -> Optional[ArgT]:
if value is not None:
ctx.obj[name] = value
return value

return callback


def create_config_callback(*option_names: str) -> ClickCallback:
"""Helper function to define a Click option callback for simple cases where we only
have to set a configuration attribute if the option is defined.
Expand Down
23 changes: 10 additions & 13 deletions ggshield/cmd/iac/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,19 @@ def scan_cmd(
"""
Scan a directory for IaC vulnerabilities.
"""
update_context(
ctx, exit_zero, minimum_severity, ignore_policies, ignore_paths, json
)
update_context(ctx, exit_zero, minimum_severity, ignore_policies, ignore_paths)
result = iac_scan(ctx, directory)
scan = ScanCollection(id=str(directory), type="path_scan", iac_result=result)

output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler_cls: Type[OutputHandler]
if json:
output_handler_cls = IaCJSONOutputHandler
else:
output_handler_cls = IaCTextOutputHandler
config: Config = ctx.obj["config"]
output_handler = output_handler_cls(
show_secrets=False, verbose=config.user_config.verbose
)
return output_handler.process_scan(scan)


Expand All @@ -104,7 +110,6 @@ def update_context(
minimum_severity: str,
ignore_policies: Sequence[str],
ignore_paths: Sequence[str],
json: bool,
) -> None:
config: Config = ctx.obj["config"]
ctx.obj["client"] = create_client_from_config(config)
Expand All @@ -125,14 +130,6 @@ def update_context(
if minimum_severity is not None:
config.user_config.iac.minimum_severity = minimum_severity

output_handler_cls: Type[OutputHandler] = IaCTextOutputHandler
if json:
output_handler_cls = IaCJSONOutputHandler

ctx.obj["output_handler"] = output_handler_cls(
show_secrets=False, verbose=config.user_config.verbose
)


def iac_scan(ctx: click.Context, directory: Path) -> Optional[IaCScanResult]:
files = get_iac_files_from_paths(
Expand Down
36 changes: 2 additions & 34 deletions ggshield/cmd/scan/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, List, Optional
from typing import Any, Optional

import click

Expand All @@ -18,7 +18,6 @@
scan_group_impl,
)
from ggshield.core.text_utils import display_warning
from ggshield.core.utils import json_output_option_decorator


@click.group(
Expand All @@ -37,27 +36,6 @@
"archive": archive_cmd,
},
)
@json_output_option_decorator
@click.option(
"--show-secrets",
is_flag=True,
default=None,
help="Show secrets in plaintext instead of hiding them.",
)
@click.option(
"--output",
"-o",
type=click.Path(exists=False, resolve_path=True),
default=None,
help="Route ggshield output to file.",
)
@click.option(
"--banlist-detector",
"-b",
default=None,
help="Exclude results from a detector.",
multiple=True,
)
# Deprecated options
@click.option(
"--all-policies",
Expand All @@ -75,10 +53,6 @@
@click.pass_context
def deprecated_scan_group(
ctx: click.Context,
show_secrets: bool,
json_output: bool,
output: Optional[str],
banlist_detector: Optional[List[str]] = None,
all_policies: Optional[bool] = None,
ignore_default_excludes: bool = False,
**kwargs: Any,
Expand All @@ -89,10 +63,4 @@ def deprecated_scan_group(
display_warning(
"Warning: Using `ggshield scan (...)` is deprecated. Use `ggshield secret scan (...)` instead.",
)
return scan_group_impl(
ctx,
show_secrets,
json_output,
output,
banlist_detector,
)
return scan_group_impl(ctx)
59 changes: 3 additions & 56 deletions ggshield/cmd/secret/scan/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from typing import Any, List, Optional, Type
from typing import Any, Optional

import click

Expand All @@ -21,8 +21,6 @@
from ggshield.core.client import create_client_from_config
from ggshield.core.config import Config
from ggshield.core.text_utils import display_error
from ggshield.core.utils import json_output_option_decorator
from ggshield.output import JSONOutputHandler, OutputHandler, TextOutputHandler


@click.group(
Expand All @@ -41,27 +39,6 @@
"docset": docset_cmd,
},
)
@json_output_option_decorator
@click.option(
"--show-secrets",
is_flag=True,
default=None,
help="Show secrets in plaintext instead of hiding them.",
)
@click.option(
"--output",
"-o",
type=click.Path(exists=False, resolve_path=True),
default=None,
help="Route ggshield output to file.",
)
@click.option(
"--banlist-detector",
"-b",
default=None,
help="Exclude results from a detector.",
multiple=True,
)
# Deprecated options
@click.option(
"--all-policies",
Expand All @@ -79,56 +56,26 @@
@click.pass_context
def scan_group(
ctx: click.Context,
show_secrets: bool,
json_output: bool,
output: Optional[str],
banlist_detector: Optional[List[str]] = None,
all_policies: Optional[bool] = None,
ignore_default_excludes: bool = False,
**kwargs: Any,
) -> int:
"""Commands to scan various contents."""
return scan_group_impl(
ctx,
show_secrets,
json_output,
output,
banlist_detector,
)
return scan_group_impl(ctx)


def scan_group_impl(
ctx: click.Context,
show_secrets: bool,
json_output: bool,
output: Optional[str],
banlist_detector: Optional[List[str]] = None,
) -> int:
def scan_group_impl(ctx: click.Context) -> int:
"""Implementation for scan_group(). Must be a separate function so that its code can
be reused from the deprecated `cmd.scan` package."""
ctx.obj["client"] = create_client_from_config(ctx.obj["config"])
return_code = 0

config: Config = ctx.obj["config"]

if show_secrets is not None:
config.secret.show_secrets = show_secrets

if banlist_detector:
config.secret.ignored_detectors.update(banlist_detector)

max_commits = get_max_commits_for_hook()
if max_commits:
config.max_commits_for_hook = max_commits

output_handler_cls: Type[OutputHandler] = TextOutputHandler
if json_output:
output_handler_cls = JSONOutputHandler

ctx.obj["output_handler"] = output_handler_cls(
show_secrets=config.secret.show_secrets, verbose=config.verbose, output=output
)

return return_code


Expand Down
4 changes: 2 additions & 2 deletions ggshield/cmd/secret/scan/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.config import Config
from ggshield.core.file_utils import get_files_from_paths
from ggshield.core.text_utils import create_progress_bar
from ggshield.output import OutputHandler
from ggshield.scan import Files, ScanCollection, ScanContext, ScanMode, SecretScanner


Expand Down Expand Up @@ -71,5 +71,5 @@ def archive_cmd(

scan = ScanCollection(id=path, type="archive_scan", results=results)

output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)
return output_handler.process_scan(scan)
3 changes: 2 additions & 1 deletion ggshield/cmd/secret/scan/ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.cache import ReadOnlyCache
from ggshield.core.git_shell import check_git_dir, get_list_commit_SHA
Expand Down Expand Up @@ -319,7 +320,7 @@ def ci_cmd(ctx: click.Context, **kwargs: Any) -> int:
client=ctx.obj["client"],
cache=ReadOnlyCache(),
commit_list=commit_list,
output_handler=ctx.obj["output_handler"],
output_handler=create_output_handler(ctx),
exclusion_regexes=ctx.obj["exclusion_regexes"],
matches_ignore=config.secret.ignored_matches,
scan_context=scan_context,
Expand Down
4 changes: 2 additions & 2 deletions ggshield/cmd/secret/scan/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.utils import handle_exception
from ggshield.output import OutputHandler
from ggshield.scan import ScanContext, ScanMode
from ggshield.scan.docker import docker_save_to_tmp, docker_scan_archive

Expand Down Expand Up @@ -40,7 +40,7 @@ def docker_name_cmd(

with tempfile.TemporaryDirectory(suffix="ggshield") as temporary_dir:
config = ctx.obj["config"]
output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)

try:
archive = Path(temporary_dir) / "archive.tar"
Expand Down
4 changes: 2 additions & 2 deletions ggshield/cmd/secret/scan/dockerarchive.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.utils import handle_exception
from ggshield.output import OutputHandler
from ggshield.scan import ScanContext, ScanMode
from ggshield.scan.docker import docker_scan_archive

Expand All @@ -29,7 +29,7 @@ def docker_archive_cmd(
Hidden command `ggshield secret scan docker-archive`
"""
config = ctx.obj["config"]
output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)

scan_context = ScanContext(
scan_mode=ScanMode.DOCKER,
Expand Down
4 changes: 2 additions & 2 deletions ggshield/cmd/secret/scan/docset.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.constants import MAX_WORKERS
from ggshield.core.text_utils import create_progress_bar, display_info
from ggshield.core.utils import handle_exception
from ggshield.output import OutputHandler
from ggshield.scan import File, ScanCollection, ScanContext, ScanMode, SecretScanner


Expand Down Expand Up @@ -59,7 +59,7 @@ def docset_cmd(
scan docset JSONL files.
"""
config = ctx.obj["config"]
output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)
try:
with create_progress_bar(doc_type="files") as progress:
task_scan = progress.add_task(
Expand Down
4 changes: 2 additions & 2 deletions ggshield/cmd/secret/scan/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.constants import MAX_WORKERS
from ggshield.core.file_utils import get_files_from_paths
from ggshield.core.text_utils import create_progress_bar
from ggshield.core.utils import handle_exception
from ggshield.output import OutputHandler
from ggshield.scan import ScanCollection, ScanContext, ScanMode, SecretScanner


Expand All @@ -33,7 +33,7 @@ def path_cmd(
scan files and directories.
"""
config = ctx.obj["config"]
output_handler: OutputHandler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)
try:
files = get_files_from_paths(
paths=paths,
Expand Down
3 changes: 2 additions & 1 deletion ggshield/cmd/secret/scan/prepush.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.git_shell import (
check_git_dir,
Expand Down Expand Up @@ -119,7 +120,7 @@ def prepush_cmd(ctx: click.Context, prepush_args: List[str], **kwargs: Any) -> i
client=ctx.obj["client"],
cache=ctx.obj["cache"],
commit_list=commit_list,
output_handler=ctx.obj["output_handler"],
output_handler=create_output_handler(ctx),
exclusion_regexes=ctx.obj["exclusion_regexes"],
matches_ignore=config.secret.ignored_matches,
scan_context=scan_context,
Expand Down
3 changes: 2 additions & 1 deletion ggshield/cmd/secret/scan/prereceive.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from ggshield.cmd.secret.scan.secret_scan_common_options import (
add_secret_scan_common_options,
create_output_handler,
)
from ggshield.core.cache import ReadOnlyCache
from ggshield.core.git_shell import get_list_commit_SHA, git
Expand Down Expand Up @@ -138,7 +139,7 @@ def prereceive_cmd(
scan as a pre-receive git hook.
"""
config = ctx.obj["config"]
output_handler = ctx.obj["output_handler"]
output_handler = create_output_handler(ctx)

if os.getenv("GL_PROTOCOL") == "web":
# We are inside GitLab web UI
Expand Down
Loading

0 comments on commit 2d70f87

Please sign in to comment.