]> xenbits.xensource.com Git - people/gdunlap/xsatool.git/commitdiff
Use new branching scheme
authorGeorge Dunlap <george.dunlap@citrix.com>
Thu, 8 Jun 2017 16:37:45 +0000 (17:37 +0100)
committerGeorge Dunlap <george.dunlap@citrix.com>
Thu, 8 Jun 2017 16:37:45 +0000 (17:37 +0100)
New branching scheme:

 - $v-stable based on the recorded stable branch at the time the xsa
   was created

 - $v-baseline; the above, but with 'prerequisites' (outstanding XSAs
   not published yet)

 - $v: Branch with actual patches, only present when patches exist (or
   are being created)

To do this:

 - Separate Recipe.Apply() into ApplyBaseline (which only does -stable
   and -baseline) and ApplyPatches (which makes the main branch)

 - Get rid of IsApplied(), which doesn't do what it says on the tin

 - Implement HasPatchBranch, which detect whether the "patch"
   branch(es) exist for a given recipe

Then:

 - During Init, call only ApplyBaseline for all branches; only call
   ApplyPatches for master.

 - When calling sync-patches with 'all', have VersionsFromArgs filter
   out patches based on HasPatchBranch.  (sync-branches and test will still
   test all supported branches for 'all'.)

 - Add a test for the failure path of sync-branches with a
   non-existent branch

While we're here:

 - Use fmt.Print instead of fmt.Printf when there are no format tokens

 - Add missing '\n' to many status output messages

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
main.go
meta.go
recipe.go
systemtest.go
test.go
xsa.go

diff --git a/main.go b/main.go
index 99a540bc5e387d003197ea66bfdecc68ae510aa3..bb116b76790612bcb7b2d633c33371ecd33b6707 100644 (file)
--- a/main.go
+++ b/main.go
@@ -31,9 +31,15 @@ func ForEachXenRepo(f func(*XenRepo, Tree) error) error {
        return ForEachCodeTree(f2)
 }
 
