From c0751ef116642a8074b2d8f124f18b24c89447cc Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 13 Jan 2025 03:39:15 +0800 Subject: [PATCH 1/4] Fix upload file form (#33230) Fix #33228 --- web_src/js/features/repo-editor.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts index 64d0402d84..d7097787d2 100644 --- a/web_src/js/features/repo-editor.ts +++ b/web_src/js/features/repo-editor.ts @@ -38,9 +38,6 @@ export function initRepoEditor() { const dropzoneUpload = document.querySelector('.page-content.repository.editor.upload .dropzone'); if (dropzoneUpload) initDropzone(dropzoneUpload); - const editArea = document.querySelector('.page-content.repository.editor textarea#edit_area'); - if (!editArea) return; - for (const el of queryElems(document, '.js-quick-pull-choice-option')) { el.addEventListener('input', () => { if (el.value === 'commit-to-new-branch') { @@ -55,6 +52,7 @@ export function initRepoEditor() { } const filenameInput = document.querySelector('#file-name'); + if (!filenameInput) return; function joinTreePath() { const parts = []; for (const el of document.querySelectorAll('.breadcrumb span.section')) { @@ -144,6 +142,10 @@ export function initRepoEditor() { } }); + // on the upload page, there is no editor(textarea) + const editArea = document.querySelector('.page-content.repository.editor textarea#edit_area'); + if (!editArea) return; + const elForm = document.querySelector('.repository.editor .edit.form'); initEditPreviewTab(elForm); From 604365efd7aca2d82d4f63510c8271ec13155565 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 13 Jan 2025 00:34:26 +0000 Subject: [PATCH 2/4] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 29 ++++++++++++++++------------- options/locale/locale_ja-JP.ini | 6 ++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 3615c6b24d..a63613cf88 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -46,7 +46,7 @@ webauthn_unsupported_browser=Votre navigateur ne prend actuellement pas en charg webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer. webauthn_error_insecure=`WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1"` webauthn_error_unable_to_process=Le serveur n'a pas pu traiter votre demande. -webauthn_error_duplicated=La clé de sécurité n'est pas autorisée pour cette demande. Veuillez vous assurer que la clé n'est pas déjà enregistrée. +webauthn_error_duplicated=La clé de sécurité n’est pas autorisée pour cette demande. Veuillez vous assurer que la clé n’est pas déjà enregistrée. webauthn_error_empty=Vous devez définir un nom pour cette clé. webauthn_error_timeout=Le délai d'attente imparti a été atteint avant que votre clé ne puisse être lue. Veuillez recharger la page pour réessayer. webauthn_reload=Recharger @@ -469,7 +469,7 @@ sspi_auth_failed=Échec de l'authentification SSPI password_pwned=Le mot de passe que vous avez choisi fait partit des mots de passe ayant fuité sur internet. Veuillez réessayer avec un mot de passe différent et considérez remplacer ce mot de passe si vous l’utilisez ailleurs. password_pwned_err=Impossible d'envoyer la demande à HaveIBeenPwned last_admin=Vous ne pouvez pas supprimer ce compte car au moins un administrateur est requis. -signin_passkey=Se connecter avec une clé d’identification (passkey) +signin_passkey=Se connecter avec une clé d’accès (passkey) back_to_sign_in=Revenir à la page de connexion [mail] @@ -818,7 +818,7 @@ manage_ssh_keys=Gérer les clés SSH manage_ssh_principals=Gérer les certificats principaux SSH manage_gpg_keys=Gérer les clés GPG add_key=Ajouter une clé -ssh_desc=Ces clefs SSH publiques sont associées à votre compte. Les clefs privées correspondantes permettent l'accès complet à vos repos. +ssh_desc=Ces clés SSH publiques sont associées à votre compte. Les clés privées correspondantes permettent l’accès complet à vos dépôts. principal_desc=Ces Principaux de certificats SSH sont associés à votre compte et permettent un accès complet à vos dépôts. gpg_desc=Ces clés GPG sont associées à votre compte. Conservez-les en lieu sûr, car elles permettent de vérifier vos révisions. ssh_helper=Besoin d'aide ? Consultez le guide de GitHub pour créer vos propres clés SSH ou résoudre les problèmes courants que vous pourriez rencontrer en utilisant SSH. @@ -969,7 +969,7 @@ passcode_invalid=Le mot de passe est invalide. Réessayez. twofa_enrolled=L’authentification à deux facteurs a été activée pour votre compte. Gardez votre clé de secours (%s) en lieu sûr, car il ne vous sera montré qu'une seule fois. twofa_failed_get_secret=Impossible d'obtenir le secret. -webauthn_desc=Les clefs de sécurité sont des dispositifs matériels contenant des clefs cryptographiques. Elles peuvent être utilisées pour l’authentification à deux facteurs. La clef de sécurité doit supporter le standard WebAuthn Authenticator. +webauthn_desc=Les clés de sécurité sont des dispositifs matériels contenant des clés cryptographiques. Elles peuvent être utilisées pour l’authentification à deux facteurs. La clé de sécurité doit supporter le standard WebAuthn Authenticator. webauthn_register_key=Ajouter une clé de sécurité webauthn_nickname=Pseudonyme webauthn_delete_key=Retirer la clé de sécurité @@ -2400,17 +2400,17 @@ settings.packagist_api_token=Jeton API settings.packagist_package_url=URL du paquet Packagist settings.deploy_keys=Clés de déploiement settings.add_deploy_key=Ajouter une clé de déploiement -settings.deploy_key_desc=Les clefs de déploiement ont un accès en lecture seule au dépôt. +settings.deploy_key_desc=Les clés de déploiement ont un accès en lecture seule au dépôt. settings.is_writable=Activer l'accès en écriture settings.is_writable_info=Autoriser cette clé de déploiement à soumettre sur le dépôt. -settings.no_deploy_keys=Il n'y a pas encore de clefs de déploiement. +settings.no_deploy_keys=Il n’y a pas encore de clés de déploiement. settings.title=Titre settings.deploy_key_content=Contenu -settings.key_been_used=Une clef de déploiement identique est déjà en cours d'utilisation. -settings.key_name_used=Une clef de déploiement du même nom existe déjà. -settings.add_key_success=La clé de déploiement "%s" a été ajoutée. -settings.deploy_key_deletion=Supprimer une clef de déploiement -settings.deploy_key_deletion_desc=La suppression d'une clef de déploiement révoque son accès à ce dépôt. Continuer ? +settings.key_been_used=Une clé de déploiement identique est déjà en cours d’utilisation. +settings.key_name_used=Une clé de déploiement du même nom existe déjà. +settings.add_key_success=La clé de déploiement « %s » a été ajoutée. +settings.deploy_key_deletion=Supprimer une clé de déploiement +settings.deploy_key_deletion_desc=La suppression d’une clé de déploiement révoque son accès à ce dépôt. Continuer ? settings.deploy_key_deletion_success=La clé de déploiement a été supprimée. settings.branches=Branches settings.protected_branch=Protection de branche @@ -2627,6 +2627,9 @@ diff.image.overlay=Superposition diff.has_escaped=Cette ligne contient des caractères Unicode cachés diff.show_file_tree=Afficher l’arborescence des fichiers diff.hide_file_tree=Masquer l’arborescence des fichiers +diff.submodule_added=Sous-module %[1]s ajouté à %[2]s +diff.submodule_deleted=Sous-module %[1]s supprimé de %[2]s +diff.submodule_updated=Sous-module %[1]s mis-à-jour : %[2]s releases.desc=Suivi des publications et des téléchargements. release.releases=Publications @@ -3116,7 +3119,7 @@ auths.attribute_username_placeholder=Laisser vide afin d'utiliser le nom d'utili auths.attribute_name=Attribut prénom auths.attribute_surname=Attribut nom de famille auths.attribute_mail=Attribut e-mail -auths.attribute_ssh_public_key=Attribut clef SSH publique +auths.attribute_ssh_public_key=Attribut clé SSH publique auths.attribute_avatar=Attribut de l'avatar auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN auths.allow_deactivate_all=Permettre à un résultat de recherche vide de désactiver tous les utilisateurs @@ -3240,7 +3243,7 @@ config.ssh_port=Port config.ssh_listen_port=Port d'écoute config.ssh_root_path=Emplacement racine config.ssh_key_test_path=Chemin de test des clés -config.ssh_keygen_path=Chemin vers le générateur de clefs ("ssh-keygen") +config.ssh_keygen_path=Chemin vers le générateur de clés (« ssh-keygen ») config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale config.ssh_minimum_key_sizes=Tailles de clé minimales diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 4fa61eb494..e5f3d14115 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1015,6 +1015,7 @@ new_repo_helper=リポジトリには、プロジェクトのすべてのファ owner=オーナー owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。 repo_name=リポジトリ名 +repo_name_helper=リポジトリ名は、短く、覚えやすく、他と重複しないキーワードを使用しましょう。 リポジトリ名を ".profile" または ".profile-private" にして README.md を追加すると、ユーザーや組織のプロフィールとなります。 repo_size=リポジトリサイズ template=テンプレート template_select=テンプレートを選択してください。 @@ -2852,6 +2853,8 @@ teams.invite.title=あなたは組織 %[2]s 内のチーム /etc/pacman.conf にリポジトリとアーキテクチャを含めてサーバーを追加します: +arch.install=pacmanでパッケージを同期します: arch.repository=リポジトリ情報 arch.repository.repositories=リポジトリ arch.repository.architectures=Architectures @@ -3712,6 +3717,7 @@ runners.status.active=稼働中 runners.status.offline=オフライン runners.version=バージョン runners.reset_registration_token=登録トークンをリセット +runners.reset_registration_token_confirm=現在のトークンを無効にして、新しいトークンを生成しますか? runners.reset_registration_token_success=ランナー登録トークンをリセットしました runs.all_workflows=すべてのワークフロー From 81352542fd29d1809bd483dec60849ec39d84388 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 13 Jan 2025 09:07:05 +0800 Subject: [PATCH 3/4] Refactor context RefName and RepoAssignment (#33226) The `ctx.Repo.RefName` was used to be a "short name", it causes a lot of ambiguity. This PR does some refactoring and use `RefFullName` to replace the legacy `RefName`, and simplify RepoAssignment --- models/repo/archiver.go | 11 +- modules/git/ref.go | 4 + modules/git/repo_archive.go | 36 ++-- modules/git/repo_archive_test.go | 32 ++++ options/locale/locale_en-US.ini | 4 +- routers/api/v1/repo/download.go | 8 +- routers/api/v1/repo/file.go | 9 +- routers/web/feed/file.go | 2 +- routers/web/repo/commit.go | 4 +- routers/web/repo/helper.go | 15 +- routers/web/repo/repo.go | 18 +- routers/web/repo/view_file.go | 2 +- routers/web/repo/view_home.go | 2 +- services/context/repo.go | 155 ++++++++---------- services/repository/archiver/archiver.go | 57 +++---- services/repository/archiver/archiver_test.go | 27 ++- templates/repo/branch/list.tmpl | 4 +- templates/repo/clone_panel.tmpl | 10 +- templates/repo/view_file.tmpl | 2 +- tests/integration/empty_repo_test.go | 4 +- 20 files changed, 187 insertions(+), 219 deletions(-) create mode 100644 modules/git/repo_archive_test.go diff --git a/models/repo/archiver.go b/models/repo/archiver.go index 14ffa1d89b..5a3eac9f14 100644 --- a/models/repo/archiver.go +++ b/models/repo/archiver.go @@ -56,16 +56,11 @@ func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) { if err != nil { return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument} } - nameExts := strings.SplitN(parts[2], ".", 2) - if len(nameExts) != 2 { + commitID, archiveType := git.SplitArchiveNameType(parts[2]) + if archiveType == git.ArchiveUnknown { return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument} } - - return &RepoArchiver{ - RepoID: repoID, - CommitID: parts[1] + nameExts[0], - Type: git.ToArchiveType(nameExts[1]), - }, nil + return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil } // GetRepoArchiver get an archiver diff --git a/modules/git/ref.go b/modules/git/ref.go index aab4c5d77d..051b75a15a 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -80,6 +80,10 @@ func RefNameFromTag(shortName string) RefName { return RefName(TagPrefix + shortName) } +func RefNameFromCommit(shortName string) RefName { + return RefName(shortName) +} + func (ref RefName) String() string { return string(ref) } diff --git a/modules/git/repo_archive.go b/modules/git/repo_archive.go index 2b45a50f19..92f3e88f7c 100644 --- a/modules/git/repo_archive.go +++ b/modules/git/repo_archive.go @@ -16,37 +16,35 @@ import ( type ArchiveType int const ( - // ZIP zip archive type - ZIP ArchiveType = iota + 1 - // TARGZ tar gz archive type - TARGZ - // BUNDLE bundle archive type - BUNDLE + ArchiveUnknown ArchiveType = iota + ArchiveZip // 1 + ArchiveTarGz // 2 + ArchiveBundle // 3 ) -// String converts an ArchiveType to string +// String converts an ArchiveType to string: the extension of the archive file without prefix dot func (a ArchiveType) String() string { switch a { - case ZIP: + case ArchiveZip: return "zip" - case TARGZ: + case ArchiveTarGz: return "tar.gz" - case BUNDLE: + case ArchiveBundle: return "bundle" } return "unknown" } -func ToArchiveType(s string) ArchiveType { - switch s { - case "zip": - return ZIP - case "tar.gz": - return TARGZ - case "bundle": - return BUNDLE +func SplitArchiveNameType(s string) (string, ArchiveType) { + switch { + case strings.HasSuffix(s, ".zip"): + return strings.TrimSuffix(s, ".zip"), ArchiveZip + case strings.HasSuffix(s, ".tar.gz"): + return strings.TrimSuffix(s, ".tar.gz"), ArchiveTarGz + case strings.HasSuffix(s, ".bundle"): + return strings.TrimSuffix(s, ".bundle"), ArchiveBundle } - return 0 + return s, ArchiveUnknown } // CreateArchive create archive content to the target path diff --git a/modules/git/repo_archive_test.go b/modules/git/repo_archive_test.go new file mode 100644 index 0000000000..ff7e2dfce1 --- /dev/null +++ b/modules/git/repo_archive_test.go @@ -0,0 +1,32 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestArchiveType(t *testing.T) { + name, archiveType := SplitArchiveNameType("test.tar.gz") + assert.Equal(t, "test", name) + assert.Equal(t, "tar.gz", archiveType.String()) + + name, archiveType = SplitArchiveNameType("a/b/test.zip") + assert.Equal(t, "a/b/test", name) + assert.Equal(t, "zip", archiveType.String()) + + name, archiveType = SplitArchiveNameType("1234.bundle") + assert.Equal(t, "1234", name) + assert.Equal(t, "bundle", archiveType.String()) + + name, archiveType = SplitArchiveNameType("test") + assert.Equal(t, "test", name) + assert.Equal(t, "unknown", archiveType.String()) + + name, archiveType = SplitArchiveNameType("test.xz") + assert.Equal(t, "test.xz", name) + assert.Equal(t, "unknown", archiveType.String()) +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9d240ac897..93155caa10 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1115,9 +1115,7 @@ blame.ignore_revs = Ignoring revisions in .git-blame-ignore-revs.git-blame-ignore-revs. user_search_tooltip = Shows a maximum of 30 users -tree_path_not_found_commit = Path %[1]s doesn't exist in commit %[2]s -tree_path_not_found_branch = Path %[1]s doesn't exist in branch %[2]s -tree_path_not_found_tag = Path %[1]s doesn't exist in tag %[2]s +tree_path_not_found = Path %[1]s doesn't exist in %[2]s transfer.accept = Accept Transfer transfer.accept_desc = Transfer to "%s" diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go index a8a23c4a8d..e6296c9fe7 100644 --- a/routers/api/v1/repo/download.go +++ b/routers/api/v1/repo/download.go @@ -17,11 +17,11 @@ func DownloadArchive(ctx *context.APIContext) { var tp git.ArchiveType switch ballType := ctx.PathParam("ball_type"); ballType { case "tarball": - tp = git.TARGZ + tp = git.ArchiveTarGz case "zipball": - tp = git.ZIP + tp = git.ArchiveZip case "bundle": - tp = git.BUNDLE + tp = git.ArchiveBundle default: ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType)) return @@ -36,7 +36,7 @@ func DownloadArchive(ctx *context.APIContext) { } } - r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"), tp) + r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")+"."+tp.String()) if err != nil { ctx.ServerError("NewRequest", err) return diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 7c7f53a565..3eefd2ae29 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -293,14 +293,7 @@ func GetArchive(ctx *context.APIContext) { } func archiveDownload(ctx *context.APIContext) { - uri := ctx.PathParam("*") - ext, tp, err := archiver_service.ParseFileName(uri) - if err != nil { - ctx.Error(http.StatusBadRequest, "ParseFileName", err) - return - } - - aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp) + aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { ctx.Error(http.StatusBadRequest, "unknown archive format", err) diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go index 9732264351..518d995ccb 100644 --- a/routers/web/feed/file.go +++ b/routers/web/feed/file.go @@ -24,7 +24,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string } commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange( git.CommitsByFileAndRangeOptions{ - Revision: ctx.Repo.RefName, + Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName File: fileName, Page: 1, }) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 638b5e680a..b5498ccd2c 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -222,7 +222,7 @@ func FileHistory(ctx *context.Context) { return } - commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ctx.Repo.RefName, fileName) + commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ctx.Repo.RefFullName.ShortName(), fileName) // FIXME: legacy code used ShortName if err != nil { ctx.ServerError("FileCommitsCount", err) return @@ -238,7 +238,7 @@ func FileHistory(ctx *context.Context) { commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange( git.CommitsByFileAndRangeOptions{ - Revision: ctx.Repo.RefName, + Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName File: fileName, Page: page, }) diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go index ed6216fa5c..3bf064c1e3 100644 --- a/routers/web/repo/helper.go +++ b/routers/web/repo/helper.go @@ -4,25 +4,14 @@ package repo import ( - "net/url" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/services/context" ) func HandleGitError(ctx *context.Context, msg string, err error) { if git.IsErrNotExist(err) { - refType := "" - switch { - case ctx.Repo.IsViewBranch: - refType = "branch" - case ctx.Repo.IsViewTag: - refType = "tag" - case ctx.Repo.IsViewCommit: - refType = "commit" - } - ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found_"+refType, ctx.Repo.TreePath, url.PathEscape(ctx.Repo.RefName)) - ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + refType + "/" + url.PathEscape(ctx.Repo.RefName) + ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found", ctx.Repo.TreePath, ctx.Repo.RefTypeNameSubURL()) + ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() ctx.NotFound(msg, err) } else { ctx.ServerError(msg, err) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 0f408b22e0..e5c397ec54 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -463,13 +463,7 @@ func RedirectDownload(ctx *context.Context) { // Download an archive of a repository func Download(ctx *context.Context) { - uri := ctx.PathParam("*") - ext, tp, err := archiver_service.ParseFileName(uri) - if err != nil { - ctx.ServerError("ParseFileName", err) - return - } - aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp) + aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { ctx.Error(http.StatusBadRequest, err.Error()) @@ -527,15 +521,9 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep // a request that's already in-progress, but the archiver service will just // kind of drop it on the floor if this is the case. func InitiateDownload(ctx *context.Context) { - uri := ctx.PathParam("*") - ext, tp, err := archiver_service.ParseFileName(uri) + aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { - ctx.ServerError("ParseFileName", err) - return - } - aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp) - if err != nil { - ctx.ServerError("archiver_service.NewRequest", err) + ctx.Error(http.StatusBadRequest, "invalid archive request") return } if aReq == nil { diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go index f4be4783fb..0b4381edfb 100644 --- a/routers/web/repo/view_file.go +++ b/routers/web/repo/view_file.go @@ -42,7 +42,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { } defer dataRc.Close() - ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName) + ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName()) ctx.Data["FileIsSymlink"] = entry.IsLink() ctx.Data["FileName"] = blob.Name() ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index 7aa8a72430..622072adeb 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -135,7 +135,7 @@ func prepareToRenderDirectory(ctx *context.Context) { if ctx.Repo.TreePath != "" { ctx.Data["HideRepoInfo"] = true - ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName) + ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName()) } subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries, true) diff --git a/services/context/repo.go b/services/context/repo.go index 121910235f..05f6bb40f9 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -58,10 +58,10 @@ type Repository struct { IsViewTag bool IsViewCommit bool - RefName string - BranchName string - TagName string - TreePath string + RefFullName git.RefName + BranchName string + TagName string + TreePath string // Commit it is always set to the commit for the branch or tag Commit *git.Commit @@ -392,33 +392,25 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { // RepoAssignment returns a middleware to handle repository assignment func RepoAssignment(ctx *Context) { - if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce { - // FIXME: it should panic in dev/test modes to have a clear behavior - if !setting.IsProd || setting.IsInTesting { - panic("RepoAssignment should not be executed twice") - } - return + if ctx.Data["Repository"] != nil { + setting.PanicInDevOrTesting("RepoAssignment should not be executed twice") } - ctx.Data["repoAssignmentExecuted"] = true - - var ( - owner *user_model.User - err error - ) + var err error userName := ctx.PathParam("username") repoName := ctx.PathParam("reponame") repoName = strings.TrimSuffix(repoName, ".git") if setting.Other.EnableFeed { + ctx.Data["EnableFeed"] = true repoName = strings.TrimSuffix(repoName, ".rss") repoName = strings.TrimSuffix(repoName, ".atom") } // Check if the user is the same as the repository owner if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) { - owner = ctx.Doer + ctx.Repo.Owner = ctx.Doer } else { - owner, err = user_model.GetUserByName(ctx, userName) + ctx.Repo.Owner, err = user_model.GetUserByName(ctx, userName) if err != nil { if user_model.IsErrUserNotExist(err) { // go-get does not support redirects @@ -441,8 +433,7 @@ func RepoAssignment(ctx *Context) { return } } - ctx.Repo.Owner = owner - ctx.ContextUser = owner + ctx.ContextUser = ctx.Repo.Owner ctx.Data["ContextUser"] = ctx.ContextUser // redirect link to wiki @@ -466,10 +457,10 @@ func RepoAssignment(ctx *Context) { } // Get repository. - repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, repoName) + repo, err := repo_model.GetRepositoryByName(ctx, ctx.Repo.Owner.ID, repoName) if err != nil { if repo_model.IsErrRepoNotExist(err) { - redirectRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, repoName) + redirectRepoID, err := repo_model.LookupRedirect(ctx, ctx.Repo.Owner.ID, repoName) if err == nil { RedirectToRepo(ctx.Base, redirectRepoID) } else if repo_model.IsErrRedirectNotExist(err) { @@ -486,7 +477,7 @@ func RepoAssignment(ctx *Context) { } return } - repo.Owner = owner + repo.Owner = ctx.Repo.Owner repoAssignment(ctx, repo) if ctx.Written() { @@ -495,11 +486,7 @@ func RepoAssignment(ctx *Context) { ctx.Repo.RepoLink = repo.Link() ctx.Data["RepoLink"] = ctx.Repo.RepoLink - - if setting.Other.EnableFeed { - ctx.Data["EnableFeed"] = true - ctx.Data["FeedURL"] = ctx.Repo.RepoLink - } + ctx.Data["FeedURL"] = ctx.Repo.RepoLink unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker) if err == nil { @@ -526,7 +513,7 @@ func RepoAssignment(ctx *Context) { return } - ctx.Data["Title"] = owner.Name + "/" + repo.Name + ctx.Data["Title"] = repo.Owner.Name + "/" + repo.Name ctx.Data["Repository"] = repo ctx.Data["Owner"] = ctx.Repo.Repository.Owner ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(unit_model.TypeCode) @@ -596,7 +583,6 @@ func RepoAssignment(ctx *Context) { // Disable everything when the repo is being created if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() { - ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch if !isHomeOrSettings { ctx.Redirect(ctx.Repo.RepoLink) } @@ -604,9 +590,7 @@ func RepoAssignment(ctx *Context) { } if ctx.Repo.GitRepo != nil { - if !setting.IsProd || setting.IsInTesting { - panic("RepoAssignment: GitRepo should be nil") - } + setting.PanicInDevOrTesting("RepoAssignment: GitRepo should be nil") _ = ctx.Repo.GitRepo.Close() ctx.Repo.GitRepo = nil } @@ -616,7 +600,6 @@ func RepoAssignment(ctx *Context) { if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") { log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err) ctx.Repo.Repository.MarkAsBrokenEmpty() - ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch // Only allow access to base of repo or settings if !isHomeOrSettings { ctx.Redirect(ctx.Repo.RepoLink) @@ -629,7 +612,6 @@ func RepoAssignment(ctx *Context) { // Stop at this point when the repo is empty. if ctx.Repo.Repository.IsEmpty { - ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch return } @@ -655,22 +637,6 @@ func RepoAssignment(ctx *Context) { ctx.Data["BranchesCount"] = branchesTotal - // If no branch is set in the request URL, try to guess a default one. - if len(ctx.Repo.BranchName) == 0 { - if len(ctx.Repo.Repository.DefaultBranch) > 0 && ctx.Repo.GitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) { - ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch - } else { - ctx.Repo.BranchName, _ = gitrepo.GetDefaultBranch(ctx, ctx.Repo.Repository) - if ctx.Repo.BranchName == "" { - // If it still can't get a default branch, fall back to default branch from setting. - // Something might be wrong. Either site admin should fix the repo sync or Gitea should fix a potential bug. - ctx.Repo.BranchName = setting.Repository.DefaultBranch - } - } - ctx.Repo.RefName = ctx.Repo.BranchName - } - ctx.Data["BranchName"] = ctx.Repo.BranchName - // People who have push access or have forked repository can propose a new pull request. canPush := ctx.Repo.CanWrite(unit_model.TypeCode) || (ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)) @@ -713,7 +679,7 @@ func RepoAssignment(ctx *Context) { } if ctx.FormString("go-get") == "1" { - ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, owner.Name, repo.Name) + ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, repo.Owner.Name, repo.Name) fullURLPrefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName) ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}" ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}" @@ -844,26 +810,39 @@ type RepoRefByTypeOptions struct { IgnoreNotExistErr bool } +func repoRefFullName(shortName string, typ RepoRefType) git.RefName { + switch typ { + case RepoRefBranch: + return git.RefNameFromBranch(shortName) + case RepoRefTag: + return git.RefNameFromTag(shortName) + case RepoRefCommit: + return git.RefNameFromCommit(shortName) + default: + setting.PanicInDevOrTesting("Unknown RepoRefType: %v", typ) + return git.RefNameFromBranch("main") // just a dummy result, it shouldn't happen + } +} + // RepoRefByType handles repository reference name for a specific type // of repository reference func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func(*Context) { opt := util.OptionalArg(opts) return func(ctx *Context) { + var err error refType := detectRefType // Empty repository does not have reference information. if ctx.Repo.Repository.IsEmpty { // assume the user is viewing the (non-existent) default branch ctx.Repo.IsViewBranch = true ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch + ctx.Repo.RefFullName = git.RefNameFromBranch(ctx.Repo.BranchName) + // these variables are used by the template to "add/upload" new files + ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["TreePath"] = "" return } - var ( - refName string - err error - ) - if ctx.Repo.GitRepo == nil { ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { @@ -873,22 +852,23 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func } // Get default branch. + var refShortName string reqPath := ctx.PathParam("*") if reqPath == "" { - refName = ctx.Repo.Repository.DefaultBranch - if !ctx.Repo.GitRepo.IsBranchExist(refName) { + refShortName = ctx.Repo.Repository.DefaultBranch + if !ctx.Repo.GitRepo.IsBranchExist(refShortName) { brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1) if err == nil && len(brs) != 0 { - refName = brs[0].Name + refShortName = brs[0].Name } else if len(brs) == 0 { log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path) } else { log.Error("GetBranches error: %v", err) } } - ctx.Repo.RefName = refName - ctx.Repo.BranchName = refName - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) + ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName) + ctx.Repo.BranchName = refShortName + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName) if err == nil { ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() } else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") { @@ -902,35 +882,37 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func } else { // there is a path in request guessLegacyPath := refType == RepoRefUnknown if guessLegacyPath { - refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "") + refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "") } else { - refName = getRefName(ctx.Base, ctx.Repo, reqPath, refType) + refShortName = getRefName(ctx.Base, ctx.Repo, reqPath, refType) } - ctx.Repo.RefName = refName + ctx.Repo.RefFullName = repoRefFullName(refShortName, refType) isRenamedBranch, has := ctx.Data["IsRenamedBranch"].(bool) if isRenamedBranch && has { renamedBranchName := ctx.Data["RenamedBranchName"].(string) - ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refName, renamedBranchName)) - link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refName), util.PathEscapeSegments(renamedBranchName), 1) + ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refShortName, renamedBranchName)) + link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refShortName), util.PathEscapeSegments(renamedBranchName), 1) ctx.Redirect(link) return } - if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refName) { + if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) { ctx.Repo.IsViewBranch = true - ctx.Repo.BranchName = refName + ctx.Repo.BranchName = refShortName + ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName) - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName) if err != nil { ctx.ServerError("GetBranchCommit", err) return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refName) { + } else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refShortName) { ctx.Repo.IsViewTag = true - ctx.Repo.TagName = refName + ctx.Repo.RefFullName = git.RefNameFromTag(refShortName) + ctx.Repo.TagName = refShortName - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName) if err != nil { if git.IsErrNotExist(err) { ctx.NotFound("GetTagCommit", err) @@ -940,25 +922,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refName, 7) { + } else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refShortName, 7) { ctx.Repo.IsViewCommit = true - ctx.Repo.CommitID = refName + ctx.Repo.RefFullName = git.RefNameFromCommit(refShortName) + ctx.Repo.CommitID = refShortName - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) + ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refShortName) if err != nil { ctx.NotFound("GetCommit", err) return } // If short commit ID add canonical link header - if len(refName) < ctx.Repo.GetObjectFormat().FullLength() { - canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)) + if len(refShortName) < ctx.Repo.GetObjectFormat().FullLength() { + canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refShortName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)) ctx.RespHeader().Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, canonicalURL)) } } else { if opt.IgnoreNotExistErr { return } - ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName)) + ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refShortName)) return } @@ -975,15 +958,19 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func } } - ctx.Data["BranchName"] = ctx.Repo.BranchName - ctx.Data["RefName"] = ctx.Repo.RefName + ctx.Data["RefFullName"] = ctx.Repo.RefFullName ctx.Data["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL() - ctx.Data["TagName"] = ctx.Repo.TagName - ctx.Data["CommitID"] = ctx.Repo.CommitID ctx.Data["TreePath"] = ctx.Repo.TreePath + ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch + ctx.Data["BranchName"] = ctx.Repo.BranchName + ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag + ctx.Data["TagName"] = ctx.Repo.TagName + ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit + ctx.Data["CommitID"] = ctx.Repo.CommitID + ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() // only used by the branch selector dropdown: AllowCreateNewRef ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount() diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index e1addbed33..d39acc080d 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -31,19 +31,20 @@ import ( // handle elsewhere. type ArchiveRequest struct { RepoID int64 - refName string Type git.ArchiveType CommitID string + + archiveRefShortName string // the ref short name to download the archive, for example: "master", "v1.0.0", "commit id" } // ErrUnknownArchiveFormat request archive format is not supported type ErrUnknownArchiveFormat struct { - RequestFormat string + RequestNameType string } // Error implements error func (err ErrUnknownArchiveFormat) Error() string { - return fmt.Sprintf("unknown format: %s", err.RequestFormat) + return fmt.Sprintf("unknown format: %s", err.RequestNameType) } // Is implements error @@ -54,12 +55,12 @@ func (ErrUnknownArchiveFormat) Is(err error) bool { // RepoRefNotFoundError is returned when a requested reference (commit, tag) was not found. type RepoRefNotFoundError struct { - RefName string + RefShortName string } // Error implements error. func (e RepoRefNotFoundError) Error() string { - return fmt.Sprintf("unrecognized repository reference: %s", e.RefName) + return fmt.Sprintf("unrecognized repository reference: %s", e.RefShortName) } func (e RepoRefNotFoundError) Is(err error) bool { @@ -67,43 +68,23 @@ func (e RepoRefNotFoundError) Is(err error) bool { return ok } -func ParseFileName(uri string) (ext string, tp git.ArchiveType, err error) { - switch { - case strings.HasSuffix(uri, ".zip"): - ext = ".zip" - tp = git.ZIP - case strings.HasSuffix(uri, ".tar.gz"): - ext = ".tar.gz" - tp = git.TARGZ - case strings.HasSuffix(uri, ".bundle"): - ext = ".bundle" - tp = git.BUNDLE - default: - return "", 0, ErrUnknownArchiveFormat{RequestFormat: uri} - } - return ext, tp, nil -} - // NewRequest creates an archival request, based on the URI. The // resulting ArchiveRequest is suitable for being passed to Await() // if it's determined that the request still needs to be satisfied. -func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git.ArchiveType) (*ArchiveRequest, error) { - if fileType < git.ZIP || fileType > git.BUNDLE { - return nil, ErrUnknownArchiveFormat{RequestFormat: fileType.String()} - } - - r := &ArchiveRequest{ - RepoID: repoID, - refName: refName, - Type: fileType, +func NewRequest(repoID int64, repo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) { + // here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id + archiveRefShortName, archiveType := git.SplitArchiveNameType(archiveRefExt) + if archiveType == git.ArchiveUnknown { + return nil, ErrUnknownArchiveFormat{archiveRefExt} } // Get corresponding commit. - commitID, err := repo.ConvertToGitID(r.refName) + commitID, err := repo.ConvertToGitID(archiveRefShortName) if err != nil { - return nil, RepoRefNotFoundError{RefName: r.refName} + return nil, RepoRefNotFoundError{RefShortName: archiveRefShortName} } + r := &ArchiveRequest{RepoID: repoID, archiveRefShortName: archiveRefShortName, Type: archiveType} r.CommitID = commitID.String() return r, nil } @@ -111,11 +92,11 @@ func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git // GetArchiveName returns the name of the caller, based on the ref used by the // caller to create this request. func (aReq *ArchiveRequest) GetArchiveName() string { - return strings.ReplaceAll(aReq.refName, "/", "-") + "." + aReq.Type.String() + return strings.ReplaceAll(aReq.archiveRefShortName, "/", "-") + "." + aReq.Type.String() } // Await awaits the completion of an ArchiveRequest. If the archive has -// already been prepared the method returns immediately. Otherwise an archiver +// already been prepared the method returns immediately. Otherwise, an archiver // process will be started and its completion awaited. On success the returned // RepoArchiver may be used to download the archive. Note that even if the // context is cancelled/times out a started archiver will still continue to run @@ -208,8 +189,8 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver rd, w := io.Pipe() defer func() { - w.Close() - rd.Close() + _ = w.Close() + _ = rd.Close() }() done := make(chan error, 1) // Ensure that there is some capacity which will ensure that the goroutine below can always finish repo, err := repo_model.GetRepositoryByID(ctx, archiver.RepoID) @@ -230,7 +211,7 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver } }() - if archiver.Type == git.BUNDLE { + if archiver.Type == git.ArchiveBundle { err = gitRepo.CreateBundle( ctx, archiver.CommitID, diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go index 1d0c6e513d..522f90558a 100644 --- a/services/repository/archiver/archiver_test.go +++ b/services/repository/archiver/archiver_test.go @@ -9,7 +9,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/services/contexttest" _ "code.gitea.io/gitea/models/actions" @@ -31,47 +30,47 @@ func TestArchive_Basic(t *testing.T) { contexttest.LoadGitRepo(t, ctx) defer ctx.Repo.GitRepo.Close() - bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP) + bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName()) // Check a series of bogus requests. // Step 1, valid commit with a bad extension. - bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, 100) + bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".unknown") assert.Error(t, err) assert.Nil(t, bogusReq) // Step 2, missing commit. - bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff", git.ZIP) + bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff.zip") assert.Error(t, err) assert.Nil(t, bogusReq) // Step 3, doesn't look like branch/tag/commit. - bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db", git.ZIP) + bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db.zip") assert.Error(t, err) assert.Nil(t, bogusReq) - bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master", git.ZIP) + bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName()) - bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive", git.ZIP) + bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName()) // Now two valid requests, firstCommit with valid extensions. - zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP) + zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) assert.NotNil(t, zipReq) - tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.TARGZ) + tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".tar.gz") assert.NoError(t, err) assert.NotNil(t, tgzReq) - secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.ZIP) + secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".bundle") assert.NoError(t, err) assert.NotNil(t, secondReq) @@ -91,7 +90,7 @@ func TestArchive_Basic(t *testing.T) { // Sleep two seconds to make sure the queue doesn't change. time.Sleep(2 * time.Second) - zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP) + zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) // This zipReq should match what's sitting in the queue, as we haven't // let it release yet. From the consumer's point of view, this looks like @@ -106,12 +105,12 @@ func TestArchive_Basic(t *testing.T) { // Now we'll submit a request and TimedWaitForCompletion twice, before and // after we release it. We should trigger both the timeout and non-timeout // cases. - timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.TARGZ) + timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz") assert.NoError(t, err) assert.NotNil(t, timedReq) doArchive(db.DefaultContext, timedReq) - zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP) + zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) // Now, we're guaranteed to have released the original zipReq from the queue. // Ensure that we don't get handed back the released entry somehow, but they @@ -129,6 +128,6 @@ func TestArchive_Basic(t *testing.T) { } func TestErrUnknownArchiveFormat(t *testing.T) { - err := ErrUnknownArchiveFormat{RequestFormat: "master"} + err := ErrUnknownArchiveFormat{RequestNameType: "xxx"} assert.ErrorIs(t, err, ErrUnknownArchiveFormat{}) } diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index cb504e2b75..25614d0df4 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -42,7 +42,7 @@ {{end}} {{if .EnableFeed}} - {{svg "octicon-rss"}} + {{svg "octicon-rss"}} {{end}} {{if not $.DisableDownloadSourceArchives}}