From 6ec07a6bd7d1f88f0685efa4e1b62a32cbb25e43 Mon Sep 17 00:00:00 2001
From: Phil Hopper <philhopper@sibertec.com>
Date: Tue, 6 Jun 2017 05:09:54 -0400
Subject: [PATCH] Make `LocalCopyPath` a setting instead of a hard-coded path
 (#1881)

---
 conf/app.ini               |  4 ++++
 models/repo.go             |  5 ++++-
 models/repo_test.go        | 22 ++++++++++++++++++++++
 modules/setting/setting.go | 14 ++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/conf/app.ini b/conf/app.ini
index 3eb46465cf..29836748d6 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -32,6 +32,10 @@ LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd,
 ; Separate values by commas. Preview tab in edit mode won't show if the file extension doesn't match
 PREVIEWABLE_FILE_MODES = markdown
 
+[repository.local]
+; Path for uploads. Defaults to `tmp/local-repo`
+LOCAL_COPY_PATH = tmp/local-repo
+
 [repository.upload]
 ; Whether repository file uploads are enabled. Defaults to `true`
 ENABLED = true
diff --git a/models/repo.go b/models/repo.go
index 7aaeb6e0e7..f92f753b92 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -676,7 +676,10 @@ func (repo *Repository) DescriptionHTML() template.HTML {
 
 // LocalCopyPath returns the local repository copy path
 func (repo *Repository) LocalCopyPath() string {
-	return path.Join(setting.AppDataPath, "tmp/local-repo", com.ToStr(repo.ID))
+	if filepath.IsAbs(setting.Repository.Local.LocalCopyPath) {
+		return path.Join(setting.Repository.Local.LocalCopyPath, com.ToStr(repo.ID))
+	}
+	return path.Join(setting.AppDataPath, setting.Repository.Local.LocalCopyPath, com.ToStr(repo.ID))
 }
 
 // UpdateLocalCopyBranch pulls latest changes of given branch from repoPath to localPath.
diff --git a/models/repo_test.go b/models/repo_test.go
index a538d44c0e..13ac272b6d 100644
--- a/models/repo_test.go
+++ b/models/repo_test.go
@@ -5,11 +5,14 @@
 package models
 
 import (
+	"path"
 	"testing"
 
 	"code.gitea.io/gitea/modules/markdown"
+	"code.gitea.io/gitea/modules/setting"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/Unknwon/com"
 )
 
 func TestRepo(t *testing.T) {
@@ -132,3 +135,22 @@ func TestRepoAPIURL(t *testing.T) {
 
 	assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
 }
+
+func TestRepoLocalCopyPath(t *testing.T) {
+	assert.NoError(t, PrepareTestDatabase())
+
+	repo, err := GetRepositoryByID(10)
+	assert.NoError(t, err)
+	assert.NotNil(t, repo)
+
+	// test default
+	repoID := com.ToStr(repo.ID)
+	expected := path.Join(setting.AppDataPath, setting.Repository.Local.LocalCopyPath, repoID)
+	assert.Equal(t, expected, repo.LocalCopyPath())
+
+	// test absolute setting
+	tempPath := "/tmp/gitea/local-copy-path"
+	expected = path.Join(tempPath, repoID)
+	setting.Repository.Local.LocalCopyPath = tempPath
+	assert.Equal(t, expected, repo.LocalCopyPath())
+}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index a948527a2c..cd2d4ab720 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -174,6 +174,11 @@ var (
 			FileMaxSize  int64
 			MaxFiles     int
 		} `ini:"-"`
+
+		// Repository local settings
+		Local struct {
+			LocalCopyPath       string
+		} `ini:"-"`
 	}{
 		AnsiCharset:            "",
 		ForcePrivate:           false,
@@ -206,6 +211,13 @@ var (
 			FileMaxSize:  3,
 			MaxFiles:     5,
 		},
+
+		// Repository local settings
+		Local: struct {
+			LocalCopyPath  string
+		}{
+			LocalCopyPath: "tmp/local-repo",
+		},
 	}
 	RepoRootPath string
 	ScriptType   = "bash"
@@ -887,6 +899,8 @@ please consider changing to GITEA_CUSTOM`)
 		log.Fatal(4, "Failed to map Repository.Editor settings: %v", err)
 	} else if err = Cfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
 		log.Fatal(4, "Failed to map Repository.Upload settings: %v", err)
+	} else if err = Cfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
+		log.Fatal(4, "Failed to map Repository.Local settings: %v", err)
 	}
 
 	if !filepath.IsAbs(Repository.Upload.TempPath) {