mirror of
https://github.com/mudler/luet.git
synced 2025-09-03 00:06:36 +00:00
Add 'tree bump' command
This commit is contained in:
@@ -33,5 +33,6 @@ func init() {
|
|||||||
treeGroupCmd.AddCommand(
|
treeGroupCmd.AddCommand(
|
||||||
NewTreePkglistCommand(),
|
NewTreePkglistCommand(),
|
||||||
NewTreeValidateCommand(),
|
NewTreeValidateCommand(),
|
||||||
|
NewTreeBumpCommand(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
67
cmd/tree/bump.go
Normal file
67
cmd/tree/bump.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
// Copyright © 2020 Ettore Di Giacinto <mudler@gentoo.org>
|
||||||
|
// Daniele Rondina <geaaru@sabayonlinux.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package cmd_tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
//"os"
|
||||||
|
//"sort"
|
||||||
|
|
||||||
|
. "github.com/mudler/luet/pkg/logger"
|
||||||
|
tree "github.com/mudler/luet/pkg/tree"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTreeBumpCommand() *cobra.Command {
|
||||||
|
|
||||||
|
var ans = &cobra.Command{
|
||||||
|
Use: "bump [OPTIONS]",
|
||||||
|
Short: "Bump a new package build version.",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
df, _ := cmd.Flags().GetString("definition-file")
|
||||||
|
if df == "" {
|
||||||
|
Fatal("Mandatory definition.yaml path missing.")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
spec, _ := cmd.Flags().GetString("definition-file")
|
||||||
|
pack, err := tree.ReadDefinitionFile(spec)
|
||||||
|
if err != nil {
|
||||||
|
Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve version build section with Gentoo parser
|
||||||
|
err = pack.BumpBuildVersion()
|
||||||
|
if err != nil {
|
||||||
|
Fatal("Error on increment build version: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tree.WriteDefinitionFile(&pack, spec)
|
||||||
|
if err != nil {
|
||||||
|
Fatal("Error on write definition file: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Bumped package %s/%s-%s.\n", pack.Category, pack.Name, pack.Version)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ans.Flags().StringP("definition-file", "f", "", "Path of the definition to bump.")
|
||||||
|
|
||||||
|
return ans
|
||||||
|
}
|
@@ -22,16 +22,17 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// . "github.com/mudler/luet/pkg/logger"
|
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
||||||
|
|
||||||
"github.com/crillab/gophersat/bf"
|
"github.com/crillab/gophersat/bf"
|
||||||
|
"github.com/ghodss/yaml"
|
||||||
version "github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/ghodss/yaml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package is a package interface (TBD)
|
// Package is a package interface (TBD)
|
||||||
@@ -62,6 +63,7 @@ type Package interface {
|
|||||||
GetVersion() string
|
GetVersion() string
|
||||||
RequiresContains(PackageDatabase, Package) (bool, error)
|
RequiresContains(PackageDatabase, Package) (bool, error)
|
||||||
Matches(m Package) bool
|
Matches(m Package) bool
|
||||||
|
BumpBuildVersion() error
|
||||||
|
|
||||||
AddUse(use string)
|
AddUse(use string)
|
||||||
RemoveUse(use string)
|
RemoveUse(use string)
|
||||||
@@ -334,7 +336,6 @@ func (p *DefaultPackage) Matches(m Package) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error) {
|
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error) {
|
||||||
var versionsInWorld []Package
|
var versionsInWorld []Package
|
||||||
|
|
||||||
@@ -608,3 +609,89 @@ func (p *DefaultPackage) Explain() {
|
|||||||
fmt.Println("====================")
|
fmt.Println("====================")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *DefaultPackage) BumpBuildVersion() error {
|
||||||
|
cat := p.Category
|
||||||
|
if cat == "" {
|
||||||
|
// Use fake category for parse package
|
||||||
|
cat = "app"
|
||||||
|
}
|
||||||
|
gp, err := gentoo.ParsePackageStr(
|
||||||
|
fmt.Sprintf("%s/%s-%s", cat,
|
||||||
|
p.Name, p.GetVersion()))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error on parser version")
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPrefix := ""
|
||||||
|
buildId := 0
|
||||||
|
|
||||||
|
if gp.VersionBuild != "" {
|
||||||
|
// Check if version build is a number
|
||||||
|
buildId, err = strconv.Atoi(gp.VersionBuild)
|
||||||
|
if err == nil {
|
||||||
|
goto end
|
||||||
|
}
|
||||||
|
// POST: is not only a number
|
||||||
|
|
||||||
|
// TODO: check if there is a better way to handle all use cases.
|
||||||
|
|
||||||
|
r1 := regexp.MustCompile(`^r[0-9]*$`)
|
||||||
|
if r1 == nil {
|
||||||
|
return errors.New("Error on create regex for -r[0-9]")
|
||||||
|
}
|
||||||
|
if r1.MatchString(gp.VersionBuild) {
|
||||||
|
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "r", ""))
|
||||||
|
if err == nil {
|
||||||
|
buildPrefix = "r"
|
||||||
|
goto end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p1 := regexp.MustCompile(`^p[0-9]*$`)
|
||||||
|
if p1 == nil {
|
||||||
|
return errors.New("Error on create regex for -p[0-9]")
|
||||||
|
}
|
||||||
|
if p1.MatchString(gp.VersionBuild) {
|
||||||
|
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "p", ""))
|
||||||
|
if err == nil {
|
||||||
|
buildPrefix = "p"
|
||||||
|
goto end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc1 := regexp.MustCompile(`^rc[0-9]*$`)
|
||||||
|
if rc1 == nil {
|
||||||
|
return errors.New("Error on create regex for -rc[0-9]")
|
||||||
|
}
|
||||||
|
if rc1.MatchString(gp.VersionBuild) {
|
||||||
|
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "rc", ""))
|
||||||
|
if err == nil {
|
||||||
|
buildPrefix = "rc"
|
||||||
|
goto end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if version build contains a dot
|
||||||
|
dotIdx := strings.LastIndex(gp.VersionBuild, ".")
|
||||||
|
if dotIdx > 0 {
|
||||||
|
buildPrefix = gp.VersionBuild[0 : dotIdx+1]
|
||||||
|
bVersion := gp.VersionBuild[dotIdx+1:]
|
||||||
|
buildId, err = strconv.Atoi(bVersion)
|
||||||
|
if err == nil {
|
||||||
|
goto end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPrefix = gp.VersionBuild + "."
|
||||||
|
buildId = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
buildId++
|
||||||
|
p.Version = fmt.Sprintf("%s%s+%s%d",
|
||||||
|
gp.Version, gp.VersionSuffix, buildPrefix, buildId)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -252,4 +252,69 @@ var _ = Describe("Package", func() {
|
|||||||
Expect(len(a1.GetUses())).To(Equal(0))
|
Expect(len(a1.GetUses())).To(Equal(0))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("Check Bump build Version", func() {
|
||||||
|
It("Bump without build version", func() {
|
||||||
|
a1 := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := a1.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(a1.GetVersion()).To(Equal("1.0+1"))
|
||||||
|
})
|
||||||
|
It("Bump 2", func() {
|
||||||
|
p := NewPackage("A", "1.0+1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+2"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 3", func() {
|
||||||
|
p := NewPackage("A", "1.0+100", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+101"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 4", func() {
|
||||||
|
p := NewPackage("A", "1.0+r1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+r2"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 5", func() {
|
||||||
|
p := NewPackage("A", "1.0+p1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+p2"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 6", func() {
|
||||||
|
p := NewPackage("A", "1.0+pre20200315", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+pre20200315.1"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 7", func() {
|
||||||
|
p := NewPackage("A", "1.0+pre20200315.1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+pre20200315.2"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 8", func() {
|
||||||
|
p := NewPackage("A", "1.0+d-r1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+d-r1.1"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Bump 9", func() {
|
||||||
|
p := NewPackage("A", "1.0+p20200315.1", []*DefaultPackage{}, []*DefaultPackage{})
|
||||||
|
err := p.BumpBuildVersion()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(p.GetVersion()).To(Equal("1.0+p20200315.2"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@@ -38,6 +38,20 @@ func NewCompilerRecipe(d pkg.PackageDatabase) Builder {
|
|||||||
return &CompilerRecipe{Recipe: Recipe{Database: d}}
|
return &CompilerRecipe{Recipe: Recipe{Database: d}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadDefinitionFile(path string) (pkg.DefaultPackage, error) {
|
||||||
|
empty := pkg.DefaultPackage{}
|
||||||
|
dat, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return empty, errors.Wrap(err, "Error reading file "+path)
|
||||||
|
}
|
||||||
|
pack, err := pkg.DefaultPackageFromYaml(dat)
|
||||||
|
if err != nil {
|
||||||
|
return empty, errors.Wrap(err, "Error reading yaml "+path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pack, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Recipe is the "general" reciper for Trees
|
// Recipe is the "general" reciper for Trees
|
||||||
type CompilerRecipe struct {
|
type CompilerRecipe struct {
|
||||||
Recipe
|
Recipe
|
||||||
@@ -64,13 +78,9 @@ func (r *CompilerRecipe) Load(path string) error {
|
|||||||
return nil // Skip with no errors
|
return nil // Skip with no errors
|
||||||
}
|
}
|
||||||
|
|
||||||
dat, err := ioutil.ReadFile(currentpath)
|
pack, err := ReadDefinitionFile(currentpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Error reading file "+currentpath)
|
return err
|
||||||
}
|
|
||||||
pack, err := pkg.DefaultPackageFromYaml(dat)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "Error reading yaml "+currentpath)
|
|
||||||
}
|
}
|
||||||
// Path is set only internally when tree is loaded from disk
|
// Path is set only internally when tree is loaded from disk
|
||||||
pack.SetPath(filepath.Dir(currentpath))
|
pack.SetPath(filepath.Dir(currentpath))
|
||||||
@@ -78,7 +88,7 @@ func (r *CompilerRecipe) Load(path string) error {
|
|||||||
// Instead of rdeps, have a different tree for build deps.
|
// Instead of rdeps, have a different tree for build deps.
|
||||||
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
||||||
if helpers.Exists(compileDefPath) {
|
if helpers.Exists(compileDefPath) {
|
||||||
dat, err = ioutil.ReadFile(compileDefPath)
|
dat, err := ioutil.ReadFile(compileDefPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err,
|
return errors.Wrap(err,
|
||||||
"Error reading file "+CompilerDefinitionFile+" from "+
|
"Error reading file "+CompilerDefinitionFile+" from "+
|
||||||
|
@@ -41,20 +41,28 @@ type Recipe struct {
|
|||||||
Database pkg.PackageDatabase
|
Database pkg.PackageDatabase
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Recipe) Save(path string) error {
|
func WriteDefinitionFile(p pkg.Package, definitionFilePath string) error {
|
||||||
|
data, err := p.Yaml()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = ioutil.WriteFile(definitionFilePath, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Recipe) Save(path string) error {
|
||||||
for _, p := range r.Database.World() {
|
for _, p := range r.Database.World() {
|
||||||
dir := filepath.Join(path, p.GetCategory(), p.GetName(), p.GetVersion())
|
dir := filepath.Join(path, p.GetCategory(), p.GetName(), p.GetVersion())
|
||||||
os.MkdirAll(dir, os.ModePerm)
|
os.MkdirAll(dir, os.ModePerm)
|
||||||
data, err := p.Yaml()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ioutil.WriteFile(filepath.Join(dir, DefinitionFile), data, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
err := WriteDefinitionFile(p, filepath.Join(dir, DefinitionFile))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user