2014-02-20 06:45:43 +04:00
// Copyright 2014 The Gogs 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 repo
import (
2014-07-26 10:28:04 +04:00
"fmt"
2014-07-26 08:24:27 +04:00
"os"
2014-03-22 21:50:50 +04:00
"path"
2014-07-26 10:28:04 +04:00
"strings"
2014-03-22 21:50:50 +04:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
2019-03-27 12:33:00 +03:00
"code.gitea.io/gitea/modules/git"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/log"
2019-05-07 04:12:51 +03:00
"code.gitea.io/gitea/modules/migrations"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/setting"
2019-10-13 16:23:14 +03:00
"code.gitea.io/gitea/modules/task"
2017-12-04 04:48:03 +03:00
"code.gitea.io/gitea/modules/util"
2019-10-26 09:54:11 +03:00
repo_service "code.gitea.io/gitea/services/repository"
2019-03-27 12:33:00 +03:00
2019-08-23 19:40:30 +03:00
"github.com/unknwon/com"
2014-02-20 06:45:43 +04:00
)
2014-06-23 07:11:12 +04:00
const (
2016-11-24 10:04:31 +03:00
tplCreate base . TplName = "repo/create"
tplMigrate base . TplName = "repo/migrate"
2014-06-23 07:11:12 +04:00
)
2019-01-18 03:01:04 +03:00
// MustBeNotEmpty render when a repo is a empty git dir
func MustBeNotEmpty ( ctx * context . Context ) {
if ctx . Repo . Repository . IsEmpty {
ctx . NotFound ( "MustBeNotEmpty" , nil )
2016-01-07 06:07:17 +03:00
}
}
2017-10-30 05:04:25 +03:00
// MustBeEditable check that repo can be edited
func MustBeEditable ( ctx * context . Context ) {
if ! ctx . Repo . Repository . CanEnableEditor ( ) || ctx . Repo . IsViewCommit {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "" , nil )
2017-10-30 05:04:25 +03:00
return
}
}
// MustBeAbleToUpload check that repo can be uploaded to
func MustBeAbleToUpload ( ctx * context . Context ) {
if ! setting . Repository . Upload . Enabled {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "" , nil )
2017-10-30 05:04:25 +03:00
}
}
2016-03-11 19:56:52 +03:00
func checkContextUser ( ctx * context . Context , uid int64 ) * models . User {
2019-11-20 14:27:49 +03:00
orgs , err := models . GetOrgsCanCreateRepoByUserID ( ctx . User . ID )
2015-09-07 20:58:23 +03:00
if err != nil {
2019-11-20 14:27:49 +03:00
ctx . ServerError ( "GetOrgsCanCreateRepoByUserID" , err )
2015-08-28 13:33:09 +03:00
return nil
}
2015-09-07 20:58:23 +03:00
ctx . Data [ "Orgs" ] = orgs
2015-08-28 13:33:09 +03:00
2015-07-19 12:11:16 +03:00
// Not equal means current user is an organization.
2016-07-23 20:08:22 +03:00
if uid == ctx . User . ID || uid == 0 {
2015-07-19 12:11:16 +03:00
return ctx . User
}
2015-08-08 17:43:14 +03:00
org , err := models . GetUserByID ( uid )
2015-08-05 06:14:17 +03:00
if models . IsErrUserNotExist ( err ) {
2015-07-19 12:11:16 +03:00
return ctx . User
}
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetUserByID" , fmt . Errorf ( "[%d]: %v" , uid , err ) )
2015-07-19 12:11:16 +03:00
return nil
2015-08-28 13:33:09 +03:00
}
// Check ownership of organization.
2017-12-21 10:43:26 +03:00
if ! org . IsOrganization ( ) {
2015-07-19 12:11:16 +03:00
ctx . Error ( 403 )
return nil
2014-11-06 07:30:04 +03:00
}
2017-12-21 10:43:26 +03:00
if ! ctx . User . IsAdmin {
2019-11-20 14:27:49 +03:00
canCreate , err := org . CanCreateOrgRepo ( ctx . User . ID )
2017-12-21 10:43:26 +03:00
if err != nil {
2019-11-20 14:27:49 +03:00
ctx . ServerError ( "CanCreateOrgRepo" , err )
2017-12-21 10:43:26 +03:00
return nil
2019-11-20 14:27:49 +03:00
} else if ! canCreate {
2017-12-21 10:43:26 +03:00
ctx . Error ( 403 )
return nil
}
}
2015-07-19 12:11:16 +03:00
return org
2014-11-06 07:30:04 +03:00
}
2017-12-20 15:59:56 +03:00
func getRepoPrivate ( ctx * context . Context ) bool {
switch strings . ToLower ( setting . Repository . DefaultPrivate ) {
case setting . RepoCreatingLastUserVisibility :
return ctx . User . LastRepoVisibility
case setting . RepoCreatingPrivate :
return true
case setting . RepoCreatingPublic :
return false
default :
return ctx . User . LastRepoVisibility
}
}
2016-11-24 10:04:31 +03:00
// Create render creating repository page
2016-03-11 19:56:52 +03:00
func Create ( ctx * context . Context ) {
2017-05-20 11:47:48 +03:00
if ! ctx . User . CanCreateRepo ( ) {
2017-05-24 09:01:02 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.form.reach_limit_of_creation" , ctx . User . MaxCreationLimit ( ) ) , tplCreate , nil )
2017-05-20 11:47:48 +03:00
}
2014-07-26 08:24:27 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "new_repo" )
// Give default value for template to render.
ctx . Data [ "Gitignores" ] = models . Gitignores
2019-09-08 11:28:40 +03:00
ctx . Data [ "LabelTemplates" ] = models . LabelTemplates
2014-03-19 21:14:56 +04:00
ctx . Data [ "Licenses" ] = models . Licenses
2015-08-28 11:44:04 +03:00
ctx . Data [ "Readmes" ] = models . Readmes
ctx . Data [ "readme" ] = "Default"
2017-12-20 15:59:56 +03:00
ctx . Data [ "private" ] = getRepoPrivate ( ctx )
2015-10-25 11:26:26 +03:00
ctx . Data [ "IsForcedPrivate" ] = setting . Repository . ForcePrivate
2014-06-25 11:55:59 +04:00
2015-07-19 12:11:16 +03:00
ctxUser := checkContextUser ( ctx , ctx . QueryInt64 ( "org" ) )
if ctx . Written ( ) {
2014-11-06 07:30:04 +03:00
return
2014-07-26 10:28:04 +04:00
}
2014-06-28 23:43:25 +04:00
ctx . Data [ "ContextUser" ] = ctxUser
2019-11-11 18:15:29 +03:00
ctx . Data [ "repo_template_name" ] = ctx . Tr ( "repo.template_select" )
templateID := ctx . QueryInt64 ( "template_id" )
if templateID > 0 {
templateRepo , err := models . GetRepositoryByID ( templateID )
if err == nil && templateRepo . CheckUnitUser ( ctxUser . ID , ctxUser . IsAdmin , models . UnitTypeCode ) {
ctx . Data [ "repo_template" ] = templateID
ctx . Data [ "repo_template_name" ] = templateRepo . Name
}
}
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplCreate )
2014-04-11 02:09:57 +04:00
}
2014-03-08 01:05:18 +04:00
2016-03-11 19:56:52 +03:00
func handleCreateError ( ctx * context . Context , owner * models . User , err error , name string , tpl base . TplName , form interface { } ) {
2015-08-28 13:33:09 +03:00
switch {
2015-12-10 20:37:53 +03:00
case models . IsErrReachLimitOfRepo ( err ) :
2017-05-24 03:27:08 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.form.reach_limit_of_creation" , owner . MaxCreationLimit ( ) ) , tpl , form )
2015-08-28 13:33:09 +03:00
case models . IsErrRepoAlreadyExist ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "form.repo_name_been_taken" ) , tpl , form )
case models . IsErrNameReserved ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_reserved" , err . ( models . ErrNameReserved ) . Name ) , tpl , form )
case models . IsErrNamePatternNotAllowed ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_pattern_not_allowed" , err . ( models . ErrNamePatternNotAllowed ) . Pattern ) , tpl , form )
default :
2018-01-11 00:34:17 +03:00
ctx . ServerError ( name , err )
2015-08-28 13:33:09 +03:00
}
}
2016-11-24 10:04:31 +03:00
// CreatePost response for creating repository
2016-03-11 19:56:52 +03:00
func CreatePost ( ctx * context . Context , form auth . CreateRepoForm ) {
2014-07-26 08:24:27 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "new_repo" )
ctx . Data [ "Gitignores" ] = models . Gitignores
2019-09-08 11:28:40 +03:00
ctx . Data [ "LabelTemplates" ] = models . LabelTemplates
2014-04-11 02:09:57 +04:00
ctx . Data [ "Licenses" ] = models . Licenses
2015-08-28 11:44:04 +03:00
ctx . Data [ "Readmes" ] = models . Readmes
2014-02-20 06:45:43 +04:00
2016-11-27 09:03:59 +03:00
ctxUser := checkContextUser ( ctx , form . UID )
2015-07-19 12:11:16 +03:00
if ctx . Written ( ) {
return
2014-07-26 10:28:04 +04:00
}
2014-07-26 08:24:27 +04:00
ctx . Data [ "ContextUser" ] = ctxUser
2014-03-23 00:00:46 +04:00
if ctx . HasError ( ) {
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplCreate )
2014-03-23 00:00:46 +04:00
return
}
2019-11-11 18:15:29 +03:00
var err error
if form . RepoTemplate > 0 {
opts := models . GenerateRepoOptions {
Name : form . RepoName ,
Description : form . Description ,
Private : form . Private ,
GitContent : form . GitContent ,
Topics : form . Topics ,
2019-11-24 20:57:52 +03:00
GitHooks : form . GitHooks ,
Webhooks : form . Webhooks ,
2019-11-25 08:17:51 +03:00
Avatar : form . Avatar ,
IssueLabels : form . Labels ,
2019-11-11 18:15:29 +03:00
}
if ! opts . IsValid ( ) {
ctx . RenderWithErr ( ctx . Tr ( "repo.template.one_item" ) , tplCreate , form )
return
}
templateRepo := getRepository ( ctx , form . RepoTemplate )
if ctx . Written ( ) {
return
}
if ! templateRepo . IsTemplate {
ctx . RenderWithErr ( ctx . Tr ( "repo.template.invalid" ) , tplCreate , form )
return
}
repo , err := repo_service . GenerateRepository ( ctx . User , ctxUser , templateRepo , opts )
if err == nil {
log . Trace ( "Repository generated [%d]: %s/%s" , repo . ID , ctxUser . Name , repo . Name )
ctx . Redirect ( setting . AppSubURL + "/" + ctxUser . Name + "/" + repo . Name )
return
}
} else {
repo , err := repo_service . CreateRepository ( ctx . User , ctxUser , models . CreateRepoOptions {
Name : form . RepoName ,
Description : form . Description ,
Gitignores : form . Gitignores ,
IssueLabels : form . IssueLabels ,
License : form . License ,
Readme : form . Readme ,
IsPrivate : form . Private || setting . Repository . ForcePrivate ,
AutoInit : form . AutoInit ,
} )
if err == nil {
log . Trace ( "Repository created [%d]: %s/%s" , repo . ID , ctxUser . Name , repo . Name )
ctx . Redirect ( setting . AppSubURL + "/" + ctxUser . Name + "/" + repo . Name )
return
}
2014-03-10 04:06:29 +04:00
}
2014-04-13 04:35:35 +04:00
2016-11-24 10:04:31 +03:00
handleCreateError ( ctx , ctxUser , err , "CreatePost" , tplCreate , & form )
2014-04-11 02:09:57 +04:00
}
2014-04-09 17:28:00 +04:00
2016-11-24 10:04:31 +03:00
// Migrate render migration of repository page
2016-03-11 19:56:52 +03:00
func Migrate ( ctx * context . Context ) {
2014-08-01 08:06:19 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "new_migrate" )
2017-12-20 15:59:56 +03:00
ctx . Data [ "private" ] = getRepoPrivate ( ctx )
2015-10-25 11:26:26 +03:00
ctx . Data [ "IsForcedPrivate" ] = setting . Repository . ForcePrivate
2015-12-09 19:24:56 +03:00
ctx . Data [ "mirror" ] = ctx . Query ( "mirror" ) == "1"
2019-05-07 04:12:51 +03:00
ctx . Data [ "wiki" ] = ctx . Query ( "wiki" ) == "1"
ctx . Data [ "milestones" ] = ctx . Query ( "milestones" ) == "1"
ctx . Data [ "labels" ] = ctx . Query ( "labels" ) == "1"
ctx . Data [ "issues" ] = ctx . Query ( "issues" ) == "1"
ctx . Data [ "pull_requests" ] = ctx . Query ( "pull_requests" ) == "1"
ctx . Data [ "releases" ] = ctx . Query ( "releases" ) == "1"
2017-03-16 14:33:22 +03:00
ctx . Data [ "LFSActive" ] = setting . LFS . StartServer
2014-08-01 08:06:19 +04:00
2015-07-19 12:11:16 +03:00
ctxUser := checkContextUser ( ctx , ctx . QueryInt64 ( "org" ) )
if ctx . Written ( ) {
2014-11-06 07:30:04 +03:00
return
2014-08-01 08:06:19 +04:00
}
ctx . Data [ "ContextUser" ] = ctxUser
2014-07-26 08:24:27 +04:00
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplMigrate )
2014-07-26 10:28:04 +04:00
}
2014-07-26 08:24:27 +04:00
2019-10-13 16:23:14 +03:00
func handleMigrateError ( ctx * context . Context , owner * models . User , err error , name string , tpl base . TplName , form * auth . MigrateRepoForm ) {
switch {
case migrations . IsRateLimitError ( err ) :
ctx . RenderWithErr ( ctx . Tr ( "form.visit_rate_limit" ) , tpl , form )
case migrations . IsTwoFactorAuthError ( err ) :
ctx . RenderWithErr ( ctx . Tr ( "form.2fa_auth_required" ) , tpl , form )
case models . IsErrReachLimitOfRepo ( err ) :
ctx . RenderWithErr ( ctx . Tr ( "repo.form.reach_limit_of_creation" , owner . MaxCreationLimit ( ) ) , tpl , form )
case models . IsErrRepoAlreadyExist ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "form.repo_name_been_taken" ) , tpl , form )
case models . IsErrNameReserved ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_reserved" , err . ( models . ErrNameReserved ) . Name ) , tpl , form )
case models . IsErrNamePatternNotAllowed ( err ) :
ctx . Data [ "Err_RepoName" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_pattern_not_allowed" , err . ( models . ErrNamePatternNotAllowed ) . Pattern ) , tpl , form )
default :
remoteAddr , _ := form . ParseRemoteAddr ( owner )
err = util . URLSanitizedError ( err , remoteAddr )
if strings . Contains ( err . Error ( ) , "Authentication failed" ) ||
strings . Contains ( err . Error ( ) , "Bad credentials" ) ||
strings . Contains ( err . Error ( ) , "could not read Username" ) {
ctx . Data [ "Err_Auth" ] = true
ctx . RenderWithErr ( ctx . Tr ( "form.auth_failed" , err . Error ( ) ) , tpl , form )
} else if strings . Contains ( err . Error ( ) , "fatal:" ) {
ctx . Data [ "Err_CloneAddr" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.migrate.failed" , err . Error ( ) ) , tpl , form )
} else {
ctx . ServerError ( name , err )
}
}
}
2016-11-24 10:04:31 +03:00
// MigratePost response for migrating from external git repository
2016-03-11 19:56:52 +03:00
func MigratePost ( ctx * context . Context , form auth . MigrateRepoForm ) {
2014-08-01 08:06:19 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "new_migrate" )
2016-11-27 09:03:59 +03:00
ctxUser := checkContextUser ( ctx , form . UID )
2015-07-19 12:11:16 +03:00
if ctx . Written ( ) {
return
2014-08-01 08:06:19 +04:00
}
ctx . Data [ "ContextUser" ] = ctxUser
2014-07-26 08:24:27 +04:00
2014-07-26 10:28:04 +04:00
if ctx . HasError ( ) {
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplMigrate )
2014-07-26 10:28:04 +04:00
return
}
2014-07-26 08:24:27 +04:00
2015-11-04 02:40:52 +03:00
remoteAddr , err := form . ParseRemoteAddr ( ctx . User )
if err != nil {
if models . IsErrInvalidCloneAddr ( err ) {
2015-02-22 17:49:25 +03:00
ctx . Data [ "Err_CloneAddr" ] = true
2015-11-04 02:40:52 +03:00
addrErr := err . ( models . ErrInvalidCloneAddr )
switch {
case addrErr . IsURLError :
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.url_error" ) , tplMigrate , & form )
2015-11-04 02:40:52 +03:00
case addrErr . IsPermissionDenied :
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.migrate.permission_denied" ) , tplMigrate , & form )
2015-11-04 02:40:52 +03:00
case addrErr . IsInvalidPath :
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.migrate.invalid_local_path" ) , tplMigrate , & form )
2015-11-04 02:40:52 +03:00
default :
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "Unknown error" , err )
2015-11-04 02:40:52 +03:00
}
} else {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "ParseRemoteAddr" , err )
2015-02-22 17:49:25 +03:00
}
2015-01-02 13:14:11 +03:00
return
}
2019-05-07 04:12:51 +03:00
var opts = migrations . MigrateOptions {
2019-11-20 21:01:09 +03:00
OriginalURL : form . CloneAddr ,
2019-10-13 16:23:14 +03:00
CloneAddr : remoteAddr ,
RepoName : form . RepoName ,
2019-05-07 04:12:51 +03:00
Description : form . Description ,
Private : form . Private || setting . Repository . ForcePrivate ,
Mirror : form . Mirror ,
AuthUsername : form . AuthUsername ,
AuthPassword : form . AuthPassword ,
Wiki : form . Wiki ,
Issues : form . Issues ,
Milestones : form . Milestones ,
Labels : form . Labels ,
Comments : true ,
PullRequests : form . PullRequests ,
Releases : form . Releases ,
}
if opts . Mirror {
opts . Issues = false
opts . Milestones = false
opts . Labels = false
opts . Comments = false
opts . PullRequests = false
opts . Releases = false
}
2019-10-13 16:23:14 +03:00
err = models . CheckCreateRepository ( ctx . User , ctxUser , opts . RepoName )
if err != nil {
handleMigrateError ( ctx , ctxUser , err , "MigratePost" , tplMigrate , & form )
2014-07-26 10:28:04 +04:00
return
}
2014-07-26 08:24:27 +04:00
2019-10-13 16:23:14 +03:00
err = task . MigrateRepository ( ctx . User , ctxUser , opts )
if err == nil {
ctx . Redirect ( setting . AppSubURL + "/" + ctxUser . Name + "/" + opts . RepoName )
return
2014-07-26 10:28:04 +04:00
}
2019-10-13 16:23:14 +03:00
handleMigrateError ( ctx , ctxUser , err , "MigratePost" , tplMigrate , & form )
2014-07-26 10:28:04 +04:00
}
2014-07-26 08:24:27 +04:00
2016-11-24 10:04:31 +03:00
// Action response for actions to a repository
2016-03-11 19:56:52 +03:00
func Action ( ctx * context . Context ) {
2014-08-11 07:11:18 +04:00
var err error
switch ctx . Params ( ":action" ) {
case "watch" :
2016-07-23 20:08:22 +03:00
err = models . WatchRepo ( ctx . User . ID , ctx . Repo . Repository . ID , true )
2014-08-11 07:11:18 +04:00
case "unwatch" :
2016-07-23 20:08:22 +03:00
err = models . WatchRepo ( ctx . User . ID , ctx . Repo . Repository . ID , false )
2014-08-11 07:11:18 +04:00
case "star" :
2016-07-23 20:08:22 +03:00
err = models . StarRepo ( ctx . User . ID , ctx . Repo . Repository . ID , true )
2014-08-11 07:11:18 +04:00
case "unstar" :
2016-07-23 20:08:22 +03:00
err = models . StarRepo ( ctx . User . ID , ctx . Repo . Repository . ID , false )
2016-01-07 06:07:17 +03:00
case "desc" : // FIXME: this is not used
2015-02-16 13:51:56 +03:00
if ! ctx . Repo . IsOwner ( ) {
2014-08-11 07:11:18 +04:00
ctx . Error ( 404 )
return
}
ctx . Repo . Repository . Description = ctx . Query ( "desc" )
ctx . Repo . Repository . Website = ctx . Query ( "site" )
2015-03-16 11:52:11 +03:00
err = models . UpdateRepository ( ctx . Repo . Repository , false )
2014-08-11 07:11:18 +04:00
}
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( fmt . Sprintf ( "Action (%s)" , ctx . Params ( ":action" ) ) , err )
2014-08-11 07:11:18 +04:00
return
}
2015-07-23 23:50:05 +03:00
2018-03-16 00:13:34 +03:00
ctx . RedirectToFirst ( ctx . Query ( "redirect_to" ) , ctx . Repo . RepoLink )
2014-08-11 07:11:18 +04:00
}
2014-07-26 08:24:27 +04:00
2019-01-07 01:37:30 +03:00
// RedirectDownload return a file based on the following infos:
func RedirectDownload ( ctx * context . Context ) {
var (
vTag = ctx . Params ( "vTag" )
fileName = ctx . Params ( "fileName" )
)
tagNames := [ ] string { vTag }
curRepo := ctx . Repo . Repository
releases , err := models . GetReleasesByRepoIDAndNames ( curRepo . ID , tagNames )
if err != nil {
if models . IsErrAttachmentNotExist ( err ) {
ctx . Error ( 404 )
return
}
ctx . ServerError ( "RedirectDownload" , err )
return
}
if len ( releases ) == 1 {
release := releases [ 0 ]
att , err := models . GetAttachmentByReleaseIDFileName ( release . ID , fileName )
if err != nil {
ctx . Error ( 404 )
return
}
if att != nil {
2019-12-29 02:33:13 +03:00
ctx . Redirect ( att . DownloadURL ( ) )
2019-01-07 01:37:30 +03:00
return
}
}
ctx . Error ( 404 )
}
2016-11-24 10:04:31 +03:00
// Download download an archive of a repository
2016-03-11 19:56:52 +03:00
func Download ( ctx * context . Context ) {
2014-09-25 01:43:33 +04:00
var (
uri = ctx . Params ( "*" )
refName string
ext string
archivePath string
2014-11-02 08:18:37 +03:00
archiveType git . ArchiveType
2014-09-25 01:43:33 +04:00
)
switch {
case strings . HasSuffix ( uri , ".zip" ) :
ext = ".zip"
2014-07-26 08:24:27 +04:00
archivePath = path . Join ( ctx . Repo . GitRepo . Path , "archives/zip" )
2014-11-02 08:18:37 +03:00
archiveType = git . ZIP
2014-09-25 01:43:33 +04:00
case strings . HasSuffix ( uri , ".tar.gz" ) :
ext = ".tar.gz"
2014-07-26 08:24:27 +04:00
archivePath = path . Join ( ctx . Repo . GitRepo . Path , "archives/targz" )
2014-11-02 08:18:37 +03:00
archiveType = git . TARGZ
2014-07-26 08:24:27 +04:00
default :
2015-12-14 02:20:39 +03:00
log . Trace ( "Unknown format: %s" , uri )
2014-07-26 08:24:27 +04:00
ctx . Error ( 404 )
2014-06-25 13:35:23 +04:00
return
}
2014-09-25 01:43:33 +04:00
refName = strings . TrimSuffix ( uri , ext )
2014-06-25 13:35:23 +04:00
2014-07-26 08:24:27 +04:00
if ! com . IsDir ( archivePath ) {
if err := os . MkdirAll ( archivePath , os . ModePerm ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "Download -> os.MkdirAll(archivePath)" , err )
2014-06-25 13:35:23 +04:00
return
}
}
2014-09-25 01:43:33 +04:00
// Get corresponding commit.
var (
commit * git . Commit
err error
)
gitRepo := ctx . Repo . GitRepo
if gitRepo . IsBranchExist ( refName ) {
2015-12-10 04:46:05 +03:00
commit , err = gitRepo . GetBranchCommit ( refName )
2014-09-25 01:43:33 +04:00
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetBranchCommit" , err )
2014-09-25 01:43:33 +04:00
return
}
} else if gitRepo . IsTagExist ( refName ) {
2015-12-10 04:46:05 +03:00
commit , err = gitRepo . GetTagCommit ( refName )
2014-09-25 01:43:33 +04:00
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetTagCommit" , err )
2014-09-25 01:43:33 +04:00
return
}
2016-11-24 00:06:56 +03:00
} else if len ( refName ) >= 4 && len ( refName ) <= 40 {
2014-09-25 01:43:33 +04:00
commit , err = gitRepo . GetCommit ( refName )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "GetCommit" , nil )
2014-09-25 01:43:33 +04:00
return
}
} else {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "Download" , nil )
2014-09-25 01:43:33 +04:00
return
}
2015-11-04 06:49:06 +03:00
archivePath = path . Join ( archivePath , base . ShortSha ( commit . ID . String ( ) ) + ext )
2014-07-26 08:24:27 +04:00
if ! com . IsFile ( archivePath ) {
2014-11-02 08:18:37 +03:00
if err := commit . CreateArchive ( archivePath , archiveType ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "Download -> CreateArchive " + archivePath , err )
2014-03-22 21:50:50 +04:00
return
}
}
2016-01-07 23:28:38 +03:00
ctx . ServeFile ( archivePath , ctx . Repo . Repository . Name + "-" + refName + ext )
2014-03-22 21:50:50 +04:00
}
2019-10-13 16:23:14 +03:00
// Status returns repository's status
func Status ( ctx * context . Context ) {
task , err := models . GetMigratingTask ( ctx . Repo . Repository . ID )
if err != nil {
ctx . JSON ( 500 , map [ string ] interface { } {
"err" : err ,
} )
return
}
ctx . JSON ( 200 , map [ string ] interface { } {
"status" : ctx . Repo . Repository . Status ,
"err" : task . Errors ,
} )
}