Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b11aafa

Browse files
committed
Merge branch 'main' into improve-env
2 parents 3bc4ed7 + 8445050 commit b11aafa

File tree

12 files changed

+84
-97
lines changed

12 files changed

+84
-97
lines changed

‎.github/workflows/docker_image.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Build Docker Image
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
docker:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4
14+
15+
- name: Set up Docker Buildx
16+
uses: docker/setup-buildx-action@v3
17+
18+
- name: Build
19+
uses: docker/build-push-action@v6
20+
with:
21+
push: false
22+
context: .
23+
file: Dockerfile
24+
tags: "${{ github.sha }}"
File renamed without changes.

‎pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ requires-python = ">= 3.8"
77
dependencies = [
88
"click>=8.0.0",
99
"fastapi[standard]>=0.109.1", # Minimum safe release (https://osv.dev/vulnerability/PYSEC-2024-38)
10+
"httpx",
11+
"pathspec>=0.12.1",
1012
"pydantic",
1113
"python-dotenv",
1214
"slowapi",
1315
"starlette>=0.40.0", # Minimum safe release (https://osv.dev/vulnerability/GHSA-f96h-pmfr-66vw)
1416
"tiktoken>=0.7.0", # Support for o200k_base encoding
15-
"pathspec>=0.12.1",
1617
"typing_extensions>= 4.0.0; python_version < '3.10'",
1718
"uvicorn>=0.11.7", # Minimum safe release (https://osv.dev/vulnerability/PYSEC-2020-150)
1819
]
@@ -44,7 +45,7 @@ dev = [
4445
]
4546

4647
[project.scripts]
47-
gitingest = "gitingest.cli:main"
48+
gitingest = "gitingest.__main__:main"
4849

4950
[project.urls]
5051
homepage = "https://gitingest.com"

‎requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
click>=8.0.0
22
fastapi[standard]>=0.109.1 # Vulnerable to https://osv.dev/vulnerability/PYSEC-2024-38
3+
httpx
34
pathspec>=0.12.1
45
pydantic
56
python-dotenv
File renamed without changes.

‎src/gitingest/utils/git_utils.py

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@
44

55
import asyncio
66
import base64
7-
import os
87
import re
8+
import sys
99
from typing import Final
1010
from urllib.parse import urlparse
1111

12-
from starlette.status import (
13-
HTTP_200_OK,
14-
HTTP_301_MOVED_PERMANENTLY,
15-
HTTP_302_FOUND,
16-
HTTP_401_UNAUTHORIZED,
17-
HTTP_403_FORBIDDEN,
18-
HTTP_404_NOT_FOUND,
19-
)
12+
import httpx
13+
from starlette.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND
2014

2115
from gitingest.utils.compat_func import removesuffix
2216
from gitingest.utils.exceptions import InvalidGitHubTokenError
17+
from server.server_utils import Colors
2318

2419
# GitHub Personal-Access tokens (classic + fine-grained).
2520
# - ghp_ / gho_ / ghu_ / ghs_ / ghr_ → 36 alphanumerics
@@ -81,6 +76,8 @@ async def run_command(*args: str) -> tuple[bytes, bytes]:
8176
async def ensure_git_installed() -> None:
8277
"""Ensure Git is installed and accessible on the system.
8378
79+
On Windows, this also checks whether Git is configured to support long file paths.
80+
8481
Raises
8582
------
8683
RuntimeError
@@ -92,6 +89,20 @@ async def ensure_git_installed() -> None:
9289
except RuntimeError as exc:
9390
msg = "Git is not installed or not accessible. Please install Git first."
9491
raise RuntimeError(msg) from exc
92+
if sys.platform == "win32":
93+
try:
94+
stdout, _ = await run_command("git", "config", "core.longpaths")
95+
if stdout.decode().strip().lower() != "true":
96+
print(
97+
f"{Colors.BROWN}WARN{Colors.END}: {Colors.RED}Git clone may fail on Windows "
98+
f"due to long file paths:{Colors.END}",
99+
)
100+
print(f"{Colors.RED}To avoid this issue, consider enabling long path support with:{Colors.END}")
101+
print(f"{Colors.RED} git config --global core.longpaths true{Colors.END}")
102+
print(f"{Colors.RED}Note: This command may require administrator privileges.{Colors.END}")
103+
except RuntimeError:
104+
# Ignore if checking 'core.longpaths' fails.
105+
pass
95106

96107

97108
async def check_repo_exists(url: str, token: str | None = None) -> bool:
@@ -115,45 +126,28 @@ async def check_repo_exists(url: str, token: str | None = None) -> bool:
115126
If the host returns an unrecognised status code.
116127
117128
"""
118-
# TODO: use `requests` instead of `curl`
119-
cmd: list[str] = [
120-
"curl",
121-
"--silent", # Suppress output
122-
"--location", # Follow redirects
123-
"--write-out",
124-
"%{http_code}", # Write the HTTP status code to stdout
125-
"-o",
126-
os.devnull,
127-
]
129+
headers = {}
128130

