diff --git a/expand.go b/expand.go index e36338e..39c2341 100644 --- a/expand.go +++ b/expand.go @@ -128,7 +128,7 @@ func expandDoubleQuoted(input string, vars map[string][]string, expandBackticks return input, len(input) } -// Expand a single quoted string starting after a '\'' +// Expand a single quoted string starting after a '\” func expandSingleQuoted(input string) (string, int) { j := strings.Index(input, "'") if j < 0 { @@ -225,33 +225,6 @@ func expandSigil(input string, vars map[string][]string) ([]string, int) { return []string{"$" + input}, len(input) } -// Find and expand all sigils. -func expandSigils(input string, vars map[string][]string) []string { - parts := make([]string, 0) - expanded := "" - for i := 0; i < len(input); { - j := strings.IndexRune(input[i:], '$') - if j < 0 { - expanded += input[i:] - break - } - - ex, k := expandSigil(input[j+1:], vars) - if len(ex) > 0 { - ex[0] = expanded + ex[0] - expanded = ex[len(ex)-1] - parts = append(parts, ex[:len(ex)-1]...) - } - i = k - } - - if len(expanded) > 0 { - parts = append(parts, expanded) - } - - return parts -} - // Find and expand all sigils in a recipe, producing a flat string. func expandRecipeSigils(input string, vars map[string][]string) string { expanded := "" diff --git a/go.mod b/go.mod index 8b27133..d286ece 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,15 @@ module github.com/ctSkennerton/mk -go 1.13 +go 1.24 require ( - github.com/aws/aws-sdk-go v1.35.25 + github.com/aws/aws-sdk-go v1.55.7 github.com/google/go-cmp v0.4.0 - github.com/mattn/go-isatty v0.0.12 + github.com/mattn/go-isatty v0.0.20 github.com/sanity-io/litter v1.2.0 ) + +require ( + github.com/jmespath/go-jmespath v0.4.0 // indirect + golang.org/x/sys v0.33.0 // indirect +) diff --git a/go.sum b/go.sum index b2d1ff2..bf9878d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/aws/aws-sdk-go v1.35.25 h1:0+UC6ZquMOLvYABoz0olShCAe+M9oKllgPfr2hnv9zE= -github.com/aws/aws-sdk-go v1.35.25/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -7,10 +7,10 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -19,17 +19,11 @@ github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312 h1:UsFdQ3ZmlzS0BqZYGxvYaXvFGUbCmPGy8DM7qWJJiIQ= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/graph.go b/graph.go index c00cdb9..f6817f7 100644 --- a/graph.go +++ b/graph.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io" "log" "net/url" "os" @@ -41,16 +40,15 @@ type nodeFlag int const ( nodeFlagCycle nodeFlag = 0x0002 - nodeFlagReady = 0x0004 - nodeFlagProbable = 0x0100 - nodeFlagVacuous = 0x0200 + nodeFlagReady nodeFlag = 0x0004 + nodeFlagProbable nodeFlag = 0x0100 + nodeFlagVacuous nodeFlag = 0x0200 ) // A node in the dependency graph type node struct { r *rule // rule to be applied name string // target name - prog string // custom program to compare times t time.Time // file modification time exists bool // does a non-virtual target exist prereqs []*edge // prerequisite rules @@ -103,19 +101,6 @@ func (g *graph) newnode(name string) *node { return u } -// Print a graph in graphviz format. -func (g *graph) visualize(w io.Writer) { - fmt.Fprintln(w, "digraph mk {") - for t, u := range g.nodes { - for i := range u.prereqs { - if u.prereqs[i].v != nil { - fmt.Fprintf(w, " \"%s\" -> \"%s\";\n", t, u.prereqs[i].v.name) - } - } - } - fmt.Fprintln(w, "}") -} - // Create a new arc. func (u *node) newedge(v *node, r *rule) *edge { e := &edge{v: v, r: r} @@ -366,7 +351,7 @@ func (g *graph) ambiguous(u *node) { // Print a trace of rules, k func (g *graph) trace(name string, e *edge) { fmt.Fprintf(os.Stderr, "\t%s", name) - for true { + for { prereqname := "" if e.v != nil { prereqname = e.v.name @@ -379,9 +364,7 @@ func (g *graph) trace(name string, e *edge) { continue } } - break - } else { - break } + break } } diff --git a/lex.go b/lex.go index c778cd0..e5bd0ba 100644 --- a/lex.go +++ b/lex.go @@ -15,7 +15,7 @@ const nonBareRunes = " \t\n\r\\=:#'\"$" // Return true if the string contains whitespace only. func onlyWhitespace(s string) bool { - return strings.IndexAny(s, " \t\r\n") < 0 + return !strings.ContainsAny(s, " \t\r\n") } const ( @@ -128,7 +128,7 @@ func (l *lexer) next() rune { l.indented = true } else { l.col += 1 - if strings.IndexRune(" \t", c) < 0 { + if !strings.ContainsRune(" \t", c) { l.indented = false } } @@ -151,27 +151,17 @@ func (l *lexer) emit(typ tokenType) { // Consume the next run if it is in the given string. func (l *lexer) accept(valid string) bool { - if strings.IndexRune(valid, l.peek()) >= 0 { + if strings.ContainsRune(valid, l.peek()) { l.next() return true } return false } -// Skip the next rune if it is in the valid string. Return true if it was -// skipped. -func (l *lexer) ignore(valid string) bool { - if strings.IndexRune(valid, l.peek()) >= 0 { - l.skip() - return true - } - return false -} - // Consume characters from the valid string until the next is not. func (l *lexer) acceptRun(valid string) int { prevpos := l.pos - for strings.IndexRune(valid, l.peek()) >= 0 { + for strings.ContainsRune(valid, l.peek()) { l.next() } return l.pos - prevpos @@ -179,7 +169,7 @@ func (l *lexer) acceptRun(valid string) int { // Accept until something from the given string is encountered. func (l *lexer) acceptUntil(invalid string) { - for l.pos < len(l.input) && strings.IndexRune(invalid, l.peek()) < 0 { + for l.pos < len(l.input) && !strings.ContainsRune(invalid, l.peek()) { l.next() } @@ -191,7 +181,7 @@ func (l *lexer) acceptUntil(invalid string) { // Accept until something from the given string is encountered, or the end of th // file func (l *lexer) acceptUntilOrEof(invalid string) { - for l.pos < len(l.input) && strings.IndexRune(invalid, l.peek()) < 0 { + for l.pos < len(l.input) && !strings.ContainsRune(invalid, l.peek()) { l.next() } } @@ -199,7 +189,7 @@ func (l *lexer) acceptUntilOrEof(invalid string) { // Skip characters from the valid string until the next is not. func (l *lexer) skipRun(valid string) int { prevpos := l.pos - for strings.IndexRune(valid, l.peek()) >= 0 { + for strings.ContainsRune(valid, l.peek()) { l.skip() } return l.pos - prevpos @@ -207,7 +197,7 @@ func (l *lexer) skipRun(valid string) int { // Skip until something from the given string is encountered. func (l *lexer) skipUntil(invalid string) { - for l.pos < len(l.input) && strings.IndexRune(invalid, l.peek()) < 0 { + for l.pos < len(l.input) && !strings.ContainsRune(invalid, l.peek()) { l.skip() } diff --git a/mk.go b/mk.go index cdbfa29..e8d7c3b 100644 --- a/mk.go +++ b/mk.go @@ -4,7 +4,6 @@ import ( "bufio" "flag" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -107,7 +106,6 @@ const ( ) // Build a node's prereqs. Block until completed. -// func mkNodePrereqs(g *graph, u *node, e *edge, prereqs []*node, dryrun bool, required bool) nodeStatus { prereqstat := make(chan nodeStatus) @@ -145,11 +143,11 @@ func mkNodePrereqs(g *graph, u *node, e *edge, prereqs []*node, dryrun bool, // concurrently. // // Args: -// g: Graph in which the node lives. -// u: Node to (possibly) build. -// dryrun: Don't actually build anything, just pretend. -// required: Avoid building this node, unless its prereqs are out of date. // +// g: Graph in which the node lives. +// u: Node to (possibly) build. +// dryrun: Don't actually build anything, just pretend. +// required: Avoid building this node, unless its prereqs are out of date. func mkNode(g *graph, u *node, dryrun bool, required bool) { // try to claim on this node u.mutex.Lock() @@ -270,24 +268,6 @@ func mkPrintError(msg string) { } } -func mkPrintSuccess(msg string) { - if !color { - fmt.Println(msg) - } else { - fmt.Printf("%s%s%s\n", ansiTermGreen, msg, ansiTermDefault) - } -} - -func mkPrintMessage(msg string) { - mkMsgMutex.Lock() - if !color { - fmt.Println(msg) - } else { - fmt.Printf("%s%s%s\n", ansiTermBlue, msg, ansiTermDefault) - } - mkMsgMutex.Unlock() -} - func mkPrintRecipe(target string, recipe string, quiet bool) { mkMsgMutex.Lock() if !color { @@ -345,12 +325,10 @@ func main() { } } - mkfile, err := os.Open(mkfilepath) + input, err := os.ReadFile(mkfilepath) if err != nil { mkError("no mkfile found") } - input, _ := ioutil.ReadAll(mkfile) - mkfile.Close() abspath, err := filepath.Abs(mkfilepath) if err != nil { @@ -414,7 +392,7 @@ func main() { c, _, err := in.ReadRune() if err != nil { return - } else if strings.IndexRune(" \n\t\r", c) >= 0 { + } else if strings.ContainsRune(" \n\t\r", c) { continue } else if c == 'y' { break diff --git a/mk_test.go b/mk_test.go index 1117c0b..34717dd 100644 --- a/mk_test.go +++ b/mk_test.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "io/ioutil" "os" "os/exec" "testing" @@ -147,12 +146,7 @@ func TestBasicMaking(t *testing.T) { } } - efd, err := os.Open(tv.output) - if err != nil { - t.Errorf("%s can't open: %v", tv.input, err) - continue - } - want, err := ioutil.ReadAll(efd) + want, err := os.ReadFile(tv.output) if err != nil { t.Errorf("%s can't read: %v", tv.input, err) continue diff --git a/parse.go b/parse.go index 7e1d8a9..17fdc5d 100644 --- a/parse.go +++ b/parse.go @@ -5,7 +5,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "regexp" @@ -175,11 +174,10 @@ func parseRedirInclude(p *parser, t token) parserStateFun { // TODO(rjk): Be sure that this is the right behaviour. filename = parts[0] - file, err := os.Open(filename) + input, err := os.ReadFile(filename) if err != nil { p.basicErrorAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0]) } - input, _ := ioutil.ReadAll(file) path, err := filepath.Abs(filename) if err != nil { diff --git a/recipe.go b/recipe.go index 1796228..6e23aa2 100644 --- a/recipe.go +++ b/recipe.go @@ -25,7 +25,7 @@ func stripIndentation(s string, mincol int) string { i := 0 for i < len(line) && col < mincol { c, w := utf8.DecodeRuneInString(line[i:]) - if strings.IndexRune(" \t\n", c) >= 0 { + if strings.ContainsRune(" \t\n", c) { col += 1 i += w } else { @@ -130,16 +130,17 @@ func dorecipe(target string, u *node, e *edge, dryrun bool) bool { // Execute a subprocess (typically a recipe). // // Args: -// program: Program path or name located in PATH -// input: String piped into the program's stdin -// capture_out: If true, capture and return the program's stdout rather than echoing it. +// +// program: Program path or name located in PATH +// input: String piped into the program's stdin +// capture_out: If true, capture and return the program's stdout rather than echoing it. // // Returns -// (output, success) -// output is an empty string of catputer_out is false, or the collected output from the profram is true. // -// success is true if the exit code was 0 and false otherwise +// (output, success) +// output is an empty string of catputer_out is false, or the collected output from the profram is true. // +// success is true if the exit code was 0 and false otherwise func subprocess(program string, args []string, env []string, diff --git a/remote.go b/remote.go index 03947bd..5d41508 100644 --- a/remote.go +++ b/remote.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "log" "net/http" "net/url" @@ -36,7 +37,11 @@ func updateHttpTimestamp(u *node) { } func updateS3Timestamp(u *node, uri *url.URL) { - svc := s3.New(session.New()) + ses, err := session.NewSession() + if err != nil { + panic(fmt.Errorf("unable to create a session: %w", err)) + } + svc := s3.New(ses) input := &s3.HeadObjectInput{ Bucket: aws.String(uri.Host), Key: aws.String(uri.Path[1:]), diff --git a/rules_test.go b/rules_test.go index 210a700..b833d2d 100644 --- a/rules_test.go +++ b/rules_test.go @@ -6,7 +6,7 @@ import ( ) func TestMatchMetaRule(t *testing.T) { - regex, err := regexp.Compile("^data/processed/(\\d+)/mapping_k10.bam.bai$") + regex, err := regexp.Compile(`^data/processed/(\d+)/mapping_k10.bam.bai$`) if err != nil { t.Error("Failure to compile regex pattern") }