diff --git a/Gopkg.lock b/Gopkg.lock index ff89d6f..e6db37e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,6 +1,12 @@ # 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]] name = "github.com/Luzifer/rconfig" packages = ["."] @@ -117,6 +123,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "8231595c752fdf2d3c5a412ea10826718df940e6afb2c9e501aa79ee84704dba" + inputs-digest = "d03c24ca54cfeb2db8d69ce43727eb0ea2a31fa382a9c15719855dcbf63cf509" solver-name = "gps-cdcl" solver-version = 1 diff --git a/main.go b/main.go index 18c540c..522e5f3 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "golang.org/x/oauth2" + "github.com/Luzifer/go_helpers/str" "github.com/Luzifer/rconfig" "github.com/flosch/pongo2" "github.com/google/go-github/github" @@ -20,6 +21,7 @@ import ( var ( 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"` 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"` @@ -71,6 +73,10 @@ func main() { continue } + if str.StringInSlice(*repo.FullName, cfg.Blacklist) { + continue + } + skip := false for _, f := range cfg.Filters { diff --git a/vendor/github.com/Luzifer/go_helpers/.travis.yml b/vendor/github.com/Luzifer/go_helpers/.travis.yml new file mode 100644 index 0000000..b721422 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.7 + - 1.8 + - 1.9 + - tip diff --git a/vendor/github.com/Luzifer/go_helpers/History.md b/vendor/github.com/Luzifer/go_helpers/History.md new file mode 100644 index 0000000..9371fbe --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/History.md @@ -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 diff --git a/vendor/github.com/Luzifer/go_helpers/accessLogger/accessLogger.go b/vendor/github.com/Luzifer/go_helpers/accessLogger/accessLogger.go new file mode 100644 index 0000000..b800a68 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/accessLogger/accessLogger.go @@ -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]) +} diff --git a/vendor/github.com/Luzifer/go_helpers/duration/time.go b/vendor/github.com/Luzifer/go_helpers/duration/time.go new file mode 100644 index 0000000..f560a2a --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/duration/time.go @@ -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 +} diff --git a/vendor/github.com/Luzifer/go_helpers/duration/time_test.go b/vendor/github.com/Luzifer/go_helpers/duration/time_test.go new file mode 100644 index 0000000..ddf9aa0 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/duration/time_test.go @@ -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) + } +} diff --git a/vendor/github.com/Luzifer/go_helpers/env/env.go b/vendor/github.com/Luzifer/go_helpers/env/env.go new file mode 100644 index 0000000..14c9958 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/env/env.go @@ -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 +} diff --git a/vendor/github.com/Luzifer/go_helpers/env/env_suite_test.go b/vendor/github.com/Luzifer/go_helpers/env/env_suite_test.go new file mode 100644 index 0000000..0054723 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/env/env_suite_test.go @@ -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") +} diff --git a/vendor/github.com/Luzifer/go_helpers/env/env_test.go b/vendor/github.com/Luzifer/go_helpers/env/env_test.go new file mode 100644 index 0000000..8cce912 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/env/env_test.go @@ -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)) + }) + }) + +}) diff --git a/vendor/github.com/Luzifer/go_helpers/float/float_suite_test.go b/vendor/github.com/Luzifer/go_helpers/float/float_suite_test.go new file mode 100644 index 0000000..ea52763 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/float/float_suite_test.go @@ -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") +} diff --git a/vendor/github.com/Luzifer/go_helpers/float/round.go b/vendor/github.com/Luzifer/go_helpers/float/round.go new file mode 100644 index 0000000..9c201d0 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/float/round.go @@ -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) +} diff --git a/vendor/github.com/Luzifer/go_helpers/float/round_test.go b/vendor/github.com/Luzifer/go_helpers/float/round_test.go new file mode 100644 index 0000000..a6257bf --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/float/round_test.go @@ -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)) + }) + +}) diff --git a/vendor/github.com/Luzifer/go_helpers/github/updater.go b/vendor/github.com/Luzifer/go_helpers/github/updater.go new file mode 100644 index 0000000..2a322b9 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/github/updater.go @@ -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 /") + } + + 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 +} diff --git a/vendor/github.com/Luzifer/go_helpers/http/digest.go b/vendor/github.com/Luzifer/go_helpers/http/digest.go new file mode 100644 index 0000000..40cc5aa --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/http/digest.go @@ -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)) +} diff --git a/vendor/github.com/Luzifer/go_helpers/http/logHandler.go b/vendor/github.com/Luzifer/go_helpers/http/logHandler.go new file mode 100644 index 0000000..7a55372 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/http/logHandler.go @@ -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), + ) +} diff --git a/vendor/github.com/Luzifer/go_helpers/position/haversine.go b/vendor/github.com/Luzifer/go_helpers/position/haversine.go new file mode 100644 index 0000000..8f9f1ca --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/position/haversine.go @@ -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 +} diff --git a/vendor/github.com/Luzifer/go_helpers/position/haversine_test.go b/vendor/github.com/Luzifer/go_helpers/position/haversine_test.go new file mode 100644 index 0000000..67df327 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/position/haversine_test.go @@ -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)) + } + }) + +}) diff --git a/vendor/github.com/Luzifer/go_helpers/position/position_suite_test.go b/vendor/github.com/Luzifer/go_helpers/position/position_suite_test.go new file mode 100644 index 0000000..51b1c2a --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/position/position_suite_test.go @@ -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") +} diff --git a/vendor/github.com/Luzifer/go_helpers/str/slice.go b/vendor/github.com/Luzifer/go_helpers/str/slice.go new file mode 100644 index 0000000..f93af69 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/str/slice.go @@ -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 +} diff --git a/vendor/github.com/Luzifer/go_helpers/str/slice_test.go b/vendor/github.com/Luzifer/go_helpers/str/slice_test.go new file mode 100644 index 0000000..d24ef6b --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/str/slice_test.go @@ -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)) + }) + }) + +}) diff --git a/vendor/github.com/Luzifer/go_helpers/str/str_suite_test.go b/vendor/github.com/Luzifer/go_helpers/str/str_suite_test.go new file mode 100644 index 0000000..9ec9128 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/str/str_suite_test.go @@ -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") +} diff --git a/vendor/github.com/Luzifer/go_helpers/which/which.go b/vendor/github.com/Luzifer/go_helpers/which/which.go new file mode 100644 index 0000000..4190ea4 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/which/which.go @@ -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 + } +} diff --git a/vendor/github.com/Luzifer/go_helpers/which/which_suite_test.go b/vendor/github.com/Luzifer/go_helpers/which/which_suite_test.go new file mode 100644 index 0000000..90a20b5 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/which/which_suite_test.go @@ -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") +} diff --git a/vendor/github.com/Luzifer/go_helpers/which/which_test.go b/vendor/github.com/Luzifer/go_helpers/which/which_test.go new file mode 100644 index 0000000..d9a30c2 --- /dev/null +++ b/vendor/github.com/Luzifer/go_helpers/which/which_test.go @@ -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)) + }) + }) + +})