From 968d5dbc40ba31456aff42dbca77738065ee09d3 Mon Sep 17 00:00:00 2001 From: Kevin Hanselman Date: Wed, 22 Sep 2021 18:35:26 -0400 Subject: [PATCH] add project lock file to discourage concurrent use fixes #22 (sufficiently, for now) * remove io/ioutil, comment on possible race conditions, update deps * show DVC config in benchmarks, hide dep update from changelog --- .goreleaser.yml | 1 + go.mod | 16 +- go.sum | 150 +++++++++++++++--- .../benchmarks/generate_front_matter.sh | 6 + .../tests/basic_commit_copy/expected_fs.txt | 2 +- .../00_commit/expected_fs.txt | 2 +- .../01_checkout/expected_fs.txt | 2 +- .../00_commit/expected_fs.txt | 2 +- .../01_checkout/expected_fs.txt | 2 +- .../expected_fs.txt | 2 +- .../03_checkout_copy/expected_fs.txt | 2 +- .../04_push/expected_fs.txt | 2 +- .../05_fetch/expected_fs.txt | 2 +- .../00_commit/expected_fs.txt | 2 +- .../01_checkout/expected_fs.txt | 2 +- .../expected_fs.txt | 2 +- .../03_checkout_copy/expected_fs.txt | 2 +- .../basic_run/00_base_stage/expected_fs.txt | 2 +- .../01_secondary_stage/expected_fs.txt | 2 +- .../external_cache/00_commit/expected_fs.txt | 2 +- .../01_checkout_copy/expected_fs.txt | 2 +- integration/tests/lock_project/run.sh | 30 ++++ .../00_checkout/expected_fs.txt | 2 +- .../01_add_new_file/expected_fs.txt | 2 +- .../02_checkout/expected_fs.txt | 2 +- .../tests/pull/00_pull/expected_fs.txt | 2 +- .../tests/pull/01_pull_copy/expected_fs.txt | 2 +- .../tests/pull/02_pull_stage/expected_fs.txt | 2 +- .../02_run_and_commit/expected_fs.txt | 2 +- src/cache/commit.go | 14 +- src/cache/dir_checkout_test.go | 3 + src/cache/dir_commit_test.go | 8 +- src/cache/dir_status_test.go | 2 + src/cache/status.go | 5 +- src/cmd/checkout.go | 18 +-- src/cmd/commit.go | 18 +-- src/cmd/config.go | 21 +-- src/cmd/fetch.go | 29 +--- src/cmd/graph.go | 11 +- src/cmd/init.go | 9 +- src/cmd/pull.go | 7 + src/cmd/push.go | 21 +-- src/cmd/root.go | 92 +++++++++-- src/cmd/run.go | 18 +-- src/cmd/status.go | 17 +- src/index/index.go | 2 + src/stage/stage.go | 4 +- src/testutil/testutil.go | 9 +- 48 files changed, 344 insertions(+), 215 deletions(-) create mode 100755 integration/tests/lock_project/run.sh diff --git a/.goreleaser.yml b/.goreleaser.yml index b7b0891..7ff8ac0 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -23,3 +23,4 @@ changelog: - '^docs:' - '^test:' - '^misc:' + - '^deps:' diff --git a/go.mod b/go.mod index 020ae5f..9dfd109 100644 --- a/go.mod +++ b/go.mod @@ -8,22 +8,22 @@ require ( github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 github.com/cheggaaa/pb/v3 v3.0.8 github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect - github.com/fatih/color v1.12.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/felixge/fgprof v0.9.1 github.com/google/go-cmp v0.5.6 - github.com/google/pprof v0.0.0-20210726183535-c50bf4fe5303 // indirect - github.com/mattn/go-isatty v0.0.13 + github.com/google/pprof v0.0.0-20210827144239-02619b876842 // indirect + github.com/mattn/go-isatty v0.0.14 github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 - github.com/spf13/cast v1.4.0 // indirect github.com/spf13/cobra v1.2.1 - github.com/spf13/viper v1.8.1 + github.com/spf13/viper v1.9.0 github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.7.0 - github.com/zeebo/blake3 v0.2.0 + github.com/zeebo/blake3 v0.2.1 + go.uber.org/goleak v1.1.11 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/sys v0.0.0-20210921065528-437939a70204 // indirect + golang.org/x/text v0.3.7 // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index fe62974..e42a401 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,11 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -27,6 +32,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -39,6 +45,7 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= @@ -46,6 +53,7 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= @@ -53,6 +61,7 @@ github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqO github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 h1:t8KYCwSKsOEZBFELI4Pn/phbp38iJ1RRAkDFNin1aak= github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -62,6 +71,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -76,15 +86,18 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs= github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -103,6 +116,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -120,6 +134,7 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -139,6 +154,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -151,23 +167,31 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210726183535-c50bf4fe5303 h1:UP+GUfRSErTzM7UtTMt4TjnfXKK3ybrGQasgSOp7vLY= -github.com/google/pprof v0.0.0-20210726183535-c50bf4fe5303/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210827144239-02619b876842 h1:JCrt5MIE1fHQtdy1825HwJ45oVQaqHE6lgssRhjcg/o= +github.com/google/pprof v0.0.0-20210827144239-02619b876842/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -179,8 +203,11 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -188,30 +215,38 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= -github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -220,14 +255,16 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -235,6 +272,7 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= @@ -245,25 +283,26 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.0 h1:WhlbjwB9EGCc8W5Rxdkus+wmH2ASRwwTJk6tgHKwdqQ= -github.com/spf13/cast v1.4.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -283,10 +322,10 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.0 h1:1SGx3IvKWFUU/xl+/7kjdcjjMcvVSm+3dMo/N42afC8= -github.com/zeebo/blake3 v0.2.0/go.mod h1:G9pM4qQwjRzF1/v7+vabMj/c5mWpGZ2Wzo3Eb4z0pb4= -github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0= -github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +github.com/zeebo/blake3 v0.2.1 h1:O+N0Y8Re2XAYjp0adlZDA2juyRguhMfPCgh8YIf7vyE= +github.com/zeebo/blake3 v0.2.1/go.mod h1:TSQ0KjMH+pht+bRyvVooJ1rBpvvngSGaPISafq9MxJk= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= @@ -297,7 +336,10 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -305,8 +347,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -330,6 +374,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -356,6 +401,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -378,6 +424,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -390,6 +437,10 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -406,6 +457,7 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -413,13 +465,18 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -444,9 +501,17 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210921065528-437939a70204 h1:JJhkWtBuTQKyz2bd5WG9H8iUsJRU3En/KRfN8B2RnDs= +golang.org/x/sys v0.0.0-20210921065528-437939a70204/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -455,8 +520,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -474,6 +540,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -510,7 +577,12 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -538,6 +610,12 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -585,7 +663,18 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -605,7 +694,13 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -618,12 +713,15 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/integration/benchmarks/generate_front_matter.sh b/integration/benchmarks/generate_front_matter.sh index d633f0c..740e39b 100755 --- a/integration/benchmarks/generate_front_matter.sh +++ b/integration/benchmarks/generate_front_matter.sh @@ -23,4 +23,10 @@ cat << EOF Dud version: $(dud version | xargs) $(dvc version | head -n1 | xargs) + +DVC non-default configuration: + EOF + +# Add spaces to each line to treat the output as a Markdown code block. +dvc config --list --global | awk '{ print " " $0 }' diff --git a/integration/tests/basic_commit_copy/expected_fs.txt b/integration/tests/basic_commit_copy/expected_fs.txt index 07b7d5e..7fd5b05 100644 --- a/integration/tests/basic_commit_copy/expected_fs.txt +++ b/integration/tests/basic_commit_copy/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/49 [-r--r--r-- user 4] ./.dud/cache/49/dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92 diff --git a/integration/tests/basic_directory_operations/00_commit/expected_fs.txt b/integration/tests/basic_directory_operations/00_commit/expected_fs.txt index 5aab164..38c1753 100644 --- a/integration/tests/basic_directory_operations/00_commit/expected_fs.txt +++ b/integration/tests/basic_directory_operations/00_commit/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_operations/01_checkout/expected_fs.txt b/integration/tests/basic_directory_operations/01_checkout/expected_fs.txt index 5aab164..38c1753 100644 --- a/integration/tests/basic_directory_operations/01_checkout/expected_fs.txt +++ b/integration/tests/basic_directory_operations/01_checkout/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/00_commit/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/00_commit/expected_fs.txt index 0b97325..1bade11 100644 --- a/integration/tests/basic_directory_ops_recursive/00_commit/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/00_commit/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/01_checkout/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/01_checkout/expected_fs.txt index 0b97325..1bade11 100644 --- a/integration/tests/basic_directory_ops_recursive/01_checkout/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/01_checkout/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/02_commit_noop_when_uptodate/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/02_commit_noop_when_uptodate/expected_fs.txt index 0b97325..1bade11 100644 --- a/integration/tests/basic_directory_ops_recursive/02_commit_noop_when_uptodate/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/02_commit_noop_when_uptodate/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/03_checkout_copy/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/03_checkout_copy/expected_fs.txt index 5257dcd..b73a739 100644 --- a/integration/tests/basic_directory_ops_recursive/03_checkout_copy/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/03_checkout_copy/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/04_push/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/04_push/expected_fs.txt index 5eaa1d7..bc4daef 100644 --- a/integration/tests/basic_directory_ops_recursive/04_push/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/04_push/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_directory_ops_recursive/05_fetch/expected_fs.txt b/integration/tests/basic_directory_ops_recursive/05_fetch/expected_fs.txt index 5eaa1d7..bc4daef 100644 --- a/integration/tests/basic_directory_ops_recursive/05_fetch/expected_fs.txt +++ b/integration/tests/basic_directory_ops_recursive/05_fetch/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-r--r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/basic_file_operations/00_commit/expected_fs.txt b/integration/tests/basic_file_operations/00_commit/expected_fs.txt index a6603d4..5652d5c 100644 --- a/integration/tests/basic_file_operations/00_commit/expected_fs.txt +++ b/integration/tests/basic_file_operations/00_commit/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/49 [-r--r--r-- user 4] ./.dud/cache/49/dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92 diff --git a/integration/tests/basic_file_operations/01_checkout/expected_fs.txt b/integration/tests/basic_file_operations/01_checkout/expected_fs.txt index a6603d4..5652d5c 100644 --- a/integration/tests/basic_file_operations/01_checkout/expected_fs.txt +++ b/integration/tests/basic_file_operations/01_checkout/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/49 [-r--r--r-- user 4] ./.dud/cache/49/dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92 diff --git a/integration/tests/basic_file_operations/02_commit_noop_when_uptodate/expected_fs.txt b/integration/tests/basic_file_operations/02_commit_noop_when_uptodate/expected_fs.txt index a6603d4..5652d5c 100644 --- a/integration/tests/basic_file_operations/02_commit_noop_when_uptodate/expected_fs.txt +++ b/integration/tests/basic_file_operations/02_commit_noop_when_uptodate/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/49 [-r--r--r-- user 4] ./.dud/cache/49/dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92 diff --git a/integration/tests/basic_file_operations/03_checkout_copy/expected_fs.txt b/integration/tests/basic_file_operations/03_checkout_copy/expected_fs.txt index 07b7d5e..7fd5b05 100644 --- a/integration/tests/basic_file_operations/03_checkout_copy/expected_fs.txt +++ b/integration/tests/basic_file_operations/03_checkout_copy/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/49 [-r--r--r-- user 4] ./.dud/cache/49/dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92 diff --git a/integration/tests/basic_run/00_base_stage/expected_fs.txt b/integration/tests/basic_run/00_base_stage/expected_fs.txt index a5f9008..5faf483 100644 --- a/integration/tests/basic_run/00_base_stage/expected_fs.txt +++ b/integration/tests/basic_run/00_base_stage/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [-rw-r--r-- user 621] ./.dud/config.yaml [-rw-r--r-- user 10] ./.dud/index diff --git a/integration/tests/basic_run/01_secondary_stage/expected_fs.txt b/integration/tests/basic_run/01_secondary_stage/expected_fs.txt index 44d7f85..3975fcb 100644 --- a/integration/tests/basic_run/01_secondary_stage/expected_fs.txt +++ b/integration/tests/basic_run/01_secondary_stage/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [-rw-r--r-- user 621] ./.dud/config.yaml [-rw-r--r-- user 22] ./.dud/index diff --git a/integration/tests/external_cache/00_commit/expected_fs.txt b/integration/tests/external_cache/00_commit/expected_fs.txt index 80aea5d..96e772e 100644 --- a/integration/tests/external_cache/00_commit/expected_fs.txt +++ b/integration/tests/external_cache/00_commit/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [-rw-r--r-- user 50] ./.dud/config.yaml [-rw-r--r-- user 11] ./.dud/index diff --git a/integration/tests/external_cache/01_checkout_copy/expected_fs.txt b/integration/tests/external_cache/01_checkout_copy/expected_fs.txt index 248b25e..a9613bc 100644 --- a/integration/tests/external_cache/01_checkout_copy/expected_fs.txt +++ b/integration/tests/external_cache/01_checkout_copy/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [-rw-r--r-- user 50] ./.dud/config.yaml [-rw-r--r-- user 11] ./.dud/index diff --git a/integration/tests/lock_project/run.sh b/integration/tests/lock_project/run.sh new file mode 100755 index 0000000..14784a4 --- /dev/null +++ b/integration/tests/lock_project/run.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -euo pipefail + +dud init + +dud stage gen -o foo.txt -- sleep 10 > sleep.yaml + +dud stage add sleep.yaml + +# This loop is mainly to ensure this concurrent test code is working well. +for _ in $(seq 1 10); do + dud run & + + # Give 'dud run' enough time to start + sleep 0.02 + + if dud status; then + echo 1>&2 'expected second concurrent dud command to fail' + exit 1 + fi + + # Kill dud run's command and wait for it stop. This should cause 'run' to + # fail, but we still expect Dud to release the project lock file. + killall sleep + wait + if test -f .dud/lock; then + echo 1>&2 'expected first dud command to clean up its lock file' + exit 1 + fi +done diff --git a/integration/tests/old_dir_manifest_schema/00_checkout/expected_fs.txt b/integration/tests/old_dir_manifest_schema/00_checkout/expected_fs.txt index 5039c0e..6db0d02 100644 --- a/integration/tests/old_dir_manifest_schema/00_checkout/expected_fs.txt +++ b/integration/tests/old_dir_manifest_schema/00_checkout/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-rw-r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/old_dir_manifest_schema/01_add_new_file/expected_fs.txt b/integration/tests/old_dir_manifest_schema/01_add_new_file/expected_fs.txt index 099fe83..76b6075 100644 --- a/integration/tests/old_dir_manifest_schema/01_add_new_file/expected_fs.txt +++ b/integration/tests/old_dir_manifest_schema/01_add_new_file/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-rw-r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/old_dir_manifest_schema/02_checkout/expected_fs.txt b/integration/tests/old_dir_manifest_schema/02_checkout/expected_fs.txt index 099fe83..76b6075 100644 --- a/integration/tests/old_dir_manifest_schema/02_checkout/expected_fs.txt +++ b/integration/tests/old_dir_manifest_schema/02_checkout/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/00 [-rw-r--r-- user 2] ./.dud/cache/00/51fb8f5c8288b80163ea72ab2f482fc402ca9944b580aa57e694eedfc3ad1c diff --git a/integration/tests/pull/00_pull/expected_fs.txt b/integration/tests/pull/00_pull/expected_fs.txt index 748851f..82d5115 100644 --- a/integration/tests/pull/00_pull/expected_fs.txt +++ b/integration/tests/pull/00_pull/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/b3 [-r--r--r-- user 4] ./.dud/cache/b3/199d36d434044e6778b77d13f8dbaba32a73d9522c1ae8d0f73ef1ff14e71f diff --git a/integration/tests/pull/01_pull_copy/expected_fs.txt b/integration/tests/pull/01_pull_copy/expected_fs.txt index 88e38ca..bf19aa2 100644 --- a/integration/tests/pull/01_pull_copy/expected_fs.txt +++ b/integration/tests/pull/01_pull_copy/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/b3 [-r--r--r-- user 4] ./.dud/cache/b3/199d36d434044e6778b77d13f8dbaba32a73d9522c1ae8d0f73ef1ff14e71f diff --git a/integration/tests/pull/02_pull_stage/expected_fs.txt b/integration/tests/pull/02_pull_stage/expected_fs.txt index 748851f..82d5115 100644 --- a/integration/tests/pull/02_pull_stage/expected_fs.txt +++ b/integration/tests/pull/02_pull_stage/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/b3 [-r--r--r-- user 4] ./.dud/cache/b3/199d36d434044e6778b77d13f8dbaba32a73d9522c1ae8d0f73ef1ff14e71f diff --git a/integration/tests/working_in_subdirs/02_run_and_commit/expected_fs.txt b/integration/tests/working_in_subdirs/02_run_and_commit/expected_fs.txt index cf824cb..64d654f 100644 --- a/integration/tests/working_in_subdirs/02_run_and_commit/expected_fs.txt +++ b/integration/tests/working_in_subdirs/02_run_and_commit/expected_fs.txt @@ -1,6 +1,6 @@ . [drwxr-xr-x user 4096] ./.dud -[-rw-r--r-- user 7] ./.dud/.gitignore +[-rw-r--r-- user 14] ./.dud/.gitignore [drwxr-xr-x user 4096] ./.dud/cache [drwxr-xr-x user 4096] ./.dud/cache/53 [-r--r--r-- user 7] ./.dud/cache/53/4659321d2eea6b13aea4f4c94c3b4f624622295da31506722b47a8eb9d726c diff --git a/src/cache/commit.go b/src/cache/commit.go index 0a4e951..59ad9f5 100644 --- a/src/cache/commit.go +++ b/src/cache/commit.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "io" - "io/ioutil" "os" "path/filepath" @@ -63,12 +62,12 @@ func (ch LocalCache) Commit( var canRenameFileBetweenDirs = func(srcDir, dstDir string) (bool, error) { // Touch a file in each directory. - srcFile, err := ioutil.TempFile(srcDir, "") + srcFile, err := os.CreateTemp(srcDir, "") if err != nil { return false, err } srcFile.Close() - dstFile, err := ioutil.TempFile(dstDir, "") + dstFile, err := os.CreateTemp(dstDir, "") if err != nil { return false, err } @@ -166,7 +165,7 @@ func (ch LocalCache) commitBytes(reader io.Reader, moveFile string) (string, err // If there's no file we can move, we need to copy the bytes from reader to // the cache. if moveFile == "" { - tempFile, err := ioutil.TempFile(ch.dir, "") + tempFile, err := os.CreateTemp(ch.dir, "") if err != nil { return "", err } @@ -188,6 +187,13 @@ func (ch LocalCache) commitBytes(reader io.Reader, moveFile string) (string, err if err = os.MkdirAll(dstDir, 0o755); err != nil { return "", err } + // This rename may race others, but luckily we don't care who wins the + // race. Everyone in the race is trying to put the same exact file in the + // cache (because of content-addressed storage), so the outcome is the same + // no matter who wins the race. At the OS level rename is atomic, so + // there's no risk of corrupting the destination file with multiple + // concurrent syscalls. (This is at least true for UNIX, but that's all we + // support. See also: https://github.com/golang/go/issues/8914) if err = os.Rename(moveFile, cachePath); err != nil { return "", err } diff --git a/src/cache/dir_checkout_test.go b/src/cache/dir_checkout_test.go index 23653c5..61c5477 100644 --- a/src/cache/dir_checkout_test.go +++ b/src/cache/dir_checkout_test.go @@ -10,6 +10,7 @@ import ( "github.com/kevin-hanselman/dud/src/artifact" "github.com/kevin-hanselman/dud/src/fsutil" "github.com/kevin-hanselman/dud/src/strategy" + "go.uber.org/goleak" ) func TestDirectoryCheckoutIntegration(t *testing.T) { @@ -17,6 +18,8 @@ func TestDirectoryCheckoutIntegration(t *testing.T) { t.Skip() } + defer goleak.VerifyNone(t) + logger := agglog.NewNullLogger() maxSharedWorkers = 1 diff --git a/src/cache/dir_commit_test.go b/src/cache/dir_commit_test.go index 28ae12a..648f34d 100644 --- a/src/cache/dir_commit_test.go +++ b/src/cache/dir_commit_test.go @@ -2,7 +2,6 @@ package cache import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -13,6 +12,7 @@ import ( "github.com/kevin-hanselman/dud/src/fsutil" "github.com/kevin-hanselman/dud/src/strategy" "github.com/kevin-hanselman/dud/src/testutil" + "go.uber.org/goleak" ) func TestDirectoryCommitIntegration(t *testing.T) { @@ -20,6 +20,8 @@ func TestDirectoryCommitIntegration(t *testing.T) { t.Skip() } + defer goleak.VerifyNone(t) + makeExpectedStatus := func(art artifact.Artifact) artifact.Status { upToDate := func(art artifact.Artifact) *artifact.Status { return &artifact.Status{ @@ -187,7 +189,7 @@ func setupDirTest(t *testing.T) (testutil.TempDirs, artifact.Artifact, LocalCach for i := 1; i <= 5; i++ { s := fmt.Sprint(i) path := filepath.Join(dirs.WorkDir, "foo", fmt.Sprintf("%s.txt", s)) - if err := ioutil.WriteFile(path, []byte(s), 0o644); err != nil { + if err := os.WriteFile(path, []byte(s), 0o644); err != nil { t.Fatal(err) } } @@ -196,7 +198,7 @@ func setupDirTest(t *testing.T) (testutil.TempDirs, artifact.Artifact, LocalCach for i := 4; i <= 8; i++ { s := fmt.Sprint(i) path := filepath.Join(dirs.WorkDir, "foo", "bar", fmt.Sprintf("%s.txt", s)) - if err := ioutil.WriteFile(path, []byte(s), 0o644); err != nil { + if err := os.WriteFile(path, []byte(s), 0o644); err != nil { t.Fatal(err) } } diff --git a/src/cache/dir_status_test.go b/src/cache/dir_status_test.go index 43fc597..0853c95 100644 --- a/src/cache/dir_status_test.go +++ b/src/cache/dir_status_test.go @@ -8,12 +8,14 @@ import ( "github.com/kevin-hanselman/dud/src/fsutil" "github.com/google/go-cmp/cmp" + "go.uber.org/goleak" ) func TestDirectoryStatusIntegration(t *testing.T) { if testing.Short() { t.Skip() } + defer goleak.VerifyNone(t) notCommitted := func(art artifact.Artifact) *artifact.Status { return &artifact.Status{ diff --git a/src/cache/status.go b/src/cache/status.go index a43b050..0f96c16 100644 --- a/src/cache/status.go +++ b/src/cache/status.go @@ -195,8 +195,9 @@ func dirArtifactStatus( } for _, entry := range entries { newArt := artifact.Artifact{Path: entry.Name(), IsDir: entry.IsDir()} - // We've already checked all entries in the manifest. - // (While assigning to a nil map panics, accessing a nil map is safe.) + // Ignore all entries in the manifest; we've already checked them + // above. (While assigning to a nil map panics, accessing a nil map is + // safe.) if _, ok := manifest.Contents[newArt.Path]; ok { continue } diff --git a/src/cmd/checkout.go b/src/cmd/checkout.go index d3ddb7e..e3db4c9 100644 --- a/src/cmd/checkout.go +++ b/src/cmd/checkout.go @@ -1,11 +1,8 @@ package cmd import ( - "github.com/kevin-hanselman/dud/src/cache" - "github.com/kevin-hanselman/dud/src/index" "github.com/kevin-hanselman/dud/src/strategy" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -45,20 +42,7 @@ stage(s).`, strat = strategy.CopyStrategy } - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) - if err != nil { - fatal(err) - } - - idx, err := index.FromFile(indexPath) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } diff --git a/src/cmd/commit.go b/src/cmd/commit.go index edb8334..1945b11 100644 --- a/src/cmd/commit.go +++ b/src/cmd/commit.go @@ -1,11 +1,8 @@ package cmd import ( - "github.com/kevin-hanselman/dud/src/cache" - "github.com/kevin-hanselman/dud/src/index" "github.com/kevin-hanselman/dud/src/strategy" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -34,20 +31,7 @@ recursively on all stages upstream of the given stage(s).`, strat = strategy.CopyStrategy } - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) - if err != nil { - fatal(err) - } - - idx, err := index.FromFile(indexPath) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } diff --git a/src/cmd/config.go b/src/cmd/config.go index 4ea69a7..32f67e5 100644 --- a/src/cmd/config.go +++ b/src/cmd/config.go @@ -33,6 +33,9 @@ func init() { if err != nil { fatal(err) } + if err := lockProject(rootDir); err != nil { + fatal(err) + } if err := readConfig(rootDir); err != nil { fatal(err) } @@ -51,21 +54,16 @@ func init() { return fmt.Errorf("expected two arguments, got %d", len(args)) } - isValid := false for _, field := range validFields { if args[0] == field { - isValid = true - break + return nil } } - if !isValid { - return fmt.Errorf( - "invalid argument; expected one of [%s]", - strings.Join(validFields, ", "), - ) - } - return nil + return fmt.Errorf( + "invalid argument; expected one of [%s]", + strings.Join(validFields, ", "), + ) }, Run: func(cmd *cobra.Command, args []string) { var err error @@ -78,6 +76,9 @@ func init() { if err != nil { fatal(err) } + if err := lockProject(rootDir); err != nil { + fatal(err) + } _, err = readProjectConfig(rootDir) } diff --git a/src/cmd/fetch.go b/src/cmd/fetch.go index 4414188..a7b83a1 100644 --- a/src/cmd/fetch.go +++ b/src/cmd/fetch.go @@ -1,10 +1,6 @@ package cmd import ( - "errors" - - "github.com/kevin-hanselman/dud/src/cache" - "github.com/kevin-hanselman/dud/src/index" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -20,9 +16,11 @@ func init() { ) } -const ( - noRemote = "no remote specified in the config" -) +type noRemoteError struct{} + +func (e noRemoteError) Error() string { + return "no remote specified in the config" +} var fetchCmd = &cobra.Command{ Use: "fetch [flags] [stage_file]...", @@ -37,27 +35,14 @@ recursively on all stages upstream of the given stage(s). This command requires rclone to be installed on your machine. Visit https://rclone.org/ for more information and installation instructions.`, Run: func(cmd *cobra.Command, paths []string) { - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } remote := viper.GetString("remote") if remote == "" { - fatal(errors.New(noRemote)) - } - - idx, err := index.FromFile(indexPath) - if err != nil { - fatal(err) + fatal(noRemoteError{}) } if len(paths) == 0 { diff --git a/src/cmd/graph.go b/src/cmd/graph.go index 1c68d8f..84a3068 100644 --- a/src/cmd/graph.go +++ b/src/cmd/graph.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/awalterschulze/gographviz" - "github.com/kevin-hanselman/dud/src/index" "github.com/spf13/cobra" ) @@ -32,15 +31,7 @@ generate images of the stage graph. Visit https://graphviz.org for more information about Graphviz and for installation instructions.`, Example: "dud graph | dot -Tpng -o dud.png", Run: func(cmd *cobra.Command, paths []string) { - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - idx, err := index.FromFile(indexPath) + _, _, idx, err := prepare(paths...) if err != nil { fatal(err) } diff --git a/src/cmd/init.go b/src/cmd/init.go index 785a544..d108afc 100644 --- a/src/cmd/init.go +++ b/src/cmd/init.go @@ -1,7 +1,6 @@ package cmd import ( - "io/ioutil" "os" "github.com/spf13/cobra" @@ -37,15 +36,15 @@ func init() { # https://rclone.org/docs/#syntax-of-remote-paths ` - if err := ioutil.WriteFile(".dud/config.yaml", []byte(dudConf), 0o644); err != nil { + if err := os.WriteFile(".dud/config.yaml", []byte(dudConf), 0o644); err != nil { fatal(err) } - if err := ioutil.WriteFile(indexPath, []byte{}, 0o644); err != nil { + if err := os.WriteFile(indexPath, []byte{}, 0o644); err != nil { fatal(err) } - if err := ioutil.WriteFile(".dud/.gitignore", []byte("/cache/"), 0o644); err != nil { + if err := os.WriteFile(".dud/.gitignore", []byte("/cache/\n/lock\n"), 0o644); err != nil { fatal(err) } @@ -55,7 +54,7 @@ func init() { # path. # See: https://rclone.org/docs/#syntax-of-remote-paths ` - if err := ioutil.WriteFile(".dud/rclone.conf", []byte(rcloneConf), 0o644); err != nil { + if err := os.WriteFile(".dud/rclone.conf", []byte(rcloneConf), 0o644); err != nil { fatal(err) } diff --git a/src/cmd/pull.go b/src/cmd/pull.go index c1257e6..6be04c2 100644 --- a/src/cmd/pull.go +++ b/src/cmd/pull.go @@ -31,6 +31,13 @@ This command requires rclone to be installed on your machine. Visit https://rclone.org/ for more information and installation instructions.`, Run: func(cmd *cobra.Command, args []string) { fetchCmd.Run(cmd, args) + // After fetch completes, remove its lock file so checkout can take + // control. + // TODO: Removing the lock file between operations is awkward and + // probably buggy. We definitely should revisit this. + if err := unlockProject(); err != nil { + fatal(err) + } checkoutCmd.Run(cmd, args) }, } diff --git a/src/cmd/push.go b/src/cmd/push.go index 9bc2928..d866251 100644 --- a/src/cmd/push.go +++ b/src/cmd/push.go @@ -1,10 +1,6 @@ package cmd import ( - "errors" - - "github.com/kevin-hanselman/dud/src/cache" - "github.com/kevin-hanselman/dud/src/index" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -33,27 +29,14 @@ act recursively on all stages upstream of the given stage(s). This command requires rclone to be installed on your machine. Visit https://rclone.org/ for more information and installation instructions.`, Run: func(cmd *cobra.Command, paths []string) { - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } remote := viper.GetString("remote") if remote == "" { - fatal(errors.New(noRemote)) - } - - idx, err := index.FromFile(indexPath) - if err != nil { - fatal(err) + fatal(noRemoteError{}) } if len(idx) == 0 { diff --git a/src/cmd/root.go b/src/cmd/root.go index 1e57514..7a61afb 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -1,7 +1,6 @@ package cmd import ( - "errors" "fmt" "io" "log" @@ -10,18 +9,21 @@ import ( "runtime/trace" "strings" + "github.com/felixge/fgprof" "github.com/kevin-hanselman/dud/src/agglog" + "github.com/kevin-hanselman/dud/src/cache" "github.com/kevin-hanselman/dud/src/fsutil" + "github.com/kevin-hanselman/dud/src/index" "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" "github.com/spf13/viper" - - "github.com/felixge/fgprof" ) const ( indexPath = ".dud/index" + lockPath = ".dud/lock" ) type emptyIndexError struct{} @@ -47,6 +49,8 @@ building data pipelines.`, } if doProfile { logger.Info.Println("enabled profiling") + // TODO: If we stop relying on the project-wide lock file, this + // should be flocked. debugOutput, err := os.Create("dud.pprof") if err != nil { fatal(err) @@ -55,6 +59,8 @@ building data pipelines.`, fgprof.Start(debugOutput, fgprof.FormatPprof) } else if doTrace { logger.Info.Println("enabled tracing") + // TODO: If we stop relying on the project-wide lock file, this + // should be flocked. debugOutput, err := os.Create("dud.trace") if err != nil { fatal(err) @@ -70,9 +76,9 @@ building data pipelines.`, // This is the Logger for the entire application. logger *agglog.AggLogger - doProfile, doTrace, verbose bool - debugOutput *os.File - stopProfiling func() error + doProfile, doTrace, verbose, projectLocked bool + debugOutput *os.File + stopProfiling func() error ) func init() { @@ -125,6 +131,9 @@ func Main() { if err := rootCmd.Execute(); err != nil { fatal(err) } + if err := unlockProject(); err != nil { + fatal(err) + } if err := stopDebugging(); err != nil { logger.Error.Fatal(err) } @@ -132,9 +141,11 @@ func Main() { // fatal ensures we gracefully stop profiling or tracing before exiting. func fatal(err error) { - debugErr := stopDebugging() - if debugErr != nil { - logger.Error.Println(debugErr) + if err := unlockProject(); err != nil { + logger.Error.Println(err) + } + if err := stopDebugging(); err != nil { + logger.Error.Println(err) } logger.Error.Fatal(err) } @@ -197,6 +208,8 @@ func readProjectConfig(rootDir string) (path string, err error) { return } +// Read the project and user config files and merge them. Project config files +// take precedence over user config files. func readConfig(rootDir string) (err error) { viper.SetDefault("cache", ".dud/cache") @@ -244,3 +257,64 @@ func pathAbsThenRel(base, target string) (string, error) { } return filepath.Rel(base, target) } + +// Prevent concurrent invocations to Dud in the current project using a simple +// lock file. This isn't a comprehensive solution for concurrent user errors, +// but it should prevent the most common problems. +func lockProject(rootDir string) (err error) { + // If we're already in the project root, we technically can use lockPath + // directly, but this approach explicitly requires we know the project + // root. + lockFile, err := os.OpenFile( + filepath.Join(rootDir, lockPath), + // O_EXCL is key. If the file already exists, someone else has already + // claimed the file. + os.O_CREATE|os.O_RDWR|os.O_EXCL, + 0o600, + ) + if err == nil { + lockFile.Close() + } else if os.IsExist(err) { + err = fmt.Errorf("project lock file '%s' exists", lockPath) + logger.Error.Println(`Another invocation of Dud may be running, or Dud may have exited +unexpectedly and orphaned the lock file. If you are certain Dud is not already +running and your project is healthy, you may remove the lock file and try +running Dud again.`) + } + projectLocked = true + return err +} + +func unlockProject() error { + if projectLocked { + // If os.Remove succeeds, we're unlocked. If it fails, we should be calling + // fatal(), and we don't want try unlocking again. + projectLocked = false + return os.Remove(lockPath) + } + return nil +} + +// Do a bunch of bookkeeping to prepare for usual execution of Dud operations. +func prepare(paths ...string) (rootDir string, ch cache.LocalCache, idx index.Index, err error) { + rootDir, err = cdToProjectRoot(paths...) + if err != nil { + return + } + + if err = lockProject(rootDir); err != nil { + return + } + + if err = readConfig(rootDir); err != nil { + return + } + + ch, err = cache.NewLocalCache(viper.GetString("cache")) + if err != nil { + return + } + + idx, err = index.FromFile(indexPath) + return +} diff --git a/src/cmd/run.go b/src/cmd/run.go index 9ec9bcd..89d0d87 100644 --- a/src/cmd/run.go +++ b/src/cmd/run.go @@ -1,10 +1,7 @@ package cmd import ( - "github.com/kevin-hanselman/dud/src/cache" - "github.com/kevin-hanselman/dud/src/index" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -31,20 +28,7 @@ default, run will act recursively on all stages upstream of the given stage, and thus run will execute a stage's command if any upstream stages are out-of-date.`, Run: func(cmd *cobra.Command, paths []string) { - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) - if err != nil { - fatal(err) - } - - idx, err := index.FromFile(indexPath) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } diff --git a/src/cmd/status.go b/src/cmd/status.go index 5042120..e6cacc9 100644 --- a/src/cmd/status.go +++ b/src/cmd/status.go @@ -6,11 +6,9 @@ import ( "os" "text/tabwriter" - "github.com/kevin-hanselman/dud/src/cache" "github.com/kevin-hanselman/dud/src/index" "github.com/kevin-hanselman/dud/src/stage" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -44,20 +42,7 @@ stage. If no stage files are passed in, status will act on all stages in the index. By default, status will act recursively on all stages upstream of the given stage(s).`, Run: func(cmd *cobra.Command, paths []string) { - rootDir, err := cdToProjectRoot(paths...) - if err != nil { - fatal(err) - } - if err := readConfig(rootDir); err != nil { - fatal(err) - } - - ch, err := cache.NewLocalCache(viper.GetString("cache")) - if err != nil { - fatal(err) - } - - idx, err := index.FromFile(indexPath) + rootDir, ch, idx, err := prepare(paths...) if err != nil { fatal(err) } diff --git a/src/index/index.go b/src/index/index.go index 88a526d..e44c1ad 100644 --- a/src/index/index.go +++ b/src/index/index.go @@ -41,6 +41,8 @@ func (idx *Index) AddStage(stg stage.Stage, path string) error { // TODO no tests func (idx Index) ToFile(indexPath string) error { errPrefix := fmt.Sprintf("writing index to %s", indexPath) + // TODO: If we stop relying on the project-wide lock file, this should be + // flocked. file, err := os.Create(indexPath) if err != nil { return errors.Wrap(err, errPrefix) diff --git a/src/stage/stage.go b/src/stage/stage.go index d2d6e8b..81ff8bb 100644 --- a/src/stage/stage.go +++ b/src/stage/stage.go @@ -145,7 +145,7 @@ func FromFile(stagePath string) (stg Stage, err error) { // Validate returns an error describing a problem with the given Stage. // If there are no problems with the Stage definition this method returns nil. -// If stagePath is non-empty, Artifacts matching stagePath will cause an error; +// If stagePath is not empty, Artifacts matching stagePath will cause an error; // stage cannot track or reference themselves. func (stg Stage) Validate(stagePath string) error { if strings.Contains(stg.WorkingDir, "..") { @@ -213,6 +213,8 @@ func (stg *Stage) Serialize(writer io.Writer) error { // ToFile writes a Stage to the given file path. func (stg *Stage) ToFile(path string) error { errPrefix := "writing stage " + path + // TODO: If we stop relying on the project-wide lock file, this should be + // flocked. stageFile, err := os.Create(path) if err != nil { return errors.Wrap(err, errPrefix) diff --git a/src/testutil/testutil.go b/src/testutil/testutil.go index d1c0393..0434917 100644 --- a/src/testutil/testutil.go +++ b/src/testutil/testutil.go @@ -1,7 +1,6 @@ package testutil import ( - "io/ioutil" "os" "path/filepath" "time" @@ -56,11 +55,11 @@ type TempDirs struct { // CreateTempDirs creates a Dud cache and workspace in the OS temp FS. func CreateTempDirs() (dirs TempDirs, err error) { - dirs.CacheDir, err = ioutil.TempDir("", "dud_cache") + dirs.CacheDir, err = os.MkdirTemp("", "dud_cache") if err != nil { return } - dirs.WorkDir, err = ioutil.TempDir("", "dud_wspace") + dirs.WorkDir, err = os.MkdirTemp("", "dud_wspace") if err != nil { os.RemoveAll(dirs.CacheDir) return @@ -156,7 +155,7 @@ func CreateArtifactTestCase(status artifact.Status) (dirs TempDirs, art artifact if err = os.Mkdir(fileCacheDir, 0o755); err != nil { return } - if err = ioutil.WriteFile(fileCachePath, fileContents, 0o444); err != nil { + if err = os.WriteFile(fileCachePath, fileContents, 0o444); err != nil { return } } @@ -172,7 +171,7 @@ func CreateArtifactTestCase(status artifact.Status) (dirs TempDirs, art artifact if !status.ContentsMatch { fileContents = []byte("Not the same as in the cache") } - if err = ioutil.WriteFile(fileWorkspacePath, fileContents, 0o644); err != nil { + if err = os.WriteFile(fileWorkspacePath, fileContents, 0o644); err != nil { return } case fsutil.StatusLink: