1
0
Fork 0
mirror of https://github.com/Luzifer/repo-template.git synced 2024-12-22 20:21:19 +00:00

Add blacklist for repos

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2018-02-08 22:39:33 +01:00
parent 7037e74c92
commit f14ad8331c
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
25 changed files with 939 additions and 1 deletions

8
Gopkg.lock generated
View file

@ -1,6 +1,12 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/Luzifer/go_helpers"
packages = ["str"]
revision = "8fdddb7041fe962e750caa553a0714f94e261c4a"
version = "v2.3.1"
[[projects]] [[projects]]
name = "github.com/Luzifer/rconfig" name = "github.com/Luzifer/rconfig"
packages = ["."] packages = ["."]
@ -117,6 +123,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "8231595c752fdf2d3c5a412ea10826718df940e6afb2c9e501aa79ee84704dba" inputs-digest = "d03c24ca54cfeb2db8d69ce43727eb0ea2a31fa382a9c15719855dcbf63cf509"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View file

@ -12,6 +12,7 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
"github.com/Luzifer/go_helpers/str"
"github.com/Luzifer/rconfig" "github.com/Luzifer/rconfig"
"github.com/flosch/pongo2" "github.com/flosch/pongo2"
"github.com/google/go-github/github" "github.com/google/go-github/github"
@ -20,6 +21,7 @@ import (
var ( var (
cfg = struct { cfg = struct {
Blacklist []string `flag;"blacklist,b" default:"" description:"Repos to ignore even when matched through filters"`
ExpandMatches bool `flag:"expand-matches" default:"false" description:"Replace matched repos with their full version"` ExpandMatches bool `flag:"expand-matches" default:"false" description:"Replace matched repos with their full version"`
Filters []string `flag:"filter,f" default:"" description:"Filters to match the repos against"` Filters []string `flag:"filter,f" default:"" description:"Filters to match the repos against"`
GithubToken string `flag:"token" default:"" env:"GITHUB_TOKEN" description:"Token to access Github API"` GithubToken string `flag:"token" default:"" env:"GITHUB_TOKEN" description:"Token to access Github API"`
@ -71,6 +73,10 @@ func main() {
continue continue
} }
if str.StringInSlice(*repo.FullName, cfg.Blacklist) {
continue
}
skip := false skip := false
for _, f := range cfg.Filters { for _, f := range cfg.Filters {

7
vendor/github.com/Luzifer/go_helpers/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,7 @@
language: go
go:
- 1.7
- 1.8
- 1.9
- tip

43
vendor/github.com/Luzifer/go_helpers/History.md generated vendored Normal file
View file

@ -0,0 +1,43 @@
# 2.3.1 / 2017-11-05
* Fix TIP version error: Sprintf format %s has arg of wrong type byte
* Travis: Test on Go 1.7, 1.8, 1.9, tip
# 2.3.0 / 2017-11-05
* Implement digest header generation
# 2.2.0 / 2017-04-13
* Add HTTPLogHandler
# 2.1.0 / 2016-12-23
* Add time.Duration formatter
# 2.0.0 / 2016-10-12
* Drop Go1.5 / Go1.6 support with using contexts
* Add github-binary update helper
# 1.4.0 / 2016-05-29
* Added environment helpers
# 1.3.0 / 2016-05-18
* Added AccessLogResponseWriter
# 1.2.0 / 2016-05-16
* Added helper to find binaries in path or directory
# 1.1.0 / 2016-05-06
* Added Haversine helper functions
1.0.0 / 2016-04-23
==================
* First versioned revision for use with gopkg.in

View file

@ -0,0 +1,37 @@
package accessLogger
import (
"fmt"
"net/http"
"strconv"
)
type AccessLogResponseWriter struct {
StatusCode int
Size int
http.ResponseWriter
}
func New(res http.ResponseWriter) *AccessLogResponseWriter {
return &AccessLogResponseWriter{
StatusCode: 200,
Size: 0,
ResponseWriter: res,
}
}
func (a *AccessLogResponseWriter) Write(out []byte) (int, error) {
s, err := a.ResponseWriter.Write(out)
a.Size += s
return s, err
}
func (a *AccessLogResponseWriter) WriteHeader(code int) {
a.StatusCode = code
a.ResponseWriter.WriteHeader(code)
}
func (a *AccessLogResponseWriter) HTTPResponseType() string {
return fmt.Sprintf("%cxx", strconv.FormatInt(int64(a.StatusCode), 10)[0])
}

61
vendor/github.com/Luzifer/go_helpers/duration/time.go generated vendored Normal file
View file

@ -0,0 +1,61 @@
package duration
import (
"bytes"
"math"
"strings"
"text/template"
"time"
"github.com/leekchan/gtf"
)
const defaultDurationFormat = `{{if gt .Years 0}}{{.Years}} year{{.Years|pluralize "s"}}, {{end}}` +
`{{if gt .Days 0}}{{.Days}} day{{.Days|pluralize "s"}}, {{end}}` +
`{{if gt .Hours 0}}{{.Hours}} hour{{.Hours|pluralize "s"}}, {{end}}` +
`{{if gt .Minutes 0}}{{.Minutes}} minute{{.Minutes|pluralize "s"}}, {{end}}` +
`{{if gt .Seconds 0}}{{.Seconds}} second{{.Seconds|pluralize "s"}}{{end}}`
func HumanizeDuration(in time.Duration) string {
f, err := CustomHumanizeDuration(in, defaultDurationFormat)
if err != nil {
panic(err)
}
return strings.Trim(f, " ,")
}
func CustomHumanizeDuration(in time.Duration, tpl string) (string, error) {
result := struct{ Years, Days, Hours, Minutes, Seconds int64 }{}
in = time.Duration(math.Abs(float64(in)))
for in > 0 {
switch {
case in > 365.25*24*time.Hour:
result.Years = int64(in / (365 * 24 * time.Hour))
in = in - time.Duration(result.Years)*365*24*time.Hour
case in > 24*time.Hour:
result.Days = int64(in / (24 * time.Hour))
in = in - time.Duration(result.Days)*24*time.Hour
case in > time.Hour:
result.Hours = int64(in / time.Hour)
in = in - time.Duration(result.Hours)*time.Hour
case in > time.Minute:
result.Minutes = int64(in / time.Minute)
in = in - time.Duration(result.Minutes)*time.Minute
default:
result.Seconds = int64(in / time.Second)
in = 0
}
}
tmpl, err := template.New("timeformat").Funcs(template.FuncMap(gtf.GtfFuncMap)).Parse(tpl)
if err != nil {
return "", err
}
buf := bytes.NewBuffer([]byte{})
tmpl.Execute(buf, result)
return buf.String(), nil
}

View file

@ -0,0 +1,35 @@
package duration
import (
"testing"
"time"
)
func TestCustomFormat(t *testing.T) {
d := 389*24*time.Hour +
12*time.Hour +
31*time.Minute +
54*time.Second +
346*time.Millisecond
f := `{{.Years}} - {{.Days}} - {{.Hours}} - {{.Minutes}} - {{.Seconds}}`
e := `1 - 24 - 12 - 31 - 54`
if s, _ := CustomHumanizeDuration(d, f); s != e {
t.Errorf("Got unexpected result: expected=%q result=%q", e, s)
}
}
func TestDefaultFormat(t *testing.T) {
d := 389*24*time.Hour +
12*time.Hour +
31*time.Minute +
54*time.Second +
346*time.Millisecond
e := `1 year, 24 days, 12 hours, 31 minutes, 54 seconds`
if s := HumanizeDuration(d); s != e {
t.Errorf("Got unexpected result: expected=%q result=%q", e, s)
}
}

26
vendor/github.com/Luzifer/go_helpers/env/env.go generated vendored Normal file
View file

@ -0,0 +1,26 @@
package env
import "strings"
// ListToMap converts a list of strings in format KEY=VALUE into a map
func ListToMap(list []string) map[string]string {
out := map[string]string{}
for _, entry := range list {
if len(entry) == 0 || entry[0] == '#' {
continue
}
parts := strings.SplitN(entry, "=", 2)
out[parts[0]] = strings.Trim(parts[1], "\"")
}
return out
}
// MapToList converts a map into a list of strings in format KEY=VALUE
func MapToList(envMap map[string]string) []string {
out := []string{}
for k, v := range envMap {
out = append(out, k+"="+v)
}
return out
}

View file

@ -0,0 +1,13 @@
package env_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestEnv(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Env Suite")
}

55
vendor/github.com/Luzifer/go_helpers/env/env_test.go generated vendored Normal file
View file

@ -0,0 +1,55 @@
package env_test
import (
"sort"
. "github.com/Luzifer/go_helpers/env"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Env", func() {
Context("ListToMap", func() {
var (
list = []string{
"FIRST_KEY=firstvalue",
"SECOND_KEY=secondvalue",
"WEIRD=",
"",
}
emap = map[string]string{
"FIRST_KEY": "firstvalue",
"SECOND_KEY": "secondvalue",
"WEIRD": "",
}
)
It("should convert the list in the expected way", func() {
Expect(ListToMap(list)).To(Equal(emap))
})
})
Context("MapToList", func() {
var (
list = []string{
"FIRST_KEY=firstvalue",
"SECOND_KEY=secondvalue",
"WEIRD=",
}
emap = map[string]string{
"FIRST_KEY": "firstvalue",
"SECOND_KEY": "secondvalue",
"WEIRD": "",
}
)
It("should convert the map in the expected way", func() {
l := MapToList(emap)
sort.Strings(l) // Workaround: The test needs the elements to be in same order
Expect(l).To(Equal(list))
})
})
})

View file

@ -0,0 +1,13 @@
package float_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestFloat(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Float Suite")
}

14
vendor/github.com/Luzifer/go_helpers/float/round.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
package float
import "math"
// Round returns a float rounded according to "Round to nearest, ties away from zero" IEEE floaing point rounding rule
func Round(x float64) float64 {
var absx, y float64
absx = math.Abs(x)
y = math.Floor(absx)
if absx-y >= 0.5 {
y += 1.0
}
return math.Copysign(y, x)
}

View file

@ -0,0 +1,35 @@
package float_test
import (
"math"
. "github.com/Luzifer/go_helpers/float"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Round", func() {
It("should match the example table of IEEE 754 rules", func() {
Expect(Round(11.5)).To(Equal(12.0))
Expect(Round(12.5)).To(Equal(13.0))
Expect(Round(-11.5)).To(Equal(-12.0))
Expect(Round(-12.5)).To(Equal(-13.0))
})
It("should have correct rounding for numbers near 0.5", func() {
Expect(Round(0.499999999997)).To(Equal(0.0))
Expect(Round(-0.499999999997)).To(Equal(0.0))
})
It("should be able to handle +/-Inf", func() {
Expect(Round(math.Inf(1))).To(Equal(math.Inf(1)))
Expect(Round(math.Inf(-1))).To(Equal(math.Inf(-1)))
})
It("should be able to handle NaN", func() {
Expect(math.IsNaN(Round(math.NaN()))).To(Equal(true))
})
})

213
vendor/github.com/Luzifer/go_helpers/github/updater.go generated vendored Normal file
View file

@ -0,0 +1,213 @@
package github
import (
"bufio"
"bytes"
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"runtime"
"strings"
"text/template"
"time"
update "github.com/inconshreveable/go-update"
)
const (
defaultTimeout = 60 * time.Second
defaultNamingScheme = `{{.ProductName}}_{{.GOOS}}_{{.GOARCH}}{{.EXT}}`
)
var (
errReleaseNotFound = errors.New("Release not found")
)
// Updater is the core struct of the update library holding all configurations
type Updater struct {
repo string
myVersion string
HTTPClient *http.Client
RequestTimeout time.Duration
Context context.Context
Filename string
releaseCache string
}
// NewUpdater initializes a new Updater and tries to guess the Filename
func NewUpdater(repo, myVersion string) (*Updater, error) {
var err error
u := &Updater{
repo: repo,
myVersion: myVersion,
HTTPClient: http.DefaultClient,
RequestTimeout: defaultTimeout,
Context: context.Background(),
}
u.Filename, err = u.compileFilename()
return u, err
}
// HasUpdate checks which tag was used in the latest version and compares it to the current version. If it differs the function will return true. No comparison is done to determine whether the found version is higher than the current one.
func (u *Updater) HasUpdate(forceRefresh bool) (bool, error) {
if forceRefresh {
u.releaseCache = ""
}
latest, err := u.getLatestRelease()
switch err {
case nil:
return u.myVersion != latest, nil
case errReleaseNotFound:
return false, nil
default:
return false, err
}
}
// Apply downloads the new binary from Github, fetches the SHA256 sum from the SHA256SUMS file and applies the update to the currently running binary
func (u *Updater) Apply() error {
updateAvailable, err := u.HasUpdate(false)
if err != nil {
return err
}
if !updateAvailable {
return nil
}
checksum, err := u.getSHA256(u.Filename)
if err != nil {
return err
}
newRelease, err := u.getFile(u.Filename)
if err != nil {
return err
}
defer newRelease.Close()
return update.Apply(newRelease, update.Options{
Checksum: checksum,
})
}
func (u Updater) getSHA256(filename string) ([]byte, error) {
shaFile, err := u.getFile("SHA256SUMS")
if err != nil {
return nil, err
}
defer shaFile.Close()
scanner := bufio.NewScanner(shaFile)
for scanner.Scan() {
line := scanner.Text()
if !strings.Contains(line, u.Filename) {
continue
}
return hex.DecodeString(line[0:64])
}
return nil, fmt.Errorf("No SHA256 found for file %q", u.Filename)
}
func (u Updater) getFile(filename string) (io.ReadCloser, error) {
release, err := u.getLatestRelease()
if err != nil {
return nil, err
}
requestURL := fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", u.repo, release, filename)
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return nil, err
}
ctx, _ := context.WithTimeout(u.Context, u.RequestTimeout)
res, err := u.HTTPClient.Do(req.WithContext(ctx))
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("File not found: %q", requestURL)
}
return res.Body, nil
}
func (u *Updater) getLatestRelease() (string, error) {
if u.releaseCache != "" {
return u.releaseCache, nil
}
result := struct {
TagName string `json:"tag_name"`
}{}
requestURL := fmt.Sprintf("https://api.github.com/repos/%s/releases/latest", u.repo)
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return "", err
}
ctx, cancel := context.WithTimeout(u.Context, u.RequestTimeout)
defer cancel()
res, err := u.HTTPClient.Do(req.WithContext(ctx))
if err != nil {
return "", err
}
defer res.Body.Close()
if err = json.NewDecoder(res.Body).Decode(&result); err != nil {
return "", err
}
if res.StatusCode != 200 || result.TagName == "" {
return "", errReleaseNotFound
}
u.releaseCache = result.TagName
return result.TagName, nil
}
func (u Updater) compileFilename() (string, error) {
repoName := strings.Split(u.repo, "/")
if len(repoName) != 2 {
return "", errors.New("Repository name not in format <owner>/<repository>")
}
tpl, err := template.New("filename").Parse(defaultNamingScheme)
if err != nil {
return "", err
}
var ext string
if runtime.GOOS == "windows" {
ext = ".exe"
}
buf := bytes.NewBuffer([]byte{})
if err = tpl.Execute(buf, map[string]interface{}{
"GOOS": runtime.GOOS,
"GOARCH": runtime.GOARCH,
"EXT": ext,
"ProductName": repoName[1],
}); err != nil {
return "", err
}
return buf.String(), nil
}

55
vendor/github.com/Luzifer/go_helpers/http/digest.go generated vendored Normal file
View file

@ -0,0 +1,55 @@
package http
import (
"crypto/md5"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"net/http"
"strings"
"github.com/Luzifer/go_helpers/str"
)
func GetDigestAuth(resp *http.Response, method, requestPath, user, password string) string {
params := map[string]string{}
for _, part := range strings.Split(resp.Header.Get("Www-Authenticate"), " ") {
if !strings.Contains(part, `="`) {
continue
}
spl := strings.Split(strings.Trim(part, " ,"), "=")
if !str.StringInSlice(spl[0], []string{"nonce", "realm", "qop"}) {
continue
}
params[spl[0]] = strings.Trim(spl[1], `"`)
}
b := make([]byte, 8)
io.ReadFull(rand.Reader, b)
params["cnonce"] = fmt.Sprintf("%x", b)
params["nc"] = "1"
params["uri"] = requestPath
params["username"] = user
params["response"] = getMD5([]string{
getMD5([]string{params["username"], params["realm"], password}),
params["nonce"],
params["nc"],
params["cnonce"],
params["qop"],
getMD5([]string{method, requestPath}),
})
authParts := []string{}
for k, v := range params {
authParts = append(authParts, fmt.Sprintf("%s=%q", k, v))
}
return "Digest " + strings.Join(authParts, ", ")
}
func getMD5(in []string) string {
h := md5.New()
h.Write([]byte(strings.Join(in, ":")))
return hex.EncodeToString(h.Sum(nil))
}

View file

@ -0,0 +1,35 @@
package http
import (
"log"
"net/http"
"time"
"github.com/Luzifer/go_helpers/accessLogger"
)
type HTTPLogHandler struct {
Handler http.Handler
}
func NewHTTPLogHandler(h http.Handler) http.Handler {
return HTTPLogHandler{Handler: h}
}
func (l HTTPLogHandler) ServeHTTP(res http.ResponseWriter, r *http.Request) {
start := time.Now()
ares := accessLogger.New(res)
l.Handler.ServeHTTP(ares, r)
log.Printf("%s - \"%s %s\" %d %d \"%s\" \"%s\" %s",
r.RemoteAddr,
r.Method,
r.URL.Path,
ares.StatusCode,
ares.Size,
r.Header.Get("Referer"),
r.Header.Get("User-Agent"),
time.Since(start),
)
}

View file

@ -0,0 +1,21 @@
package position
import "math"
const (
earthRadius = float64(6371)
)
func Haversine(lonFrom float64, latFrom float64, lonTo float64, latTo float64) (distance float64) {
var deltaLat = (latTo - latFrom) * (math.Pi / 180)
var deltaLon = (lonTo - lonFrom) * (math.Pi / 180)
var a = math.Sin(deltaLat/2)*math.Sin(deltaLat/2) +
math.Cos(latFrom*(math.Pi/180))*math.Cos(latTo*(math.Pi/180))*
math.Sin(deltaLon/2)*math.Sin(deltaLon/2)
var c = 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
distance = earthRadius * c
return
}

View file

@ -0,0 +1,34 @@
package position_test
import (
. "github.com/Luzifer/go_helpers/position"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Haversine", func() {
var testCases = []struct {
SourceLat float64
SourceLon float64
DestLat float64
DestLon float64
Distance float64
}{
{50.066389, -5.714722, 58.643889, -3.070000, 968.8535441168448},
{50.063995, -5.609464, 53.553027, 9.993782, 1137.894906816002},
{53.553027, 9.993782, 53.554528, 9.991357, 0.23133816528015647},
{50, 9, 51, 9, 111.19492664455873},
{0, 9, 0, 10, 111.19492664455873},
{1, 0, -1, 0, 222.38985328911747},
}
It("should have the documented distance", func() {
for i := range testCases {
tc := testCases[i]
Expect(Haversine(tc.SourceLon, tc.SourceLat, tc.DestLon, tc.DestLat)).To(Equal(tc.Distance))
}
})
})

