diff --git a/commands/mod.go b/commands/mod.go index 61e3c74e6..0b88df666 100644 --- a/commands/mod.go +++ b/commands/mod.go @@ -49,6 +49,30 @@ func (c *modCmd) newVerifyCmd() *cobra.Command { return verifyCmd } +func (c *modCmd) newCleanCmd() *cobra.Command { + var pattern string + cmd := &cobra.Command{ + Use: "clean", + Short: "Delete the Hugo Module cache for the current project.", + Long: `Delete the Hugo Module cache for the current project. + +Note that after you run this command, all of your dependencies will be re-downloaded next time you run "hugo". + +Also note that if you configure a positive maxAge for the "modules" file cache, it will also be cleaned as part of "hugo --gc". + +`, + RunE: func(cmd *cobra.Command, args []string) error { + return c.withModsClient(true, func(c *modules.Client) error { + return c.Clean(pattern) + }) + }, + } + + cmd.Flags().StringVarP(&pattern, "pattern", "", "", `pattern matching module paths to clean (all if not set), e.g. "**hugo*"`) + + return cmd +} + func (b *commandsBuilder) newModCmd() *modCmd { c := &modCmd{} @@ -215,27 +239,7 @@ If a module is vendored, that is where Hugo will look for it's dependencies. }) }, }, - &cobra.Command{ - Use: "clean", - Short: "Delete the entire Hugo Module cache.", - Long: `Delete the entire Hugo Module cache. - -Note that after you run this command, all of your dependencies will be re-downloaded next time you run "hugo". - -Also note that if you configure a positive maxAge for the "modules" file cache, it will also be cleaned as part of "hugo --gc". - -`, - RunE: func(cmd *cobra.Command, args []string) error { - com, err := c.initConfig(true) - if err != nil { - return err - } - - _, err = com.hugo().FileCaches.ModulesCache().Prune(true) - return err - - }, - }, + c.newCleanCmd(), ) c.baseBuilderCmd = b.newBuilderCmd(cmd) diff --git a/hugofs/fs.go b/hugofs/fs.go index c8c4c8afd..75beda970 100644 --- a/hugofs/fs.go +++ b/hugofs/fs.go @@ -15,6 +15,7 @@ package hugofs import ( + "fmt" "os" "strings" @@ -97,7 +98,7 @@ func isWrite(flag int) bool { func MakeReadableAndRemoveAllModulePkgDir(fs afero.Fs, dir string) (int, error) { // Safe guard if !strings.Contains(dir, "pkg") { - panic("invalid dir") + panic(fmt.Sprint("invalid dir:", dir)) } counter := 0 diff --git a/modules/client.go b/modules/client.go index 601b5e109..a82300b37 100644 --- a/modules/client.go +++ b/modules/client.go @@ -26,6 +26,9 @@ import ( "path/filepath" "regexp" + "github.com/gobwas/glob" + hglob "github.com/gohugoio/hugo/hugofs/glob" + "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/hugofs/files" @@ -339,6 +342,38 @@ func (c *Client) Verify(clean bool) error { return err } +func (c *Client) Clean(pattern string) error { + mods, err := c.listGoMods() + if err != nil { + return err + } + + var g glob.Glob + + if pattern != "" { + var err error + g, err = hglob.GetGlob(pattern) + if err != nil { + return err + } + } + + for _, m := range mods { + if m.Replace != nil || m.Main { + continue + } + + if g != nil && !g.Match(m.Path) { + continue + } + _, err = hugofs.MakeReadableAndRemoveAllModulePkgDir(c.fs, m.Dir) + if err == nil { + c.logger.FEEDBACK.Printf("hugo: cleaned module cache for %q", m.Path) + } + } + return err +} + func (c *Client) runVerify() error { return c.runGo(context.Background(), ioutil.Discard, "mod", "verify") }