diff options
| author | 2023-04-28 01:36:55 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:55 +0800 | |
| commit | fc8c5fdce62fb229202659408798a7b6c98f6e8b (patch) | |
| tree | 7554f80e50de4af6fd255afa7c21bcdd58a7af34 /cli/internal/util | |
| parent | dd84b9d64fb98746a230cd24233ff50a562c39c9 (diff) | |
| download | HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.tar.gz HydroRoll-fc8c5fdce62fb229202659408798a7b6c98f6e8b.zip | |
Diffstat (limited to 'cli/internal/util')
| -rw-r--r-- | cli/internal/util/backends.go | 30 | ||||
| -rw-r--r-- | cli/internal/util/browser/open.go | 37 | ||||
| -rw-r--r-- | cli/internal/util/closer.go | 15 | ||||
| -rw-r--r-- | cli/internal/util/cmd.go | 24 | ||||
| -rw-r--r-- | cli/internal/util/filter/filter.go | 133 | ||||
| -rw-r--r-- | cli/internal/util/filter/filter_test.go | 116 | ||||
| -rw-r--r-- | cli/internal/util/graph.go | 35 | ||||
| -rw-r--r-- | cli/internal/util/modulo.go | 13 | ||||
| -rw-r--r-- | cli/internal/util/parse_concurrency.go | 39 | ||||
| -rw-r--r-- | cli/internal/util/parse_concurrency_test.go | 79 | ||||
| -rw-r--r-- | cli/internal/util/printf.go | 63 | ||||
| -rw-r--r-- | cli/internal/util/run_opts.go | 53 | ||||
| -rw-r--r-- | cli/internal/util/semaphore.go | 43 | ||||
| -rw-r--r-- | cli/internal/util/set.go | 147 | ||||
| -rw-r--r-- | cli/internal/util/set_test.go | 149 | ||||
| -rw-r--r-- | cli/internal/util/status.go | 47 | ||||
| -rw-r--r-- | cli/internal/util/task_id.go | 66 | ||||
| -rw-r--r-- | cli/internal/util/task_output_mode.go | 100 |
18 files changed, 0 insertions, 1189 deletions
diff --git a/cli/internal/util/backends.go b/cli/internal/util/backends.go deleted file mode 100644 index 66941ad..0000000 --- a/cli/internal/util/backends.go +++ /dev/null @@ -1,30 +0,0 @@ -package util - -import ( - "fmt" - "io/ioutil" - "path/filepath" - - "github.com/vercel/turbo/cli/internal/yaml" -) - -// YarnRC Represents contents of .yarnrc.yml -type YarnRC struct { - NodeLinker string `yaml:"nodeLinker"` -} - -// IsNMLinker Checks that Yarn is set to use the node-modules linker style -func IsNMLinker(cwd string) (bool, error) { - yarnRC := &YarnRC{} - - bytes, err := ioutil.ReadFile(filepath.Join(cwd, ".yarnrc.yml")) - if err != nil { - return false, fmt.Errorf(".yarnrc.yml: %w", err) - } - - if yaml.Unmarshal(bytes, yarnRC) != nil { - return false, fmt.Errorf(".yarnrc.yml: %w", err) - } - - return yarnRC.NodeLinker == "node-modules", nil -} diff --git a/cli/internal/util/browser/open.go b/cli/internal/util/browser/open.go deleted file mode 100644 index a6171e9..0000000 --- a/cli/internal/util/browser/open.go +++ /dev/null @@ -1,37 +0,0 @@ -package browser - -import ( - "fmt" - "os/exec" - "runtime" -) - -// OpenBrowser attempts to interactively open a browser window at the given URL -func OpenBrowser(url string) error { - var err error - - switch runtime.GOOS { - case "linux": - if posixBinExists("wslview") { - err = exec.Command("wslview", url).Start() - } else { - err = exec.Command("xdg-open", url).Start() - } - case "windows": - err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() - case "darwin": - err = exec.Command("open", url).Start() - default: - err = fmt.Errorf("unsupported platform") - } - if err != nil { - return err - } - return nil -} - -func posixBinExists(bin string) bool { - err := exec.Command("which", bin).Run() - // we mostly don't care what the error is, it suggests the binary is not usable - return err == nil -} diff --git a/cli/internal/util/closer.go b/cli/internal/util/closer.go deleted file mode 100644 index 996760b..0000000 --- a/cli/internal/util/closer.go +++ /dev/null @@ -1,15 +0,0 @@ -package util - -// CloseAndIgnoreError is a utility to tell our linter that we explicitly deem it okay -// to not check a particular error on closing of a resource. -// -// We use `errcheck` as a linter, which is super-opinionated about checking errors, -// even in places where we don't necessarily care to check the error. -// -// `golangci-lint` has a default ignore list for this lint problem (EXC0001) which -// can be used to sidestep this problem but it's possibly a little too-heavy-handed -// in exclusion. At the expense of discoverability, this utility function forces -// opt-in to ignoring errors on closing of things that can be `Close`d. -func CloseAndIgnoreError(closer interface{ Close() error }) { - _ = closer.Close() -} diff --git a/cli/internal/util/cmd.go b/cli/internal/util/cmd.go deleted file mode 100644 index ae79aa0..0000000 --- a/cli/internal/util/cmd.go +++ /dev/null @@ -1,24 +0,0 @@ -package util - -import ( - "bytes" - - "github.com/spf13/cobra" -) - -// ExitCodeError is a specific error that is returned by the command to specify the exit code -type ExitCodeError struct { - ExitCode int -} - -func (e *ExitCodeError) Error() string { return "exit code error" } - -// HelpForCobraCmd returns the help string for a given command -// Note that this overwrites the output for the command -func HelpForCobraCmd(cmd *cobra.Command) string { - f := cmd.HelpFunc() - buf := bytes.NewBufferString("") - cmd.SetOut(buf) - f(cmd, []string{}) - return buf.String() -} diff --git a/cli/internal/util/filter/filter.go b/cli/internal/util/filter/filter.go deleted file mode 100644 index fbc475d..0000000 --- a/cli/internal/util/filter/filter.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2015-2020 InfluxData Inc. MIT License (MIT) -// https://github.com/influxdata/telegraf -package filter - -import ( - "strings" - - "github.com/gobwas/glob" -) - -type Filter interface { - Match(string) bool -} - -// Compile takes a list of string filters and returns a Filter interface -// for matching a given string against the filter list. The filter list -// supports glob matching too, ie: -// -// f, _ := Compile([]string{"cpu", "mem", "net*"}) -// f.Match("cpu") // true -// f.Match("network") // true -// f.Match("memory") // false -func Compile(filters []string) (Filter, error) { - // return if there is nothing to compile - if len(filters) == 0 { - return nil, nil - } - - // check if we can compile a non-glob filter - noGlob := true - for _, filter := range filters { - if hasMeta(filter) { - noGlob = false - break - } - } - - switch { - case noGlob: - // return non-globbing filter if not needed. - return compileFilterNoGlob(filters), nil - case len(filters) == 1: - return glob.Compile(filters[0]) - default: - return glob.Compile("{" + strings.Join(filters, ",") + "}") - } -} - -// hasMeta reports whether path contains any magic glob characters. -func hasMeta(s string) bool { - return strings.ContainsAny(s, "*?[") -} - -type filter struct { - m map[string]struct{} -} - -func (f *filter) Match(s string) bool { - _, ok := f.m[s] - return ok -} - -type filtersingle struct { - s string -} - -func (f *filtersingle) Match(s string) bool { - return f.s == s -} - -func compileFilterNoGlob(filters []string) Filter { - if len(filters) == 1 { - return &filtersingle{s: filters[0]} - } - out := filter{m: make(map[string]struct{})} - for _, filter := range filters { - out.m[filter] = struct{}{} - } - return &out -} - -type IncludeExcludeFilter struct { - include Filter - exclude Filter - includeDefault bool - excludeDefault bool -} - -func NewIncludeExcludeFilter( - include []string, - exclude []string, -) (Filter, error) { - return NewIncludeExcludeFilterDefaults(include, exclude, true, false) -} - -func NewIncludeExcludeFilterDefaults( - include []string, - exclude []string, - includeDefault bool, - excludeDefault bool, -) (Filter, error) { - in, err := Compile(include) - if err != nil { - return nil, err - } - - ex, err := Compile(exclude) - if err != nil { - return nil, err - } - - return &IncludeExcludeFilter{in, ex, includeDefault, excludeDefault}, nil -} - -func (f *IncludeExcludeFilter) Match(s string) bool { - if f.include != nil { - if !f.include.Match(s) { - return false - } - } else if !f.includeDefault { - return false - } - - if f.exclude != nil { - if f.exclude.Match(s) { - return false - } - } else if f.excludeDefault { - return false - } - - return true -} diff --git a/cli/internal/util/filter/filter_test.go b/cli/internal/util/filter/filter_test.go deleted file mode 100644 index 727a4b6..0000000 --- a/cli/internal/util/filter/filter_test.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2015-2020 InfluxData Inc. MIT License (MIT) -// https://github.com/influxdata/telegraf -package filter - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCompile(t *testing.T) { - f, err := Compile([]string{}) - assert.NoError(t, err) - assert.Nil(t, f) - - f, err = Compile([]string{"cpu"}) - assert.NoError(t, err) - assert.True(t, f.Match("cpu")) - assert.False(t, f.Match("cpu0")) - assert.False(t, f.Match("mem")) - - f, err = Compile([]string{"cpu*"}) - assert.NoError(t, err) - assert.True(t, f.Match("cpu")) - assert.True(t, f.Match("cpu0")) - assert.False(t, f.Match("mem")) - - f, err = Compile([]string{"cpu", "mem"}) - assert.NoError(t, err) - assert.True(t, f.Match("cpu")) - assert.False(t, f.Match("cpu0")) - assert.True(t, f.Match("mem")) - - f, err = Compile([]string{"cpu", "mem", "net*"}) - assert.NoError(t, err) - assert.True(t, f.Match("cpu")) - assert.False(t, f.Match("cpu0")) - assert.True(t, f.Match("mem")) - assert.True(t, f.Match("network")) -} - -func TestIncludeExclude(t *testing.T) { - tags := []string{} - labels := []string{"best", "com_influxdata", "timeseries", "com_influxdata_telegraf", "ever"} - - filter, err := NewIncludeExcludeFilter([]string{}, []string{"com_influx*"}) - if err != nil { - t.Fatalf("Failed to create include/exclude filter - %v", err) - } - - for i := range labels { - if filter.Match(labels[i]) { - tags = append(tags, labels[i]) - } - } - - assert.Equal(t, []string{"best", "timeseries", "ever"}, tags) -} - -var benchbool bool - -func BenchmarkFilterSingleNoGlobFalse(b *testing.B) { - f, _ := Compile([]string{"cpu"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("network") - } - benchbool = tmp -} - -func BenchmarkFilterSingleNoGlobTrue(b *testing.B) { - f, _ := Compile([]string{"cpu"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("cpu") - } - benchbool = tmp -} - -func BenchmarkFilter(b *testing.B) { - f, _ := Compile([]string{"cpu", "mem", "net*"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("network") - } - benchbool = tmp -} - -func BenchmarkFilterNoGlob(b *testing.B) { - f, _ := Compile([]string{"cpu", "mem", "net"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("net") - } - benchbool = tmp -} - -func BenchmarkFilter2(b *testing.B) { - f, _ := Compile([]string{"aa", "bb", "c", "ad", "ar", "at", "aq", - "aw", "az", "axxx", "ab", "cpu", "mem", "net*"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("network") - } - benchbool = tmp -} - -func BenchmarkFilter2NoGlob(b *testing.B) { - f, _ := Compile([]string{"aa", "bb", "c", "ad", "ar", "at", "aq", - "aw", "az", "axxx", "ab", "cpu", "mem", "net"}) - var tmp bool - for n := 0; n < b.N; n++ { - tmp = f.Match("net") - } - benchbool = tmp -} diff --git a/cli/internal/util/graph.go b/cli/internal/util/graph.go deleted file mode 100644 index 89de18c..0000000 --- a/cli/internal/util/graph.go +++ /dev/null @@ -1,35 +0,0 @@ -package util - -import ( - "fmt" - "strings" - - "github.com/pyr-sh/dag" -) - -// ValidateGraph checks that a given DAG has no cycles and no self-referential edges. -// We differ from the underlying DAG Validate method in that we allow multiple roots. -func ValidateGraph(graph *dag.AcyclicGraph) error { - // We use Cycles instead of Validate because - // our DAG has multiple roots (entrypoints). - // Validate mandates that there is only a single root node. - cycles := graph.Cycles() - if len(cycles) > 0 { - cycleLines := make([]string, len(cycles)) - for i, cycle := range cycles { - vertices := make([]string, len(cycle)) - for j, vertex := range cycle { - vertices[j] = vertex.(string) - } - cycleLines[i] = "\t" + strings.Join(vertices, ",") - } - return fmt.Errorf("cyclic dependency detected:\n%s", strings.Join(cycleLines, "\n")) - } - - for _, e := range graph.Edges() { - if e.Source() == e.Target() { - return fmt.Errorf("%s depends on itself", e.Source()) - } - } - return nil -} diff --git a/cli/internal/util/modulo.go b/cli/internal/util/modulo.go deleted file mode 100644 index ec2957a..0000000 --- a/cli/internal/util/modulo.go +++ /dev/null @@ -1,13 +0,0 @@ -package util - -// PostitiveMod returns a modulo operator like JavaScripts -func PositiveMod(x, d int) int { - x = x % d - if x >= 0 { - return x - } - if d < 0 { - return x - d - } - return x + d -} diff --git a/cli/internal/util/parse_concurrency.go b/cli/internal/util/parse_concurrency.go deleted file mode 100644 index 6917600..0000000 --- a/cli/internal/util/parse_concurrency.go +++ /dev/null @@ -1,39 +0,0 @@ -package util - -import ( - "fmt" - "math" - "runtime" - "strconv" - "strings" -) - -var ( - // alias so we can mock in tests - runtimeNumCPU = runtime.NumCPU - // positive values check for +Inf - _positiveInfinity = 1 -) - -// ParseConcurrency parses a concurrency value, which can be a number (e.g. 2) or a percentage (e.g. 50%). -func ParseConcurrency(concurrencyRaw string) (int, error) { - if strings.HasSuffix(concurrencyRaw, "%") { - if percent, err := strconv.ParseFloat(concurrencyRaw[:len(concurrencyRaw)-1], 64); err != nil { - return 0, fmt.Errorf("invalid value for --concurrency CLI flag. This should be a number --concurrency=4 or percentage of CPU cores --concurrency=50%% : %w", err) - } else { - if percent > 0 && !math.IsInf(percent, _positiveInfinity) { - return int(math.Max(1, float64(runtimeNumCPU())*percent/100)), nil - } else { - return 0, fmt.Errorf("invalid percentage value for --concurrency CLI flag. This should be a percentage of CPU cores, between 1%% and 100%% : %w", err) - } - } - } else if i, err := strconv.Atoi(concurrencyRaw); err != nil { - return 0, fmt.Errorf("invalid value for --concurrency CLI flag. This should be a positive integer greater than or equal to 1: %w", err) - } else { - if i >= 1 { - return i, nil - } else { - return 0, fmt.Errorf("invalid value %v for --concurrency CLI flag. This should be a positive integer greater than or equal to 1", i) - } - } -} diff --git a/cli/internal/util/parse_concurrency_test.go b/cli/internal/util/parse_concurrency_test.go deleted file mode 100644 index b732724..0000000 --- a/cli/internal/util/parse_concurrency_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package util - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestParseConcurrency(t *testing.T) { - cases := []struct { - Input string - Expected int - }{ - { - "12", - 12, - }, - { - "200%", - 20, - }, - { - "100%", - 10, - }, - { - "50%", - 5, - }, - { - "25%", - 2, - }, - { - "1%", - 1, - }, - { - "0644", // we parse in base 10 - 644, - }, - } - - // mock runtime.NumCPU() to 10 - runtimeNumCPU = func() int { - return 10 - } - - for i, tc := range cases { - t.Run(fmt.Sprintf("%d) '%s' should be parsed at '%d'", i, tc.Input, tc.Expected), func(t *testing.T) { - if result, err := ParseConcurrency(tc.Input); err != nil { - t.Fatalf("invalid parse: %#v", err) - } else { - assert.EqualValues(t, tc.Expected, result) - } - }) - } -} - -func TestInvalidPercents(t *testing.T) { - inputs := []string{ - "asdf", - "-1", - "-l%", - "infinity%", - "-infinity%", - "nan%", - "0b01", - "0o644", - "0xFF", - } - for _, tc := range inputs { - t.Run(tc, func(t *testing.T) { - val, err := ParseConcurrency(tc) - assert.Error(t, err, "input %v got %v", tc, val) - }) - } -} diff --git a/cli/internal/util/printf.go b/cli/internal/util/printf.go deleted file mode 100644 index 9cd6dce..0000000 --- a/cli/internal/util/printf.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright Thought Machine, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -package util - -import ( - "fmt" - "io" - "os" - - "github.com/vercel/turbo/cli/internal/ui" -) - -// initPrintf sets up the replacements used by printf. -func InitPrintf() { - if !ui.IsTTY { - replacements = map[string]string{} - } -} - -// printf is used throughout this package to print something to stderr with some -// replacements for pseudo-shell variables for ANSI formatting codes. -func Sprintf(format string, args ...interface{}) string { - return os.Expand(fmt.Sprintf(format, args...), replace) -} - -func Printf(format string, args ...interface{}) { - fmt.Fprint(os.Stderr, os.Expand(fmt.Sprintf(format, args...), replace)) -} - -func Fprintf(writer io.Writer, format string, args ...interface{}) { - fmt.Fprint(writer, os.Expand(fmt.Sprintf(format, args...), replace)) -} - -func replace(s string) string { - return replacements[s] -} - -// These are the standard set of replacements we use. -var replacements = map[string]string{ - "BOLD": "\x1b[1m", - "BOLD_GREY": "\x1b[30;1m", - "BOLD_RED": "\x1b[31;1m", - "BOLD_GREEN": "\x1b[32;1m", - "BOLD_YELLOW": "\x1b[33;1m", - "BOLD_BLUE": "\x1b[34;1m", - "BOLD_MAGENTA": "\x1b[35;1m", - "BOLD_CYAN": "\x1b[36;1m", - "BOLD_WHITE": "\x1b[37;1m", - "UNDERLINE": "\x1b[4m", - "GREY": "\x1b[2m", - "RED": "\x1b[31m", - "GREEN": "\x1b[32m", - "YELLOW": "\x1b[33m", - "BLUE": "\x1b[34m", - "MAGENTA": "\x1b[35m", - "CYAN": "\x1b[36m", - "WHITE": "\x1b[37m", - "WHITE_ON_RED": "\x1b[37;41;1m", - "RED_NO_BG": "\x1b[31;49;1m", - "RESET": "\x1b[0m", - "ERASE_AFTER": "\x1b[K", - "CLEAR_END": "\x1b[0J", -} diff --git a/cli/internal/util/run_opts.go b/cli/internal/util/run_opts.go deleted file mode 100644 index 08676a0..0000000 --- a/cli/internal/util/run_opts.go +++ /dev/null @@ -1,53 +0,0 @@ -package util - -import "strings" - -// EnvMode specifies if we will be using strict env vars -type EnvMode string - -const ( - // Infer - infer environment variable constraints from turbo.json - Infer EnvMode = "Infer" - // Loose - environment variables are unconstrained - Loose EnvMode = "Loose" - // Strict - environment variables are limited - Strict EnvMode = "Strict" -) - -// MarshalText implements TextMarshaler for the struct. -func (s EnvMode) MarshalText() (text []byte, err error) { - return []byte(strings.ToLower(string(s))), nil -} - -// RunOpts holds the options that control the execution of a turbo run -type RunOpts struct { - // Force execution to be serially one-at-a-time - Concurrency int - // Whether to execute in parallel (defaults to false) - Parallel bool - - EnvMode EnvMode - // The filename to write a perf profile. - Profile string - // If true, continue task executions even if a task fails. - ContinueOnError bool - PassThroughArgs []string - // Restrict execution to only the listed task names. Default false - Only bool - // Dry run flags - DryRun bool - DryRunJSON bool - // Graph flags - GraphDot bool - GraphFile string - NoDaemon bool - SinglePackage bool - - // logPrefix controls whether we should print a prefix in task logs - LogPrefix string - - // Whether turbo should create a run summary - Summarize bool - - ExperimentalSpaceID string -} diff --git a/cli/internal/util/semaphore.go b/cli/internal/util/semaphore.go deleted file mode 100644 index ef29df0..0000000 --- a/cli/internal/util/semaphore.go +++ /dev/null @@ -1,43 +0,0 @@ -package util - -// Semaphore is a wrapper around a channel to provide -// utility methods to clarify that we are treating the -// channel as a semaphore -type Semaphore chan struct{} - -// NewSemaphore creates a semaphore that allows up -// to a given limit of simultaneous acquisitions -func NewSemaphore(n int) Semaphore { - if n <= 0 { - panic("semaphore with limit <=0") - } - ch := make(chan struct{}, n) - return Semaphore(ch) -} - -// Acquire is used to acquire an available slot. -// Blocks until available. -func (s Semaphore) Acquire() { - s <- struct{}{} -} - -// TryAcquire is used to do a non-blocking acquire. -// Returns a bool indicating success -func (s Semaphore) TryAcquire() bool { - select { - case s <- struct{}{}: - return true - default: - return false - } -} - -// Release is used to return a slot. Acquire must -// be called as a pre-condition. -func (s Semaphore) Release() { - select { - case <-s: - default: - panic("release without an acquire") - } -} diff --git a/cli/internal/util/set.go b/cli/internal/util/set.go deleted file mode 100644 index b6c5f86..0000000 --- a/cli/internal/util/set.go +++ /dev/null @@ -1,147 +0,0 @@ -package util - -// Set is a set data structure. -type Set map[interface{}]interface{} - -// SetFromStrings creates a Set containing the strings from the given slice -func SetFromStrings(sl []string) Set { - set := make(Set, len(sl)) - for _, item := range sl { - set.Add(item) - } - return set -} - -// Hashable is the interface used by set to get the hash code of a value. -// If this isn't given, then the value of the item being added to the set -// itself is used as the comparison value. -type Hashable interface { - Hashcode() interface{} -} - -// hashcode returns the hashcode used for set elements. -func hashcode(v interface{}) interface{} { - if h, ok := v.(Hashable); ok { - return h.Hashcode() - } - - return v -} - -// Add adds an item to the set -func (s Set) Add(v interface{}) { - s[hashcode(v)] = v -} - -// Delete removes an item from the set. -func (s Set) Delete(v interface{}) { - delete(s, hashcode(v)) -} - -// Includes returns true/false of whether a value is in the set. -func (s Set) Includes(v interface{}) bool { - _, ok := s[hashcode(v)] - return ok -} - -// Intersection computes the set intersection with other. -func (s Set) Intersection(other Set) Set { - result := make(Set) - if s == nil || other == nil { - return result - } - // Iteration over a smaller set has better performance. - if other.Len() < s.Len() { - s, other = other, s - } - for _, v := range s { - if other.Includes(v) { - result.Add(v) - } - } - return result -} - -// Difference returns a set with the elements that s has but -// other doesn't. -func (s Set) Difference(other Set) Set { - result := make(Set) - for k, v := range s { - var ok bool - if other != nil { - _, ok = other[k] - } - if !ok { - result.Add(v) - } - } - - return result -} - -// Some tests whether at least one element in the array passes the test implemented by the provided function. -// It returns a Boolean value. -func (s Set) Some(cb func(interface{}) bool) bool { - for _, v := range s { - if cb(v) { - return true - } - } - return false -} - -// Filter returns a set that contains the elements from the receiver -// where the given callback returns true. -func (s Set) Filter(cb func(interface{}) bool) Set { - result := make(Set) - - for _, v := range s { - if cb(v) { - result.Add(v) - } - } - - return result -} - -// Len is the number of items in the set. -func (s Set) Len() int { - return len(s) -} - -// List returns the list of set elements. -func (s Set) List() []interface{} { - if s == nil { - return nil - } - - r := make([]interface{}, 0, len(s)) - for _, v := range s { - r = append(r, v) - } - - return r -} - -// UnsafeListOfStrings dangerously casts list to a string -func (s Set) UnsafeListOfStrings() []string { - if s == nil { - return nil - } - - r := make([]string, 0, len(s)) - for _, v := range s { - r = append(r, v.(string)) - } - - return r -} - -// Copy returns a shallow copy of the set. -func (s Set) Copy() Set { - c := make(Set) - for k, v := range s { - c[k] = v - } - return c -} diff --git a/cli/internal/util/set_test.go b/cli/internal/util/set_test.go deleted file mode 100644 index 52736b4..0000000 --- a/cli/internal/util/set_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package util - -import ( - "fmt" - "testing" -) - -func TestSetDifference(t *testing.T) { - cases := []struct { - Name string - A, B []interface{} - Expected []interface{} - }{ - { - "same", - []interface{}{1, 2, 3}, - []interface{}{3, 1, 2}, - []interface{}{}, - }, - - { - "A has extra elements", - []interface{}{1, 2, 3}, - []interface{}{3, 2}, - []interface{}{1}, - }, - - { - "B has extra elements", - []interface{}{1, 2, 3}, - []interface{}{3, 2, 1, 4}, - []interface{}{}, - }, - } - - for i, tc := range cases { - t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { - one := make(Set) - two := make(Set) - expected := make(Set) - for _, v := range tc.A { - one.Add(v) - } - for _, v := range tc.B { - two.Add(v) - } - for _, v := range tc.Expected { - expected.Add(v) - } - - actual := one.Difference(two) - match := actual.Intersection(expected) - if match.Len() != expected.Len() { - t.Fatalf("bad: %#v", actual.List()) - } - }) - } -} - -func TestSetFilter(t *testing.T) { - cases := []struct { - Input []interface{} - Expected []interface{} - }{ - { - []interface{}{1, 2, 3}, - []interface{}{1, 2, 3}, - }, - - { - []interface{}{4, 5, 6}, - []interface{}{4}, - }, - - { - []interface{}{7, 8, 9}, - []interface{}{}, - }, - } - - for i, tc := range cases { - t.Run(fmt.Sprintf("%d-%#v", i, tc.Input), func(t *testing.T) { - input := make(Set) - expected := make(Set) - for _, v := range tc.Input { - input.Add(v) - } - for _, v := range tc.Expected { - expected.Add(v) - } - - actual := input.Filter(func(v interface{}) bool { - return v.(int) < 5 - }) - match := actual.Intersection(expected) - if match.Len() != expected.Len() { - t.Fatalf("bad: %#v", actual.List()) - } - }) - } -} - -func TestSetCopy(t *testing.T) { - a := make(Set) - a.Add(1) - a.Add(2) - - b := a.Copy() - b.Add(3) - - diff := b.Difference(a) - - if diff.Len() != 1 { - t.Fatalf("expected single diff value, got %#v", diff) - } - - if !diff.Includes(3) { - t.Fatalf("diff does not contain 3, got %#v", diff) - } - -} - -func makeSet(n int) Set { - ret := make(Set, n) - for i := 0; i < n; i++ { - ret.Add(i) - } - return ret -} - -func BenchmarkSetIntersection_100_100000(b *testing.B) { - small := makeSet(100) - large := makeSet(100000) - - b.ResetTimer() - for n := 0; n < b.N; n++ { - small.Intersection(large) - } -} - -func BenchmarkSetIntersection_100000_100(b *testing.B) { - small := makeSet(100) - large := makeSet(100000) - - b.ResetTimer() - for n := 0; n < b.N; n++ { - large.Intersection(small) - } -} diff --git a/cli/internal/util/status.go b/cli/internal/util/status.go deleted file mode 100644 index 23ae165..0000000 --- a/cli/internal/util/status.go +++ /dev/null @@ -1,47 +0,0 @@ -package util - -import "fmt" - -// CachingStatus represents the api server's perspective -// on whether remote caching should be allowed -type CachingStatus int - -const ( - // CachingStatusDisabled indicates that the server will not accept or serve artifacts - CachingStatusDisabled CachingStatus = iota - // CachingStatusEnabled indicates that the server will accept and serve artifacts - CachingStatusEnabled - // CachingStatusOverLimit indicates that a usage limit has been hit and the - // server will temporarily not accept or serve artifacts - CachingStatusOverLimit - // CachingStatusPaused indicates that a customer's spending has been paused and the - // server will temporarily not accept or serve artifacts - CachingStatusPaused -) - -// CachingStatusFromString parses a raw string to a caching status enum value -func CachingStatusFromString(raw string) (CachingStatus, error) { - switch raw { - case "disabled": - return CachingStatusDisabled, nil - case "enabled": - return CachingStatusEnabled, nil - case "over_limit": - return CachingStatusOverLimit, nil - case "paused": - return CachingStatusPaused, nil - default: - return CachingStatusDisabled, fmt.Errorf("unknown caching status: %v", raw) - } -} - -// CacheDisabledError is an error used to indicate that remote caching -// is not available. -type CacheDisabledError struct { - Status CachingStatus - Message string -} - -func (cd *CacheDisabledError) Error() string { - return cd.Message -} diff --git a/cli/internal/util/task_id.go b/cli/internal/util/task_id.go deleted file mode 100644 index e4415b6..0000000 --- a/cli/internal/util/task_id.go +++ /dev/null @@ -1,66 +0,0 @@ -package util - -import ( - "fmt" - "strings" -) - -const ( - // TaskDelimiter separates a package name from a task name in a task id - TaskDelimiter = "#" - // RootPkgName is the reserved name that specifies the root package - RootPkgName = "//" -) - -// GetTaskId returns a package-task identifier (e.g @feed/thing#build). -func GetTaskId(pkgName interface{}, target string) string { - if IsPackageTask(target) { - return target - } - return fmt.Sprintf("%v%v%v", pkgName, TaskDelimiter, target) -} - -// RootTaskID returns the task id for running the given task in the root package -func RootTaskID(target string) string { - return GetTaskId(RootPkgName, target) -} - -// GetPackageTaskFromId returns a tuple of the package name and target task -func GetPackageTaskFromId(taskId string) (packageName string, task string) { - arr := strings.Split(taskId, TaskDelimiter) - return arr[0], arr[1] -} - -// RootTaskTaskName returns the task portion of a root task taskID -func RootTaskTaskName(taskID string) string { - return strings.TrimPrefix(taskID, RootPkgName+TaskDelimiter) -} - -// IsPackageTask returns true if input is a package-specific task -// whose name has a length greater than 0. -// -// Accepted: myapp#build -// Rejected: #build, build -func IsPackageTask(task string) bool { - return strings.Index(task, TaskDelimiter) > 0 -} - -// IsTaskInPackage returns true if the task does not belong to a different package -// note that this means unscoped tasks will always return true -func IsTaskInPackage(task string, packageName string) bool { - if !IsPackageTask(task) { - return true - } - packageNameExpected, _ := GetPackageTaskFromId(task) - return packageNameExpected == packageName -} - -// StripPackageName removes the package portion of a taskID if it -// is a package task. Non-package tasks are returned unmodified -func StripPackageName(taskID string) string { - if IsPackageTask(taskID) { - _, task := GetPackageTaskFromId(taskID) - return task - } - return taskID -} diff --git a/cli/internal/util/task_output_mode.go b/cli/internal/util/task_output_mode.go deleted file mode 100644 index eee42e0..0000000 --- a/cli/internal/util/task_output_mode.go +++ /dev/null @@ -1,100 +0,0 @@ -package util - -import ( - "encoding/json" - "fmt" -) - -// TaskOutputMode defines the ways turbo can display task output during a run -type TaskOutputMode int - -const ( - // FullTaskOutput will show all task output - FullTaskOutput TaskOutputMode = iota - // NoTaskOutput will hide all task output - NoTaskOutput - // HashTaskOutput will display turbo-computed task hashes - HashTaskOutput - // NewTaskOutput will show all new task output and turbo-computed task hashes for cached output - NewTaskOutput - // ErrorTaskOutput will show task output for failures only; no cache miss/hit messages are emitted - ErrorTaskOutput -) - -const ( - fullTaskOutputString = "full" - noTaskOutputString = "none" - hashTaskOutputString = "hash-only" - newTaskOutputString = "new-only" - errorTaskOutputString = "errors-only" -) - -// TaskOutputModeStrings is an array containing the string representations for task output modes -var TaskOutputModeStrings = []string{ - fullTaskOutputString, - noTaskOutputString, - hashTaskOutputString, - newTaskOutputString, - errorTaskOutputString, -} - -// FromTaskOutputModeString converts a task output mode's string representation into the enum value -func FromTaskOutputModeString(value string) (TaskOutputMode, error) { - switch value { - case fullTaskOutputString: - return FullTaskOutput, nil - case noTaskOutputString: - return NoTaskOutput, nil - case hashTaskOutputString: - return HashTaskOutput, nil - case newTaskOutputString: - return NewTaskOutput, nil - case errorTaskOutputString: - return ErrorTaskOutput, nil - } - - return FullTaskOutput, fmt.Errorf("invalid task output mode: %v", value) -} - -// ToTaskOutputModeString converts a task output mode enum value into the string representation -func ToTaskOutputModeString(value TaskOutputMode) (string, error) { - switch value { - case FullTaskOutput: - return fullTaskOutputString, nil - case NoTaskOutput: - return noTaskOutputString, nil - case HashTaskOutput: - return hashTaskOutputString, nil - case NewTaskOutput: - return newTaskOutputString, nil - case ErrorTaskOutput: - return errorTaskOutputString, nil - } - - return "", fmt.Errorf("invalid task output mode: %v", value) -} - -// UnmarshalJSON converts a task output mode string representation into an enum -func (c *TaskOutputMode) UnmarshalJSON(data []byte) error { - var rawTaskOutputMode string - if err := json.Unmarshal(data, &rawTaskOutputMode); err != nil { - return err - } - - taskOutputMode, err := FromTaskOutputModeString(rawTaskOutputMode) - if err != nil { - return err - } - - *c = taskOutputMode - return nil -} - -// MarshalJSON converts a task output mode to its string representation -func (c TaskOutputMode) MarshalJSON() ([]byte, error) { - outputModeString, err := ToTaskOutputModeString(c) - if err != nil { - return nil, err - } - return json.Marshal(outputModeString) -} |
