mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-08-01 17:58:45 +00:00
* set version in one place * rename ExecutionContext to CommandContext * delete unneeded PullRequestContext since it just duplicated what is in CommandContext * split fields inside CommandContext into Repo, PullRequest, and User models * clean up unused fields * remove base_executor stuff which was trying to do inheritance in go and didn't get us anywhere * clean up unused code and assets * created a locking.Client that creates the Keys that are used on the front-end. This allows the backends to store the locks any way they like as long as they support the interface
71 lines
1.7 KiB
Go
71 lines
1.7 KiB
Go
package locking
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/hootsuite/atlantis/models"
|
|
"regexp"
|
|
)
|
|
|
|
type Backend interface {
|
|
TryLock(project models.Project, env string, pullNum int) (bool, int, error)
|
|
Unlock(project models.Project, env string) error
|
|
List() ([]models.ProjectLock, error)
|
|
UnlockByPull(repoFullName string, pullNum int) error
|
|
}
|
|
|
|
type TryLockResponse struct {
|
|
LockAcquired bool
|
|
LockingPullNum int
|
|
LockKey string
|
|
}
|
|
|
|
type Client struct {
|
|
backend Backend
|
|
}
|
|
|
|
func NewClient(backend Backend) *Client {
|
|
return &Client{
|
|
backend: backend,
|
|
}
|
|
}
|
|
|
|
// keyRegex matches and captures {repoFullName}/{path}/{env} where path can have multiple /'s in it
|
|
var keyRegex = regexp.MustCompile(`^(.*?\/.*?)\/(.*)\/(.*)$`)
|
|
|
|
func (c *Client) TryLock(p models.Project, env string, pullNum int) (TryLockResponse, error) {
|
|
lockAcquired, lockingPullNum, err := c.backend.TryLock(p, env, pullNum)
|
|
if err != nil {
|
|
return TryLockResponse{}, err
|
|
}
|
|
return TryLockResponse{lockAcquired, lockingPullNum, c.key(p, env)}, nil
|
|
}
|
|
|
|
func (c *Client) Unlock(key string) error {
|
|
matches := keyRegex.FindStringSubmatch(key)
|
|
if len(matches) != 4 {
|
|
return errors.New("invalid key format")
|
|
}
|
|
return c.backend.Unlock(models.Project{matches[1], matches[2]}, matches[3])
|
|
}
|
|
|
|
func (c *Client) List() (map[string]models.ProjectLock, error) {
|
|
m := make(map[string]models.ProjectLock)
|
|
locks, err := c.backend.List()
|
|
if err != nil {
|
|
return m, err
|
|
}
|
|
for _, lock := range locks {
|
|
m[c.key(lock.Project, lock.Env)] = lock
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (c *Client) UnlockByPull(repoFullName string, pullNum int) error {
|
|
return c.backend.UnlockByPull(repoFullName, pullNum)
|
|
}
|
|
|
|
func (c *Client) key(p models.Project, env string) string {
|
|
return fmt.Sprintf("%s/%s/%s", p.RepoFullName, p.Path, env)
|
|
}
|