github.com/StackExchange/blackbox/v2@v2.0.1-0.20220331193400-d84e904973ab/pkg/vcs/vcs.go (about) 1 package vcs 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "sort" 8 "strings" 9 10 "github.com/StackExchange/blackbox/v2/models" 11 ) 12 13 // Vcs is the handle 14 type Vcs interface { 15 models.Vcs 16 } 17 18 // NewFnSig function signature needed by reg. 19 type NewFnSig func() (Vcs, error) 20 21 // Item stores one item 22 type Item struct { 23 Name string 24 New NewFnSig 25 Priority int 26 } 27 28 // Catalog is the list of registered vcs's. 29 var Catalog []*Item 30 31 // Discover polls the VCS plug-ins to determine the VCS of directory. 32 // The first to succeed is returned. 33 // It never returns nil, since "NONE" is always valid. 34 func Discover() (Vcs, string) { 35 for _, v := range Catalog { 36 h, err := v.New() 37 if err != nil { 38 return nil, "" // No idea how that would happen. 39 } 40 if b, repodir := h.Discover(); b { 41 42 // Try to find the rel path from CWD to RepoBase 43 wd, err := os.Getwd() 44 if err != nil { 45 fmt.Printf("ERROR: Can not determine cwd! Failing!\n") 46 os.Exit(1) 47 } 48 //fmt.Printf("DISCCOVER: WD=%q REPO=%q\n", wd, repodir) 49 if repodir != wd && strings.HasSuffix(repodir, wd) { 50 // This is a terrible hack. We're basically guessing 51 // at the filesystem layout. That said, it works on macOS. 52 // TODO(tlim): Abstract this out into a separate function 53 // so we can do integration tests on it (to know if it fails on 54 // a particular operating system.) 55 repodir = wd 56 } 57 r, err := filepath.Rel(wd, repodir) 58 if err != nil { 59 // Wait, we're not relative to each other? Give up and 60 // just return the abs repodir. 61 return h, repodir 62 } 63 return h, r 64 } 65 } 66 // This can't happen. If it does, we'll panic and that's ok. 67 return nil, "" 68 } 69 70 // Register a new VCS. 71 func Register(name string, priority int, newfn NewFnSig) { 72 //fmt.Printf("VCS registered: %v\n", name) 73 item := &Item{ 74 Name: name, 75 New: newfn, 76 Priority: priority, 77 } 78 Catalog = append(Catalog, item) 79 80 // Keep the list sorted. 81 sort.Slice(Catalog, func(i, j int) bool { return Catalog[j].Priority < Catalog[i].Priority }) 82 }