Add source code files

This commit is contained in:
2026-02-01 02:55:38 +00:00
parent d5d769e056
commit f3f4104ff6

View File

@@ -0,0 +1,202 @@
"""CLI module for CodeGuard."""
import sys
from typing import Optional
import click
from codeguard.core.scanner import CodeScanner
from codeguard.git.hooks import HookManager
from codeguard.utils.config import ConfigLoader
from codeguard.utils.output import OutputFormatter
@click.group()
@click.option(
"--ollama-url",
default="http://localhost:11434",
help="Ollama server URL",
envvar="CODEGUARD_OLLAMA_URL",
)
@click.option(
"--model",
default="codellama",
help="Ollama model to use",
envvar="CODEGUARD_MODEL",
)
@click.option(
"--timeout",
default=120,
help="Request timeout in seconds",
envvar="CODEGUARD_TIMEOUT",
type=int,
)
@click.option(
"--config",
default="codeguard.yaml",
help="Path to config file",
envvar="CODEGUARD_CONFIG",
)
@click.pass_context
def main(
ctx: click.Context,
ollama_url: str,
model: str,
timeout: int,
config: str,
) -> None:
"""CodeGuard: Local LLM-based code security analysis."""
ctx.ensure_object(dict)
ctx.obj["ollama_url"] = ollama_url
ctx.obj["model"] = model
ctx.obj["timeout"] = timeout
ctx.obj["config"] = config
@main.command()
@click.option(
"--path",
default=".",
help="Path to scan",
type=click.Path(exists=True, file_okay=False, dir_okay=True),
)
@click.option(
"--output",
type=click.Choice(["text", "json"]),
default="text",
help="Output format",
)
@click.option(
"--fail-level",
type=click.Choice(["critical", "high", "medium", "low", "none"]),
default="none",
help="Exit with error if findings at or above this level",
)
@click.option(
"--include",
multiple=True,
help="File patterns to include",
)
@click.option(
"--exclude",
multiple=True,
help="File patterns to exclude",
)
@click.pass_context
def scan(
ctx: click.Context,
path: str,
output: str,
fail_level: str,
include: tuple,
exclude: tuple,
) -> None:
"""Scan code for security vulnerabilities."""
config = ConfigLoader.load(ctx.obj["config"])
scanner = CodeScanner(
ollama_url=ctx.obj["ollama_url"],
model=ctx.obj["model"],
timeout=ctx.obj["timeout"],
config=config,
)
findings = scanner.scan(path, include=list(include), exclude=list(exclude))
OutputFormatter.print(findings, output_format=output)
if fail_level != "none":
severity_levels = ["low", "medium", "high", "critical"]
fail_index = severity_levels.index(fail_level)
for finding in findings:
if finding.severity.value in severity_levels[: fail_index + 1]:
sys.exit(1)
@main.command()
@click.option(
"--path",
default=".",
help="Path to git repository",
type=click.Path(exists=True, file_okay=False, dir_okay=True),
)
@click.option(
"--force",
is_flag=True,
help="Force reinstall existing hook",
)
def install_hook(path: str, force: bool) -> None:
"""Install git pre-commit hook."""
manager = HookManager(path)
manager.install(force=force)
click.echo("Pre-commit hook installed successfully")
@main.command()
@click.argument(
"paths",
nargs=-1,
type=click.Path(exists=True),
)
@click.option(
"--output",
type=click.Choice(["text", "json"]),
default="text",
help="Output format",
)
@click.pass_context
def check(
ctx: click.Context,
paths: tuple[str, ...],
output: str,
) -> None:
"""Check specific files for security issues."""
if not paths:
click.echo("No files specified", err=True)
sys.exit(1)
config = ConfigLoader.load(ctx.obj["config"])
scanner = CodeScanner(
ollama_url=ctx.obj["ollama_url"],
model=ctx.obj["model"],
timeout=ctx.obj["timeout"],
config=config,
)
findings = scanner.check_files(list(paths))
OutputFormatter.print(findings, output_format=output)
@main.command()
def version() -> None:
"""Show version."""
from codeguard import __version__
click.echo(f"CodeGuard-CLI v{__version__}")
@main.command()
@click.option(
"--ollama-url",
default=None,
help="Ollama server URL",
)
@click.option(
"--model",
default=None,
help="Ollama model to use",
)
@click.option(
"--timeout",
default=None,
help="Request timeout in seconds",
type=int,
)
def status(ollama_url: Optional[str], model: Optional[str], timeout: Optional[str]) -> None:
"""Check CodeGuard and Ollama status."""
from codeguard.llm.client import OllamaClient
url = ollama_url or "http://localhost:11434"
client = OllamaClient(url)
click.echo("Checking Ollama connection...")
if client.health_check():
click.secho("Ollama is running", fg="green")
else:
click.secho("Ollama is not accessible", fg="red")
return
click.echo(f"Available models: {', '.join(client.list_models())}")