Skip to content

Commit 07e07cc

Browse files
committed
add private files in clone_manager
1 parent fa0aae1 commit 07e07cc

1 file changed

Lines changed: 52 additions & 2 deletions

File tree

src/portfolio_auditor/fetchers/clone_manager.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import os
34
import shutil
45
import subprocess
56
from dataclasses import dataclass
@@ -27,6 +28,11 @@ class CloneResult:
2728
class CloneManager:
2829
"""
2930
Handles local repository cloning for deeper file-level analysis.
31+
32+
Important behavior:
33+
- public repositories can be cloned anonymously over HTTPS
34+
- private repositories require an authenticated clone URL
35+
- SSH remains supported if enabled in settings
3036
"""
3137

3238
def __init__(self, settings: Settings) -> None:
@@ -114,6 +120,50 @@ def _resolve_clone_url(self, repo: RepoMetadata) -> str:
114120
return repo.links.ssh_url
115121

116122
if repo.links.clone_url:
117-
return str(repo.links.clone_url)
123+
https_clone_url = str(repo.links.clone_url)
124+
return self._build_authenticated_https_clone_url(https_clone_url)
125+
126+
raise CloneError(f"HTTPS clone URL is missing for repository {repo.full_name}.")
127+
128+
def _build_authenticated_https_clone_url(self, clone_url: str) -> str:
129+
"""
130+
Build an authenticated HTTPS clone URL when a GitHub token is available.
131+
132+
Example:
133+
https://github.com/owner/repo.git
134+
becomes:
135+
https://x-access-token:<TOKEN>@github.com/owner/repo.git
136+
137+
Notes:
138+
- This is only applied to GitHub HTTPS URLs.
139+
- If no token is available, the original URL is returned unchanged.
140+
- The authenticated URL must never be logged.
141+
"""
142+
token = self._resolve_github_token()
143+
if not token:
144+
return clone_url
145+
146+
github_prefix = "https://github.com/"
147+
if not clone_url.startswith(github_prefix):
148+
return clone_url
149+
150+
return clone_url.replace(
151+
github_prefix,
152+
f"https://x-access-token:{token}@github.com/",
153+
1,
154+
)
155+
156+
def _resolve_github_token(self) -> str | None:
157+
"""
158+
Resolve the GitHub token from environment variables.
159+
160+
This works both:
161+
- locally when .env is loaded into the environment
162+
- on Streamlit Community Cloud after secrets are copied into os.environ
163+
"""
164+
token = os.getenv("GITHUB_TOKEN")
165+
if not token:
166+
return None
118167

119-
raise CloneError(f"HTTPS clone URL is missing for repository {repo.full_name}.")
168+
token = token.strip()
169+
return token or None

0 commit comments

Comments
 (0)