Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions scripts/profiling/apis.py

This file was deleted.

4 changes: 2 additions & 2 deletions src/codegen/cli/auth/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from codegen.cli.git.repo import get_git_repo
from codegen.cli.rich.codeblocks import format_command
from codegen.configs.constants import CODEGEN_DIR_NAME, ENV_FILENAME
from codegen.configs.constants import CODEGEN_DIR_NAME
from codegen.configs.session_manager import session_manager
from codegen.configs.user_config import UserConfig
from codegen.git.repo_operator.local_git_repo import LocalGitRepo
Expand All @@ -30,7 +30,7 @@ def __init__(self, repo_path: Path, git_token: str | None = None) -> None:
self.repo_path = repo_path
self.local_git = LocalGitRepo(repo_path=repo_path)
self.codegen_dir = repo_path / CODEGEN_DIR_NAME
self.config = UserConfig(env_filepath=repo_path / ENV_FILENAME)
self.config = UserConfig(root_path=repo_path)
self.config.secrets.github_token = git_token or self.config.secrets.github_token
self.existing = session_manager.get_session(repo_path) is not None

Expand Down
8 changes: 4 additions & 4 deletions src/codegen/cli/commands/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import rich_click as click
from rich.table import Table

from codegen.configs.constants import ENV_FILENAME, GLOBAL_ENV_FILE
from codegen.configs.constants import ENV_FILENAME, GLOBAL_CONFIG_DIR
from codegen.configs.user_config import UserConfig
from codegen.shared.path import get_git_root_path

Expand Down Expand Up @@ -117,8 +117,8 @@ def set_command(key: str, value: str):

def _get_user_config() -> UserConfig:
if (project_root := get_git_root_path()) is None:
env_filepath = GLOBAL_ENV_FILE
root_path = GLOBAL_CONFIG_DIR
else:
env_filepath = project_root / ENV_FILENAME
root_path = project_root

return UserConfig(env_filepath)
return UserConfig(root_path)
4 changes: 2 additions & 2 deletions src/codegen/cli/commands/run/run_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

