116 lines
3.6 KiB
Python
116 lines
3.6 KiB
Python
from typing import TYPE_CHECKING, Optional
|
|
from ..codebase_utils import load_unverified_project_from_config
|
|
from safety.errors import SafetyError, SafetyException
|
|
from pathlib import Path
|
|
from safety.codebase.constants import (
|
|
CODEBASE_INIT_ERROR,
|
|
CODEBASE_INIT_NOT_FOUND_LINK_TO,
|
|
CODEBASE_INIT_NOT_FOUND_PROJECT_FILE,
|
|
)
|
|
from safety.init.main import create_project
|
|
from typer import Context
|
|
from rich.console import Console
|
|
import sys
|
|
|
|
if TYPE_CHECKING:
|
|
from ..codebase_utils import UnverifiedProjectModel
|
|
|
|
|
|
def initialize_codebase(
|
|
ctx: Context,
|
|
console: Console,
|
|
codebase_path: Path,
|
|
unverified_codebase: "UnverifiedProjectModel",
|
|
org_slug: str,
|
|
link_to: Optional[str] = None,
|
|
should_enable_firewall: bool = False,
|
|
):
|
|
is_interactive = sys.stdin.isatty()
|
|
link_behavior = "prompt"
|
|
create_if_missing = True
|
|
is_codebase_file_created = unverified_codebase.created
|
|
|
|
if link_to or is_codebase_file_created:
|
|
link_behavior = "always"
|
|
create_if_missing = False
|
|
elif not is_interactive:
|
|
link_behavior = "never"
|
|
|
|
project_file_created, project_status = create_project(
|
|
ctx=ctx,
|
|
console=console,
|
|
target=codebase_path,
|
|
unverified_project=unverified_codebase,
|
|
create_if_missing=create_if_missing,
|
|
link_behavior=link_behavior,
|
|
)
|
|
|
|
if project_status == "not_found":
|
|
codebase_name = "Unknown"
|
|
msg = "Codebase not found."
|
|
|
|
if link_to:
|
|
msg = CODEBASE_INIT_NOT_FOUND_LINK_TO
|
|
codebase_name = link_to
|
|
elif is_codebase_file_created:
|
|
msg = CODEBASE_INIT_NOT_FOUND_PROJECT_FILE
|
|
codebase_name = unverified_codebase.id
|
|
|
|
raise SafetyError(msg.format(codebase_name=codebase_name))
|
|
elif project_status == "found" and not is_interactive:
|
|
# Non-TTY mode: Project exists but we can't link (link_behavior="never")
|
|
suggested_name = unverified_codebase.id
|
|
raise SafetyError(
|
|
f"Project '{suggested_name}' already exists. "
|
|
f"In non-interactive mode, use --link-to '{suggested_name}' to link to the existing project, "
|
|
f"or use --name with a different project name to create a new one."
|
|
)
|
|
|
|
if not ctx.obj.project:
|
|
raise SafetyException(CODEBASE_INIT_ERROR)
|
|
|
|
if should_enable_firewall:
|
|
from ..tool.main import configure_local_directory
|
|
|
|
configure_local_directory(codebase_path, org_slug, ctx.obj.project.id)
|
|
|
|
return project_file_created, project_status
|
|
|
|
|
|
def fail_if_codebase_name_mismatch(
|
|
provided_name: str,
|
|
unverified_codebase: "UnverifiedProjectModel",
|
|
) -> None:
|
|
"""
|
|
Useful to prevent the user from overwriting an existing codebase by mistyping the name.
|
|
"""
|
|
if unverified_codebase.id and provided_name != unverified_codebase.id:
|
|
from safety.codebase.constants import CODEBASE_INIT_ALREADY_EXISTS
|
|
|
|
raise SafetyError(CODEBASE_INIT_ALREADY_EXISTS)
|
|
|
|
|
|
def prepare_unverified_codebase(
|
|
codebase_path: Path,
|
|
user_provided_name: Optional[str] = None,
|
|
user_provided_link_to: Optional[str] = None,
|
|
) -> "UnverifiedProjectModel":
|
|
"""
|
|
Prepare the unverified codebase object based on the provided name and link to.
|
|
"""
|
|
unverified_codebase = load_unverified_project_from_config(
|
|
project_root=codebase_path
|
|
)
|
|
|
|
provided_name = user_provided_name or user_provided_link_to
|
|
|
|
if provided_name:
|
|
fail_if_codebase_name_mismatch(
|
|
provided_name=provided_name,
|
|
unverified_codebase=unverified_codebase,
|
|
)
|
|
|
|
unverified_codebase.id = provided_name
|
|
|
|
return unverified_codebase
|