refactor: clean up git migration forms (#39672)

Only extracted shared code, removed unnecessary code, and use
form-fetch-action to replace RenderWithErrDeprecated, slightly
refactored JS to use data-global-init

Nothing else is changed, although there are still many problems.

Written by AI

Diff with hiding spaces:
https://github.com/go-gitea/gitea/pull/39672/changes?w=1
This commit is contained in:
wxiaoguang
2026-10-08 16:36:08 +08:00
committed by GitHub
parent 89ec271d9c
commit cc623c5f2f
18 changed files with 274 additions and 724 deletions
+30 -53
View File
@@ -22,7 +22,6 @@ import (
"gitea.dev/modules/structs"
"gitea.dev/modules/templates"
"gitea.dev/modules/util"
"gitea.dev/modules/web"
"gitea.dev/services/context"
"gitea.dev/services/forms"
"gitea.dev/services/migrations"
@@ -54,14 +53,7 @@ func Migrate(ctx *context.Context) {
}
ctx.Data["private"] = getRepoPrivate(ctx)
ctx.Data["mirror"] = ctx.FormString("mirror") == "1"
ctx.Data["lfs"] = ctx.FormString("lfs") == "1"
ctx.Data["wiki"] = ctx.FormString("wiki") == "1"
ctx.Data["milestones"] = ctx.FormString("milestones") == "1"
ctx.Data["labels"] = ctx.FormString("labels") == "1"
ctx.Data["issues"] = ctx.FormString("issues") == "1"
ctx.Data["pull_requests"] = ctx.FormString("pull_requests") == "1"
ctx.Data["releases"] = ctx.FormString("releases") == "1"
ctx.Data["mirror"] = ctx.FormBool("mirror") // from "gogs#2037": "new mirror" button on org's home page
ctxUser := checkContextUser(ctx, ctx.FormInt64("org"))
if ctx.Written() {
@@ -72,7 +64,7 @@ func Migrate(ctx *context.Context) {
ctx.HTML(http.StatusOK, templates.TplName("repo/migrate/"+serviceType.Name()))
}
func handleMigrateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl templates.TplName, form *forms.MigrateRepoForm) {
func handleMigrateError(ctx *context.Context, owner *user_model.User, err error) {
if setting.Repository.DisableMigrations {
ctx.HTTPError(http.StatusForbidden, "MigrateError: the site administrator has disabled migrations")
return
@@ -84,67 +76,65 @@ func handleMigrateError(ctx *context.Context, owner *user_model.User, err error,
case repo_model.IsErrReachLimitOfRepo(err):
maxCreationLimit := owner.MaxCreationLimit()
msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit)
ctx.RenderWithErrDeprecated(msg, tpl, form)
ctx.JSONError(msg)
case repo_model.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErrDeprecated(ctx.Tr("form.repo_name_been_taken"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.repo_name_been_taken"), "repo_name")
case repo_model.IsErrRepoFilesAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
switch {
case ctx.IsUserSiteAdmin() || (setting.Repository.AllowAdoptionOfUnadoptedRepositories && setting.Repository.AllowDeleteOfUnadoptedRepositories):
ctx.RenderWithErrDeprecated(ctx.Tr("form.repository_files_already_exist.adopt_or_delete"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.repository_files_already_exist.adopt_or_delete"), "repo_name")
case setting.Repository.AllowAdoptionOfUnadoptedRepositories:
ctx.RenderWithErrDeprecated(ctx.Tr("form.repository_files_already_exist.adopt"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.repository_files_already_exist.adopt"), "repo_name")
case setting.Repository.AllowDeleteOfUnadoptedRepositories:
ctx.RenderWithErrDeprecated(ctx.Tr("form.repository_files_already_exist.delete"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.repository_files_already_exist.delete"), "repo_name")
default:
ctx.RenderWithErrDeprecated(ctx.Tr("form.repository_files_already_exist"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.repository_files_already_exist"), "repo_name")
}
case errors.As(err, &errNameReserved):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErrDeprecated(ctx.Tr("repo.form.name_reserved", errNameReserved.Name), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.form.name_reserved", errNameReserved.Name), "repo_name")
case errors.As(err, &errNamePatternNotAllowed):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErrDeprecated(ctx.Tr("repo.form.name_pattern_not_allowed", errNamePatternNotAllowed.Pattern), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.form.name_pattern_not_allowed", errNamePatternNotAllowed.Pattern), "repo_name")
default:
err = util.SanitizeErrorCredentialURLs(err)
if _, fromGit := gitcmd.ErrorAsStderr(err); fromGit {
ctx.Data["Err_CloneAddr"] = true
ctx.RenderWithErrDeprecated(ctx.Tr("repo.migrate.failed", err.Error()), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.migrate.failed", err.Error()), "clone_addr")
} else {
ctx.ServerError(name, err)
ctx.JSONErrorAuto(err)
}
}
}
func handleMigrateRemoteAddrError(ctx *context.Context, err error, tpl templates.TplName, form *forms.MigrateRepoForm) {
func handleMigrateRemoteAddrError(ctx *context.Context, err error, field string) {
if addrErr, ok := err.(*git.ErrInvalidCloneAddr); ok {
switch {
case addrErr.IsProtocolInvalid:
ctx.RenderWithErrDeprecated(ctx.Tr("repo.mirror_address_protocol_invalid"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.mirror_address_protocol_invalid"), field)
case addrErr.IsURLError:
ctx.RenderWithErrDeprecated(ctx.Tr("form.url_error", addrErr.Host), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.url_error", addrErr.Host), field)
case addrErr.IsPermissionDenied:
if addrErr.LocalPath {
ctx.RenderWithErrDeprecated(ctx.Tr("repo.migrate.permission_denied"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.migrate.permission_denied"), field)
} else {
ctx.RenderWithErrDeprecated(ctx.Tr("repo.migrate.permission_denied_blocked"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.migrate.permission_denied_blocked"), field)
}
case addrErr.IsInvalidPath:
ctx.RenderWithErrDeprecated(ctx.Tr("repo.migrate.invalid_local_path"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("repo.migrate.invalid_local_path"), field)
default:
log.Error("Error whilst updating url: %v", err)
ctx.RenderWithErrDeprecated(ctx.Tr("form.url_error", "unknown"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.url_error", "unknown"), field)
}
} else {
log.Error("Error whilst updating url: %v", err)
ctx.RenderWithErrDeprecated(ctx.Tr("form.url_error", "unknown"), tpl, form)
ctx.JSONErrorWithField(ctx.Tr("form.url_error", "unknown"), field)
}
}
// MigratePost response for migrating from external git repository
func MigratePost(ctx *context.Context) {
form := web.GetForm[*forms.MigrateRepoForm](ctx)
form := context.GetFetchActionForm[*forms.MigrateRepoForm](ctx)
if form == nil {
return
}
if setting.Repository.DisableMigrations {
ctx.HTTPError(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations")
return
@@ -155,28 +145,17 @@ func MigratePost(ctx *context.Context) {
return
}
setMigrationContextData(ctx, form.Service)
ctxUser := checkContextUser(ctx, form.UID)
if ctx.Written() {
return
}
ctx.Data["ContextUser"] = ctxUser
tpl := templates.TplName("repo/migrate/" + form.Service.Name())
if ctx.HasError() {
ctx.HTML(http.StatusOK, tpl)
return
}
remoteAddr, err := git.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
if err == nil {
err = migrations.IsMigrateURLAllowed(remoteAddr, ctx.Doer)
}
if err != nil {
ctx.Data["Err_CloneAddr"] = true
handleMigrateRemoteAddrError(ctx, err, tpl, form)
handleMigrateRemoteAddrError(ctx, err, "clone_addr")
return
}
@@ -185,14 +164,12 @@ func MigratePost(ctx *context.Context) {
if form.LFS && len(form.LFSEndpoint) > 0 {
ep := lfs.DetermineEndpoint("", form.LFSEndpoint)
if ep == nil {
ctx.Data["Err_LFSEndpoint"] = true
ctx.RenderWithErrDeprecated(ctx.Tr("repo.migrate.invalid_lfs_endpoint"), tpl, &form)
ctx.JSONErrorWithField(ctx.Tr("repo.migrate.invalid_lfs_endpoint"), "lfs_endpoint")
return
}
err = migrations.IsMigrateURLAllowed(ep.String(), ctx.Doer)
if err != nil {
ctx.Data["Err_LFSEndpoint"] = true
handleMigrateRemoteAddrError(ctx, err, tpl, form)
handleMigrateRemoteAddrError(ctx, err, "lfs_endpoint")
return
}
}
@@ -233,17 +210,17 @@ func MigratePost(ctx *context.Context) {
err = repo_service.CheckCreateRepository(ctx, ctx.Doer, ctxUser, opts.RepoName, false)
if err != nil {
handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form)
handleMigrateError(ctx, ctxUser, err)
return
}
err = task.MigrateRepository(ctx, ctx.Doer, ctxUser, opts)
if err == nil {
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(opts.RepoName))
ctx.JSONRedirect(ctxUser.HomeLink() + "/" + url.PathEscape(opts.RepoName))
return
}
handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form)
handleMigrateError(ctx, ctxUser, err)
}
func setMigrationContextData(ctx *context.Context, serviceType structs.GitServiceType) {
+1 -1
View File
@@ -1092,7 +1092,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) {
m.Get("/create", repo.Create)
m.Post("/create", web.Bind[*forms.CreateRepoForm](), repo.CreatePost)
m.Get("/migrate", repo.Migrate)
m.Post("/migrate", web.Bind[*forms.MigrateRepoForm](), repo.MigratePost)
m.Post("/migrate", repo.MigratePost)
m.Get("/search", repo.SearchRepo)
}, reqSignIn)
// end "/repo": create, migrate, search
+15 -67
View File
@@ -6,50 +6,48 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_username">{{ctx.Locale.Tr "username"}}</label>
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "username"}}</label>
<input name="auth_username">
</div>
<div class="inline field">
<label for="auth_password">{{ctx.Locale.Tr "password"}}</label>
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
<label>{{ctx.Locale.Tr "password"}}</label>
<input name="auth_password" type="password">
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div id="migrate_items">
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_merge_requests"}}</label>
</div>
</div>
@@ -57,57 +55,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+16 -68
View File
@@ -6,41 +6,39 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline required field">
<label for="aws_access_key_id">{{ctx.Locale.Tr "repo.migrate.codecommit.aws_access_key_id"}}</label>
<input id="aws_access_key_id" name="aws_access_key_id" value="{{.aws_access_key_id}}" required>
<label>{{ctx.Locale.Tr "repo.migrate.codecommit.aws_access_key_id"}}</label>
<input name="aws_access_key_id" required>
</div>
<div class="inline required field">
<label for="aws_secret_access_key">{{ctx.Locale.Tr "repo.migrate.codecommit.aws_secret_access_key"}}</label>
<input id="aws_secret_access_key" name="aws_secret_access_key" type="password" value="{{.aws_secret_access_key}}" required>
<label>{{ctx.Locale.Tr "repo.migrate.codecommit.aws_secret_access_key"}}</label>
<input name="aws_secret_access_key" type="password" required>
</div>
<div class="inline required field">
<label for="auth_username">{{ctx.Locale.Tr "repo.migrate.codecommit.https_git_credentials_username"}}</label>
<input id="auth_username" name="auth_username" value="{{.auth_username}}" required>
<label>{{ctx.Locale.Tr "repo.migrate.codecommit.https_git_credentials_username"}}</label>
<input name="auth_username" required>
</div>
<div class="inline required field">
<label for="auth_password">{{ctx.Locale.Tr "repo.migrate.codecommit.https_git_credentials_password"}}</label>
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}" required>
<label>{{ctx.Locale.Tr "repo.migrate.codecommit.https_git_credentials_password"}}</label>
<input name="auth_password" type="password" required>
</div>
{{if not .DisableNewPullMirrors}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_options"}}</label>
<div class="ui checkbox">
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
<input name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.migrate_options_mirror_helper"}}</label>
</div>
</div>
@@ -50,7 +48,7 @@
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_pullrequests"}}</label>
</div>
</div>
@@ -58,57 +56,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+2
View File
@@ -0,0 +1,2 @@
{{template "base/disable_form_autofill"}}
<input type="hidden" name="service" value="{{.ServiceType}}" data-global-init="initGitMigrateForm">
@@ -0,0 +1,51 @@
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" name="uid" value="{{ctx.RootData.ContextUser.ID}}" required>
<span class="text" title="{{ctx.RootData.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar ctx.RootData.ContextUser 28 "mini"}}
{{ctx.RootData.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{ctx.RootData.SignedUser.Name}}">
<div class="item" data-value="{{ctx.RootData.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar ctx.RootData.SignedUser 28 "mini"}}
{{ctx.RootData.SignedUser.ShortName 40}}
</div>
{{range $org := ctx.RootData.Orgs}}
<div class="item" data-value="{{$org.ID}}" title="{{$org.Name}}">
{{ctx.AvatarUtils.Avatar $org 28 "mini"}}
{{$org.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input name="repo_name" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if ctx.RootData.IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if ctx.RootData.private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea name="description" maxlength="2048"></textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
@@ -2,7 +2,7 @@
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_options"}}</label>
<div class="ui checkbox">
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
<input name="mirror" type="checkbox" {{if .mirror}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.migrate_options_mirror_helper"}}</label>
</div>
</div>
@@ -11,16 +11,16 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input id="lfs" name="lfs" type="checkbox" {{if .lfs}} checked{{end}}>
<input name="lfs" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_options_lfs"}}</label>
</div>
<span id="lfs_settings" class="tw-hidden">(<a id="lfs_settings_show" href="#">{{ctx.Locale.Tr "repo.settings.advanced_settings"}}</a>)</span>
</div>
<div id="lfs_endpoint" class="tw-hidden">
<span class="help">{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.description" "https://github.com/git-lfs/git-lfs/blob/main/docs/api/server-discovery.md#server-discovery"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.description.local"}}{{end}}</span>
<div class="inline field {{if .Err_LFSEndpoint}}error{{end}}">
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.label"}}</label>
<input name="lfs_endpoint" value="{{.lfs_endpoint}}" placeholder="{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.placeholder"}}">
<input name="lfs_endpoint" placeholder="{{ctx.Locale.Tr "repo.migrate_options_lfs_endpoint.placeholder"}}">
</div>
</div>
{{end}}
+11 -63
View File
@@ -6,82 +6,30 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_username">{{ctx.Locale.Tr "username"}}</label>
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "username"}}</label>
<input name="auth_username">
</div>
<div class="inline field">
<label for="auth_password">{{ctx.Locale.Tr "password"}}</label>
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
<label>{{ctx.Locale.Tr "password"}}</label>
<input name="auth_password" type="password">
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar .}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+17 -69
View File
@@ -6,34 +6,32 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_username">{{ctx.Locale.Tr "username"}}</label>
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "username"}}</label>
<input name="auth_username">
</div>
<div class="inline field">
<label for="auth_password">{{ctx.Locale.Tr "password"}}</label>
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
<label>{{ctx.Locale.Tr "password"}}</label>
<input name="auth_password" type="password">
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}>
<input name="wiki" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_wiki"}}</label>
</div>
</div>
@@ -43,29 +41,29 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_pullrequests"}}</label>
</div>
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}}checked{{end}}>
<input name="releases" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_releases"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
</div>
@@ -73,57 +71,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+15 -66
View File
@@ -6,30 +6,29 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_token">{{ctx.Locale.Tr "access_token"}}</label>
<input id="auth_token" name="auth_token" type="password" autocomplete="new-password" value="{{.auth_token}}" {{if not .auth_token}} data-need-clear="true" {{end}}>
<label>{{ctx.Locale.Tr "access_token"}}</label>
<input name="auth_token" type="password" autocomplete="new-password">
<a target="_blank" href="https://docs.gitea.com/development/api-usage">{{svg "octicon-question"}}</a>
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .wiki}} checked{{end}}>
<input name="wiki" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_wiki"}}</label>
</div>
</div>
@@ -39,29 +38,29 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}} checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}} checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}} checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_pullrequests"}}</label>
</div>
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}} checked{{end}}>
<input name="releases" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_releases"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}} checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
</div>
@@ -69,57 +68,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar .}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+15 -66
View File
@@ -6,33 +6,32 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}
</span>
</div>
<div class="inline field">
<label for="auth_token">{{ctx.Locale.Tr "access_token"}}</label>
<input id="auth_token" name="auth_token" type="password" autocomplete="new-password" value="{{.auth_token}}" {{if not .auth_token}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "access_token"}}</label>
<input name="auth_token" type="password" autocomplete="new-password">
<a target="_blank" href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">{{svg "octicon-question"}}</a>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.github_token_desc"}}
</span>
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}>
<input name="wiki" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_wiki"}}</label>
</div>
</div>
@@ -41,29 +40,29 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_pullrequests"}}</label>
</div>
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}}checked{{end}}>
<input name="releases" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_releases"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
</div>
@@ -71,57 +70,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+15 -66
View File
@@ -6,30 +6,29 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_token">{{ctx.Locale.Tr "access_token"}}</label>
<input id="auth_token" name="auth_token" type="password" autocomplete="new-password" value="{{.auth_token}}" {{if not .auth_token}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "access_token"}}</label>
<input name="auth_token" type="password" autocomplete="new-password">
<a target="_blank" href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html">{{svg "octicon-question"}}</a>
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}>
<input name="wiki" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_wiki"}}</label>
</div>
</div>
@@ -38,29 +37,29 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_merge_requests"}}</label>
</div>
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}}checked{{end}}>
<input name="releases" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_releases"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
</div>
@@ -68,57 +67,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+13 -77
View File
@@ -6,30 +6,29 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_token">{{ctx.Locale.Tr "access_token"}}</label>
<input id="auth_token" name="auth_token" type="password" autocomplete="new-password" value="{{.auth_token}}" {{if not .auth_token}} data-need-clear="true" {{end}}>
<label>{{ctx.Locale.Tr "access_token"}}</label>
<input name="auth_token" type="password" autocomplete="new-password">
<!-- <a target="_blank" href="https://docs.gitea.com/development/api-usage">{{svg "octicon-question"}}</a> -->
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="wiki" type="checkbox" {{if .wiki}} checked{{end}}>
<input name="wiki" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_wiki"}}</label>
</div>
</div>
@@ -39,89 +38,26 @@
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}} checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}} checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}} checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
</div>
{{/* Gogs do not support it
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.migrate_items_merge_requests"}}</label>
</div>
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.migrate_items_releases"}}</label>
</div>
</div>
*/}}
</div>
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar .}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}} checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+15 -67
View File
@@ -6,51 +6,49 @@
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<form class="ui form left-right-form" action="{{.Link}}" method="post">
{{template "base/disable_form_autofill"}}
<form class="ui form left-right-form form-fetch-action" action="{{.Link}}" method="post">
{{template "repo/migrate/common-init" (dict "ServiceType" .service)}}
<input id="service_type" type="hidden" name="service" value="{{.service}}">
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
<label for="clone_addr">{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
<div class="inline required field">
<label>{{ctx.Locale.Tr "repo.migrate.clone_address"}}</label>
<input name="clone_addr" autofocus required>
<span class="help">
{{ctx.Locale.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{ctx.Locale.Tr "repo.migrate.clone_local_path"}}{{end}}
</span>
</div>
<div class="inline field">
<label for="auth_username">{{ctx.Locale.Tr "username"}}</label>
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
<label>{{ctx.Locale.Tr "username"}}</label>
<input name="auth_username">
</div>
<div class="inline field">
<label for="auth_password">{{ctx.Locale.Tr "password"}}</label>
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
<label>{{ctx.Locale.Tr "password"}}</label>
<input name="auth_password" type="password">
</div>
{{template "repo/migrate/options" .}}
{{template "repo/migrate/common-options" .}}
<div id="migrate_items" class="inline field">
<label></label>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.migrate_items"}}</label>
<div class="ui checkbox">
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
<input name="milestones" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_milestones"}}</label>
</div>
<div class="ui checkbox">
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
<input name="labels" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_labels"}}</label>
</div>
</div>
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
<input name="issues" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_issues"}}</label>
</div>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
<input name="pull_requests" type="checkbox">
<label>{{ctx.Locale.Tr "repo.migrate_items_pullrequests"}}</label>
</div>
</div>
@@ -58,57 +56,7 @@
<div class="divider"></div>
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown ellipsis-text-items">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text" title="{{.ContextUser.Name}}">
{{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}}
{{.ContextUser.ShortName 40}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu" title="{{.SignedUser.Name}}">
<div class="item" data-value="{{.SignedUser.ID}}">
{{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}}
{{.SignedUser.ShortName 40}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
{{ctx.AvatarUtils.Avatar . 28 "mini"}}
{{.ShortName 40}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required maxlength="100">
</div>
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.visibility"}}</label>
<div class="ui checkbox">
{{if .IsForcedPrivate}}
<input name="private" type="checkbox" checked disabled>
<label>{{ctx.Locale.Tr "repo.visibility_helper_forced"}}</label>
{{else}}
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.visibility_helper"}}</label>
{{end}}
</div>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
<textarea id="description" name="description" maxlength="2048">{{.description}}</textarea>
</div>
<div class="inline field">
<label></label>
<button type="submit" class="ui primary button">
{{ctx.Locale.Tr "repo.migrate_repo"}}
</button>
</div>
{{template "repo/migrate/common-migrated-repo"}}
</form>
</div>
</div>
+2 -2
View File
@@ -161,11 +161,11 @@
<div class="tw-p-1">
<div class="inline field">
<label for="mirror_username">{{ctx.Locale.Tr "username"}}</label>
<input id="mirror_username" name="mirror_username" value="{{$address.Username}}" {{if not .mirror_username}}data-need-clear="true"{{end}}>
<input id="mirror_username" name="mirror_username" value="{{$address.Username}}">
</div>
<div class="inline field">
<label for="mirror_password">{{ctx.Locale.Tr "password"}}</label>
<input id="mirror_password" name="mirror_password" type="password" placeholder="{{if $address.Password}}{{ctx.Locale.Tr "repo.mirror_password_placeholder"}}{{else}}{{ctx.Locale.Tr "repo.mirror_password_blank_placeholder"}}{{end}}" value="" {{if not .mirror_password}}data-need-clear="true"{{end}} autocomplete="off">
<input id="mirror_password" name="mirror_password" type="password" placeholder="{{if $address.Password}}{{ctx.Locale.Tr "repo.mirror_password_placeholder"}}{{else}}{{ctx.Locale.Tr "repo.mirror_password_blank_placeholder"}}{{end}}" value="" autocomplete="off">
</div>
<p class="help">{{ctx.Locale.Tr "repo.mirror_password_help"}}</p>
</div>
+2 -2
View File
@@ -94,9 +94,9 @@ func TestMigrateGiteaForm(t *testing.T) {
"description": "",
"uid": strconv.FormatInt(repoOwner.ID, 10),
})
resp = session.MakeRequest(t, req, http.StatusSeeOther)
resp = session.MakeRequest(t, req, http.StatusOK)
// Step 5: a redirection displays the migrated repository
loc := resp.Header().Get("Location")
loc := *test.ParseJSONRedirect(resp.Body.Bytes()).Redirect
assert.Equal(t, fmt.Sprintf("/%s/%s", ownerName, migratedRepoName), loc)
// Step 6: check the repo was created
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: migratedRepoName})
+5 -3
View File
@@ -10,6 +10,7 @@ import (
"testing"
"gitea.dev/modules/structs"
"gitea.dev/modules/test"
"gitea.dev/tests"
"github.com/stretchr/testify/assert"
@@ -23,7 +24,7 @@ func testRepoMigrate(t testing.TB, session *TestSession, cloneAddr, repoName str
link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action")
assert.True(t, exists, "The template has changed")
uid, exists := htmlDoc.doc.Find("#uid").Attr("value")
uid, exists := htmlDoc.doc.Find(`input[name="uid"]`).Attr("value")
assert.True(t, exists, "The template has changed")
req = NewRequestWithValues(t, "POST", link, map[string]string{
@@ -32,7 +33,7 @@ func testRepoMigrate(t testing.TB, session *TestSession, cloneAddr, repoName str
"repo_name": repoName,
"service": fmt.Sprintf("%d", structs.PlainGitService),
})
resp = session.MakeRequest(t, req, http.StatusSeeOther)
resp = session.MakeRequest(t, req, http.StatusOK)
return resp
}
@@ -40,5 +41,6 @@ func testRepoMigrate(t testing.TB, session *TestSession, cloneAddr, repoName str
func TestRepoMigrate(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
testRepoMigrate(t, session, "https://github.com/go-gitea/test_repo.git", "git")
resp := testRepoMigrate(t, session, "https://github.com/go-gitea/test_repo.git", "git")
assert.Equal(t, "/user2/git", *test.ParseJSONRedirect(resp.Body.Bytes()).Redirect)
}
+45 -50
View File
@@ -1,33 +1,35 @@
import {hideElem, showElem, toggleElem} from '../utils/dom.ts';
import {sanitizeRepoName} from './repo-common.ts';
import {registerGlobalInitFunc} from '../modules/observer.ts';
const service = document.querySelector<HTMLInputElement>('#service_type');
const user = document.querySelector<HTMLInputElement>('#auth_username');
const pass = document.querySelector<HTMLInputElement>('#auth_password');
const token = document.querySelector<HTMLInputElement>('#auth_token');
const mirror = document.querySelector<HTMLInputElement>('#mirror');
const lfs = document.querySelector<HTMLInputElement>('#lfs');
const lfsSettings = document.querySelector<HTMLElement>('#lfs_settings')!;
const lfsEndpoint = document.querySelector<HTMLElement>('#lfs_endpoint')!;
const items = document.querySelectorAll<HTMLInputElement>('#migrate_items input[type=checkbox]');
export const initRepoMigration = () => registerGlobalInitFunc('initGitMigrateForm', (el: HTMLElement) => {
const elForm = el.closest('form')!;
const service = elForm.querySelector<HTMLInputElement>('input[name="service"]')!;
const user = elForm.querySelector<HTMLInputElement>('input[name="auth_username"]');
const pass = elForm.querySelector<HTMLInputElement>('input[name="auth_password"]');
const token = elForm.querySelector<HTMLInputElement>('input[name="auth_token"]');
const mirror = elForm.querySelector<HTMLInputElement>('input[name="mirror"]');
const lfs = elForm.querySelector<HTMLInputElement>('input[name="lfs"]');
const lfsSettings = elForm.querySelector<HTMLElement>('#lfs_settings');
const lfsEndpoint = elForm.querySelector<HTMLElement>('#lfs_endpoint');
const items = elForm.querySelectorAll<HTMLInputElement>('#migrate_items input[type=checkbox]');
export function initRepoMigration() {
checkAuth();
checkItems(Number(service.value) !== 1); // 1 = plain git service
setLFSSettingsVisibility();
user?.addEventListener('input', () => {checkItems(false)});
pass?.addEventListener('input', () => {checkItems(false)});
token?.addEventListener('input', () => {checkItems(true)});
mirror?.addEventListener('change', () => {checkItems(true)});
document.querySelector('#lfs_settings_show')?.addEventListener('click', (e) => {
user?.addEventListener('input', () => checkItems(false));
pass?.addEventListener('input', () => checkItems(false));
token?.addEventListener('input', () => checkItems(true));
mirror?.addEventListener('change', () => checkItems(true));
elForm.querySelector('#lfs_settings_show')?.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
showElem(lfsEndpoint);
showElem(lfsEndpoint!);
});
lfs?.addEventListener('change', setLFSSettingsVisibility);
const elCloneAddr = document.querySelector<HTMLInputElement>('#clone_addr');
const elRepoName = document.querySelector<HTMLInputElement>('#repo_name');
const elCloneAddr = elForm.querySelector<HTMLInputElement>('input[name="clone_addr"]');
const elRepoName = elForm.querySelector<HTMLInputElement>('input[name="repo_name"]');
if (elCloneAddr && elRepoName) {
let repoNameChanged = false;
elRepoName.addEventListener('input', () => {repoNameChanged = true});
@@ -43,38 +45,31 @@ export function initRepoMigration() {
elRepoName.value = sanitizeRepoName(repoNameFromUrl);
});
}
}
function checkAuth() {
if (!service) return;
const serviceType = Number(service.value);
checkItems(serviceType !== 1);
}
function checkItems(tokenAuth: boolean) {
let enableItems: boolean;
if (tokenAuth) {
enableItems = token?.value !== '';
} else {
enableItems = user?.value !== '' || pass?.value !== '';
}
if (enableItems && Number(service?.value) > 1) {
if (mirror?.checked) {
for (const item of items) {
item.disabled = item.name !== 'wiki';
}
return;
function checkItems(tokenAuth: boolean) {
let enableItems: boolean;
if (tokenAuth) {
enableItems = token?.value !== '';
} else {
enableItems = user?.value !== '' || pass?.value !== '';
}
if (enableItems && Number(service?.value) > 1) {
if (mirror?.checked) {
for (const item of items) {
item.disabled = item.name !== 'wiki';
}
return;
}
for (const item of items) item.disabled = false;
} else {
for (const item of items) item.disabled = true;
}
for (const item of items) item.disabled = false;
} else {
for (const item of items) item.disabled = true;
}
}
function setLFSSettingsVisibility() {
if (!lfs) return;
const visible = lfs.checked;
toggleElem(lfsSettings, visible);
hideElem(lfsEndpoint);
}
function setLFSSettingsVisibility() {
if (!lfs) return;
const visible = lfs.checked;
toggleElem(lfsSettings!, visible);
hideElem(lfsEndpoint!);
}
});