github.com/anthonymayer/glide@v0.0.0-20160224162501-bff8b50d232e/dependency/delete.go (about) 1 package dependency 2 3 import ( 4 "errors" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/Masterminds/glide/cfg" 10 "github.com/Masterminds/glide/msg" 11 gpath "github.com/Masterminds/glide/path" 12 ) 13 14 // DeleteUnused removes packages from vendor/ that are no longer used. 15 // 16 // TODO: This should work off of a Lock file, not glide.yaml. 17 func DeleteUnused(conf *cfg.Config) error { 18 vpath, err := gpath.Vendor() 19 if err != nil { 20 return err 21 } 22 if vpath == "" { 23 return errors.New("Vendor not set") 24 } 25 26 // Build directory tree of what to keep. 27 var pkgList []string 28 for _, dep := range conf.Imports { 29 pkgList = append(pkgList, dep.Name) 30 } 31 32 var searchPath string 33 var markForDelete []string 34 // Callback function for filepath.Walk to delete packages not in yaml file. 35 fn := func(path string, info os.FileInfo, err error) error { 36 // Bubble up the error 37 if err != nil { 38 return err 39 } 40 41 if info.IsDir() == false || path == searchPath || path == vpath { 42 return nil 43 } 44 45 localPath := strings.TrimPrefix(path, searchPath) 46 keep := false 47 48 // First check if the path has a prefix that's a specific package. If 49 // so we keep it to keep the package. 50 for _, name := range pkgList { 51 if strings.HasPrefix(localPath, name) { 52 keep = true 53 } 54 } 55 56 // If a package is, for example, github.com/Masterminds/glide the 57 // previous look will not mark the directories github.com or 58 // github.com/Masterminds to keep. Here we see if these names prefix 59 // and packages we know about to mark as keepers. 60 if keep == false { 61 for _, name := range pkgList { 62 if strings.HasPrefix(name, localPath) { 63 keep = true 64 } 65 } 66 } 67 68 // If the parent directory has already been marked for delete this 69 // directory doesn't need to be marked. 70 for _, markedDirectory := range markForDelete { 71 if strings.HasPrefix(path, markedDirectory) { 72 return nil 73 } 74 } 75 76 // Remove the directory if we are not keeping it. 77 if keep == false { 78 // Mark for deletion 79 markForDelete = append(markForDelete, path) 80 } 81 82 return nil 83 } 84 85 // Walk vendor directory 86 searchPath = vpath + string(os.PathSeparator) 87 err = filepath.Walk(searchPath, fn) 88 if err != nil { 89 return err 90 } 91 92 // Perform the actual delete. 93 for _, path := range markForDelete { 94 localPath := strings.TrimPrefix(path, searchPath) 95 msg.Info("Removing unused package: %s\n", localPath) 96 rerr := os.RemoveAll(path) 97 if rerr != nil { 98 return rerr 99 } 100 } 101 102 return nil 103 }