Original post

a little code samples copied from spf13/cobra

go.mod

module cobra-demo
go 1.15
require (
        github.com/mitchellh/go-homedir v1.1.0
        github.com/spf13/cobra v1.1.0
        github.com/spf13/viper v1.7.1
)

main.go

package main
import (
  "cobra-demo/cmd"
)
func main() {
  cmd.Execute()
}

cmd/version.go

package cmd
import (
  "fmt"
  "github.com/spf13/cobra"
)
func init() {
  rootCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
  Use:   "version",
  Short: "Print the version number of Hugo",
  Long:  `All software has versions. This is Hugo's`,
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
  },
}

cmd/root.go

package cmd
import (
        "fmt"
        "os"
        homedir "github.com/mitchellh/go-homedir"
        "github.com/spf13/cobra"
        "github.com/spf13/viper"
)
var (
        // Used for flags.
        cfgFile     string
        userLicense string

        rootCmd = &cobra.Command{
                Use:   "cobra",
                Short: "A generator for Cobra based Applications",
                Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
        }
)

func Execute() error {
        return rootCmd.Execute()
}

func init() {
        cobra.OnInitialize(initConfig)
}

func er(msg interface{}) {
        fmt.Println("Error:", msg)
        os.Exit(1)
}

func initConfig() {
        if cfgFile != "" {
                viper.SetConfigFile(cfgFile)
        } else {
                home, err := homedir.Dir()
                if err != nil {
                        er(err)
                }
                viper.AddConfigPath(home)
                viper.SetConfigName(".cobra")
        }

        viper.AutomaticEnv()

        if err := viper.ReadInConfig(); err == nil {
                fmt.Println("Using config file:", viper.ConfigFileUsed())
        }
}

after run go mod tidy, there is a long list in go.sum

i see cloud.google.com/go there, but when i run go mod why cloud.google.com/go

$ go mod why cloud.google.com/go
# cloud.google.com/go
(main module does not need package cloud.google.com/go)

after some digging, i found viper import github.com/bketelsen/crypt and crypt imports cloud.google.com/go.

so github.com/bketelsen/crypt and cloud.google.com/go are indirect dependencies for cobra-demo, right ?

viper depends on github.com/bketelsen/crypt and crypt depends on cloud.google.com/go, so why this project does not need package cloud.google.com/go ?

and after run go mod vendor

λ  tree -L 2 vendor
vendor
├── github.com
│   ├── fsnotify
│   ├── hashicorp
│   ├── inconshreveable
│   ├── magiconair
│   ├── mitchellh
│   ├── pelletier
│   ├── spf13
│   └── subosito
├── golang.org
│   └── x
├── gopkg.in
│   ├── ini.v1
│   └── yaml.v2
└── modules.txt

14 directories, 1 file

there is no cloud.google.com/go