github.com/whyrusleeping/gx@v0.14.3/update.go (about) 1 package main 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 8 gx "github.com/whyrusleeping/gx/gxutil" 9 log "github.com/whyrusleeping/stump" 10 ) 11 12 func RecursiveDepUpdate(pkg *gx.Package, from, to string) error { 13 log.Log("recursively updating %s to %s", from, to) 14 todo := map[string]string{ 15 from: to, 16 } 17 cwd, err := os.Getwd() 18 if err != nil { 19 return err 20 } 21 22 checked := make(map[string]bool) 23 24 _, err = cascadingUpdate(pkg, cwd, todo, checked) 25 return err 26 } 27 28 func cascadingUpdate(cur *gx.Package, dir string, updates map[string]string, checked map[string]bool) (bool, error) { 29 log.Log("cascading update of package %s in %s", cur.Name, dir) 30 var changed bool 31 err := cur.ForEachDep(func(dep *gx.Dependency, child *gx.Package) error { 32 if checked[dep.Hash] { 33 return nil 34 } 35 log.Log(" - processing %s...", dep.Name) 36 37 if to, ok := updates[dep.Hash]; ok { 38 log.Log(" ==> updating dep %s on %s", dep.Name, cur.Name) 39 dep.Hash = to 40 dep.Version = child.Version 41 changed = true 42 } else { 43 nchild, err := fetchAndUpdate(dep.Hash, updates, checked) 44 if err != nil { 45 return err 46 } 47 48 if nchild != "" { 49 updates[dep.Hash] = nchild 50 dep.Hash = nchild 51 changed = true 52 } else { 53 checked[dep.Hash] = true 54 } 55 } 56 57 return nil 58 }) 59 60 if err != nil { 61 return false, err 62 } 63 64 return changed, nil 65 } 66 67 func fetchAndUpdate(tofetch string, updates map[string]string, checked map[string]bool) (string, error) { 68 log.Log("fetch and update: %s", tofetch) 69 dir, err := ioutil.TempDir("", "gx-update") 70 if err != nil { 71 return "", err 72 } 73 74 dir = filepath.Join(dir, tofetch) 75 76 pkg, err := pm.GetPackageTo(tofetch, dir) 77 if err != nil { 78 return "", err 79 } 80 81 changed, err := cascadingUpdate(pkg, dir, updates, checked) 82 if err != nil { 83 return "", err 84 } 85 86 if changed { 87 err := gx.SavePackageFile(pkg, filepath.Join(dir, pkg.Name, gx.PkgFileName)) 88 if err != nil { 89 return "", err 90 } 91 92 return pm.PublishPackage(dir, &pkg.PackageBase) 93 } 94 95 return "", nil 96 }