github.com/hattya/nazuna@v0.7.1-0.20240331055452-55e14c275c1c/cmd/nzn/update.go (about) 1 // 2 // nazuna/cmd/nzn :: update.go 3 // 4 // Copyright (c) 2013-2020 Akinori Hattori <hattya@gmail.com> 5 // 6 // SPDX-License-Identifier: MIT 7 // 8 9 package main 10 11 import ( 12 "fmt" 13 "path/filepath" 14 "strings" 15 16 "github.com/hattya/go.cli" 17 "github.com/hattya/nazuna" 18 ) 19 20 func init() { 21 flags := cli.NewFlagSet() 22 23 app.Add(&cli.Command{ 24 Name: []string{"update"}, 25 Usage: "update", 26 Desc: strings.TrimSpace(cli.Dedent(` 27 update working copy 28 29 Update links in the working copy to match with the repository configuration. 30 `)), 31 Flags: flags, 32 Action: update, 33 Data: true, 34 }) 35 } 36 37 func update(ctx *cli.Context) error { 38 repo := ctx.Data.(*nazuna.Repository) 39 wc, err := repo.WC() 40 if err != nil { 41 return err 42 } 43 ul, err := wc.MergeLayers() 44 if err != nil { 45 return wc.Errorf(err) 46 } 47 48 updated, removed, failed := 0, 0, 0 49 for _, e := range ul { 50 switch { 51 case !wc.Exists(e.Path): 52 continue 53 case !wc.IsLink(e.Path): 54 return fmt.Errorf("%v: not tracked", e.Path) 55 } 56 app.Println(e.Format("unlink %v -/- %v")) 57 switch e.Type { 58 case "link": 59 if !wc.LinksTo(e.Path, e.Origin) { 60 return fmt.Errorf("not linked to '%v'", e.Origin) 61 } 62 case "subrepo": 63 if !wc.LinksTo(e.Path, repo.SubrepoFor(e.Origin)) { 64 return fmt.Errorf("not linked to '%v'", e.Origin) 65 } 66 default: 67 var origin string 68 if e.Origin != "" { 69 origin = e.Origin 70 } else { 71 origin = e.Path 72 } 73 if !wc.LinksTo(e.Path, repo.PathFor(nil, filepath.Join(e.Layer, origin))) { 74 return fmt.Errorf("not linked to layer '%v'", e.Layer) 75 } 76 } 77 if err := wc.Unlink(e.Path); err != nil { 78 return err 79 } 80 removed++ 81 } 82 83 for i := 0; i < len(wc.State.WC); i++ { 84 e := wc.State.WC[i] 85 var origin string 86 switch e.Type { 87 case "link": 88 origin = e.Origin 89 case "subrepo": 90 origin = repo.SubrepoFor(e.Origin) 91 if !nazuna.IsDir(origin) { 92 continue 93 } 94 default: 95 l, _ := repo.LayerOf(e.Layer) 96 if e.Origin != "" { 97 origin = repo.PathFor(l, e.Origin) 98 } else { 99 origin = repo.PathFor(l, e.Path) 100 } 101 } 102 if wc.LinksTo(e.Path, origin) { 103 continue 104 } 105 app.Println(e.Format("link %v --> %v")) 106 if err := wc.Link(origin, e.Path); err != nil { 107 app.Errorln("error:", wc.Errorf(err)) 108 copy(wc.State.WC[i:], wc.State.WC[i+1:]) 109 wc.State.WC = wc.State.WC[:len(wc.State.WC)-1] 110 i-- 111 failed++ 112 } else { 113 updated++ 114 } 115 } 116 117 app.Printf("%d updated, %d removed, %d failed\n", updated, removed, failed) 118 if err := wc.Flush(); err != nil { 119 return err 120 } 121 if failed > 0 { 122 return SystemExit(1) 123 } 124 return nil 125 }