kcl-lang.io/kpm@v0.8.7-0.20240520061008-9fc4c5efc8c7/pkg/cmd/cmd_graph.go (about) 1 // Copyright 2024 The KCL Authors. All rights reserved. 2 3 package cmd 4 5 import ( 6 "fmt" 7 "os" 8 9 "github.com/dominikbraun/graph" 10 "github.com/urfave/cli/v2" 11 "golang.org/x/mod/module" 12 "kcl-lang.io/kpm/pkg/client" 13 "kcl-lang.io/kpm/pkg/env" 14 pkg "kcl-lang.io/kpm/pkg/package" 15 "kcl-lang.io/kpm/pkg/reporter" 16 ) 17 18 // NewGraphCmd new a Command for `kpm graph`. 19 func NewGraphCmd(kpmcli *client.KpmClient) *cli.Command { 20 return &cli.Command{ 21 Hidden: false, 22 Name: "graph", 23 Usage: "prints the module dependency graph", 24 Action: func(c *cli.Context) error { 25 return KpmGraph(c, kpmcli) 26 }, 27 } 28 } 29 30 func KpmGraph(c *cli.Context, kpmcli *client.KpmClient) error { 31 // acquire the lock of the package cache. 32 err := kpmcli.AcquirePackageCacheLock() 33 if err != nil { 34 return err 35 } 36 37 defer func() { 38 // release the lock of the package cache after the function returns. 39 releaseErr := kpmcli.ReleasePackageCacheLock() 40 if releaseErr != nil && err == nil { 41 err = releaseErr 42 } 43 }() 44 45 pwd, err := os.Getwd() 46 47 if err != nil { 48 return reporter.NewErrorEvent(reporter.Bug, err, "internal bugs, please contact us to fix it.") 49 } 50 51 globalPkgPath, err := env.GetAbsPkgPath() 52 if err != nil { 53 return err 54 } 55 56 kclPkg, err := pkg.LoadKclPkg(pwd) 57 if err != nil { 58 return err 59 } 60 61 err = kclPkg.ValidateKpmHome(globalPkgPath) 62 if err != (*reporter.KpmEvent)(nil) { 63 return err 64 } 65 66 _, depGraph, err := kpmcli.InitGraphAndDownloadDeps(kclPkg) 67 if err != nil { 68 return err 69 } 70 71 adjMap, err := depGraph.AdjacencyMap() 72 if err != nil { 73 return err 74 } 75 76 format := func(m module.Version) string { 77 formattedMsg := m.Path 78 if m.Version != "" { 79 formattedMsg += "@" + m.Version 80 } 81 return formattedMsg 82 } 83 84 // print the dependency graph to stdout. 85 root := module.Version{Path: kclPkg.GetPkgName(), Version: kclPkg.GetPkgVersion()} 86 err = graph.BFS(depGraph, root, func(source module.Version) bool { 87 for target := range adjMap[source] { 88 reporter.ReportMsgTo( 89 fmt.Sprint(format(source), " ", format(target)), 90 kpmcli.GetLogWriter(), 91 ) 92 } 93 return false 94 }) 95 if err != nil { 96 return err 97 } 98 return nil 99 }