-func VersionsFromArgs(xsa *XSAMeta, args []string) (vers []XenVersion) {
+func VersionsFromArgs(xsa *XSAMeta, args []string, hasPatches bool) (vers []XenVersion) {
        if len(args) == 0 || (len(args) == 1 && args[0] == "all") {
-               vers = append(vers, xsa.SupportedVersions...)
+               for _, v := range xsa.SupportedVersions {
+                       // Check to see if the branch exists
+                       if hasPatches && !xsa.RepoHasPatches(v) {
+                               continue
+                       }
+                       vers = append(vers, v)
+               }
        } else {
                // FIXME: Verify xenversion format
                for _, v := range args {
diff --git a/meta.go b/meta.go
index 66b98b0cc4f4c52e89c159a4cf9451f9e0223aba..9588b3240059a652af9a65857040b1b6284282ef 100644 (file)
--- a/meta.go
+++ b/meta.go
@@ -237,6 +237,16 @@ func (m *XSAMeta) NewRecipe(v XenVersion) *Recipe {
        return &r
 }
 
+func (m *XSAMeta) RepoHasPatches(v XenVersion) bool {
+       r := m.GetRecipe(v)
+
+       if r == nil {
+               return false
+       }
+
+       return r.HasPatchBranch("xsa") == nil
+}
+
 func getXSAPath(xsanum int) string {
        return fmt.Sprintf("%s/xsa%d.meta", G.config.Tool.GetPath(TreeXSA), xsanum)
 }
index 56fc3e6703da13b17b4ce88d3ae92b4eb341004e..61341ed1a9c3595401242ec87738c8fc4700349d 100644 (file)
--- a/recipe.go
+++ b/recipe.go
@@ -82,7 +82,7 @@ func (r *Recipe) HasPatches() (has bool) {
 }
 
 func (r *Recipe) MakePatches(prefix string, sync bool) (count int, err error) {
-       branch, baseline := r.branchName(prefix)
+       _, baseline, branch := r.branchName(prefix)
 
        // rm -rf /tmp/xsa
        if err = os.RemoveAll(FPPath); err != nil {
@@ -264,6 +264,11 @@ func (r *Recipe) MakePatches(prefix string, sync bool) (count int, err error) {
 
 type ErrorMissingBranch string
 
+func IsMissingBranch(err error) (is bool) {
+       _, is = err.(ErrorMissingBranch)
+       return
+}
+
 func (s ErrorMissingBranch) Error() string {
        return fmt.Sprintf("Missing branch: %s", s)
 }
@@ -273,12 +278,12 @@ func (s ErrorMissingBranch) Error() string {
 // branch (which is aliased as a string which tells you the name of
 // the missing branch); otherwise it returns whatever error it
 // encountered when processing.
-func (r *Recipe) IsApplied(prefix string) (err error) {
-       branch, baseline := r.branchName(prefix)
+func (r *Recipe) HasPatchBranch(prefix string) (err error) {
+       _, _, branch := r.branchName(prefix)
 
        check := func(tree Tree) (err error) {
-               tr, prs := r.Recipes[tree]
-               if !prs || !tr.HasPatches() {
+               _, prs := r.Recipes[tree]
+               if !prs {
                        return
                }
 
@@ -287,11 +292,6 @@ func (r *Recipe) IsApplied(prefix string) (err error) {
                if !xr.VerifyRef(branch) {
                        return ErrorMissingBranch(branch)
                }
-               if !xr.VerifyRef(baseline) {
-                       return ErrorMissingBranch(baseline)
-               }
-
-               // FIXME: Actually check to see if something is applied
 
                return
        }
@@ -303,18 +303,19 @@ func (r *Recipe) IsApplied(prefix string) (err error) {
        return
 }
 
-func BranchName(prefix string, xsa int, v XenVersion) (branch, baseline string) {
+func BranchName(prefix string, xsa int, v XenVersion) (stable, baseline, branch string) {
        // Construct branchname
        branch = prefix + "/" + strconv.Itoa(xsa) + "/" + v.String()
+       stable = branch + "-stable"
        baseline = branch + "-baseline"
 
        return
 }
 
-func (r *Recipe) branchName(prefix string) (branch, baseline string) {
-       branch, baseline = BranchName(prefix, r.xsa, r.XenVersion)
+func (r *Recipe) branchName(prefix string) (stable, baseline, branch string) {
+       stable, baseline, branch = BranchName(prefix, r.xsa, r.XenVersion)
 
-       fmt.Printf("Branchnames: %s %s\n", branch, baseline)
+       fmt.Printf("Branchnames: %s %s %s\n", stable, baseline, branch)
 
        return
 }
@@ -322,47 +323,50 @@ func (r *Recipe) branchName(prefix string) (branch, baseline string) {
 // Naming convention:
 //
 // XSA patches:
-// xsa/NNN/VV.v-baseline
-// xsa/NNN/VV.v
+// xsa/NNN/VV-stable
+// xsa/NNN/VV-baseline
+// xsa/NNN/VV
 //
 // Testing:
 // test/NN/MM.m
 
-// Create branches and apply whatever patches exist.
-func (r *Recipe) apply(xr *XenRepo, tr *TreeRecipe, prefix string) (err error) {
-       branch, baseline := r.branchName(prefix)
+// Create a "patch series" branch and apply it
+func (r *Recipe) ApplyPatches(prefix string) (err error) {
+       apply := func(tree Tree) (err error) {
+               tr, prs := r.Recipes[tree]
 
-       // FIXME change this to tr.StableRef
-       // Make "baseline" branch, based on XenVersion, with Prereq patches
-       err = xr.MakeBranch(baseline, tr.StableRef)
-       if err != nil {
-               return fmt.Errorf("Making baseline %s for xenversion %v: %v\n",
-                       baseline, r.XenVersion)
-       }
+               if !prs {
+                       err = fmt.Errorf("Internal data error: no recipe for tree %s\n", tree)
+                       return
+               }
 
-       for _, xsanum := range tr.Prereqs {
-               err = fmt.Errorf("%d: Don't know how to apply XSA prerequisites yet!", xsanum)
-               return
-       }
+               xr := G.repos.XenRepos[tree]
 
-       // Make xsa branch based on "baseline" branch
-       err = xr.MakeBranch(branch, baseline)
-       if err != nil {
-               return fmt.Errorf("Making tempbranch %s for xenversion %v: %v\n",
-                       branch, r.XenVersion)
-       }
+               _, baseline, branch := r.branchName(prefix)
 
-       for _, glob := range tr.Patches {
-               // git am
-               _, err = xr.AmClean(G.config.Tool.GetPath(TreeXSA) + "/" + glob)
+               // Make xsa branch based on "baseline" branch
+               err = xr.MakeBranch(branch, baseline)
                if err != nil {
-                       return fmt.Errorf("Appling am %s: %v\n", glob, err)
+                       return fmt.Errorf("Making tempbranch %s for xenversion %v: %v\n",
+                               branch, r.XenVersion)
                }
+               
+               for _, glob := range tr.Patches {
+                       // git am
+                       _, err = xr.AmClean(G.config.Tool.GetPath(TreeXSA) + "/" + glob)
+                       if err != nil {
+                               return fmt.Errorf("Appling am %s: %v\n", glob, err)
+                       }
+               }
+               return
        }
+
+       err = r.ForEachTree(apply)
+
        return
 }
 
-func (r *Recipe) Apply(prefix string) (err error) {
+func (r *Recipe) ApplyBaselines(prefix string) (err error) {
        apply := func(tree Tree) (err error) {
                tr, prs := r.Recipes[tree]
 
@@ -373,11 +377,40 @@ func (r *Recipe) Apply(prefix string) (err error) {
 
                xr := G.repos.XenRepos[tree]
 
-               err = r.apply(xr, tr, prefix)
+               stable, baseline, _ := r.branchName(prefix)
+
+               // Create xsa/NNN/VV-stable based on tr.StableRef
+               if err = xr.MakeBranch(stable, tr.StableRef); err != nil {
+                       return fmt.Errorf("Making stable baseline %s for xenversion %v: %v\n",
+                               stable, r.XenVersion, err)
+               }
+
+               // Create xsa/NNN/VV-baseline based on -stable
+               if err = xr.MakeBranch(baseline, stable); err != nil {
+                       return fmt.Errorf("Making patch baseline %s for xenversion %v: %v\n",
+                               baseline, r.XenVersion, err)
+               }
+
+               // FIXME Apply previous patches
+               for _, xsanum := range tr.Prereqs {
+                       err = fmt.Errorf("%d: Don't know how to apply XSA prerequisites yet!", xsanum)
+                       return
+               }
+               
                return
        }
 
        err = r.ForEachTree(apply)
+       
+       return
+}
+
+func (r *Recipe) ApplyAll(prefix string) (err error) {
+       if err = r.ApplyBaselines(prefix); err != nil {
+               return
+       }
+
+       err = r.ApplyPatches(prefix)
 
        return
 }
@@ -394,7 +427,7 @@ func (r *Recipe) GetTreeRecipe(tree Tree) (tr *TreeRecipe, err error) {
 }
 
 func (r *Recipe) Build(prefix string) (err error) {
-       branch, _ := r.branchName(prefix)
+       _, _, branch := r.branchName(prefix)
 
        xenrepo := G.repos.XenRepos[TreeXen]
 
index d86841a4afbbd8694d5d7db6754b75a1ed36e169..ef6c26568afb2692e7385cad7cd038c1a9fd89dc 100644 (file)
@@ -242,7 +242,7 @@ func GlobalInit(st *SystemTest) (pass bool) {
 }
 
 func Story206Init(st *SystemTest) (pass bool) {
-       fmt.Printf(" xsatool 206 init xen")
+       fmt.Print(" xsatool 206 init xen\n")
        if MainHarness("206", "init", "xen") != 0 {
                st.Errorf("xsatool 206 init failed\n")
                return false
@@ -383,7 +383,7 @@ func Story206Implement(st *SystemTest) (pass bool) {
 }
 
 func Story206SyncOne(st *SystemTest) (pass bool) {
-       fmt.Printf(" xsatool 206 sync-patches")
+       fmt.Print(" xsatool 206 sync-patches\n")
        if MainHarness("206", "sync-patches") != 0 {
                st.Errorf("xsatool 206 sync-patches failed\n")
                return false
@@ -415,11 +415,21 @@ func Story206SyncOne(st *SystemTest) (pass bool) {
                }
        }
 
-       return pass
+       if !pass {
+               return
+       }
+
+       fmt.Print(" xsatool 206 sync-patches 4.8 [should fail]\n")
+       if MainHarness("206", "sync-patches", "4.8") == 0 {
+               st.Errorf("xsatool 206 sync-patches 4.8 succeeded without any patches!\n")
+               return false
+       }
+
+       return
 }
 
 func Story206TestMaster(st *SystemTest) bool {
-       fmt.Printf(" xsatool 206 test (initial)")
+       fmt.Print(" xsatool 206 test (initial)\n")
        if MainHarness("206", "test") != 0 {
                st.Errorf("xsatool 206 test (initial - master) failed\n")
                return false
@@ -428,7 +438,7 @@ func Story206TestMaster(st *SystemTest) bool {
 }
 
 func Story206(st *SystemTest) bool {
-       fmt.Printf("Starting XSA-206 'story'")
+       fmt.Print("Starting XSA-206 'story'\n")
        // xsatool 206 init xen
        if !Story206Init(st) {
                return false
diff --git a/test.go b/test.go
index 99bf0e823ec4355d98d783afd90e3ad39fac4921..5ba91e1e0c880f55469952891e6bcc86788ae4ae 100644 (file)
--- a/test.go
+++ b/test.go
@@ -6,7 +6,7 @@ import (
 
 func test(xsa *XSAMeta, args []string, apply bool, build bool) (ret int) {
 
-       vers := VersionsFromArgs(xsa, args)
+       vers := VersionsFromArgs(xsa, args, false)
 
        for _, v := range vers {
                prefix := "test"
@@ -22,22 +22,19 @@ func test(xsa *XSAMeta, args []string, apply bool, build bool) (ret int) {
                }
 
                if apply {
-                       err := r.Apply(prefix)
-                       if err != nil {
+                       if err := r.ApplyAll(prefix); err != nil {
                                fmt.Printf("Applying recipe: %v\n", err)
                                fmt.Printf("FAILED: %v\n", r.XenVersion)
                                return 1
                        }
                } else {
-                       err := r.IsApplied(prefix)
-                       if err != nil {
-                               emb, missing := err.(ErrorMissingBranch)
-                               if !missing {
+                       if err := r.HasPatchBranch(prefix); err != nil {
+                               if !IsMissingBranch(err) {
                                        fmt.Printf("Error checking to see if recipe has been applied: %v\n", err)
                                        return 1
                                }
                                fmt.Printf("Error: recipe for xsa %d version %v not applied (missing branch %s)\n",
-                                       xsa.XSA, v, string(emb))
+                                       xsa.XSA, v, string(err.(ErrorMissingBranch)))
                                return 1
                        }
                }
diff --git a/xsa.go b/xsa.go
index 7b046316736ec95e428b4aaef0abf03581fe8209..9069f93cb953592cc916b5c154e3ccda915f1423 100644 (file)
--- a/xsa.go
+++ b/xsa.go
@@ -5,7 +5,7 @@ import (
 )
 
 func sync(xsa *XSAMeta, args []string, sync bool) (ret int) {
-       vers := VersionsFromArgs(xsa, args)
+       vers := VersionsFromArgs(xsa, args, true)
 
        if !sync && len(vers) > 1 {
                fmt.Printf("Error: Doesn't make sense to make more than one version\n")
@@ -20,6 +20,17 @@ func sync(xsa *XSAMeta, args []string, sync bool) (ret int) {
                        return 1
                }
 
+               // Check to see if there's a branch.  If not, throw an error.
+               if err := r.HasPatchBranch("xsa"); err != nil {
+                       if IsMissingBranch(err) {
+                               fmt.Printf("Error: No patch branch for version %v (missing branch %s)\n",
+                                       v, string(err.(ErrorMissingBranch)))
+                               return 1
+                       }
+                       fmt.Printf("Error checking for patch branch: %v\n", err)
+                       return 1
+               }
+
                count, err := r.MakePatches("xsa", sync)
                if err != nil {
                        fmt.Printf("Making patches: %v\n", err)
@@ -47,7 +58,7 @@ func MainMakePatches(xsa *XSAMeta, args []string) (ret int) {
 }
 
 func MainSyncBranch(xsa *XSAMeta, args []string) (ret int) {
-       vers := VersionsFromArgs(xsa, args)
+       vers := VersionsFromArgs(xsa, args, false)
 
        for _, v := range vers {
                prefix := "xsa"
@@ -57,7 +68,7 @@ func MainSyncBranch(xsa *XSAMeta, args []string) (ret int) {
                        return 1
                }
 
-               err := r.Apply(prefix)
+               err := r.ApplyAll(prefix)
                if err != nil {
                        fmt.Printf("Applying recipe: %v\n", err)
                        fmt.Printf("FAILED: %v\n", r.XenVersion)
@@ -133,14 +144,21 @@ func MainInit(xsa *XSAMeta, args []string) (ret int) {
 
                }
 
-               if err := r.Apply("xsa"); err != nil {
-                       fmt.Printf("Applying initial recipe for version %v\n", v)
+               if err := r.ApplyBaselines("xsa"); err != nil {
+                       fmt.Printf("Making recipe baseline for version %v\n", v)
                        return 1
                }
+
+               if v == XenVersionMaster {
+                       if err := r.ApplyPatches("xsa"); err != nil {
+                               fmt.Printf("Applying recipe patches for version %v\n", v)
+                               return 1
+                       }
+               }
        }
 
        // Check out "xsa/NNN/master" on all relevant trees
-       branch, _ := BranchName("xsa", xsa.XSA, XenVersion("master"))
+       _, _, branch := BranchName("xsa", xsa.XSA, XenVersion("master"))
        for _, t := range xsa.Trees {
                _, err := G.repos.XenRepos[t].Checkout(branch)
                if err != nil {