github.com/gernest/nezuko@v0.1.2/internal/modload/list.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package modload 6 7 import ( 8 "fmt" 9 "os" 10 "strings" 11 12 "github.com/gernest/nezuko/internal/base" 13 "github.com/gernest/nezuko/internal/modinfo" 14 "github.com/gernest/nezuko/internal/module" 15 "github.com/gernest/nezuko/internal/par" 16 "github.com/gernest/nezuko/internal/search" 17 ) 18 19 func ListModules(args []string, listU, listVersions bool) []*modinfo.ModulePublic { 20 mods := listModules(args, listVersions) 21 if listU || listVersions { 22 var work par.Work 23 for _, m := range mods { 24 work.Add(m) 25 if m.Replace != nil { 26 work.Add(m.Replace) 27 } 28 } 29 work.Do(10, func(item interface{}) { 30 m := item.(*modinfo.ModulePublic) 31 if listU { 32 addUpdate(m) 33 } 34 if listVersions { 35 addVersions(m) 36 } 37 }) 38 } 39 return mods 40 } 41 42 func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { 43 LoadBuildList() 44 if len(args) == 0 { 45 return []*modinfo.ModulePublic{moduleInfo(buildList[0], true)} 46 } 47 48 var mods []*modinfo.ModulePublic 49 matchedBuildList := make([]bool, len(buildList)) 50 for _, arg := range args { 51 if strings.Contains(arg, `\`) { 52 base.Fatalf("z: module paths never use backslash") 53 } 54 if search.IsRelativePath(arg) { 55 base.Fatalf("z: cannot use relative path %s to specify module", arg) 56 } 57 if i := strings.Index(arg, "@"); i >= 0 { 58 info, err := Query(arg[:i], arg[i+1:], nil) 59 if err != nil { 60 mods = append(mods, &modinfo.ModulePublic{ 61 Path: arg[:i], 62 Version: arg[i+1:], 63 Error: &modinfo.ModuleError{ 64 Err: err.Error(), 65 }, 66 }) 67 continue 68 } 69 mods = append(mods, moduleInfo(module.Version{Path: arg[:i], Version: info.Version}, false)) 70 continue 71 } 72 73 // Module path or pattern. 74 var match func(string) bool 75 var literal bool 76 if arg == "all" { 77 match = func(string) bool { return true } 78 } else if strings.Contains(arg, "...") { 79 match = search.MatchPattern(arg) 80 } else { 81 match = func(p string) bool { return arg == p } 82 literal = true 83 } 84 matched := false 85 for i, m := range buildList { 86 if i == 0 && !HasModRoot() { 87 // The root module doesn't actually exist: omit it. 88 continue 89 } 90 if match(m.Path) { 91 matched = true 92 if !matchedBuildList[i] { 93 matchedBuildList[i] = true 94 mods = append(mods, moduleInfo(m, true)) 95 } 96 } 97 } 98 if !matched { 99 if literal { 100 if listVersions { 101 // Don't make the user provide an explicit '@latest' when they're 102 // explicitly asking what the available versions are. 103 // Instead, resolve the module, even if it isn't an existing dependency. 104 info, err := Query(arg, "latest", nil) 105 if err == nil { 106 mods = append(mods, moduleInfo(module.Version{Path: arg, Version: info.Version}, false)) 107 continue 108 } 109 } 110 mods = append(mods, &modinfo.ModulePublic{ 111 Path: arg, 112 Error: &modinfo.ModuleError{ 113 Err: fmt.Sprintf("module %q is not a known dependency", arg), 114 }, 115 }) 116 } else { 117 fmt.Fprintf(os.Stderr, "warning: pattern %q matched no module dependencies\n", arg) 118 } 119 } 120 } 121 122 return mods 123 }