View file

@ -0,0 +1,13 @@
package position_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestPosition(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Position Suite")
}

21
vendor/github.com/Luzifer/go_helpers/str/slice.go generated vendored Normal file
View file

@ -0,0 +1,21 @@
package str
// AppendIfMissing adds a string to a slice when it's not present yet
func AppendIfMissing(slice []string, s string) []string {
for _, e := range slice {
if e == s {
return slice
}
}
return append(slice, s)
}
// StringInSlice checks for the existence of a string in the slice
func StringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}

52
vendor/github.com/Luzifer/go_helpers/str/slice_test.go generated vendored Normal file
View file

@ -0,0 +1,52 @@
package str_test
import (
. "github.com/Luzifer/go_helpers/str"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Slice", func() {
Context("AppendIfMissing", func() {
var sl = []string{
"test1",
"test2",
"test3",
}
It("should not append existing elements", func() {
Expect(len(AppendIfMissing(sl, "test1"))).To(Equal(3))
Expect(len(AppendIfMissing(sl, "test2"))).To(Equal(3))
Expect(len(AppendIfMissing(sl, "test3"))).To(Equal(3))
})
It("should append not existing elements", func() {
Expect(len(AppendIfMissing(sl, "test4"))).To(Equal(4))
Expect(len(AppendIfMissing(sl, "test5"))).To(Equal(4))
Expect(len(AppendIfMissing(sl, "test6"))).To(Equal(4))
})
})
Context("StringInSlice", func() {
var sl = []string{
"test1",
"test2",
"test3",
}
It("should find elements of slice", func() {
Expect(StringInSlice("test1", sl)).To(Equal(true))
Expect(StringInSlice("test2", sl)).To(Equal(true))
Expect(StringInSlice("test3", sl)).To(Equal(true))
})
It("should not find elements not in slice", func() {
Expect(StringInSlice("test4", sl)).To(Equal(false))
Expect(StringInSlice("test5", sl)).To(Equal(false))
Expect(StringInSlice("test6", sl)).To(Equal(false))
})
})
})

View file

@ -0,0 +1,13 @@
package str_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestStr(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Str Suite")
}

54
vendor/github.com/Luzifer/go_helpers/which/which.go generated vendored Normal file
View file

@ -0,0 +1,54 @@
package which
import (
"errors"
"os"
"path"
"strings"
)
// Common named errors to match in programs using this library
var (
ErrBinaryNotFound = errors.New("Requested binary was not found")
ErrNoSearchSpecified = errors.New("You need to specify a binary to search")
)
// FindInPath searches the specified binary in directories listed in $PATH and returns first match
func FindInPath(binary string) (string, error) {
pathEnv := os.Getenv("PATH")
if len(pathEnv) == 0 {
return "", errors.New("Found empty $PATH, not able to search $PATH")
}
for _, part := range strings.Split(pathEnv, ":") {
if len(part) == 0 {
continue
}
if found, err := FindInDirectory(binary, part); err != nil {
return "", err
} else if found {
return path.Join(part, binary), nil
}
}
return "", ErrBinaryNotFound
}
// FindInDirectory checks whether the specified file is present in the directory
func FindInDirectory(binary, directory string) (bool, error) {
if len(binary) == 0 {
return false, ErrNoSearchSpecified
}
_, err := os.Stat(path.Join(directory, binary))
switch {
case err == nil:
return true, nil
case os.IsNotExist(err):
return false, nil
default:
return false, err
}
}

View file

@ -0,0 +1,13 @@
package which_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestWhich(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Which Suite")
}

View file

@ -0,0 +1,63 @@
package which_test
import (
. "github.com/Luzifer/go_helpers/which"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Which", func() {
var (
result string
err error
found bool
)
Context("With a file available on linux systems", func() {
BeforeEach(func() {
found, err = FindInDirectory("bash", "/bin")
})
It("should not have errored", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should have found the binary at /bin/bash", func() {
Expect(found).To(BeTrue())
})
})
Context("Searching bash on the system", func() {
BeforeEach(func() {
result, err = FindInPath("bash")
})
It("should not have errored", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should have a result", func() {
Expect(len(result)).NotTo(Equal(0))
})
})
Context("Searching a non existent file", func() {
BeforeEach(func() {
result, err = FindInPath("dfqoiwurgtqi3uegrds")
})
It("should have errored", func() {
Expect(err).To(Equal(ErrBinaryNotFound))
})
})
Context("Searching an empty file", func() {
BeforeEach(func() {
result, err = FindInPath("")
})
It("should have errored", func() {
Expect(err).To(Equal(ErrNoSearchSpecified))
})
})
})