Skip to content

38 clone repo and list files - #40

Merged
mshqq merged 9 commits into
mainfrom
38-clone-repo-and-list-files
Aug 14, 2026
Merged

mshqq merged 9 commits into
mainfrom
38-clone-repo-and-list-files

Conversation

@mshqq

@mshqq mshqq commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Что сделано

  • Добавлены исключения RepoCloneError / RepoTooLargeError (app/scanner/exceptions.py) чтобы вызывающий код мог различать причину сбоя, а не ловить голый Exception
  • Реализован clone_repo(url, commit_sha=None) -> tuple[str, str] (app/scanner/clone.py):
    • клон без полной истории;
    • без commit_sha берется HEAD дефолтной ветки;
    • url принимает только http(s):// или git@host:..., и только с хостов из ALLOWED_HOSTS (github.com, gitlab.com), остальные отклоняются ещё до попытки клонирования, чтобы через API нельзя было просканировать произвольную локальную директорию;
    • путь клона - случайная подпапка в SCAN_TEMP_DIR, не производная от URL/имено репо;
    • таймаут на все git-вызовы, размер репозитория сверяется с MAX_REPO_SIZE_MB -> RepoTooLargeError при превышении;
    • cleanup(repo_path) удаляет временную папку;
  • Реализован list_files(repo_path) -> list[str] (app/scanner/files.py) - рекурсивный обход, .git пропускается целиком, симлинки пропускаются, пути относительные, отсортированные, разделитель принудительно / независимо от ОС (иначе на Windows не находились бы .env-файлы во вложенных папках
  • Оба модуля чистые - без Flask и БД, как и весь app/scanner
  • Тесты (tests/test_clone.py, tests/test_files.py): валидация URL (параметризованный набор кейсов), клонирование реального репозитория на HEAD и конкретный commit_sha, несуществующий репозиторий -> RepoCloneError, превышение размера -> RepoTooLargeError, cleanup на существующей/несуществующей папке, обход вложенных директорий, исключение .git, симлинки

Связанная задача

Closes #38

mshqq added 8 commits August 14, 2026 05:01
- allowlist на github.com/gitlab.com, http(s) и git@
- shallow-клон через init/remote add/fetch --depth=1/checkout FETCH_HEAD
- проверка размера клона против MAX_REPO_SIZE_MB
- cleanup временной директории
- рекурсивный обход через os.walk, .git пропускается целиком
- относительные пути от repo_path, отсортированы
- симлинки (на файлы и директории) не дают выйти за пределы repo_path
- пустой репозиторий, файлы в корне и во вложенных директориях
- исключение .git
- симлинк на директорию и симлинк на файл за пределами repo_path
- несуществующий путь
- MAX_REPO_SIZE_MB временно занижается до 0 через модуль, чтобы проверить
превышение лимита без раздувания тестового репозитория.
- значение восстанавливается в finally, иначе оно утечёт в остальные тесты
процесса
os.path.relpath отдаёт os.sep, на Windows это "\", из-за чего _basename
в env_file.py (жёстко режет по "/") не найдёт .env-файлы во вложенных папках.
Явно приводим путь к "/" независимо от ОС.
Раньше проверялся только дефолтный HEAD и несуществующий репозиторий -
явного клонирования на заданный коммит тесты не закрывали.
@mshqq
mshqq requested a review from Ripeeerr August 14, 2026 08:00
@mshqq mshqq self-assigned this Aug 14, 2026
@mshqq mshqq added enhancement New feature or request scanner labels Aug 14, 2026
@mshqq
mshqq merged commit 0e11171 into main Aug 14, 2026
1 check passed
@mshqq
mshqq deleted the 38-clone-repo-and-list-files branch August 14, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request scanner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Клонирование репозитория и список файлов

2 participants