From 78d87ac73d29f321802dbca8813c486d8f30df15 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Mon, 10 Mar 2025 18:01:01 +0200 Subject: [PATCH 01/14] wip --- task.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/task.go b/task.go index cf690c662a..1345250de7 100644 --- a/task.go +++ b/task.go @@ -206,11 +206,13 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { defer release() return e.startExecution(ctx, t, func(ctx context.Context) error { - e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", call.Task) + e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", t.Name()) if err := e.runDeps(ctx, t); err != nil { return err } + startedAt := time.Now() + skipFingerprinting := e.ForceAll || (!call.Indirect && e.Force) if !skipFingerprinting { if err := ctx.Err(); err != nil { @@ -291,7 +293,10 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { return &errors.TaskRunError{TaskName: t.Task, Err: err} } } - e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", call.Task) + + taskDuration := time.Since(startedAt) + + e.Logger.VerboseErrf(logger.Magenta, "task: %q finished in %v\n", t.Name(), taskDuration) return nil }) } From 65e3e3419da6cdb73fabfae9a7cc202100cd3632 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Mon, 10 Mar 2025 23:39:31 +0200 Subject: [PATCH 02/14] wip --- go.mod | 3 --- go.sum | 52 +++++++------------------------------ internal/tracing/tracing.go | 50 +++++++++++++++++++++++++++++++++++ task.go | 8 ++++++ 4 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 internal/tracing/tracing.go diff --git a/go.mod b/go.mod index 3699d7d004..c2be59774c 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/muesli/cancelreader v0.2.2 // indirect github.com/otiai10/mint v1.6.3 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -54,9 +53,7 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/crypto v0.35.0 // indirect - golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.35.0 // indirect golang.org/x/sys v0.31.0 // indirect - golang.org/x/tools v0.27.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 9a8afcda1a..1ed60f71bf 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,6 @@ github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6h github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= @@ -23,14 +21,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/chainguard-dev/git-urls v1.0.2 h1:pSpT7ifrpc5X55n4aTTm7FFUE+ZQHKiqpiwNkJrVcKQ= github.com/chainguard-dev/git-urls v1.0.2/go.mod h1:rbGgj10OS7UgZlbzdUQIQpT0k/D4+An04HJY7Ol+Y/o= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= -github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= -github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -40,8 +34,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= -github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= -github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= +github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= +github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/elliotchance/orderedmap/v3 v3.1.0 h1:j4DJ5ObEmMBt/lcwIecKcoRxIQUEnw0L804lXYDt/pg= github.com/elliotchance/orderedmap/v3 v3.1.0/go.mod h1:G+Hc2RwaZvJMcS4JpGCOyViCnGeKf0bTYCGTO4uhjSo= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -56,8 +50,6 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= -github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= @@ -66,12 +58,10 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE= github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -98,8 +88,6 @@ github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= @@ -114,15 +102,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= -github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -141,22 +127,13 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -168,22 +145,15 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -194,7 +164,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4= -mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY= mvdan.cc/sh/v3 v3.11.0 h1:q5h+XMDRfUGUedCqFFsjoFjrhwf2Mvtt1rkMvVz0blw= mvdan.cc/sh/v3 v3.11.0/go.mod h1:LRM+1NjoYCzuq/WZ6y44x14YNAI0NK7FLPeQSaFagGg= diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go new file mode 100644 index 0000000000..07a65a1872 --- /dev/null +++ b/internal/tracing/tracing.go @@ -0,0 +1,50 @@ +package tracing + +import ( + "fmt" + "strings" + "time" +) + +type Tracer struct { + spans []*Span +} + +type Span struct { + name string + startedAt time.Time + endedAt time.Time +} + +func (t *Tracer) Start(name string) *Span { + result := &Span{ + name: name, + startedAt: time.Now(), + } + t.spans = append(t.spans, result) + return result +} + +func (s *Span) Stop() { + s.endedAt = time.Now() +} + +func (t *Tracer) ToMermaidOutput() string { + out := `gantt + title Task Execution Timeline + dateFormat YYYY-MM-DD HH:mm:ss.SSS + axisFormat %X + section Tasks +` + dateFormat := "2006-01-02 15:04:05.000" + for _, span := range t.spans { + if span.endedAt.IsZero() { + continue + } + name := strings.Replace(span.name, ":", "|", -1) + duration := span.endedAt.Sub(span.startedAt) + out += fmt.Sprintf(" %s-%v :done, %s, %s\n", name, duration, span.startedAt.Format(dateFormat), span.endedAt.Format(dateFormat)) + } + + return out +} diff --git a/task.go b/task.go index 1345250de7..11be5995d1 100644 --- a/task.go +++ b/task.go @@ -3,6 +3,7 @@ package task import ( "context" "fmt" + "github.com/go-task/task/v3/internal/tracing" "io" "os" "runtime" @@ -83,6 +84,8 @@ type Executor struct { mkdirMutexMap map[string]*sync.Mutex executionHashes map[string]context.Context executionHashesMutex sync.Mutex + + tracer tracing.Tracer } // MatchingTask represents a task that matches a given call. It includes the @@ -144,6 +147,9 @@ func (e *Executor) Run(ctx context.Context, calls ...*Call) error { } } } + defer func() { + e.Logger.VerboseErrf(logger.Magenta, "%s\n", e.tracer.ToMermaidOutput()) + }() if err := g.Wait(); err != nil { return err } @@ -210,6 +216,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { if err := e.runDeps(ctx, t); err != nil { return err } + tracerSpan := e.tracer.Start(t.Name()) startedAt := time.Now() @@ -297,6 +304,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { taskDuration := time.Since(startedAt) e.Logger.VerboseErrf(logger.Magenta, "task: %q finished in %v\n", t.Name(), taskDuration) + tracerSpan.Stop() return nil }) } From cc235f967739bc611c59352f0c2ca3db1cc0fe99 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 00:27:07 +0200 Subject: [PATCH 03/14] wip --- internal/tracing/tracing.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go index 07a65a1872..7843dd984c 100644 --- a/internal/tracing/tracing.go +++ b/internal/tracing/tracing.go @@ -34,7 +34,6 @@ func (t *Tracer) ToMermaidOutput() string { title Task Execution Timeline dateFormat YYYY-MM-DD HH:mm:ss.SSS axisFormat %X - section Tasks ` dateFormat := "2006-01-02 15:04:05.000" for _, span := range t.spans { @@ -42,8 +41,8 @@ func (t *Tracer) ToMermaidOutput() string { continue } name := strings.Replace(span.name, ":", "|", -1) - duration := span.endedAt.Sub(span.startedAt) - out += fmt.Sprintf(" %s-%v :done, %s, %s\n", name, duration, span.startedAt.Format(dateFormat), span.endedAt.Format(dateFormat)) + duration := span.endedAt.Sub(span.startedAt).Truncate(time.Millisecond * 100) + out += fmt.Sprintf(" %s [%v] :done, %s, %s\n", name, duration, span.startedAt.Format(dateFormat), span.endedAt.Format(dateFormat)) } return out From 7ef95da91112c59ffe6608a28e0589daf247bbdf Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 15:40:11 +0200 Subject: [PATCH 04/14] wip --- cmd/task/task.go | 3 ++ internal/flags/flags.go | 4 +++ internal/tracing/tracing.go | 42 ++++++++++++++++++++++++--- internal/tracing/tracing_test.go | 50 ++++++++++++++++++++++++++++++++ task.go | 15 +++++----- 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 internal/tracing/tracing_test.go diff --git a/cmd/task/task.go b/cmd/task/task.go index afa8945eb5..ba921b98fc 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "github.com/go-task/task/v3/internal/tracing" "os" "path/filepath" "strings" @@ -160,6 +161,8 @@ func run() error { OutputStyle: flags.Output, TaskSorter: taskSorter, EnableVersionCheck: true, + + Tracer: tracing.NewTracer(flags.ExecutionTraceOutput), } listOptions := task.NewListOptions(flags.List, flags.ListAll, flags.ListJson, flags.NoStatus) if err := listOptions.Validate(); err != nil { diff --git a/internal/flags/flags.go b/internal/flags/flags.go index be2227c166..5641e1162a 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -71,6 +71,8 @@ var ( Offline bool ClearCache bool Timeout time.Duration + + ExecutionTraceOutput string ) func init() { @@ -131,6 +133,8 @@ func init() { pflag.BoolVar(&ClearCache, "clear-cache", false, "Clear the remote cache.") } + pflag.StringVar(&ExecutionTraceOutput, "execution-trace-output", "", "When supplied, generates a Mermaid Gantt chart of each task's invocation. Useful to visualize highly parallel execution.") + pflag.Parse() } diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go index 7843dd984c..490fbad935 100644 --- a/internal/tracing/tracing.go +++ b/internal/tracing/tracing.go @@ -2,34 +2,68 @@ package tracing import ( "fmt" + "os" "strings" + "sync" "time" ) type Tracer struct { - spans []*Span + mu sync.Mutex + spans []*Span + outFile string + + timeFn func() time.Time +} + +func NewTracer(outFile string) Tracer { + return Tracer{ + outFile: outFile, + } } type Span struct { + parent *Tracer name string startedAt time.Time endedAt time.Time } func (t *Tracer) Start(name string) *Span { + t.mu.Lock() + defer t.mu.Unlock() + + if t.timeFn == nil { + t.timeFn = time.Now + } + result := &Span{ + parent: t, name: name, - startedAt: time.Now(), + startedAt: t.timeFn(), } t.spans = append(t.spans, result) return result } func (s *Span) Stop() { - s.endedAt = time.Now() + s.parent.mu.Lock() + defer s.parent.mu.Unlock() + + s.endedAt = s.parent.timeFn() +} + +func (t *Tracer) WriteOutput() error { + t.mu.Lock() + defer t.mu.Unlock() + + if t.outFile == "" { + return nil + } + return os.WriteFile(t.outFile, []byte(t.toMermaidOutput()), 0644) } -func (t *Tracer) ToMermaidOutput() string { +func (t *Tracer) toMermaidOutput() string { out := `gantt title Task Execution Timeline dateFormat YYYY-MM-DD HH:mm:ss.SSS diff --git a/internal/tracing/tracing_test.go b/internal/tracing/tracing_test.go new file mode 100644 index 0000000000..ed0f5995a9 --- /dev/null +++ b/internal/tracing/tracing_test.go @@ -0,0 +1,50 @@ +package tracing + +import ( + "github.com/stretchr/testify/require" + "os" + "testing" + "time" +) + +func TestTracer_Start(t *testing.T) { + tracer := NewTracer(t.TempDir() + "/tracing.txt") + + currentTime, err := time.Parse(time.DateTime, "2025-01-02 15:42:23") + require.NoError(t, err) + tracer.timeFn = func() time.Time { + return currentTime + } + + task1 := tracer.Start("task one") + currentTime = currentTime.Add(time.Second) + + // special chars handling: will be replaced with "namespace|task two" in the output + task2 := tracer.Start("namespace:task two") + tracer.Start("task three - did not finish, should not show up in end result") + currentTime = currentTime.Add(time.Second * 2) + + task1.Stop() + currentTime = currentTime.Add(time.Second * 3) + task2.Stop() + + // very short tasks should still show up as a point in timeline + tracer.Start("very short task").Stop() + + r := require.New(t) + r.NoError(tracer.WriteOutput()) + + contents, err := os.ReadFile(tracer.outFile) + r.NoError(err) + + expectedContents := `gantt + title Task Execution Timeline + dateFormat YYYY-MM-DD HH:mm:ss.SSS + axisFormat %X + task one [3s] :done, 2025-01-02 15:42:23.000, 2025-01-02 15:42:26.000 + namespace|task two [5s] :done, 2025-01-02 15:42:24.000, 2025-01-02 15:42:29.000 + very short task [0s] :done, 2025-01-02 15:42:29.000, 2025-01-02 15:42:29.000 +` + + r.Equal(expectedContents, string(contents)) +} diff --git a/task.go b/task.go index 11be5995d1..524a878d35 100644 --- a/task.go +++ b/task.go @@ -85,7 +85,7 @@ type Executor struct { executionHashes map[string]context.Context executionHashesMutex sync.Mutex - tracer tracing.Tracer + Tracer tracing.Tracer } // MatchingTask represents a task that matches a given call. It includes the @@ -148,7 +148,10 @@ func (e *Executor) Run(ctx context.Context, calls ...*Call) error { } } defer func() { - e.Logger.VerboseErrf(logger.Magenta, "%s\n", e.tracer.ToMermaidOutput()) + err := e.Tracer.WriteOutput() + if err != nil { + e.Logger.VerboseErrf(logger.Magenta, "failed to write execution trace: %v\n", err) + } }() if err := g.Wait(); err != nil { return err @@ -216,9 +219,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { if err := e.runDeps(ctx, t); err != nil { return err } - tracerSpan := e.tracer.Start(t.Name()) - - startedAt := time.Now() + tracerSpan := e.Tracer.Start(t.Name()) skipFingerprinting := e.ForceAll || (!call.Indirect && e.Force) if !skipFingerprinting { @@ -301,9 +302,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { } } - taskDuration := time.Since(startedAt) - - e.Logger.VerboseErrf(logger.Magenta, "task: %q finished in %v\n", t.Name(), taskDuration) + e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", t.Name()) tracerSpan.Stop() return nil }) From 5300eaf748edc0721bcc479a0216be05b66bea56 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:05:20 +0200 Subject: [PATCH 05/14] wip --- cmd/task/task.go | 3 ++- internal/tracing/tracing.go | 2 +- internal/tracing/tracing_test.go | 4 +++- task.go | 21 ++++++++++++--------- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index ba921b98fc..45d2cd1cea 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -3,11 +3,12 @@ package main import ( "context" "fmt" - "github.com/go-task/task/v3/internal/tracing" "os" "path/filepath" "strings" + "github.com/go-task/task/v3/internal/tracing" + "github.com/spf13/pflag" "mvdan.cc/sh/v3/syntax" diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go index 490fbad935..4ac0f11ee4 100644 --- a/internal/tracing/tracing.go +++ b/internal/tracing/tracing.go @@ -60,7 +60,7 @@ func (t *Tracer) WriteOutput() error { if t.outFile == "" { return nil } - return os.WriteFile(t.outFile, []byte(t.toMermaidOutput()), 0644) + return os.WriteFile(t.outFile, []byte(t.toMermaidOutput()), 0o644) } func (t *Tracer) toMermaidOutput() string { diff --git a/internal/tracing/tracing_test.go b/internal/tracing/tracing_test.go index ed0f5995a9..a6404d3bc3 100644 --- a/internal/tracing/tracing_test.go +++ b/internal/tracing/tracing_test.go @@ -1,13 +1,15 @@ package tracing import ( - "github.com/stretchr/testify/require" "os" "testing" "time" + + "github.com/stretchr/testify/require" ) func TestTracer_Start(t *testing.T) { + t.Parallel() tracer := NewTracer(t.TempDir() + "/tracing.txt") currentTime, err := time.Parse(time.DateTime, "2025-01-02 15:42:23") diff --git a/task.go b/task.go index 524a878d35..4bb27dac5b 100644 --- a/task.go +++ b/task.go @@ -3,7 +3,6 @@ package task import ( "context" "fmt" - "github.com/go-task/task/v3/internal/tracing" "io" "os" "runtime" @@ -12,6 +11,8 @@ import ( "sync/atomic" "time" + "github.com/go-task/task/v3/internal/tracing" + "github.com/go-task/task/v3/errors" "github.com/go-task/task/v3/internal/env" "github.com/go-task/task/v3/internal/execext" @@ -97,6 +98,13 @@ type MatchingTask struct { // Run runs Task func (e *Executor) Run(ctx context.Context, calls ...*Call) error { + defer func() { + err := e.Tracer.WriteOutput() + if err != nil { + e.Logger.VerboseErrf(logger.Magenta, "failed to write execution trace: %v\n", err) + } + }() + // check if given tasks exist for _, call := range calls { task, err := e.GetTask(call) @@ -147,12 +155,7 @@ func (e *Executor) Run(ctx context.Context, calls ...*Call) error { } } } - defer func() { - err := e.Tracer.WriteOutput() - if err != nil { - e.Logger.VerboseErrf(logger.Magenta, "failed to write execution trace: %v\n", err) - } - }() + if err := g.Wait(); err != nil { return err } @@ -219,7 +222,8 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { if err := e.runDeps(ctx, t); err != nil { return err } - tracerSpan := e.Tracer.Start(t.Name()) + span := e.Tracer.Start(t.Name()) + defer span.Stop() skipFingerprinting := e.ForceAll || (!call.Indirect && e.Force) if !skipFingerprinting { @@ -303,7 +307,6 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { } e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", t.Name()) - tracerSpan.Stop() return nil }) } From 45f7b93c328357e7bb1a0f70de4b7103850d02c4 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:12:08 +0200 Subject: [PATCH 06/14] wip --- cmd/task/task.go | 2 -- go.mod | 3 +++ go.sum | 52 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index edae546b53..9ec601716b 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -7,8 +7,6 @@ import ( "path/filepath" "strings" - "github.com/go-task/task/v3/internal/tracing" - "github.com/spf13/pflag" "mvdan.cc/sh/v3/syntax" diff --git a/go.mod b/go.mod index c2be59774c..3699d7d004 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect github.com/otiai10/mint v1.6.3 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -53,7 +54,9 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/crypto v0.35.0 // indirect + golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.35.0 // indirect golang.org/x/sys v0.31.0 // indirect + golang.org/x/tools v0.27.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 1ed60f71bf..9a8afcda1a 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6h github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= @@ -21,10 +23,14 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/chainguard-dev/git-urls v1.0.2 h1:pSpT7ifrpc5X55n4aTTm7FFUE+ZQHKiqpiwNkJrVcKQ= github.com/chainguard-dev/git-urls v1.0.2/go.mod h1:rbGgj10OS7UgZlbzdUQIQpT0k/D4+An04HJY7Ol+Y/o= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= -github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= +github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= +github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -34,8 +40,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= -github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= -github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= github.com/elliotchance/orderedmap/v3 v3.1.0 h1:j4DJ5ObEmMBt/lcwIecKcoRxIQUEnw0L804lXYDt/pg= github.com/elliotchance/orderedmap/v3 v3.1.0/go.mod h1:G+Hc2RwaZvJMcS4JpGCOyViCnGeKf0bTYCGTO4uhjSo= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -50,6 +56,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= @@ -58,10 +66,12 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE= github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -88,6 +98,8 @@ github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= @@ -102,13 +114,15 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -127,13 +141,22 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -145,15 +168,22 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -164,5 +194,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4= +mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY= mvdan.cc/sh/v3 v3.11.0 h1:q5h+XMDRfUGUedCqFFsjoFjrhwf2Mvtt1rkMvVz0blw= mvdan.cc/sh/v3 v3.11.0/go.mod h1:LRM+1NjoYCzuq/WZ6y44x14YNAI0NK7FLPeQSaFagGg= From 7998a756c67c7eb6b33ec53ec6f705b830572779 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:26:09 +0200 Subject: [PATCH 07/14] wip --- executor.go | 11 +++++++++ internal/flags/flags.go | 1 + task.go | 55 ----------------------------------------- task_test.go | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+), 55 deletions(-) diff --git a/executor.go b/executor.go index 6b8d991fde..78043c8933 100644 --- a/executor.go +++ b/executor.go @@ -7,6 +7,8 @@ import ( "sync" "time" + "github.com/go-task/task/v3/internal/tracing" + "github.com/sajari/fuzzy" "github.com/go-task/task/v3/internal/logger" @@ -65,6 +67,8 @@ type ( mkdirMutexMap map[string]*sync.Mutex executionHashes map[string]context.Context executionHashesMutex sync.Mutex + + Tracer tracing.Tracer } TempDir struct { Remote string @@ -317,3 +321,10 @@ func ExecutorWithVersionCheck(enableVersionCheck bool) ExecutorOption { e.EnableVersionCheck = enableVersionCheck } } + +// ExecutorWithTracer configures execution tracing +func ExecutorWithTracer(outFile string) ExecutorOption { + return func(e *Executor) { + e.Tracer = tracing.NewTracer(outFile) + } +} diff --git a/internal/flags/flags.go b/internal/flags/flags.go index e14cb1c89f..c5220ed6dd 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -224,6 +224,7 @@ func WithExecutorOptions() task.ExecutorOption { task.ExecutorWithOutputStyle(Output), task.ExecutorWithTaskSorter(sorter), task.ExecutorWithVersionCheck(true), + task.ExecutorWithTracer(ExecutionTraceOutput), ) } } diff --git a/task.go b/task.go index cae994cf1e..3f2ad01d7a 100644 --- a/task.go +++ b/task.go @@ -8,8 +8,6 @@ import ( "slices" "sync/atomic" - "github.com/go-task/task/v3/internal/tracing" - "github.com/go-task/task/v3/errors" "github.com/go-task/task/v3/internal/env" "github.com/go-task/task/v3/internal/execext" @@ -32,59 +30,6 @@ const ( MaximumTaskCall = 1000 ) -type TempDir struct { - Remote string - Fingerprint string -} - -// Executor executes a Taskfile -type Executor struct { - Taskfile *ast.Taskfile - - Dir string - Entrypoint string - TempDir TempDir - Force bool - ForceAll bool - Insecure bool - Download bool - Offline bool - Timeout time.Duration - Watch bool - Verbose bool - Silent bool - AssumeYes bool - AssumeTerm bool // Used for testing - Dry bool - Summary bool - Parallel bool - Color bool - Concurrency int - Interval time.Duration - - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - - Logger *logger.Logger - Compiler *Compiler - Output output.Output - OutputStyle ast.Output - TaskSorter sort.Sorter - UserWorkingDir string - EnableVersionCheck bool - - fuzzyModel *fuzzy.Model - - concurrencySemaphore chan struct{} - taskCallCount map[string]*int32 - mkdirMutexMap map[string]*sync.Mutex - executionHashes map[string]context.Context - executionHashesMutex sync.Mutex - - Tracer tracing.Tracer -} - // MatchingTask represents a task that matches a given call. It includes the // task itself and a list of wildcards that were matched. type MatchingTask struct { diff --git a/task_test.go b/task_test.go index 0a2c982122..70084dfaa0 100644 --- a/task_test.go +++ b/task_test.go @@ -1074,6 +1074,31 @@ func TestTaskVersion(t *testing.T) { } } +func TestTraceOutput(t *testing.T) { + t.Parallel() + + outFile := t.TempDir() + "/tracing-gantt.out" + + e := task.NewExecutor( + task.ExecutorWithDir("testdata/concurrency"), + task.ExecutorWithTracer(outFile), + ) + require.NoError(t, e.Setup()) + + err := e.Run(context.Background(), &task.Call{Task: "default"}) + require.NoError(t, err) + + contents, err := os.ReadFile(outFile) + require.NoError(t, err) + + stringContents := string(contents) + require.Contains(t, stringContents, `gantt + title Task Execution Timeline + dateFormat YYYY-MM-DD HH:mm:ss.SSS + axisFormat %X`) + require.Contains(t, stringContents, " t6 [0s]") +} + func TestTaskIgnoreErrors(t *testing.T) { t.Parallel() From 463602cdc358fb6b12e7461322433848bee0a23a Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:27:47 +0200 Subject: [PATCH 08/14] wip --- task.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/task.go b/task.go index 3f2ad01d7a..149fc9309a 100644 --- a/task.go +++ b/task.go @@ -96,7 +96,6 @@ func (e *Executor) Run(ctx context.Context, calls ...*Call) error { } } } - if err := g.Wait(); err != nil { return err } @@ -246,7 +245,6 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { return &errors.TaskRunError{TaskName: t.Task, Err: err} } } - e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", t.Name()) return nil }) From e0170dd506320d37ac66692d229d458f5a1a4b56 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:29:08 +0200 Subject: [PATCH 09/14] wip --- executor.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/executor.go b/executor.go index 78043c8933..e6c3ebe1c3 100644 --- a/executor.go +++ b/executor.go @@ -7,13 +7,12 @@ import ( "sync" "time" - "github.com/go-task/task/v3/internal/tracing" - "github.com/sajari/fuzzy" "github.com/go-task/task/v3/internal/logger" "github.com/go-task/task/v3/internal/output" "github.com/go-task/task/v3/internal/sort" + "github.com/go-task/task/v3/internal/tracing" "github.com/go-task/task/v3/taskfile/ast" ) From 70e050522278022e15aeb12de7583c7fcc7be566 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:33:00 +0200 Subject: [PATCH 10/14] wip --- executor.go | 4 ++-- internal/tracing/tracing.go | 4 ++-- task.go | 11 ++++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/executor.go b/executor.go index e6c3ebe1c3..35be14c5ef 100644 --- a/executor.go +++ b/executor.go @@ -67,7 +67,7 @@ type ( executionHashes map[string]context.Context executionHashesMutex sync.Mutex - Tracer tracing.Tracer + tracer *tracing.Tracer } TempDir struct { Remote string @@ -324,6 +324,6 @@ func ExecutorWithVersionCheck(enableVersionCheck bool) ExecutorOption { // ExecutorWithTracer configures execution tracing func ExecutorWithTracer(outFile string) ExecutorOption { return func(e *Executor) { - e.Tracer = tracing.NewTracer(outFile) + e.tracer = tracing.NewTracer(outFile) } } diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go index 4ac0f11ee4..693fe13529 100644 --- a/internal/tracing/tracing.go +++ b/internal/tracing/tracing.go @@ -16,8 +16,8 @@ type Tracer struct { timeFn func() time.Time } -func NewTracer(outFile string) Tracer { - return Tracer{ +func NewTracer(outFile string) *Tracer { + return &Tracer{ outFile: outFile, } } diff --git a/task.go b/task.go index 149fc9309a..b74931b4bd 100644 --- a/task.go +++ b/task.go @@ -40,7 +40,10 @@ type MatchingTask struct { // Run runs Task func (e *Executor) Run(ctx context.Context, calls ...*Call) error { defer func() { - err := e.Tracer.WriteOutput() + if e.tracer == nil { + return + } + err := e.tracer.WriteOutput() if err != nil { e.Logger.VerboseErrf(logger.Magenta, "failed to write execution trace: %v\n", err) } @@ -162,8 +165,10 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { if err := e.runDeps(ctx, t); err != nil { return err } - span := e.Tracer.Start(t.Name()) - defer span.Stop() + if e.tracer != nil { + span := e.tracer.Start(t.Name()) + defer span.Stop() + } skipFingerprinting := e.ForceAll || (!call.Indirect && e.Force) if !skipFingerprinting { From 4e57b99269ea3e4d8812ef943d4a816a7a882b1d Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:42:20 +0200 Subject: [PATCH 11/14] wip --- task_test.go | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/task_test.go b/task_test.go index 70084dfaa0..55b6bdb968 100644 --- a/task_test.go +++ b/task_test.go @@ -1077,26 +1077,41 @@ func TestTaskVersion(t *testing.T) { func TestTraceOutput(t *testing.T) { t.Parallel() - outFile := t.TempDir() + "/tracing-gantt.out" + tests := []struct { + inputDir string + task string + }{ + { + inputDir: "testdata/concurrency", + task: "default", + }, + { + // should produce tracing results even if task execution fails + inputDir: "testdata/exit_code", + task: "exit-one", + }, + } - e := task.NewExecutor( - task.ExecutorWithDir("testdata/concurrency"), - task.ExecutorWithTracer(outFile), - ) - require.NoError(t, e.Setup()) + for _, test := range tests { + t.Run("should produce trace output for "+test.inputDir+"-"+test.task, func(t *testing.T) { + t.Parallel() - err := e.Run(context.Background(), &task.Call{Task: "default"}) - require.NoError(t, err) + outFile := t.TempDir() + "/tracing-gantt.out" - contents, err := os.ReadFile(outFile) - require.NoError(t, err) + e := task.NewExecutor( + task.ExecutorWithDir("testdata/concurrency"), + task.ExecutorWithTracer(outFile), + ) + r := require.New(t) + r.NoError(e.Setup()) + r.NoError(e.Run(context.Background(), &task.Call{Task: "default"})) + + contents, err := os.ReadFile(outFile) + r.NoError(err) - stringContents := string(contents) - require.Contains(t, stringContents, `gantt - title Task Execution Timeline - dateFormat YYYY-MM-DD HH:mm:ss.SSS - axisFormat %X`) - require.Contains(t, stringContents, " t6 [0s]") + r.Contains(string(contents), `gantt`) + }) + } } func TestTaskIgnoreErrors(t *testing.T) { From 6c54b94b26ee5c746fb19dc671ab9182b6d7d996 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 16:56:02 +0200 Subject: [PATCH 12/14] documentation update --- website/versioned_docs/version-latest/reference/cli.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/website/versioned_docs/version-latest/reference/cli.mdx b/website/versioned_docs/version-latest/reference/cli.mdx index 4afe84b836..a163fa75a1 100644 --- a/website/versioned_docs/version-latest/reference/cli.mdx +++ b/website/versioned_docs/version-latest/reference/cli.mdx @@ -49,6 +49,7 @@ If `--` is given, all remaining arguments will be assigned to a special | `-v` | `--verbose` | `bool` | `false` | Enables verbose mode. | | | `--version` | `bool` | `false` | Show Task version. | | `-w` | `--watch` | `bool` | `false` | Enables watch of the given task. +| | `--execution-trace-output` | `string` | | Execution trace output file name. When supplied, generates a text file in Mermaid Gantt format, containing name and timing of each executed task. Useful to visualize highly parallel execution. | ## Exit Codes From 0d38e75c860e5105d936d88f74c05f00494218e0 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 18:16:05 +0200 Subject: [PATCH 13/14] wip --- internal/flags/flags.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/flags/flags.go b/internal/flags/flags.go index c5220ed6dd..f3b96f6685 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -224,7 +224,10 @@ func WithExecutorOptions() task.ExecutorOption { task.ExecutorWithOutputStyle(Output), task.ExecutorWithTaskSorter(sorter), task.ExecutorWithVersionCheck(true), - task.ExecutorWithTracer(ExecutionTraceOutput), ) + + if ExecutionTraceOutput != "" { + task.ExecutorWithTracer(ExecutionTraceOutput)(e) + } } } From 5d152e46ea81770c86702b24ad630c7da7c0e1e7 Mon Sep 17 00:00:00 2001 From: Viktoras Makauskas Date: Tue, 11 Mar 2025 18:27:19 +0200 Subject: [PATCH 14/14] wip --- task_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/task_test.go b/task_test.go index 55b6bdb968..e7ad472d7d 100644 --- a/task_test.go +++ b/task_test.go @@ -1092,19 +1092,19 @@ func TestTraceOutput(t *testing.T) { }, } - for _, test := range tests { - t.Run("should produce trace output for "+test.inputDir+"-"+test.task, func(t *testing.T) { + for _, tt := range tests { + t.Run("should produce trace output for "+tt.inputDir+"-"+tt.task, func(t *testing.T) { t.Parallel() outFile := t.TempDir() + "/tracing-gantt.out" e := task.NewExecutor( - task.ExecutorWithDir("testdata/concurrency"), + task.ExecutorWithDir(tt.inputDir), task.ExecutorWithTracer(outFile), ) r := require.New(t) r.NoError(e.Setup()) - r.NoError(e.Run(context.Background(), &task.Call{Task: "default"})) + _ = e.Run(context.Background(), &task.Call{Task: tt.task}) contents, err := os.ReadFile(outFile) r.NoError(err)