Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirects for renamed repos #807

Merged
merged 2 commits into from
Feb 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,22 @@ func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
}

// ErrRepoRedirectNotExist represents a "RepoRedirectNotExist" kind of error.
type ErrRepoRedirectNotExist struct {
OwnerID int64
RepoName string
}

// IsErrRepoRedirectNotExist check if an error is an ErrRepoRedirectNotExist
func IsErrRepoRedirectNotExist(err error) bool {
_, ok := err.(ErrRepoRedirectNotExist)
return ok
}

func (err ErrRepoRedirectNotExist) Error() string {
return fmt.Sprintf("repository redirect does not exist [uid: %d, name: %s]", err.OwnerID, err.RepoName)
}

// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
type ErrInvalidCloneAddr struct {
IsURLError bool
Expand Down
1 change: 1 addition & 0 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func init() {
new(LFSMetaObject),
new(TwoFactor),
new(RepoUnit),
new(RepoRedirect),
)

gonicNames := []string{"SSL", "UID"}
Expand Down
3 changes: 3 additions & 0 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,9 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
if _, err = e.Insert(repo); err != nil {
return err
}
if err = deleteRepoRedirect(e, u.ID, repo.Name); err != nil {
return err
}

// insert units for repo
var units = make([]RepoUnit, 0, len(defaultRepoUnits))
Expand Down
62 changes: 62 additions & 0 deletions models/repo_redirect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import "strings"

// RepoRedirect represents that a repo name should be redirected to another
type RepoRedirect struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s)"`
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
RedirectRepoID int64 // repoID to redirect to
}

// LookupRepoRedirect look up if a repository has a redirect name
func LookupRepoRedirect(ownerID int64, repoName string) (int64, error) {
repoName = strings.ToLower(repoName)
redirect := &RepoRedirect{OwnerID: ownerID, LowerName: repoName}
if has, err := x.Get(redirect); err != nil {
return 0, err
} else if !has {
return 0, ErrRepoRedirectNotExist{OwnerID: ownerID, RepoName: repoName}
}
return redirect.RedirectRepoID, nil
}

// NewRepoRedirect create a new repo redirect
func NewRepoRedirect(ownerID, repoID int64, oldRepoName, newRepoName string) error {
oldRepoName = strings.ToLower(oldRepoName)
newRepoName = strings.ToLower(newRepoName)
sess := x.NewSession()
defer sess.Close()

if err := sess.Begin(); err != nil {
return err
}

if err := deleteRepoRedirect(sess, ownerID, newRepoName); err != nil {
sess.Rollback()
return err
}

if _, err := sess.Insert(&RepoRedirect{
OwnerID: ownerID,
LowerName: oldRepoName,
RedirectRepoID: repoID,
}); err != nil {
sess.Rollback()
return err
}
return sess.Commit()
}

// deleteRepoRedirect delete any redirect from the specified repo name to
// anything else
func deleteRepoRedirect(e Engine, ownerID int64, repoName string) error {
repoName = strings.ToLower(repoName)
_, err := e.Delete(&RepoRedirect{OwnerID: ownerID, LowerName: repoName})
return err
}
35 changes: 31 additions & 4 deletions modules/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,26 @@ func earlyResponseForGoGetMeta(ctx *Context) {
})))
}

// RedirectToRepo redirect to a differently-named repository
func RedirectToRepo(ctx *Context, redirectRepoID int64) {
ownerName := ctx.Params(":username")
previousRepoName := ctx.Params(":reponame")

repo, err := models.GetRepositoryByID(redirectRepoID)
if err != nil {
ctx.Handle(500, "GetRepositoryByID", err)
return
}

redirectPath := strings.Replace(
ctx.Req.URL.Path,
fmt.Sprintf("%s/%s", ownerName, previousRepoName),
fmt.Sprintf("%s/%s", ownerName, repo.Name),
1,
)
ctx.Redirect(redirectPath)
}

