83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
package vcs
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/StackExchange/blackbox/v2/models"
|
|
)
|
|
|
|
// Vcs is the handle
|
|
type Vcs interface {
|
|
models.Vcs
|
|
}
|
|
|
|
// NewFnSig function signature needed by reg.
|
|
type NewFnSig func() (Vcs, error)
|
|
|
|
// Item stores one item
|
|
type Item struct {
|
|
Name string
|
|
New NewFnSig
|
|
Priority int
|
|
}
|
|
|
|
// Catalog is the list of registered vcs's.
|
|
var Catalog []*Item
|
|
|
|
// Discover polls the VCS plug-ins to determine the VCS of directory.
|
|
// The first to succeed is returned.
|
|
// It never returns nil, since "NONE" is always valid.
|
|
func Discover() (Vcs, string) {
|
|
for _, v := range Catalog {
|
|
h, err := v.New()
|
|
if err != nil {
|
|
return nil, "" // No idea how that would happen.
|
|
}
|
|
if b, repodir := h.Discover(); b {
|
|
|
|
// Try to find the rel path from CWD to RepoBase
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
fmt.Printf("ERROR: Can not determine cwd! Failing!\n")
|
|
os.Exit(1)
|
|
}
|
|
//fmt.Printf("DISCCOVER: WD=%q REPO=%q\n", wd, repodir)
|
|
if repodir != wd && strings.HasSuffix(repodir, wd) {
|
|
// This is a terrible hack. We're basically guessing
|
|
// at the filesystem layout. That said, it works on macOS.
|
|
// TODO(tlim): Abstract this out into a separate function
|
|
// so we can do integration tests on it (to know if it fails on
|
|
// a particular operating system.)
|
|
repodir = wd
|
|
}
|
|
r, err := filepath.Rel(wd, repodir)
|
|
if err != nil {
|
|
// Wait, we're not relative to each other? Give up and
|
|
// just return the abs repodir.
|
|
return h, repodir
|
|
}
|
|
return h, r
|
|
}
|
|
}
|
|
// This can't happen. If it does, we'll panic and that's ok.
|
|
return nil, ""
|
|
}
|
|
|
|
// Register a new VCS.
|
|
func Register(name string, priority int, newfn NewFnSig) {
|
|
//fmt.Printf("VCS registered: %v\n", name)
|
|
item := &Item{
|
|
Name: name,
|
|
New: newfn,
|
|
Priority: priority,
|
|
}
|
|
Catalog = append(Catalog, item)
|
|
|
|
// Keep the list sorted.
|
|
sort.Slice(Catalog, func(i, j int) bool { return Catalog[j].Priority < Catalog[i].Priority })
|
|
}
|