129131
if token and is_github_host(url):
130132
host, owner, repo = _parse_github_url(url)
131133
# Public GitHub vs. GitHub Enterprise
132134
base_api = "https://api.github.com" if host == "github.com" else f"https://{host}/api/v3"
133135
url = f"{base_api}/repos/{owner}/{repo}"
134-
cmd += ["--header", f"Authorization: Bearer {token}"]
135-
136-
cmd.append(url)
136+
headers["Authorization"] = f"Bearer {token}"
137137

138-
proc = await asyncio.create_subprocess_exec(
139-
*cmd,
140-
stdout=asyncio.subprocess.PIPE,
141-
stderr=asyncio.subprocess.PIPE,
142-
)
143-
stdout, _ = await proc.communicate()
138+
async with httpx.AsyncClient(follow_redirects=True) as client:
139+
try:
140+
response = await client.head(url, headers=headers)
141+
except httpx.RequestError:
142+
return False
144143

145-
if proc.returncode != 0:
146-
return False
144+
status_code = response.status_code
147145

148-
status = int(stdout.decode().strip())
149-
if status in {HTTP_200_OK, HTTP_301_MOVED_PERMANENTLY}:
146+
if status_code == HTTP_200_OK:
150147
return True
151-
# TODO: handle 302 redirects
152-
if status in {HTTP_404_NOT_FOUND, HTTP_302_FOUND}:
153-
return False
154-
if status in {HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN}:
148+
if status_code in {HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND}:
155149
return False
156-
msg = f"Unexpected HTTP status {status} for {url}"
150+
msg = f"Unexpected HTTP status {status_code} for {url}"
157151
raise RuntimeError(msg)
158152

159153

‎src/server/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,17 @@ async def robots() -> FileResponse:
8585
return FileResponse("static/robots.txt")
8686

8787

88-
@app.get("/llm.txt")
88+
@app.get("/llms.txt")
8989
async def llm_txt() -> FileResponse:
90-
"""Serve the ``llm.txt`` file to provide information about the site to LLMs.
90+
"""Serve the ``llms.txt`` file to provide information about the site to LLMs.
9191
9292
Returns
9393
-------
9494
FileResponse
95-
The ``llm.txt`` file located in the static directory.
95+
The ``llms.txt`` file located in the static directory.
9696
9797
"""
98-
return FileResponse("static/llm.txt")
98+
return FileResponse("static/llms.txt")
9999

100100

101101
# Include routers for modular endpoints

‎src/server/templates/components/navbar.jinja

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
</div>
1212
{# Navigation with updated styling #}
1313
<nav class="flex items-center space-x-6">
14-
<a href="/llm.txt" class="link-bounce flex items-center text-gray-900">
14+
<a href="/llms.txt" class="link-bounce flex items-center text-gray-900">
1515
<span class="badge-new">NEW</span>
16-
/llm.txt
16+
/llms.txt
1717
</a>
1818
{# GitHub link #}
1919
<div class="flex items-center gap-2">
File renamed without changes.

‎tests/test_cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pytest
99
from click.testing import CliRunner, Result
1010

11-
from gitingest.cli import main
11+
from gitingest.__main__ import main
1212
from gitingest.config import MAX_FILE_SIZE, OUTPUT_FILE_NAME
1313

1414

@@ -72,8 +72,8 @@ def test_cli_with_stdout_output() -> None:
7272
# ─── core expectations (stdout) ────────────────────────────────────-
7373
assert result.exit_code == 0, f"CLI exited with code {result.exit_code}, stderr: {result.stderr}"
7474
assert "---" in result.stdout, "Expected file separator '---' not found in STDOUT"
75-
assert "src/gitingest/cli.py" in result.stdout, (
76-
"Expected content (e.g., src/gitingest/cli.py) not found in STDOUT"
75+
assert "src/gitingest/__main__.py" in result.stdout, (
76+
"Expected content (e.g., src/gitingest/__main__.py) not found in STDOUT"
7777
)
7878
assert not output_file.exists(), f"Output file {output_file} was unexpectedly created."
7979

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /