From fe6f81076986cb0d37b98e0b4fe8365b3613d339 Mon Sep 17 00:00:00 2001 From: Hau Nguyen Date: Sun, 5 Mar 2023 10:26:32 +0700 Subject: [PATCH] feat: use errgroup --- go.mod | 1 + go.sum | 2 + internal/config/config_real.go | 116 +++++++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 36e144e..2c3bba1 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/make-go-great/copy-go v0.9.0 github.com/make-go-great/diff-go v0.0.5 github.com/urfave/cli/v2 v2.24.4 + golang.org/x/sync v0.1.0 ) require ( diff --git a/go.sum b/go.sum index 132e005..4d59fc8 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/urfave/cli/v2 v2.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/config/config_real.go b/internal/config/config_real.go index 09400c7..16749b7 100644 --- a/internal/config/config_real.go +++ b/internal/config/config_real.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" + "golang.org/x/sync/errgroup" + "github.com/make-go-great/copy-go" "github.com/make-go-great/diff-go" ) @@ -23,67 +25,112 @@ var _ Config = (*ConfigReal)(nil) // Install internal -> external func (c *ConfigReal) Install() error { + eg := new(errgroup.Group) + for _, app := range c.Apps { for _, p := range app.Paths { if p.External == "" { continue } - if err := copy.Replace(p.Internal, p.External); err != nil { - return fmt.Errorf("copy: failed to replace [%s] -> [%s]: %w", p.Internal, p.External, err) + p := Path{ + Internal: p.Internal, + External: p.External, + URL: p.URL, } + + eg.Go(func() error { + if err := copy.Replace(p.Internal, p.External); err != nil { + return fmt.Errorf("copy: failed to replace [%s] -> [%s]: %w", p.Internal, p.External, err) + } + + return nil + }) } } + if err := eg.Wait(); err != nil { + return err + } + return nil } // Update external -> internal func (c *ConfigReal) Update() error { + eg := new(errgroup.Group) + for _, app := range c.Apps { for _, p := range app.Paths { if p.External == "" { continue } - if err := copy.Replace(p.External, p.Internal); err != nil { - return fmt.Errorf("copy: failed to replace [%s] -> [%s]: %w", p.External, p.Internal, err) + p := Path{ + Internal: p.Internal, + External: p.External, + URL: p.URL, } + + eg.Go(func() error { + if err := copy.Replace(p.External, p.Internal); err != nil { + return fmt.Errorf("copy: failed to replace [%s] -> [%s]: %w", p.External, p.Internal, err) + } + + return nil + }) } } + if err := eg.Wait(); err != nil { + return err + } + return nil } func (c *ConfigReal) Download() error { + eg := new(errgroup.Group) + for _, app := range c.Apps { for _, p := range app.Paths { if p.URL == "" { continue } - httpRsp, err := c.httpClient.Get(p.URL) - if err != nil { - return fmt.Errorf("http client: failed to get: %w", err) + p := Path{ + Internal: p.Internal, + External: p.External, + URL: p.URL, } - data, err := io.ReadAll(httpRsp.Body) - if err != nil { - return fmt.Errorf("io: failed to read all: %w", err) - } + eg.Go(func() error { + httpRsp, err := c.httpClient.Get(p.URL) + if err != nil { + return fmt.Errorf("http client: failed to get: %w", err) + } - // Copy from github.com/make-go-great/copy-go - // Make sure nested dir is exist before copying file - dstDir := filepath.Dir(p.Internal) - if err := os.MkdirAll(dstDir, os.ModePerm); err != nil { - return fmt.Errorf("os: failed to mkdir all [%s]: %w", dstDir, err) - } + data, err := io.ReadAll(httpRsp.Body) + if err != nil { + return fmt.Errorf("io: failed to read all: %w", err) + } - if err := os.WriteFile(p.Internal, data, 0o600); err != nil { - return fmt.Errorf("os: failed to write file: %w", err) - } + // Copy from github.com/make-go-great/copy-go + // Make sure nested dir is exist before copying file + dstDir := filepath.Dir(p.Internal) + if err := os.MkdirAll(dstDir, os.ModePerm); err != nil { + return fmt.Errorf("os: failed to mkdir all [%s]: %w", dstDir, err) + } + + if err := os.WriteFile(p.Internal, data, 0o600); err != nil { + return fmt.Errorf("os: failed to write file: %w", err) + } + + httpRsp.Body.Close() + + return nil + }) - httpRsp.Body.Close() } } @@ -150,17 +197,34 @@ func (c *ConfigReal) Diff() error { } func (c *ConfigReal) Validate() error { + eg := new(errgroup.Group) + for _, app := range c.Apps { for _, p := range app.Paths { - if p.Internal == "" { - return fmt.Errorf("empty internal app [%s]: %w", app, ErrConfigInvalid) + app := app + p := Path{ + Internal: p.Internal, + External: p.External, + URL: p.URL, } - if p.External == "" && p.URL == "" { - return fmt.Errorf("empty external and url app [%s]: %w", app, ErrConfigInvalid) - } + eg.Go(func() error { + if p.Internal == "" { + return fmt.Errorf("empty internal app [%s]: %w", app, ErrConfigInvalid) + } + + if p.External == "" && p.URL == "" { + return fmt.Errorf("empty external and url app [%s]: %w", app, ErrConfigInvalid) + } + + return nil + }) } } + if err := eg.Wait(); err != nil { + return err + } + return nil }