2017-02-23 06:12:16 +01:00
|
|
|
package db
|
2016-04-04 15:44:34 +02:00
|
|
|
|
2022-01-27 13:44:35 +01:00
|
|
|
import (
|
2024-05-23 19:56:39 +02:00
|
|
|
"fmt"
|
2022-01-27 13:44:35 +01:00
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2024-07-07 10:07:09 +02:00
|
|
|
|
2024-10-26 14:56:17 +02:00
|
|
|
"github.com/semaphoreui/semaphore/util"
|
2022-01-27 13:44:35 +01:00
|
|
|
)
|
|
|
|
|
2022-03-30 17:31:00 +02:00
|
|
|
type RepositoryType string
|
2022-01-27 15:16:58 +01:00
|
|
|
|
2022-01-27 13:44:35 +01:00
|
|
|
const (
|
2022-03-30 17:31:00 +02:00
|
|
|
RepositoryGit RepositoryType = "git"
|
|
|
|
RepositorySSH RepositoryType = "ssh"
|
2024-05-30 13:50:06 +02:00
|
|
|
RepositoryHTTP RepositoryType = "https"
|
2022-03-30 17:31:00 +02:00
|
|
|
RepositoryFile RepositoryType = "file"
|
|
|
|
RepositoryLocal RepositoryType = "local"
|
2022-01-27 13:44:35 +01:00
|
|
|
)
|
|
|
|
|
2018-03-27 22:12:47 +02:00
|
|
|
// Repository is the model for code stored in a git repository
|
2016-04-04 15:44:34 +02:00
|
|
|
type Repository struct {
|
2024-10-05 22:16:25 +02:00
|
|
|
ID int `db:"id" json:"id" backup:"-"`
|
2016-04-11 12:02:10 +02:00
|
|
|
Name string `db:"name" json:"name" binding:"required"`
|
2024-10-05 22:16:25 +02:00
|
|
|
ProjectID int `db:"project_id" json:"project_id" backup:"-"`
|
2018-03-27 22:12:47 +02:00
|
|
|
GitURL string `db:"git_url" json:"git_url" binding:"required"`
|
2022-01-20 15:53:48 +01:00
|
|
|
GitBranch string `db:"git_branch" json:"git_branch" binding:"required"`
|
2024-10-05 22:16:25 +02:00
|
|
|
SSHKeyID int `db:"ssh_key_id" json:"ssh_key_id" binding:"required" backup:"-"`
|
2016-04-07 14:49:34 +02:00
|
|
|
|
2024-10-05 22:16:25 +02:00
|
|
|
SSHKey AccessKey `db:"-" json:"-" backup:"-"`
|
2016-04-07 14:49:34 +02:00
|
|
|
}
|
2022-01-22 09:16:23 +01:00
|
|
|
|
2022-01-27 13:44:35 +01:00
|
|
|
func (r Repository) ClearCache() error {
|
|
|
|
dir, err := os.Open(util.Config.TmpPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-04-28 04:42:25 +02:00
|
|
|
defer dir.Close()
|
2022-01-27 13:44:35 +01:00
|
|
|
|
|
|
|
files, err := dir.ReadDir(0)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, f := range files {
|
|
|
|
if !f.IsDir() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(f.Name(), r.getDirNamePrefix()) {
|
|
|
|
err = os.RemoveAll(path.Join(util.Config.TmpPath, f.Name()))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r Repository) getDirNamePrefix() string {
|
|
|
|
return "repository_" + strconv.Itoa(r.ID) + "_"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r Repository) GetDirName(templateID int) string {
|
|
|
|
return r.getDirNamePrefix() + strconv.Itoa(templateID)
|
|
|
|
}
|
|
|
|
|
2022-01-30 12:22:18 +01:00
|
|
|
func (r Repository) GetFullPath(templateID int) string {
|
2022-03-30 17:31:00 +02:00
|
|
|
if r.GetType() == RepositoryLocal {
|
|
|
|
return r.GetGitURL()
|
|
|
|
}
|
2022-01-27 13:44:35 +01:00
|
|
|
return path.Join(util.Config.TmpPath, r.GetDirName(templateID))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r Repository) GetGitURL() string {
|
|
|
|
url := r.GitURL
|
2022-01-27 15:16:58 +01:00
|
|
|
|
2024-05-30 13:50:06 +02:00
|
|
|
if r.GetType() == RepositoryHTTP {
|
2022-01-27 15:16:58 +01:00
|
|
|
auth := ""
|
|
|
|
switch r.SSHKey.Type {
|
|
|
|
case AccessKeyLoginPassword:
|
2024-07-07 10:07:09 +02:00
|
|
|
if r.SSHKey.LoginPassword.Login == "" {
|
|
|
|
auth = r.SSHKey.LoginPassword.Password
|
|
|
|
} else {
|
|
|
|
auth = r.SSHKey.LoginPassword.Login + ":" + r.SSHKey.LoginPassword.Password
|
|
|
|
}
|
2022-01-27 15:16:58 +01:00
|
|
|
}
|
|
|
|
if auth != "" {
|
|
|
|
auth += "@"
|
|
|
|
}
|
2024-05-23 19:56:39 +02:00
|
|
|
|
|
|
|
re := regexp.MustCompile(`^(https?)://`)
|
|
|
|
m := re.FindStringSubmatch(url)
|
|
|
|
var protocol string
|
|
|
|
|
2024-05-23 19:58:54 +02:00
|
|
|
if m == nil {
|
2024-05-23 19:56:39 +02:00
|
|
|
panic(fmt.Errorf("invalid git url: %s", url))
|
|
|
|
}
|
|
|
|
|
2024-05-23 19:58:54 +02:00
|
|
|
protocol = m[1]
|
|
|
|
|
2024-07-04 21:33:38 +02:00
|
|
|
url = protocol + "://" + auth + r.GitURL[len(protocol)+3:]
|
2022-01-27 13:44:35 +01:00
|
|
|
}
|
2022-01-27 15:16:58 +01:00
|
|
|
|
2022-01-27 13:44:35 +01:00
|
|
|
return url
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:31:00 +02:00
|
|
|
func (r Repository) GetType() RepositoryType {
|
|
|
|
if strings.HasPrefix(r.GitURL, "/") {
|
|
|
|
return RepositoryLocal
|
|
|
|
}
|
|
|
|
|
2022-01-27 13:44:35 +01:00
|
|
|
re := regexp.MustCompile(`^(\w+)://`)
|
|
|
|
m := re.FindStringSubmatch(r.GitURL)
|
|
|
|
if m == nil {
|
2022-03-30 17:31:00 +02:00
|
|
|
return RepositorySSH
|
2022-01-27 13:44:35 +01:00
|
|
|
}
|
2022-03-30 17:31:00 +02:00
|
|
|
|
2024-05-30 13:50:06 +02:00
|
|
|
protocol := m[1]
|
|
|
|
|
|
|
|
switch protocol {
|
|
|
|
case "http", "https":
|
|
|
|
return RepositoryHTTP
|
|
|
|
default:
|
|
|
|
return RepositoryType(protocol)
|
|
|
|
}
|
2022-01-27 13:44:35 +01:00
|
|
|
}
|
|
|
|
|
2022-01-22 09:16:23 +01:00
|
|
|
func (r Repository) Validate() error {
|
|
|
|
if r.Name == "" {
|
|
|
|
return &ValidationError{"repository name can't be empty"}
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.GitURL == "" {
|
|
|
|
return &ValidationError{"repository url can't be empty"}
|
|
|
|
}
|
|
|
|
|
2022-03-31 08:13:02 +02:00
|
|
|
if r.GetType() != RepositoryLocal && r.GitBranch == "" {
|
2022-01-22 09:16:23 +01:00
|
|
|
return &ValidationError{"repository branch can't be empty"}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|