// RepoAssignment returns a macaron to handle repository assignment
func RepoAssignment(args ...bool) macaron.Handler {
return func(ctx *Context) {
Expand Down Expand Up @@ -176,11 +196,18 @@ func RepoAssignment(args ...bool) macaron.Handler {
repo, err := models.GetRepositoryByName(owner.ID, repoName)
if err != nil {
if models.IsErrRepoNotExist(err) {
if ctx.Query("go-get") == "1" {
earlyResponseForGoGetMeta(ctx)
return
redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName)
if err == nil {
RedirectToRepo(ctx, redirectRepoID)
} else if models.IsErrRepoRedirectNotExist(err) {
if ctx.Query("go-get") == "1" {
earlyResponseForGoGetMeta(ctx)
return
}
ctx.Handle(404, "GetRepositoryByName", err)
} else {
ctx.Handle(500, "LookupRepoRedirect", err)
}
ctx.Handle(404, "GetRepositoryByName", err)
} else {
ctx.Handle(500, "GetRepositoryByName", err)
}
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_bg-BG.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Синхр. сега
settings.mirror_sync_in_progress=Синхронизация на огледалото е в ход, моля обновете страницата след минута.
settings.site=Официален сайт
settings.update_settings=Запази настройките
settings.change_reponame_prompt=Тази промяна ще засегне връзките, които се отнасят до това хранилището.
settings.advanced_settings=Разширени настройки
settings.wiki_desc=Включи система за уики
settings.use_internal_wiki=Използвай вградено уики
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_cs-CZ.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Provést synchronizaci
settings.mirror_sync_in_progress=Synchronizace zrcadel probíhá, prosím načtěte znovu stránku přibližně za minutu.
settings.site=Oficiální stránky
settings.update_settings=Změnit nastavení
settings.change_reponame_prompt=Tato změna ovlivní vztah odkazů k repositáři.
settings.advanced_settings=Pokročilá nastavení
settings.wiki_desc=Povolit systém Wiki
settings.use_internal_wiki=Použít vestavěný systém Wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_de-DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,6 @@ settings.sync_mirror=Jetzt synchronisieren
settings.mirror_sync_in_progress=Mirror Synchronisierung läuft, bitte die Seite in ca. einer Minute neu laden.
settings.site=Offizielle Webseite
settings.update_settings=Einstellungen speichern
settings.change_reponame_prompt=Diese Änderung wirkt sich darauf aus, wie sich Links auf Repositories beziehen.
settings.advanced_settings=Erweiterte Einstellungen
settings.wiki_desc=Wiki einschalten
settings.use_internal_wiki=Eingebautes Wiki verwenden
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,6 @@ settings.sync_mirror = Sync Now
settings.mirror_sync_in_progress = Mirror syncing is in progress, please refresh page in about a minute.
settings.site = Official Site
settings.update_settings = Update Settings
settings.change_reponame_prompt = This change will affect how links relate to the repository.
settings.advanced_settings = Advanced Settings
settings.wiki_desc = Enable wiki system
settings.use_internal_wiki = Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_es-ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ settings.sync_mirror=Sincronizar ahora
settings.mirror_sync_in_progress=Sincronización de réplica en curso, por favor actualice la página en unos minutos.
settings.site=Sitio oficial
settings.update_settings=Actualizar configuración
settings.change_reponame_prompt=Este cambio afectará a los enlaces al repositorio.
settings.advanced_settings=Ajustes avanzados
settings.wiki_desc=Activar sistema de wiki
settings.use_internal_wiki=Usar wiki integrada
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_fi-FI.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Sync Now
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=Virallinen sivusto
settings.update_settings=Päivitä asetukset
settings.change_reponame_prompt=Tämä muutos vaikuttaa siihen miten linkit liittyvät repoon.
settings.advanced_settings=Lisäasetukset
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_fr-FR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ settings.sync_mirror=Synchroniser maintenant
settings.mirror_sync_in_progress=Synchronisation du miroir en cours, merci de rafraîchir la page dans une minute environ.
settings.site=Site officiel
settings.update_settings=Valider
settings.change_reponame_prompt=Ce changement affectera comment les liens sont reliés avec le dépôt.
settings.advanced_settings=Paramètres avancés
settings.wiki_desc=Activer le wiki
settings.use_internal_wiki=Utiliser le wiki interne
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_it-IT.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Sync Now
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=Sito Ufficiale
settings.update_settings=Aggiorna Impostazioni
settings.change_reponame_prompt=Questa modifica influirà i link al repository.
settings.advanced_settings=Opzioni avanzate
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_ja-JP.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=今すぐ同期
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=公式サイト
settings.update_settings=設定の更新
settings.change_reponame_prompt=この変更はリンクがリポジトリに関連付ける方法に影響します。
settings.advanced_settings=拡張設定
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_ko-KR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ settings.sync_mirror=지금 동기화
settings.mirror_sync_in_progress=미러 동기화 진행 중입니다. 약 1분 뒤에 페이지를 새로 고침 하세요.
settings.site=공식 사이트
settings.update_settings=설정 저장
settings.change_reponame_prompt=이 변경은 이 저장소와 연관된 링크들에 영향을 줄 것입니다.
settings.advanced_settings=고급 설정
settings.wiki_desc=위키 시스템 활성화
settings.use_internal_wiki=내장 위키 사용
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_lv-LV.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Sinhronizēt tagad
settings.mirror_sync_in_progress=Notiek spoguļa sinhronizācija, uzgaidiet aptuveni minūti un atjaunojiet lapu.
settings.site=Oficiālā mājas lapa
settings.update_settings=Mainīt iestatījumus
settings.change_reponame_prompt=Šī izmaiņa ietekmēs saites, kas ir saistītas ar šo repozitoriju.
settings.advanced_settings=Papildu iestatījumi
settings.wiki_desc=Iespējot vikivietnes
settings.use_internal_wiki=Izmantot iebūvēto vikivietni
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_nl-NL.ini
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ settings.sync_mirror=Sync Now
settings.mirror_sync_in_progress=Kopie synchronisatie is bezig, vernieuw de pagina over ongeveer een minuut.
settings.site=Officiële site
settings.update_settings=Instellingen bewerken
settings.change_reponame_prompt=Deze verandering zal gevolgen hebben voor hoe links zich verhouden tot de repository.
settings.advanced_settings=Geavanceerde opties
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_pl-PL.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Synchronizuj teraz
settings.mirror_sync_in_progress=Synchronizacja kopii lustrzanej jest w toku, odśwież stronę w ciągu minuty.
settings.site=Oficjalna Strona
settings.update_settings=Aktualizuj ustawienia
settings.change_reponame_prompt=Zmiana nazwy repozytorium wpłynie na linki do niego.
settings.advanced_settings=Ustawienia zaawansowane
settings.wiki_desc=Włącz system wiki
settings.use_internal_wiki=Użyj wbudowanego wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_pt-BR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ settings.sync_mirror=Sincronizar agora
settings.mirror_sync_in_progress=A sincronização do mirror está em andamento, por favor atualize a página em aproximadamente um minuto.
settings.site=Site oficial
settings.update_settings=Atualizar configurações
settings.change_reponame_prompt=Esta mudança irá afetar os links para este repositório.
settings.advanced_settings=Configurações avançadas
settings.wiki_desc=Habilitar sistema de wiki
settings.use_internal_wiki=Usar wiki nativa
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_ru-RU.ini
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,6 @@ settings.sync_mirror=Синхронизировать
settings.mirror_sync_in_progress=Выполняется синхронизация Зеркала, пожалуйста, обновите эту страницу через минуту.
settings.site=Официальный сайт
settings.update_settings=Обновить настройки
settings.change_reponame_prompt=Это изменение повлияет на отношения ссылок к этому репозиторию.
settings.advanced_settings=Расширенные настройки
settings.wiki_desc=Включить систему Wiki
settings.use_internal_wiki=Использовать встроенную wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_sr-SP.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Изврши синхронизацију сада
settings.mirror_sync_in_progress=Синхронизација је у току, молимо вас да освежите страницу ускоро.
settings.site=Званични сајт
settings.update_settings=Примени промене
settings.change_reponame_prompt=Ова промена ће утицати на однос линкова на спремиште.
settings.advanced_settings=Напредна подешавања
settings.wiki_desc=Омогући систем вики
settings.use_internal_wiki=Користи уграђен вики
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_sv-SE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Synkronisera nu
settings.mirror_sync_in_progress=Spegningssynkronisering pågår, vänligen ladda om sidan om cirka en minut.
settings.site=Officiell webbplats
settings.update_settings=Uppdatera inställningar
settings.change_reponame_prompt=Denna ändring kommer att påverka hur länkar relaterar till detta repo.
settings.advanced_settings=Advancerade Inställningar
settings.wiki_desc=Aktivera wikisystem
settings.use_internal_wiki=Använd inbyggd wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_tr-TR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ settings.sync_mirror=Sync Now
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=Resmi Web Sitesi
settings.update_settings=Ayarları Güncelle
settings.change_reponame_prompt=Bu değişiklik, bağlantıların depoyla olan ilişkisini etkileyecektir.
settings.advanced_settings=Gelişmiş Ayarlar
settings.wiki_desc=Viki sıstemini etkinleştir
settings.use_internal_wiki=Use builtin wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_zh-CN.ini
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,6 @@ settings.sync_mirror=立即同步
settings.mirror_sync_in_progress=镜像同步请求已经生效,请稍后刷新页面。
settings.site=官方网站
settings.update_settings=更新仓库设置
settings.change_reponame_prompt=该操作将会影响到所有与该仓库有关的链接
settings.advanced_settings=高级设置
settings.wiki_desc=启用 Wiki 系统
settings.use_internal_wiki=使用内置 Wiki 系统
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_zh-HK.ini
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@ settings.sync_mirror=立即同步
settings.mirror_sync_in_progress=鏡像同步正在進行中,請大約一分鐘後刷新頁面。
settings.site=官方網站
settings.update_settings=更新儲存庫設定
settings.change_reponame_prompt=該操作將會影響到所有與該儲存庫有關的鏈接
settings.advanced_settings=高級設定
settings.wiki_desc=啓用 Wiki 系統
settings.use_internal_wiki=使用內建 wiki
Expand Down
1 change: 0 additions & 1 deletion options/locale/locale_zh-TW.ini
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@ settings.sync_mirror=立即同步
settings.mirror_sync_in_progress=鏡像同步正在進行中,請大約一分鐘後刷新頁面。
settings.site=官方網站
settings.update_settings=更新儲存庫設定
settings.change_reponame_prompt=該操作將會影響到所有與該儲存庫有關的鏈接
settings.advanced_settings=高級設定
settings.wiki_desc=啓用 Wiki 系統
settings.use_internal_wiki=使用內建 wiki
Expand Down
9 changes: 8 additions & 1 deletion routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ func repoAssignment() macaron.Handler {
repo, err := models.GetRepositoryByName(owner.ID, repoName)
if err != nil {
if models.IsErrRepoNotExist(err) {
ctx.Status(404)
redirectRepoID, err := models.LookupRepoRedirect(owner.ID, repoName)
if err == nil {
context.RedirectToRepo(ctx.Context, redirectRepoID)
} else if models.IsErrRepoRedirectNotExist(err) {
ctx.Status(404)
} else {
ctx.Error(500, "LookupRepoRedirect", err)
}
} else {
ctx.Error(500, "GetRepositoryByName", err)
}
Expand Down
5 changes: 5 additions & 0 deletions routers/repo/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
return
}

err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName)
if err != nil {
ctx.Handle(500, "NewRepoRedirect", err)
}

log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
}
// In case it's just a case change.
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/settings/options.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<div class="required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}<span class="text red hide" id="repo-name-change-prompt"> {{.i18n.Tr "repo.settings.change_reponame_prompt"}}</span></label>
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove the prompt?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prompt warns that "This change will affect how links relate to the repository". Once we have redirects, what the prompt says will no longer be true.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

<input id="repo_name" name="repo_name" value="{{.Repository.Name}}" data-repo-name="{{.Repository.Name}}" autofocus required>
</div>
<div class="field {{if .Err_Description}}error{{end}}">
Expand Down