github.com/jason-dour/hugo@v0.63.3/commands/mod.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package commands
    15  
    16  import (
    17  	"os"
    18  
    19  	"github.com/gohugoio/hugo/modules"
    20  	"github.com/spf13/cobra"
    21  )
    22  
    23  var _ cmder = (*modCmd)(nil)
    24  
    25  type modCmd struct {
    26  	*baseBuilderCmd
    27  }
    28  
    29  func (b *commandsBuilder) newModCmd() *modCmd {
    30  	c := &modCmd{}
    31  
    32  	const commonUsage = `
    33  Note that Hugo will always start out by resolving the components defined in the site
    34  configuration, provided by a _vendor directory (if no --ignoreVendor flag provided),
    35  Go Modules, or a folder inside the themes directory, in that order.
    36  
    37  See https://gohugo.io/hugo-modules/ for more information.
    38  
    39  `
    40  
    41  	cmd := &cobra.Command{
    42  		Use:   "mod",
    43  		Short: "Various Hugo Modules helpers.",
    44  		Long: `Various helpers to help manage the modules in your project's dependency graph.
    45  
    46  Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git).
    47  This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor".
    48  
    49  ` + commonUsage,
    50  
    51  		RunE: nil,
    52  	}
    53  
    54  	cmd.AddCommand(
    55  		&cobra.Command{
    56  			Use:                "get",
    57  			DisableFlagParsing: true,
    58  			Short:              "Resolves dependencies in your current Hugo Project.",
    59  			Long: `
    60  Resolves dependencies in your current Hugo Project.
    61  
    62  Some examples:
    63  
    64  Install the latest version possible for a given module:
    65  
    66      hugo mod get github.com/gohugoio/testshortcodes
    67      
    68  Install a specific version:
    69  
    70      hugo mod get github.com/gohugoio/testshortcodes@v0.3.0
    71  
    72  Install the latest versions of all module dependencies:
    73  
    74      hugo mod get -u
    75  
    76  Run "go help get" for more information. All flags available for "go get" is also relevant here.
    77  ` + commonUsage,
    78  			RunE: func(cmd *cobra.Command, args []string) error {
    79  				return c.withModsClient(false, func(c *modules.Client) error {
    80  					// We currently just pass on the flags we get to Go and
    81  					// need to do the flag handling manually.
    82  					if len(args) == 1 && args[0] == "-h" {
    83  						return cmd.Help()
    84  					}
    85  					return c.Get(args...)
    86  				})
    87  			},
    88  		},
    89  		&cobra.Command{
    90  			Use:   "graph",
    91  			Short: "Print a module dependency graph.",
    92  			Long: `Print a module dependency graph with information about module status (disabled, vendored).
    93  Note that for vendored modules, that is the version listed and not the one from go.mod.
    94  `,
    95  			RunE: func(cmd *cobra.Command, args []string) error {
    96  				return c.withModsClient(true, func(c *modules.Client) error {
    97  					return c.Graph(os.Stdout)
    98  				})
    99  			},
   100  		},
   101  		&cobra.Command{
   102  			Use:   "init",
   103  			Short: "Initialize this project as a Hugo Module.",
   104  			Long: `Initialize this project as a Hugo Module.
   105  It will try to guess the module path, but you may help by passing it as an argument, e.g:
   106  
   107      hugo mod init github.com/gohugoio/testshortcodes
   108  
   109  Note that Hugo Modules supports multi-module projects, so you can initialize a Hugo Module
   110  inside a subfolder on GitHub, as one example.
   111  `,
   112  			RunE: func(cmd *cobra.Command, args []string) error {
   113  				var path string
   114  				if len(args) >= 1 {
   115  					path = args[0]
   116  				}
   117  				return c.withModsClient(false, func(c *modules.Client) error {
   118  					return c.Init(path)
   119  				})
   120  			},
   121  		},
   122  		&cobra.Command{
   123  			Use:   "vendor",
   124  			Short: "Vendor all module dependencies into the _vendor directory.",
   125  			Long: `Vendor all module dependencies into the _vendor directory.
   126  
   127  If a module is vendored, that is where Hugo will look for it's dependencies.
   128  `,
   129  			RunE: func(cmd *cobra.Command, args []string) error {
   130  				return c.withModsClient(true, func(c *modules.Client) error {
   131  					return c.Vendor()
   132  				})
   133  			},
   134  		},
   135  		&cobra.Command{
   136  			Use:   "tidy",
   137  			Short: "Remove unused entries in go.mod and go.sum.",
   138  			RunE: func(cmd *cobra.Command, args []string) error {
   139  				return c.withModsClient(true, func(c *modules.Client) error {
   140  					return c.Tidy()
   141  				})
   142  			},
   143  		},
   144  		&cobra.Command{
   145  			Use:   "clean",
   146  			Short: "Delete the entire Hugo Module cache.",
   147  			Long: `Delete the entire Hugo Module cache.
   148  
   149  Note that after you run this command, all of your dependencies will be re-downloaded next time you run "hugo".
   150  
   151  Also note that if you configure a positive maxAge for the "modules" file cache, it will also be cleaned as part of "hugo --gc".
   152   
   153  `,
   154  			RunE: func(cmd *cobra.Command, args []string) error {
   155  				com, err := c.initConfig(true)
   156  				if err != nil {
   157  					return err
   158  				}
   159  
   160  				_, err = com.hugo().FileCaches.ModulesCache().Prune(true)
   161  				return err
   162  
   163  			},
   164  		},
   165  	)
   166  
   167  	c.baseBuilderCmd = b.newBuilderCmd(cmd)
   168  
   169  	return c
   170  
   171  }
   172  
   173  func (c *modCmd) withModsClient(failOnMissingConfig bool, f func(*modules.Client) error) error {
   174  	com, err := c.initConfig(failOnMissingConfig)
   175  	if err != nil {
   176  		return err
   177  	}
   178  
   179  	return f(com.hugo().ModulesClient)
   180  }
   181  
   182  func (c *modCmd) initConfig(failOnNoConfig bool) (*commandeer, error) {
   183  	com, err := initializeConfig(failOnNoConfig, false, &c.hugoBuilderCommon, c, nil)
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  	return com, nil
   188  }