fix: разрешить формат owner/repo в имени репозитория (E3 был слишком строг, слэш ≠ эскейп)
This commit is contained in:
@@ -370,6 +370,15 @@ func (w *Worker) clone(ctx context.Context, repo string) error {
|
||||
url := buildCloneURL(base, repo)
|
||||
dst := filepath.Join(w.Worktree, repo)
|
||||
|
||||
// Для формата "owner/repo" git clone не создаёт промежуточный каталог {worktree}/owner
|
||||
// до самого репозитория — поэтому создаём родителя явно. Worktree в целом гарантирован
|
||||
// app.New, но вложенные сегменты owner здесь обязательны.
|
||||
if parent := filepath.Dir(dst); parent != "." && parent != w.Worktree {
|
||||
if err := os.MkdirAll(parent, 0o755); err != nil {
|
||||
return fmt.Errorf("%w: создать %s: %v", ErrClone, parent, err)
|
||||
}
|
||||
}
|
||||
|
||||
args := []string{"clone"}
|
||||
if w.GitToken != "" {
|
||||
// https-базовый URL: кладём токен внутрь URL (для приватных репозиториев).
|
||||
@@ -391,12 +400,20 @@ func buildCloneURL(base, repo string) string {
|
||||
}
|
||||
|
||||
// validateRepoName отклоняет имена с пути-эскейпом (E3).
|
||||
// Допускается формат "owner/repo" (один слэш) — клон ляжет в {worktree}/owner/repo,
|
||||
// промежуточный каталог создаёт clone(). Путь с сегментами "." , ".." , пустыми или
|
||||
// абсолютный — ошибка.
|
||||
func validateRepoName(repo string) error {
|
||||
if repo == "" {
|
||||
return fmt.Errorf("%w: пустое имя", ErrRepoPathHint)
|
||||
}
|
||||
if strings.Contains(repo, "/") || strings.Contains(repo, "..") {
|
||||
if filepath.IsAbs(repo) {
|
||||
return fmt.Errorf("%w: %q", ErrRepoPathHint, repo)
|
||||
}
|
||||
for _, seg := range strings.Split(repo, "/") {
|
||||
if seg == "" || seg == "." || seg == ".." {
|
||||
return fmt.Errorf("%w: %q", ErrRepoPathHint, repo)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user