add support for custom vcs handlers
This commit is contained in:
75
pkg/vcs/cmd.go
Normal file
75
pkg/vcs/cmd.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package vcs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type cmdVCS struct {
|
||||
log logger
|
||||
module string
|
||||
cmd string
|
||||
}
|
||||
|
||||
func NewCommand(l logger, cmd string, module string) VCS {
|
||||
return &cmdVCS{log: l, cmd: cmd, module: module}
|
||||
}
|
||||
|
||||
func (c *cmdVCS) List(ctx context.Context) ([]Version, error) {
|
||||
b, err := c.exec(ctx, "MODULE="+c.module, "ACTION=list", "VERSION=latest", "FILEPATH="+c.module+"/@v/list")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
versions := []Version{}
|
||||
for _, line := range strings.Split(string(b), "\n") {
|
||||
versions = append(versions, Version(line))
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func (c *cmdVCS) Timestamp(ctx context.Context, version Version) (time.Time, error) {
|
||||
b, err := c.exec(ctx, "MODULE="+c.module, "ACTION=timestamp", "VERSION="+version.String(),
|
||||
"FILEPATH="+c.module+"/@v/"+version.String()+".info")
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
info := struct {
|
||||
Version string
|
||||
Time time.Time
|
||||
}{}
|
||||
if json.Unmarshal(b, &info) == nil {
|
||||
return info.Time, nil
|
||||
}
|
||||
if t, err := time.Parse(time.RFC3339, string(b)); err == nil {
|
||||
return t, nil
|
||||
}
|
||||
if sec, err := strconv.ParseInt(string(b), 10, 64); err == nil {
|
||||
return time.Unix(sec, 0), nil
|
||||
}
|
||||
return time.Time{}, errors.New("unknown time format")
|
||||
}
|
||||
|
||||
func (c *cmdVCS) Zip(ctx context.Context, version Version) (io.ReadCloser, error) {
|
||||
b, err := c.exec(ctx, "MODULE="+c.module, "ACTION=zip", "VERSION="+version.String(),
|
||||
"FILEPATH="+c.module+"/@v/"+version.String()+".zip")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.NopCloser(bytes.NewReader(b)), nil
|
||||
}
|
||||
|
||||
func (c *cmdVCS) exec(ctx context.Context, env ...string) ([]byte, error) {
|
||||
cmd := exec.Command("sh", "-c", c.cmd)
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Output()
|
||||
}
|
||||
@@ -27,6 +27,11 @@ func (v Version) Hash() string {
|
||||
return fields[2]
|
||||
}
|
||||
|
||||
// String returns a string representation of a version
|
||||
func (v Version) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// Module is a source code snapshot for which one can get the commit timestamp
|
||||
// or the actual ZIP with the source code in it.
|
||||
type Module interface {
|
||||
|
||||
Reference in New Issue
Block a user