from codegen.cli.auth.session import CodegenSession
from codegen.cli.utils.function_finder import DecoratedFunction
from codegen.configs.models.repository import RepositoryConfig
from codegen.git.repo_operator.repo_operator import RepoOperator
from codegen.git.schemas.repo_config import RepoConfig
from codegen.git.utils.language import determine_project_language
from codegen.sdk.codebase.config import ProjectConfig
from codegen.sdk.core.codebase import Codebase
Expand All @@ -30,7 +30,7 @@ def parse_codebase(
codebase = Codebase(
projects=[
ProjectConfig(
repo_operator=RepoOperator(repo_config=RepoConfig.from_repo_path(repo_path=repo_path)),
repo_operator=RepoOperator(repo_config=RepositoryConfig.from_path(path=repo_path)),
subdirectories=subdirectories,
programming_language=language or determine_project_language(repo_path),
)
Expand Down
17 changes: 9 additions & 8 deletions src/codegen/cli/commands/start/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

from codegen.cli.commands.start.docker_container import DockerContainer
from codegen.cli.commands.start.docker_fleet import CODEGEN_RUNNER_IMAGE
from codegen.configs.models.repository import RepositoryConfig
from codegen.configs.models.secrets import SecretsConfig
from codegen.git.repo_operator.local_git_repo import LocalGitRepo
from codegen.git.schemas.repo_config import RepoConfig
from codegen.shared.network.port import get_free_port

_default_host = "0.0.0.0"
Expand All @@ -26,7 +26,7 @@
def start_command(port: int | None, detached: bool = False, skip_build: bool = False, force: bool = False) -> None:
"""Starts a local codegen server"""
repo_path = Path.cwd().resolve()
repo_config = RepoConfig.from_repo_path(str(repo_path))
repo_config = LocalGitRepo(repo_path=repo_path).get_repo_config()
if (container := DockerContainer.get(repo_config.name)) is not None:
if force:
rich.print(f"[yellow]Removing existing runner {repo_config.name} to force restart[/yellow]")
Expand All @@ -50,7 +50,7 @@ def start_command(port: int | None, detached: bool = False, skip_build: bool = F
raise click.Abort()


def _handle_existing_container(repo_config: RepoConfig, container: DockerContainer) -> None:
def _handle_existing_container(repo_config: RepositoryConfig, container: DockerContainer) -> None:
if container.is_running():
rich.print(
Panel(
Expand Down Expand Up @@ -122,20 +122,21 @@ def _get_platform() -> str:
return "linux/amd64"


def _run_docker_container(repo_config: RepoConfig, port: int, detached: bool) -> None:
def _run_docker_container(repo_config: RepositoryConfig, port: int, detached: bool) -> None:
rich.print("[bold blue]Starting Docker container...[/bold blue]")
container_repo_path = f"/app/git/{repo_config.name}"
name_args = ["--name", f"{repo_config.name}"]
repo_path = Path(repo_config.path)
envvars = {
"REPOSITORY_LANGUAGE": repo_config.language.value,
"REPOSITORY_OWNER": LocalGitRepo(repo_config.repo_path).owner,
"REPOSITORY_LANGUAGE": repo_config.language,
"REPOSITORY_OWNER": LocalGitRepo(repo_path=repo_path).owner,
"REPOSITORY_PATH": container_repo_path,
"GITHUB_TOKEN": SecretsConfig().github_token,
"GITHUB_TOKEN": SecretsConfig(root_path=repo_path).github_token,
"PYTHONUNBUFFERED": "1", # Ensure Python output is unbuffered
"CODEBASE_SYNC_ENABLED": "True",
}
envvars_args = [arg for k, v in envvars.items() for arg in ("--env", f"{k}={v}")]
mount_args = ["-v", f"{repo_config.repo_path}:{container_repo_path}"]
mount_args = ["-v", f"{repo_config.path}:{container_repo_path}"]
entry_point = f"uv run --frozen uvicorn codegen.runner.servers.local_daemon:app --host {_default_host} --port {port}"
port_args = ["-p", f"{port}:{port}"]
detached_args = ["-d"] if detached else []
Expand Down
3 changes: 1 addition & 2 deletions src/codegen/cli/mcp/resources/system_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1417,15 +1417,14 @@ def baz():
```python
from codegen import Codebase
from codegen.git.repo_operator.repo_operator import RepoOperator
from codegen.git.schemas.repo_config import RepoConfig
from codegen.sdk.codebase.config import ProjectConfig
from codegen.shared.enums.programming_language import ProgrammingLanguage

codebase = Codebase(
projects = [
ProjectConfig(
repo_operator=RepoOperator(
repo_config=RepoConfig(name="codegen-sdk"),
repo_path="/tmp/codegen-sdk",
bot_commit=True
),
programming_language=ProgrammingLanguage.TYPESCRIPT,
Expand Down
3 changes: 2 additions & 1 deletion src/codegen/configs/models/base_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class BaseConfig(BaseSettings, ABC):

model_config = SettingsConfigDict(extra="ignore", case_sensitive=False)

def __init__(self, prefix: str, env_filepath: Path | None = None, *args, **kwargs) -> None:
def __init__(self, prefix: str, root_path: Path | None = None, *args, **kwargs) -> None:
env_filepath = root_path / ENV_FILENAME if root_path else None
if env_filepath is None:
root_path = get_git_root_path()
if root_path is not None:
Expand Down
13 changes: 7 additions & 6 deletions src/codegen/configs/models/repository.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
from pathlib import Path
from typing import Self

from codegen.configs.models.base_config import BaseConfig

Expand All @@ -13,24 +15,23 @@
language: str | None = None
user_name: str | None = None
user_email: str | None = None
subdirectories: list[str] | None = None
base_path: str | None = None # root module of the parsed codebase

def __init__(self, prefix: str = "REPOSITORY", *args, **kwargs) -> None:
super().__init__(prefix=prefix, *args, **kwargs)

Check failure on line 22 in src/codegen/configs/models/repository.py

View workflow job for this annotation

GitHub Actions / mypy

error: "__init__" of "BaseConfig" gets multiple values for keyword argument "prefix" [misc]

def _initialize(
self,
) -> None:
"""Initialize the repository config"""
if self.path is None:
self.path = os.getcwd()
@classmethod
def from_path(cls, path: str) -> Self:
return cls(root_path=Path(path), path=str(path))

@property
def base_dir(self) -> str:
return os.path.dirname(self.path)

Check failure on line 30 in src/codegen/configs/models/repository.py

View workflow job for this annotation

GitHub Actions / mypy

error: Value of type variable "AnyOrLiteralStr" of "dirname" cannot be "str | None" [type-var]

Check failure on line 30 in src/codegen/configs/models/repository.py

View workflow job for this annotation

GitHub Actions / mypy

error: Incompatible return value type (got "str | None", expected "str") [return-value]

@property
def name(self) -> str:
return os.path.basename(self.path)

Check failure on line 34 in src/codegen/configs/models/repository.py

View workflow job for this annotation

GitHub Actions / mypy

error: Value of type variable "AnyOrLiteralStr" of "basename" cannot be "str | None" [type-var]

Check failure on line 34 in src/codegen/configs/models/repository.py

View workflow job for this annotation

GitHub Actions / mypy

error: Incompatible return value type (got "str | None", expected "str") [return-value]

@property
def full_name(self) -> str | None:
Expand Down
11 changes: 6 additions & 5 deletions src/codegen/configs/user_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from pydantic import Field

from codegen.configs.constants import ENV_FILENAME
from codegen.configs.models.codebase import CodebaseConfig
from codegen.configs.models.repository import RepositoryConfig
from codegen.configs.models.secrets import SecretsConfig
Expand All @@ -14,11 +15,11 @@ class UserConfig:
codebase: CodebaseConfig = Field(default_factory=CodebaseConfig)
secrets: SecretsConfig = Field(default_factory=SecretsConfig)

def __init__(self, env_filepath: Path) -> None:
self.env_filepath = env_filepath
self.secrets = SecretsConfig(env_filepath=env_filepath)
self.repository = RepositoryConfig(env_filepath=env_filepath)
self.codebase = CodebaseConfig(env_filepath=env_filepath)
def __init__(self, root_path: Path) -> None:
self.env_filepath = root_path / ENV_FILENAME
self.secrets = SecretsConfig(root_path=root_path)
self.repository = RepositoryConfig(root_path=root_path)
self.codebase = CodebaseConfig(root_path=root_path)

def save(self) -> None:
"""Save configuration to the config file."""
Expand Down
18 changes: 2 additions & 16 deletions src/codegen/extensions/events/modal/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from codegen.extensions.events.codegen_app import CodegenApp
from codegen.extensions.events.modal.request_util import fastapi_request_adapter
from codegen.git.clients.git_repo_client import GitRepoClient
from codegen.git.schemas.repo_config import RepoConfig

logging.basicConfig(level=logging.INFO, force=True)
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -36,17 +35,11 @@ def get_event_handler_cls(self) -> modal.Cls:
raise NotImplementedError(msg)

async def handle_event(self, org: str, repo: str, provider: Literal["slack", "github", "linear"], request: Request):
repo_config = RepoConfig(
name=repo,
full_name=f"{org}/{repo}",
)

repo_snapshotdict = modal.Dict.from_name(self.snapshot_index_id, {}, create_if_missing=True)

last_snapshot_commit = repo_snapshotdict.get(f"{org}/{repo}", None)

if last_snapshot_commit is None:
git_client = GitRepoClient(repo_config=repo_config, access_token=os.environ["GITHUB_ACCESS_TOKEN"])
git_client = GitRepoClient(repo_full_name=f"{org}/{repo}", access_token=os.environ["GITHUB_ACCESS_TOKEN"])
branch = git_client.get_branch_safe(git_client.default_branch)
last_snapshot_commit = branch.commit.sha if branch and branch.commit else None

Expand Down Expand Up @@ -76,15 +69,8 @@ def refresh_repository_snapshots(self, snapshot_index_id: str):
try:
# Parse the repository full name to get org and repo
org, repo = repo_full_name.split("/")

# Create a RepoConfig for the repository
repo_config = RepoConfig(
name=repo,
full_name=repo_full_name,
)

# Initialize the GitRepoClient to fetch the latest commit
git_client = GitRepoClient(repo_config=repo_config, access_token=os.environ["GITHUB_ACCESS_TOKEN"])
git_client = GitRepoClient(repo_full_name=repo_full_name, access_token=os.environ["GITHUB_ACCESS_TOKEN"])

# Get the default branch and its latest commit
branch = git_client.get_branch_safe(git_client.default_branch)
Expand Down
11 changes: 5 additions & 6 deletions src/codegen/git/clients/git_repo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

from codegen.configs.models.secrets import SecretsConfig
from codegen.git.clients.github_client import GithubClient
from codegen.git.schemas.repo_config import RepoConfig
from codegen.git.utils.format import format_comparison
from codegen.shared.logging.get_logger import get_logger

Expand All @@ -26,22 +25,22 @@
class GitRepoClient:
"""Wrapper around PyGithub's Remote Repository."""

repo_config: RepoConfig
repo_full_name: str
gh_client: GithubClient
_repo: Repository

def __init__(self, repo_config: RepoConfig, access_token: str | None = None) -> None:
self.repo_config = repo_config
def __init__(self, repo_full_name: str, access_token: str | None = None) -> None:
self.repo_full_name = repo_full_name
self.gh_client = self._create_github_client(token=access_token or SecretsConfig().github_token)

Check failure on line 34 in src/codegen/git/clients/git_repo_client.py

View workflow job for this annotation

GitHub Actions / mypy

error: Argument "token" to "_create_github_client" of "GitRepoClient" has incompatible type "str | None"; expected "str" [arg-type]
self._repo = self._create_client()

def _create_github_client(self, token: str) -> GithubClient:
return GithubClient(token=token)

def _create_client(self) -> Repository:
client = self.gh_client.get_repo_by_full_name(self.repo_config.full_name)
client = self.gh_client.get_repo_by_full_name(self.repo_full_name)
if not client:
msg = f"Repo {self.repo_config.full_name} not found!"
msg = f"Repo {self.repo_full_name} not found!"
raise ValueError(msg)
return client

Expand Down Expand Up @@ -150,7 +149,7 @@
if not base_branch_name:
base_branch_name = self.default_branch

head_branch_name = f"{self.repo_config.organization_name}:{head_branch_name}"

Check failure on line 152 in src/codegen/git/clients/git_repo_client.py

View workflow job for this annotation

GitHub Actions / mypy

error: "GitRepoClient" has no attribute "repo_config" [attr-defined]

# retrieve all pulls ordered by created descending
prs = self.repo.get_pulls(base=base_branch_name, head=head_branch_name, state=state, sort="created", direction="desc")
Expand All @@ -175,9 +174,9 @@
def get_or_create_pull(
self,
head_branch_name: str,
base_branch_name: str | None = None, # type: ignore[assignment]

Check failure on line 177 in src/codegen/git/clients/git_repo_client.py

View workflow job for this annotation

GitHub Actions / mypy

error: Unused "type: ignore" comment [unused-ignore]
title: str | None = None, # type: ignore[assignment]

Check failure on line 178 in src/codegen/git/clients/git_repo_client.py

View workflow job for this annotation

GitHub Actions / mypy

error: Unused "type: ignore" comment [unused-ignore]
body: str | None = None, # type: ignore[assignment]

Check failure on line 179 in src/codegen/git/clients/git_repo_client.py

View workflow job for this annotation

GitHub Actions / mypy

error: Unused "type: ignore" comment [unused-ignore]
) -> PullRequest | None:
pull = self.get_pull_by_branch_and_state(head_branch_name=head_branch_name, base_branch_name=base_branch_name)
if pull:
Expand Down
21 changes: 16 additions & 5 deletions src/codegen/git/repo_operator/local_git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from git import Repo
from git.remote import Remote

from codegen.configs.models.repository import RepositoryConfig
from codegen.git.clients.git_repo_client import GitRepoClient
from codegen.git.schemas.repo_config import RepoConfig
from codegen.git.utils.language import determine_project_language


Expand All @@ -20,7 +20,11 @@ def __init__(self, repo_path: Path):

@cached_property
def git_cli(self) -> Repo:
return Repo(self.repo_path)
if not os.path.exists(self.repo_path):
os.makedirs(self.repo_path)
return Repo.init(self.repo_path)
else:
return Repo(self.repo_path)

@cached_property
def name(self) -> str:
Expand Down Expand Up @@ -72,13 +76,20 @@ def user_email(self) -> str | None:
def get_language(self, access_token: str | None = None) -> str:
"""Returns the majority language of the repository"""
if access_token is not None:
repo_config = RepoConfig.from_repo_path(repo_path=str(self.repo_path))
repo_config.full_name = self.full_name
remote_git = GitRepoClient(repo_config=repo_config, access_token=access_token)
remote_git = GitRepoClient(repo_full_name=self.full_name, access_token=access_token)
if (language := remote_git.repo.language) is not None:
return language.upper()

return str(determine_project_language(str(self.repo_path)))

def has_remote(self) -> bool:
return bool(self.git_cli.remotes)

def get_repo_config(self, access_token: str | None = None, repo_config: RepositoryConfig | None = None) -> RepositoryConfig:
config = repo_config or RepositoryConfig()
config.path = config.path or str(self.repo_path)
config.owner = config.owner or self.owner
config.user_name = config.user_name or self.user_name
config.user_email = config.user_email or self.user_email
config.language = config.language or self.get_language(access_token=access_token).upper()
return config
Loading
Loading