Merge pull request #84 from mudler/develop

Merge develop
This commit is contained in:
Ettore Di Giacinto 2020-04-11 18:24:02 +02:00 committed by GitHub
commit c2beab64cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1070 additions and 235 deletions

View File

@ -46,7 +46,7 @@ var installCmd = &cobra.Command{
},
Long: `Install packages in parallel`,
Run: func(cmd *cobra.Command, args []string) {
var toInstall []pkg.Package
var toInstall pkg.Packages
var systemDB pkg.PackageDatabase
for _, a := range args {

View File

@ -94,6 +94,7 @@ func LoadConfig(c *config.LuetConfig) error {
func Execute() {
if os.Getenv("LUET_NOLOCK") != "true" {
if len(os.Args) > 1 {
for _, lockedCmd := range LockedCommands {
if os.Args[1] == lockedCmd {
s := single.New("luet")
@ -108,6 +109,7 @@ func Execute() {
}
}
}
}
if err := RootCmd.Execute(); err != nil {
if len(os.Args) > 0 {

View File

@ -108,7 +108,7 @@ var searchCmd = &cobra.Command{
system := &installer.System{Database: systemDB, Target: LuetCfg.GetSystem().Rootfs}
var err error
iMatches := []pkg.Package{}
iMatches := pkg.Packages{}
if searchWithLabel {
iMatches, err = system.Database.FindPackageLabel(args[0])
} else if searchWithLabelMatch {

View File

@ -41,6 +41,7 @@ func NewTreeBumpCommand() *cobra.Command {
},
Run: func(cmd *cobra.Command, args []string) {
spec, _ := cmd.Flags().GetString("definition-file")
toStdout, _ := cmd.Flags().GetBool("to-stdout")
pack, err := tree.ReadDefinitionFile(spec)
if err != nil {
Fatal(err.Error())
@ -52,16 +53,26 @@ func NewTreeBumpCommand() *cobra.Command {
Fatal("Error on increment build version: " + err.Error())
}
if toStdout {
data, err := pack.Yaml()
if err != nil {
Fatal("Error on yaml conversion: " + err.Error())
}
fmt.Println(string(data))
} else {
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.")
ans.Flags().BoolP("to-stdout", "o", false, "Bump package to output.")
return ans
}

View File

@ -81,6 +81,34 @@ func NewTreeValidateCommand() *cobra.Command {
for _, p := range reciper.GetDatabase().World() {
found, err := reciper.GetDatabase().FindPackages(
&pkg.DefaultPackage{
Name: p.GetName(),
Category: p.GetCategory(),
Version: ">=0",
},
)
if err != nil || len(found) < 1 {
if err != nil {
errstr = err.Error()
} else {
errstr = "No packages"
}
Error(fmt.Sprintf("%s/%s-%s: Broken. No versions could be found by database %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
errstr,
))
errors = append(errors,
fmt.Sprintf("%s/%s-%s: Broken. No versions could be found by database %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
errstr,
))
brokenPkgs++
}
pkgstr := fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(),
p.GetVersion())
@ -115,15 +143,22 @@ func NewTreeValidateCommand() *cobra.Command {
}
Info("Checking package "+fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(), p.GetVersion()), "with", len(p.GetRequires()), "dependencies.")
for _, r := range p.GetRequires() {
deps, err := reciper.GetDatabase().FindPackages(
all := p.GetRequires()
all = append(all, p.GetConflicts()...)
for _, r := range all {
var deps pkg.Packages
var err error
if r.IsSelector() {
deps, err = reciper.GetDatabase().FindPackages(
&pkg.DefaultPackage{
Name: r.GetName(),
Category: r.GetCategory(),
Version: r.GetVersion(),
},
)
} else {
deps = append(deps, r)
}
if err != nil || len(deps) < 1 {
if err != nil {
@ -154,7 +189,11 @@ func NewTreeValidateCommand() *cobra.Command {
if withSolver {
Spinner(32)
_, err := depSolver.Install([]pkg.Package{r})
solution, err := depSolver.Install(pkg.Packages{r})
ass := solution.SearchByName(r.GetPackageName())
if err == nil {
_, err = solution.Order(reciper.GetDatabase(), ass.Package.GetFingerPrint())
}
SpinnerStop()
if err != nil {

6
go.mod
View File

@ -4,8 +4,7 @@ go 1.12
require (
github.com/DataDog/zstd v1.4.4 // indirect
github.com/MottainaiCI/simplestreams-builder v0.0.0-20190710131531-efb382161f56 // indirect
github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1
github.com/Sabayon/pkgs-checker v0.6.2-0.20200404093625-076438c31739
github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154
github.com/briandowns/spinner v1.7.0
github.com/cavaliercoder/grab v2.0.0+incompatible
@ -13,16 +12,15 @@ require (
github.com/docker/docker v0.7.3-0.20180827131323-0c5f8d2b9b23
github.com/ecooper/qlearning v0.0.0-20160612200101-3075011a69fd
github.com/ghodss/yaml v1.0.0
github.com/go-yaml/yaml v2.1.0+incompatible // indirect
github.com/hashicorp/go-version v1.2.0
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
github.com/klauspost/pgzip v1.2.1
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/kr/pretty v0.2.0 // indirect
github.com/kyokomi/emoji v2.1.0+incompatible
github.com/logrusorgru/aurora v0.0.0-20190417123914-21d75270181e
github.com/marcsauter/single v0.0.0-20181104081128-f8bf46f26ec0
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mudler/docker-companion v0.4.6-0.20191110154655-b8b364100616
github.com/onsi/ginkgo v1.10.1
github.com/onsi/gomega v1.7.0

25
go.sum
View File

@ -9,24 +9,11 @@ github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/MottainaiCI/simplestreams-builder v0.0.0-20190710131531-efb382161f56 h1:XCZM9J5KqLsr5NqtrZuXiD3X5fe5IfgU7IIUZzpeFBk=
github.com/MottainaiCI/simplestreams-builder v0.0.0-20190710131531-efb382161f56/go.mod h1:+Gbv6dg6TPHWq4oDjZY1vn978PLCEZ2hOu8kvn+S7t4=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Sabayon/pkgs-checker v0.4.2-0.20200101193228-1d500105afb7 h1:Vf80sSLu1ZWjjMmUKhw0FqM43lEOvT8O5B22NaHB6AQ=
github.com/Sabayon/pkgs-checker v0.4.2-0.20200101193228-1d500105afb7/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.5.0 h1:VRyyAxo6ox41Dytyl+K+QC+Tps0IxvqYbidu+AH+HUQ=
github.com/Sabayon/pkgs-checker v0.5.1-0.20200221202320-073693f2c657 h1:VK5S2Gh9kPUxX81zCFUgKVQn+hFy6VgyZMD3QLm76u8=
github.com/Sabayon/pkgs-checker v0.5.1-0.20200221202320-073693f2c657/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.6.1 h1:7HIrrAQujfEQ0+vPjb1Px4AdUY7KWQPn8W0NjKMoGLI=
github.com/Sabayon/pkgs-checker v0.6.1/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200310081024-935615ba9d27 h1:+5UCxj8bQHrcjuZumsX+E4mvol2F2dW8lXb1K+A/VlM=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200310081024-935615ba9d27/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200311072754-f4e0aec412f0 h1:C8pSo4uPvXcb5X2ai5oxuABdsOI1mlNNBaw2oxLbzy4=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200311072754-f4e0aec412f0/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1 h1:0hkt4Na3ZDZO6e9hCKATOki+zBKOdRa0LxUtYlm9oyE=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200404093625-076438c31739 h1:cWiphrLut8a+RNwosFre5j+zWDe1m6y1OpkSzn5bu1w=
github.com/Sabayon/pkgs-checker v0.6.2-0.20200404093625-076438c31739/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
github.com/Sereal/Sereal v0.0.0-20181211220259-509a78ddbda3 h1:Xu7z47ZiE/J+sKXHZMGxEor/oY2q6dq51fkO0JqdSwY=
github.com/Sereal/Sereal v0.0.0-20181211220259-509a78ddbda3/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -66,8 +53,6 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/crillab/gophersat v1.1.7 h1:f2Phe0W9jGyN1OefygKdcTdNM99q/goSjbWrFRjZGWc=
github.com/crillab/gophersat v1.1.7/go.mod h1:S91tHga1PCZzYhCkStwZAhvp1rCc+zqtSi55I+vDWGc=
github.com/crillab/gophersat v1.1.9-0.20200211102949-9a8bf7f2f0a3 h1:HO63LCf9kTXQgUnlvFeS2qSDQhZ/cLP8DAJO89CythY=
github.com/crillab/gophersat v1.1.9-0.20200211102949-9a8bf7f2f0a3/go.mod h1:S91tHga1PCZzYhCkStwZAhvp1rCc+zqtSi55I+vDWGc=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
@ -104,8 +89,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
@ -156,6 +139,8 @@ github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d h1:X4cedH4Kn3JPupAwwWuo4AzYp16P0OyLO9d7OnMZc/c=
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d/go.mod h1:o8sgWoz3JADecfc/cTYD92/Et1yMqMy0utV1z+VaZao=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -185,8 +170,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=

View File

@ -16,6 +16,7 @@
package backend
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
@ -241,9 +242,17 @@ func (*SimpleDocker) Changes(fromImage, toImage string) ([]compiler.ArtifactLaye
return []compiler.ArtifactLayer{}, errors.Wrap(err, "Error met while creating tempdir for rootfs")
}
defer os.RemoveAll(tmpdiffs) // clean up
var errorBuffer bytes.Buffer
diffargs := []string{"diff", fromImage, toImage, "-v", "error", "-q", "--type=file", "-j", "-n", "-c", tmpdiffs}
out, err := exec.Command("container-diff", diffargs...).Output()
cmd := exec.Command("container-diff", diffargs...)
cmd.Stderr = &errorBuffer
out, err := cmd.Output()
if string(errorBuffer.Bytes()) != "" {
Warning("container-diff errored with: " + string(errorBuffer.Bytes()))
}
if err != nil {
return []compiler.ArtifactLayer{}, errors.Wrap(err, "Failed Resolving layer diffs: "+string(out))
}
@ -259,7 +268,7 @@ func (*SimpleDocker) Changes(fromImage, toImage string) ([]compiler.ArtifactLaye
return []compiler.ArtifactLayer{}, errors.Wrap(err, "Failed unmarshalling json response: "+string(out))
}
if config.LuetCfg.GetLogging().Level == "debug" {
if config.LuetCfg.GetGeneral().Debug {
summary := compiler.ComputeArtifactLayerSummary(diffs)
for _, l := range summary.Layers {
Debug(fmt.Sprintf("Diff %s -> %s: add %d (%d bytes), del %d (%d bytes), change %d (%d bytes)",

View File

@ -433,12 +433,15 @@ func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssert
s := solver.NewResolver(pkg.NewInMemoryDatabase(false), cs.Database, pkg.NewInMemoryDatabase(false), cs.Options.SolverOptions.Resolver())
solution, err := s.Install([]pkg.Package{p.GetPackage()})
solution, err := s.Install(pkg.Packages{p.GetPackage()})
if err != nil {
return nil, errors.Wrap(err, "While computing a solution for "+p.GetPackage().HumanReadableString())
}
dependencies := solution.Order(cs.Database, p.GetPackage().GetFingerPrint())
dependencies, err := solution.Order(cs.Database, p.GetPackage().GetFingerPrint())
if err != nil {
return nil, errors.Wrap(err, "While order a solution for "+p.GetPackage().HumanReadableString())
}
assertions := solver.PackagesAssertions{}
for _, assertion := range dependencies { //highly dependent on the order

View File

@ -23,6 +23,7 @@ import (
_gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
pkg "github.com/mudler/luet/pkg/package"
version "github.com/mudler/luet/pkg/versioner"
)
func CreateRegexArray(rgx []string) ([]*regexp.Regexp, error) {
@ -53,14 +54,14 @@ func ParsePackageStr(p string) (*pkg.DefaultPackage, error) {
pkgVersion := ""
if gp.VersionBuild != "" {
pkgVersion = fmt.Sprintf("%s%s%s+%s",
pkg.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
version.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
gp.Version,
gp.VersionSuffix,
gp.VersionBuild,
)
} else {
pkgVersion = fmt.Sprintf("%s%s%s",
pkg.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
version.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
gp.Version,
gp.VersionSuffix,
)

View File

@ -74,7 +74,7 @@ func (l *LuetInstaller) Upgrade(s *System) error {
return errors.Wrap(err, "Failed solving solution for upgrade")
}
toInstall := []pkg.Package{}
toInstall := pkg.Packages{}
for _, assertion := range solution {
// Be sure to filter from solutions packages already installed in the system
if _, err := s.Database.FindPackage(assertion.Package); err != nil && assertion.Value {
@ -107,7 +107,7 @@ func (l *LuetInstaller) SyncRepositories(inMemory bool) (Repositories, error) {
return syncedRepos, nil
}
func (l *LuetInstaller) Swap(toRemove []pkg.Package, toInstall []pkg.Package, s *System) error {
func (l *LuetInstaller) Swap(toRemove pkg.Packages, toInstall pkg.Packages, s *System) error {
syncedRepos, err := l.SyncRepositories(true)
if err != nil {
return err
@ -115,7 +115,7 @@ func (l *LuetInstaller) Swap(toRemove []pkg.Package, toInstall []pkg.Package, s
return l.swap(syncedRepos, toRemove, toInstall, s)
}
func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove []pkg.Package, toInstall []pkg.Package, s *System) error {
func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove pkg.Packages, toInstall pkg.Packages, s *System) error {
// First match packages against repositories by priority
allRepos := pkg.NewInMemoryDatabase(false)
syncedRepos.SyncDatabase(allRepos)
@ -153,7 +153,7 @@ func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove []pkg.Package, t
return l.install(syncedRepos, toInstall, s)
}
func (l *LuetInstaller) Install(cp []pkg.Package, s *System, downloadOnly bool) error {
func (l *LuetInstaller) Install(cp pkg.Packages, s *System, downloadOnly bool) error {
syncedRepos, err := l.SyncRepositories(true)
if err != nil {
return err
@ -161,7 +161,7 @@ func (l *LuetInstaller) Install(cp []pkg.Package, s *System, downloadOnly bool)
return l.install(syncedRepos, cp, s)
}
func (l *LuetInstaller) download(syncedRepos Repositories, cp []pkg.Package) error {
func (l *LuetInstaller) download(syncedRepos Repositories, cp pkg.Packages) error {
toDownload := map[string]ArtifactMatch{}
// FIXME: This can be optimized. We don't need to re-match this to the repository
@ -169,7 +169,7 @@ func (l *LuetInstaller) download(syncedRepos Repositories, cp []pkg.Package) err
// Gathers things to download
for _, currentPack := range cp {
matches := syncedRepos.PackageMatches([]pkg.Package{currentPack})
matches := syncedRepos.PackageMatches(pkg.Packages{currentPack})
if len(matches) == 0 {
return errors.New("Failed matching solutions against repository for " + currentPack.HumanReadableString() + " where are definitions coming from?!")
}
@ -206,8 +206,8 @@ func (l *LuetInstaller) download(syncedRepos Repositories, cp []pkg.Package) err
return nil
}
func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *System) error {
var p []pkg.Package
func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *System) error {
var p pkg.Packages
// Check if the package is installed first
for _, pi := range cp {
@ -237,7 +237,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
syncedRepos.SyncDatabase(allRepos)
p = syncedRepos.ResolveSelectors(p)
toInstall := map[string]ArtifactMatch{}
var packagesToInstall []pkg.Package
var packagesToInstall pkg.Packages
var err error
var solution solver.PackagesAssertions
@ -261,7 +261,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
// Gathers things to install
for _, currentPack := range packagesToInstall {
matches := syncedRepos.PackageMatches([]pkg.Package{currentPack})
matches := syncedRepos.PackageMatches(pkg.Packages{currentPack})
if len(matches) == 0 {
return errors.New("Failed matching solutions against repository for " + currentPack.HumanReadableString() + " where are definitions coming from?!")
}
@ -326,7 +326,10 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
// TODO: Lower those errors as warning
for _, w := range p {
// Finalizers needs to run in order and in sequence.
ordered := solution.Order(allRepos, w.GetFingerPrint())
ordered, err := solution.Order(allRepos, w.GetFingerPrint())
if err != nil {
return errors.Wrap(err, "While order a solution for "+w.HumanReadableString())
}
ORDER:
for _, ass := range ordered {
if ass.Value {

View File

@ -23,12 +23,12 @@ import (
)
type Installer interface {
Install([]pkg.Package, *System, bool) error
Install(pkg.Packages, *System, bool) error
Uninstall(pkg.Package, *System) error
Upgrade(s *System) error
Repositories([]Repository)
SyncRepositories(bool) (Repositories, error)
Swap([]pkg.Package, []pkg.Package, *System) error
Swap(pkg.Packages, pkg.Packages, *System) error
}
type Client interface {

View File

@ -701,9 +701,9 @@ func (r Repositories) Less(i, j int) bool {
return r[i].GetPriority() < r[j].GetPriority()
}
func (r Repositories) World() []pkg.Package {
func (r Repositories) World() pkg.Packages {
cache := map[string]pkg.Package{}
world := []pkg.Package{}
world := pkg.Packages{}
// Get Uniques. Walk in reverse so the definitions of most prio-repo overwrites lower ones
// In this way, when we will walk again later the deps sorting them by most higher prio we have better chance of success.
@ -741,7 +741,7 @@ type PackageMatch struct {
Package pkg.Package
}
func (re Repositories) PackageMatches(p []pkg.Package) []PackageMatch {
func (re Repositories) PackageMatches(p pkg.Packages) []PackageMatch {
// TODO: Better heuristic. here we pick the first repo that contains the atom, sorted by priority but
// we should do a permutations and get the best match, and in case there are more solutions the user should be able to pick
sort.Sort(re)
@ -762,10 +762,10 @@ PACKAGE:
}
func (re Repositories) ResolveSelectors(p []pkg.Package) []pkg.Package {
func (re Repositories) ResolveSelectors(p pkg.Packages) pkg.Packages {
// If a selector is given, get the best from each repo
sort.Sort(re) // respect prio
var matches []pkg.Package
var matches pkg.Packages
PACKAGE:
for _, pack := range p {
REPOSITORY:
@ -798,7 +798,7 @@ func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch
var err error
for _, r := range re {
var repoMatches []pkg.Package
var repoMatches pkg.Packages
switch o.Mode {
case SRegexPkg:

View File

@ -9,6 +9,6 @@ type System struct {
Target string
}
func (s *System) World() ([]pkg.Package, error) {
func (s *System) World() (pkg.Packages, error) {
return s.Database.World(), nil
}

View File

@ -33,7 +33,7 @@ type PackageSet interface {
GetPackage(ID string) (Package, error)
Clean() error
FindPackage(Package) (Package, error)
FindPackages(p Package) ([]Package, error)
FindPackages(p Package) (Packages, error)
UpdatePackage(p Package) error
GetAllPackages(packages chan Package) error
RemovePackage(Package) error
@ -41,13 +41,13 @@ type PackageSet interface {
GetPackageFiles(Package) ([]string, error)
SetPackageFiles(*PackageFile) error
RemovePackageFiles(Package) error
FindPackageVersions(p Package) ([]Package, error)
World() []Package
FindPackageVersions(p Package) (Packages, error)
World() Packages
FindPackageCandidate(p Package) (Package, error)
FindPackageLabel(labelKey string) ([]Package, error)
FindPackageLabelMatch(pattern string) ([]Package, error)
FindPackageMatch(pattern string) ([]Package, error)
FindPackageLabel(labelKey string) (Packages, error)
FindPackageLabelMatch(pattern string) (Packages, error)
FindPackageMatch(pattern string) (Packages, error)
}
type PackageFile struct {

View File

@ -233,7 +233,7 @@ func (db *BoltDatabase) getProvide(p Package) (Package, error) {
for ve, _ := range versions {
match, err := p.VersionMatchSelector(ve)
match, err := p.VersionMatchSelector(ve, nil)
if err != nil {
return nil, errors.Wrap(err, "Error on match version")
}
@ -314,7 +314,7 @@ func (db *BoltDatabase) RemovePackage(p Package) error {
return nil
}
func (db *BoltDatabase) World() []Package {
func (db *BoltDatabase) World() Packages {
var all []Package
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
@ -324,7 +324,7 @@ func (db *BoltDatabase) World() []Package {
all = append(all, pack)
}
}
return all
return Packages(all)
}
func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
@ -338,7 +338,7 @@ func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
if err != nil || len(packages) == 0 {
required = p
} else {
required = Best(packages)
required = packages.Best(nil)
}
return required, nil
@ -351,7 +351,7 @@ func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
// FindPackages return the list of the packages beloging to cat/name (any versions in requested range)
// FIXME: Optimize, see inmemorydb
func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
func (db *BoltDatabase) FindPackages(p Package) (Packages, error) {
// Provides: Treat as the replaced package here
if provided, err := db.getProvide(p); err == nil {
p = provided
@ -362,7 +362,7 @@ func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
continue
}
match, err := p.SelectorMatchVersion(w.GetVersion())
match, err := p.SelectorMatchVersion(w.GetVersion(), nil)
if err != nil {
return nil, errors.Wrap(err, "Error on match selector")
}
@ -370,11 +370,11 @@ func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
versionsInWorld = append(versionsInWorld, w)
}
}
return versionsInWorld, nil
return Packages(versionsInWorld), nil
}
// FindPackageVersions return the list of the packages beloging to cat/name
func (db *BoltDatabase) FindPackageVersions(p Package) ([]Package, error) {
func (db *BoltDatabase) FindPackageVersions(p Package) (Packages, error) {
var versionsInWorld []Package
for _, w := range db.World() {
if w.GetName() != p.GetName() || w.GetCategory() != p.GetCategory() {
@ -383,10 +383,10 @@ func (db *BoltDatabase) FindPackageVersions(p Package) ([]Package, error) {
versionsInWorld = append(versionsInWorld, w)
}
return versionsInWorld, nil
return Packages(versionsInWorld), nil
}
func (db *BoltDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
func (db *BoltDatabase) FindPackageLabel(labelKey string) (Packages, error) {
var ans []Package
for _, k := range db.GetPackages() {
@ -398,10 +398,10 @@ func (db *BoltDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
ans = append(ans, pack)
}
}
return ans, nil
return Packages(ans), nil
}
func (db *BoltDatabase) FindPackageLabelMatch(pattern string) ([]Package, error) {
func (db *BoltDatabase) FindPackageLabelMatch(pattern string) (Packages, error) {
var ans []Package
re := regexp.MustCompile(pattern)
@ -419,10 +419,10 @@ func (db *BoltDatabase) FindPackageLabelMatch(pattern string) ([]Package, error)
}
}
return ans, nil
return Packages(ans), nil
}
func (db *BoltDatabase) FindPackageMatch(pattern string) ([]Package, error) {
func (db *BoltDatabase) FindPackageMatch(pattern string) (Packages, error) {
var ans []Package
re := regexp.MustCompile(pattern)
@ -441,5 +441,5 @@ func (db *BoltDatabase) FindPackageMatch(pattern string) ([]Package, error) {
}
}
return ans, nil
return Packages(ans), nil
}

View File

@ -178,7 +178,7 @@ func (db *InMemoryDatabase) getProvide(p Package) (Package, error) {
for ve, _ := range versions {
match, err := p.VersionMatchSelector(ve)
match, err := p.VersionMatchSelector(ve, nil)
if err != nil {
return nil, errors.Wrap(err, "Error on match version")
}
@ -223,7 +223,7 @@ func (db *InMemoryDatabase) FindPackage(p Package) (Package, error) {
}
// FindPackages return the list of the packages beloging to cat/name
func (db *InMemoryDatabase) FindPackageVersions(p Package) ([]Package, error) {
func (db *InMemoryDatabase) FindPackageVersions(p Package) (Packages, error) {
versions, ok := db.CacheNoVersion[p.GetPackageName()]
if !ok {
return nil, errors.New("No versions found for package")
@ -236,11 +236,11 @@ func (db *InMemoryDatabase) FindPackageVersions(p Package) ([]Package, error) {
}
versionsInWorld = append(versionsInWorld, w)
}
return versionsInWorld, nil
return Packages(versionsInWorld), nil
}
// FindPackages return the list of the packages beloging to cat/name (any versions in requested range)
func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
func (db *InMemoryDatabase) FindPackages(p Package) (Packages, error) {
// Provides: Treat as the replaced package here
if provided, err := db.getProvide(p); err == nil {
@ -252,7 +252,7 @@ func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
}
var versionsInWorld []Package
for ve, _ := range versions {
match, err := p.SelectorMatchVersion(ve)
match, err := p.SelectorMatchVersion(ve, nil)
if err != nil {
return nil, errors.Wrap(err, "Error on match selector")
}
@ -265,7 +265,7 @@ func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
versionsInWorld = append(versionsInWorld, w)
}
}
return versionsInWorld, nil
return Packages(versionsInWorld), nil
}
func (db *InMemoryDatabase) UpdatePackage(p Package) error {
@ -327,7 +327,7 @@ func (db *InMemoryDatabase) RemovePackage(p Package) error {
delete(db.Database, p.GetFingerPrint())
return nil
}
func (db *InMemoryDatabase) World() []Package {
func (db *InMemoryDatabase) World() Packages {
var all []Package
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
for _, k := range db.GetPackages() {
@ -336,7 +336,7 @@ func (db *InMemoryDatabase) World() []Package {
all = append(all, pack)
}
}
return all
return Packages(all)
}
func (db *InMemoryDatabase) FindPackageCandidate(p Package) (Package, error) {
@ -349,7 +349,7 @@ func (db *InMemoryDatabase) FindPackageCandidate(p Package) (Package, error) {
if err != nil || len(packages) == 0 {
required = p
} else {
required = Best(packages)
required = packages.Best(nil)
}
return required, nil
@ -360,7 +360,7 @@ func (db *InMemoryDatabase) FindPackageCandidate(p Package) (Package, error) {
}
func (db *InMemoryDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
func (db *InMemoryDatabase) FindPackageLabel(labelKey string) (Packages, error) {
var ans []Package
for _, k := range db.GetPackages() {
@ -373,10 +373,10 @@ func (db *InMemoryDatabase) FindPackageLabel(labelKey string) ([]Package, error)
}
}
return ans, nil
return Packages(ans), nil
}
func (db *InMemoryDatabase) FindPackageLabelMatch(pattern string) ([]Package, error) {
func (db *InMemoryDatabase) FindPackageLabelMatch(pattern string) (Packages, error) {
var ans []Package
re := regexp.MustCompile(pattern)
@ -394,10 +394,10 @@ func (db *InMemoryDatabase) FindPackageLabelMatch(pattern string) ([]Package, er
}
}
return ans, nil
return Packages(ans), nil
}
func (db *InMemoryDatabase) FindPackageMatch(pattern string) ([]Package, error) {
func (db *InMemoryDatabase) FindPackageMatch(pattern string) (Packages, error) {
var ans []Package
re := regexp.MustCompile(pattern)
@ -416,5 +416,5 @@ func (db *InMemoryDatabase) FindPackageMatch(pattern string) ([]Package, error)
}
}
return ans, nil
return Packages(ans), nil
}

View File

@ -23,15 +23,14 @@ import (
"io"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
"github.com/crillab/gophersat/bf"
"github.com/ghodss/yaml"
version "github.com/hashicorp/go-version"
"github.com/jinzhu/copier"
version "github.com/mudler/luet/pkg/versioner"
"github.com/pkg/errors"
)
@ -47,15 +46,15 @@ type Package interface {
GetPackageName() string
Requires([]*DefaultPackage) Package
Conflicts([]*DefaultPackage) Package
Revdeps(PackageDatabase) []Package
LabelDeps(PackageDatabase, string) []Package
Revdeps(PackageDatabase) Packages
LabelDeps(PackageDatabase, string) Packages
GetProvides() []*DefaultPackage
SetProvides([]*DefaultPackage) Package
GetRequires() []*DefaultPackage
GetConflicts() []*DefaultPackage
Expand(PackageDatabase) ([]Package, error)
Expand(PackageDatabase) (Packages, error)
SetCategory(string)
GetName() string
@ -92,8 +91,8 @@ type Package interface {
MatchLabel(*regexp.Regexp) bool
IsSelector() bool
VersionMatchSelector(string) (bool, error)
SelectorMatchVersion(string) (bool, error)
VersionMatchSelector(string, version.Versioner) (bool, error)
SelectorMatchVersion(string, version.Versioner) (bool, error)
String() string
HumanReadableString() string
@ -104,10 +103,12 @@ type Tree interface {
GetPackageSet() PackageDatabase
Prelude() string // A tree might have a prelude to be able to consume a tree
SetPackageSet(s PackageDatabase)
World() ([]Package, error)
World() (Packages, error)
FindPackage(Package) (Package, error)
}
type Packages []Package
// >> Unmarshallers
// DefaultPackageFromYaml decodes a package from yaml bytes
func DefaultPackageFromYaml(yml []byte) (DefaultPackage, error) {
@ -378,15 +379,15 @@ func (p *DefaultPackage) Matches(m Package) bool {
return false
}
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error) {
var versionsInWorld []Package
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) (Packages, error) {
var versionsInWorld Packages
all, err := definitiondb.FindPackages(p)
if err != nil {
return nil, err
}
for _, w := range all {
match, err := p.SelectorMatchVersion(w.GetVersion())
match, err := p.SelectorMatchVersion(w.GetVersion(), nil)
if err != nil {
return nil, err
}
@ -398,8 +399,8 @@ func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error)
return versionsInWorld, nil
}
func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) []Package {
var versionsInWorld []Package
func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) Packages {
var versionsInWorld Packages
for _, w := range definitiondb.World() {
if w.Matches(p) {
continue
@ -415,8 +416,8 @@ func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) []Package {
return versionsInWorld
}
func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) []Package {
var pkgsWithLabelInWorld []Package
func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) Packages {
var pkgsWithLabelInWorld Packages
// TODO: check if integrate some index to improve
// research instead of iterate all list.
for _, w := range definitiondb.World() {
@ -458,7 +459,13 @@ func (pack *DefaultPackage) RequiresContains(definitiondb PackageDatabase, s Pac
return false, nil
}
func Best(set []Package) Package {
// Best returns the best version of the package (the most bigger) from a list
// Accepts a versioner interface to change the ordering policy. If null is supplied
// It defaults to version.WrappedVersioner which supports both semver and debian versioning
func (set Packages) Best(v version.Versioner) Package {
if v == nil {
v = &version.WrappedVersioner{}
}
var versionsMap map[string]Package = make(map[string]Package)
if len(set) == 0 {
panic("Best needs a list with elements")
@ -469,17 +476,9 @@ func Best(set []Package) Package {
versionsRaw = append(versionsRaw, p.GetVersion())
versionsMap[p.GetVersion()] = p
}
sorted := v.Sort(versionsRaw)
versions := make([]*version.Version, len(versionsRaw))
for i, raw := range versionsRaw {
v, _ := version.NewVersion(raw)
versions[i] = v
}
// After this, the versions are properly sorted
sort.Sort(version.Collection(versions))
return versionsMap[versions[len(versions)-1].Original()]
return versionsMap[sorted[len(sorted)-1]]
}
func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db PackageDatabase) ([]bf.Formula, error) {
@ -750,3 +749,22 @@ end:
return nil
}
func (p *DefaultPackage) SelectorMatchVersion(ver string, v version.Versioner) (bool, error) {
if !p.IsSelector() {
return false, errors.New("Package is not a selector")
}
if v == nil {
v = &version.WrappedVersioner{}
}
return v.ValidateSelector(ver, p.GetVersion()), nil
}
func (p *DefaultPackage) VersionMatchSelector(selector string, v version.Versioner) (bool, error) {
if v == nil {
v = &version.WrappedVersioner{}
}
return v.ValidateSelector(p.GetVersion(), selector), nil
}

View File

@ -58,7 +58,7 @@ var _ = Describe("Package", func() {
Expect(lst).To(ContainElement(a1))
Expect(lst).ToNot(ContainElement(a01))
Expect(len(lst)).To(Equal(2))
p := Best(lst)
p := lst.Best(nil)
Expect(p).To(Equal(a11))
})
})

View File

@ -23,6 +23,7 @@ import (
pkg "github.com/mudler/luet/pkg/package"
toposort "github.com/philopon/go-toposort"
"github.com/pkg/errors"
"github.com/stevenle/topsort"
)
@ -145,7 +146,7 @@ func (assertions PackagesAssertions) Search(f string) *PackageAssert {
return nil
}
func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fingerprint string) PackagesAssertions {
func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fingerprint string) (PackagesAssertions, error) {
orderedAssertions := PackagesAssertions{}
unorderedAssertions := PackagesAssertions{}
@ -191,19 +192,19 @@ func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fin
}
result, err := graph.TopSort(fingerprint)
if err != nil {
panic(err)
return nil, errors.Wrap(err, "fail on sorting "+fingerprint)
}
for _, res := range result {
a, ok := tmpMap[res]
if !ok {
panic("fail looking for " + res)
return nil, errors.New("fail looking for " + res)
// continue
}
orderedAssertions = append(orderedAssertions, a)
// orderedAssertions = append(PackagesAssertions{a}, orderedAssertions...) // push upfront
}
//helpers.ReverseAny(orderedAssertions)
return orderedAssertions
return orderedAssertions, nil
}
func (assertions PackagesAssertions) Explain() string {

View File

@ -72,7 +72,8 @@ var _ = Describe("Decoder", func() {
Expect(len(solution)).To(Equal(6))
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(dbDefinitions, A.GetFingerPrint())
solution, err = solution.Order(dbDefinitions, A.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
// Expect(len(solution)).To(Equal(6))
Expect(solution[0].Package.GetName()).To(Equal("G"))
Expect(solution[1].Package.GetName()).To(Equal("H"))
@ -188,7 +189,8 @@ var _ = Describe("Decoder", func() {
Expect(len(solution)).To(Equal(6))
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(dbDefinitions, A.GetFingerPrint())
solution, err = solution.Order(dbDefinitions, A.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
// Expect(len(solution)).To(Equal(6))
Expect(solution[0].Package.GetName()).To(Equal("G"))
Expect(solution[1].Package.GetName()).To(Equal("H"))
@ -206,7 +208,8 @@ var _ = Describe("Decoder", func() {
Expect(len(solution)).To(Equal(6))
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(dbDefinitions, B.GetFingerPrint())
solution, err = solution.Order(dbDefinitions, B.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
hash2 := solution.AssertionHash()
// Expect(len(solution)).To(Equal(6))
@ -243,7 +246,11 @@ var _ = Describe("Decoder", func() {
solution2, err := s.Install([]pkg.Package{Z})
Expect(err).ToNot(HaveOccurred())
Expect(solution.Order(dbDefinitions, Y.GetFingerPrint()).Drop(Y).AssertionHash() == solution2.Order(dbDefinitions, Z.GetFingerPrint()).Drop(Z).AssertionHash()).To(BeTrue())
orderY, err := solution.Order(dbDefinitions, Y.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
orderZ, err := solution2.Order(dbDefinitions, Z.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
Expect(orderY.Drop(Y).AssertionHash() == orderZ.Drop(Z).AssertionHash()).To(BeTrue())
})
It("Hashes them, Cuts them and could be used for comparison", func() {
@ -267,9 +274,13 @@ var _ = Describe("Decoder", func() {
solution2, err := s.Install([]pkg.Package{Z})
Expect(err).ToNot(HaveOccurred())
Expect(solution.Order(dbDefinitions, Y.GetFingerPrint()).Cut(Y).Drop(Y)).To(Equal(solution2.Order(dbDefinitions, Z.GetFingerPrint()).Cut(Z).Drop(Z)))
orderY, err := solution.Order(dbDefinitions, Y.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
orderZ, err := solution2.Order(dbDefinitions, Z.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
Expect(orderY.Cut(Y).Drop(Y)).To(Equal(orderZ.Cut(Z).Drop(Z)))
Expect(solution.Order(dbDefinitions, Y.GetFingerPrint()).Cut(Y).Drop(Y).AssertionHash()).To(Equal(solution2.Order(dbDefinitions, Z.GetFingerPrint()).Cut(Z).Drop(Z).AssertionHash()))
Expect(orderY.Cut(Y).Drop(Y).AssertionHash()).To(Equal(orderZ.Cut(Z).Drop(Z).AssertionHash()))
})
})

View File

@ -77,11 +77,11 @@ type QLearningResolver struct {
Solver PackageSolver
Formula bf.Formula
Targets []pkg.Package
Current []pkg.Package
Targets pkg.Packages
Current pkg.Packages
observedDelta int
observedDeltaChoice []pkg.Package
observedDeltaChoice pkg.Packages
Agent *qlearning.SimpleAgent
}
@ -177,7 +177,7 @@ func (resolver *QLearningResolver) Try(c Choice) error {
packtoAdd := pkg.FromString(pack)
resolver.Attempted[pack+strconv.Itoa(int(c.Action))] = true // increase the count
s, _ := resolver.Solver.(*Solver)
var filtered []pkg.Package
var filtered pkg.Packages
switch c.Action {
case ActionAdded:

View File

@ -27,12 +27,12 @@ import (
// PackageSolver is an interface to a generic package solving algorithm
type PackageSolver interface {
SetDefinitionDatabase(pkg.PackageDatabase)
Install(p []pkg.Package) (PackagesAssertions, error)
Uninstall(candidate pkg.Package, checkconflicts bool) ([]pkg.Package, error)
Install(p pkg.Packages) (PackagesAssertions, error)
Uninstall(candidate pkg.Package, checkconflicts bool) (pkg.Packages, error)
ConflictsWithInstalled(p pkg.Package) (bool, error)
ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error)
World() []pkg.Package
Upgrade(checkconflicts bool) ([]pkg.Package, PackagesAssertions, error)
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
World() pkg.Packages
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
SetResolver(PackageResolver)
@ -43,7 +43,7 @@ type PackageSolver interface {
type Solver struct {
DefinitionDatabase pkg.PackageDatabase
SolverDatabase pkg.PackageDatabase
Wanted []pkg.Package
Wanted pkg.Packages
InstalledDatabase pkg.PackageDatabase
Resolver PackageResolver
@ -72,11 +72,11 @@ func (s *Solver) SetResolver(r PackageResolver) {
s.Resolver = r
}
func (s *Solver) World() []pkg.Package {
func (s *Solver) World() pkg.Packages {
return s.DefinitionDatabase.World()
}
func (s *Solver) Installed() []pkg.Package {
func (s *Solver) Installed() pkg.Packages {
return s.InstalledDatabase.World()
}
@ -130,8 +130,8 @@ func (s *Solver) BuildWorld(includeInstalled bool) (bf.Formula, error) {
return bf.And(formulas...), nil
}
func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Package, error) {
var ls []pkg.Package
func (s *Solver) getList(db pkg.PackageDatabase, lsp pkg.Packages) (pkg.Packages, error) {
var ls pkg.Packages
for _, pp := range lsp {
cp, err := db.FindPackage(pp)
@ -141,7 +141,7 @@ func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Packa
if err != nil || len(packages) == 0 {
cp = pp
} else {
cp = pkg.Best(packages)
cp = packages.Best(nil)
}
}
ls = append(ls, cp)
@ -149,7 +149,7 @@ func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Packa
return ls, nil
}
func (s *Solver) ConflictsWith(pack pkg.Package, lsp []pkg.Package) (bool, error) {
func (s *Solver) ConflictsWith(pack pkg.Package, lsp pkg.Packages) (bool, error) {
p, err := s.DefinitionDatabase.FindPackage(pack)
if err != nil {
p = pack //Relax search, otherwise we cannot compute solutions for packages not in definitions
@ -210,14 +210,14 @@ func (s *Solver) ConflictsWithInstalled(p pkg.Package) (bool, error) {
return s.ConflictsWith(p, s.Installed())
}
func (s *Solver) Upgrade(checkconflicts bool) ([]pkg.Package, PackagesAssertions, error) {
func (s *Solver) Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error) {
// First get candidates that needs to be upgraded..
toUninstall := []pkg.Package{}
toInstall := []pkg.Package{}
toUninstall := pkg.Packages{}
toInstall := pkg.Packages{}
availableCache := map[string][]pkg.Package{}
availableCache := map[string]pkg.Packages{}
for _, p := range s.DefinitionDatabase.World() {
// Each one, should be expanded
availableCache[p.GetName()+p.GetCategory()] = append(availableCache[p.GetName()+p.GetCategory()], p)
@ -229,7 +229,7 @@ func (s *Solver) Upgrade(checkconflicts bool) ([]pkg.Package, PackagesAssertions
installedcopy.CreatePackage(p)
packages, ok := availableCache[p.GetName()+p.GetCategory()]
if ok && len(packages) != 0 {
best := pkg.Best(packages)
best := packages.Best(nil)
if best.GetVersion() != p.GetVersion() {
toUninstall = append(toUninstall, p)
toInstall = append(toInstall, best)
@ -261,8 +261,8 @@ func (s *Solver) Upgrade(checkconflicts bool) ([]pkg.Package, PackagesAssertions
// Uninstall takes a candidate package and return a list of packages that would be removed
// in order to purge the candidate. Returns error if unsat.
func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) ([]pkg.Package, error) {
var res []pkg.Package
func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) (pkg.Packages, error) {
var res pkg.Packages
candidate, err := s.InstalledDatabase.FindPackage(c)
if err != nil {
@ -272,13 +272,13 @@ func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) ([]pkg.Package, e
if err != nil || len(packages) == 0 {
candidate = c
} else {
candidate = pkg.Best(packages)
candidate = packages.Best(nil)
}
//Relax search, otherwise we cannot compute solutions for packages not in definitions
// return nil, errors.Wrap(err, "Package not found between installed")
}
// Build a fake "Installed" - Candidate and its requires tree
var InstalledMinusCandidate []pkg.Package
var InstalledMinusCandidate pkg.Packages
// TODO: Can be optimized
for _, i := range s.Installed() {
@ -296,7 +296,7 @@ func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) ([]pkg.Package, e
s2 := NewSolver(pkg.NewInMemoryDatabase(false), s.DefinitionDatabase, pkg.NewInMemoryDatabase(false))
s2.SetResolver(s.Resolver)
// Get the requirements to install the candidate
asserts, err := s2.Install([]pkg.Package{candidate})
asserts, err := s2.Install(pkg.Packages{candidate})
if err != nil {
return nil, err
}
@ -403,7 +403,7 @@ func (s *Solver) Solve() (PackagesAssertions, error) {
// Install given a list of packages, returns package assertions to indicate the packages that must be installed in the system in order
// to statisfy all the constraints
func (s *Solver) Install(c []pkg.Package) (PackagesAssertions, error) {
func (s *Solver) Install(c pkg.Packages) (PackagesAssertions, error) {
coll, err := s.getList(s.DefinitionDatabase, c)
if err != nil {

View File

@ -882,7 +882,7 @@ var _ = Describe("Solver", func() {
Expect(lst).To(ContainElement(a03))
Expect(lst).ToNot(ContainElement(old))
Expect(len(lst)).To(Equal(5))
p := pkg.Best(lst)
p := lst.Best(nil)
Expect(p).To(Equal(a03))
})
})

View File

@ -50,7 +50,7 @@ type GentooBuilder struct {
}
type EbuildParser interface {
ScanEbuild(string) ([]pkg.Package, error)
ScanEbuild(string) (pkg.Packages, error)
}
func (gb *GentooBuilder) scanEbuild(path string, db pkg.PackageDatabase) error {

View File

@ -27,8 +27,8 @@ import (
type FakeParser struct {
}
func (f *FakeParser) ScanEbuild(path string) ([]pkg.Package, error) {
return []pkg.Package{&pkg.DefaultPackage{Name: path}}, nil
func (f *FakeParser) ScanEbuild(path string) (pkg.Packages, error) {
return pkg.Packages{&pkg.DefaultPackage{Name: path}}, nil
}
var _ = Describe("GentooBuilder", func() {

View File

@ -323,7 +323,7 @@ func SourceFile(ctx context.Context, path string, pkg *_gentoo.GentooPackage) (m
}
// ScanEbuild returns a list of packages (always one with SimpleEbuildParser) decoded from an ebuild.
func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
func (ep *SimpleEbuildParser) ScanEbuild(path string) (pkg.Packages, error) {
Debug("Starting parsing of ebuild", path)
pkgstr := filepath.Base(path)
@ -332,7 +332,7 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
gp, err := _gentoo.ParsePackageStr(pkgstr)
if err != nil {
return []pkg.Package{}, errors.New("Error on parsing package string")
return pkg.Packages{}, errors.New("Error on parsing package string")
}
pack := &pkg.DefaultPackage{
@ -350,7 +350,7 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
vars, err := SourceFile(timeout, path, gp)
if err != nil {
Error("Error on source file ", pack.Name, ": ", err)
return []pkg.Package{}, err
return pkg.Packages{}, err
}
// TODO: Handle this a bit better
@ -405,8 +405,8 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
gRDEPEND, err := ParseRDEPEND(rdepend.String())
if err != nil {
Warning("Error on parsing RDEPEND for package ", pack.Category+"/"+pack.Name, err)
return []pkg.Package{pack}, nil
// return []pkg.Package{}, err
return pkg.Packages{pack}, nil
// return pkg.Packages{}, err
}
pack.PackageConflicts = []*pkg.DefaultPackage{}
@ -436,5 +436,5 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
Debug("Finished processing ebuild", path, "deps ", len(pack.PackageRequires))
//TODO: Deps and conflicts
return []pkg.Package{pack}, nil
return pkg.Packages{pack}, nil
}

View File

@ -65,7 +65,8 @@ var _ = Describe("Tree", func() {
solution, err := s.Install([]pkg.Package{pack})
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(generalRecipe.GetDatabase(), pack.GetFingerPrint())
solution, err = solution.Order(generalRecipe.GetDatabase(), pack.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
Expect(solution[0].Package.GetName()).To(Equal("a"))
Expect(solution[0].Value).To(BeFalse())
@ -137,7 +138,8 @@ var _ = Describe("Tree", func() {
solution, err := s.Install([]pkg.Package{Dd})
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(generalRecipe.GetDatabase(), Dd.GetFingerPrint())
solution, err = solution.Order(generalRecipe.GetDatabase(), Dd.GetFingerPrint())
Expect(err).ToNot(HaveOccurred())
pack, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "a", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())

View File

@ -0,0 +1,27 @@
// Copyright © 2019-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 version
// Versioner is responsible of sanitizing versions,
// validating them and ordering by precedence
type Versioner interface {
Sanitize(string) string
Validate(string) error
Sort([]string) []string
ValidateSelector(version string, selector string) bool
}

View File

@ -14,15 +14,14 @@
// 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 pkg
package version
import (
"errors"
"fmt"
"regexp"
"strings"
version "github.com/hashicorp/go-version"
semver "github.com/hashicorp/go-version"
)
// Package Selector Condition
@ -162,7 +161,7 @@ func ParseVersion(v string) (PkgVersionSelector, error) {
}
// Check if build number is present
buildIdx := strings.Index(v, "+")
buildIdx := strings.LastIndex(v, "+")
buildVersion := ""
if buildIdx > 0 {
// <pre-release> ::= <dot-separated pre-release identifiers>
@ -252,8 +251,8 @@ func ParseVersion(v string) (PkgVersionSelector, error) {
}
func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
var v1 *version.Version = nil
var v2 *version.Version = nil
var v1 *semver.Version = nil
var v2 *semver.Version = nil
var ans bool
var err error
var sanitizedSelectorVersion, sanitizedIVersion string
@ -262,14 +261,14 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
// TODO: This is temporary!. I promise it.
sanitizedSelectorVersion = strings.ReplaceAll(selector.Version, "_", "-")
v1, err = version.NewVersion(sanitizedSelectorVersion)
v1, err = semver.NewVersion(sanitizedSelectorVersion)
if err != nil {
return false, err
}
}
if i.Version != "" {
sanitizedIVersion = strings.ReplaceAll(i.Version, "_", "-")
v2, err = version.NewVersion(sanitizedIVersion)
v2, err = semver.NewVersion(sanitizedIVersion)
if err != nil {
return false, err
}
@ -307,7 +306,7 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
segments[len(segments)-1]++
}
nextVersion := strings.Trim(strings.Replace(fmt.Sprint(segments), " ", ".", -1), "[]")
constraints, err := version.NewConstraint(
constraints, err := semver.NewConstraint(
fmt.Sprintf(">= %s, < %s", sanitizedSelectorVersion, nextVersion),
)
if err != nil {
@ -335,35 +334,3 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
return ans, nil
}
func (p *DefaultPackage) SelectorMatchVersion(v string) (bool, error) {
if !p.IsSelector() {
return false, errors.New("Package is not a selector")
}
vS, err := ParseVersion(p.GetVersion())
if err != nil {
return false, err
}
vSI, err := ParseVersion(v)
if err != nil {
return false, err
}
return PackageAdmit(vS, vSI)
}
func (p *DefaultPackage) VersionMatchSelector(selector string) (bool, error) {
vS, err := ParseVersion(selector)
if err != nil {
return false, err
}
vSI, err := ParseVersion(p.GetVersion())
if err != nil {
return false, err
}
return PackageAdmit(vS, vSI)
}

View File

@ -14,12 +14,12 @@
// 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 pkg_test
package version_test
import (
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
. "github.com/mudler/luet/pkg/package"
. "github.com/mudler/luet/pkg/versioner"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

148
pkg/versioner/versioner.go Normal file
View File

@ -0,0 +1,148 @@
// Copyright © 2019-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 version
import (
"errors"
"regexp"
"sort"
"strconv"
"strings"
semver "github.com/hashicorp/go-version"
debversion "github.com/knqyf263/go-deb-version"
)
// WrappedVersioner uses different means to return unique result that is understendable by Luet
// It tries different approaches to sort, validate, and sanitize to a common versioning format
// that is understendable by the whole code
type WrappedVersioner struct{}
func DefaultVersioner() Versioner {
return &WrappedVersioner{}
}
func (w *WrappedVersioner) Validate(version string) error {
if !debversion.Valid(version) {
return errors.New("Invalid version")
}
return nil
}
func (w *WrappedVersioner) ValidateSelector(version string, selector string) bool {
vS, err := ParseVersion(selector)
if err != nil {
return false
}
vSI, err := ParseVersion(version)
if err != nil {
return false
}
ok, err := PackageAdmit(vS, vSI)
if err != nil {
return false
}
return ok
}
func (w *WrappedVersioner) Sanitize(s string) string {
return strings.ReplaceAll(s, "_", "-")
}
func (w *WrappedVersioner) IsSemver(v string) bool {
// Taken https://github.com/hashicorp/go-version/blob/2b13044f5cdd3833370d41ce57d8bf3cec5e62b8/version.go#L44
// semver doesn't have a Validate method, so we should filter before
// going to use it blindly (it panics)
semverRegexp := regexp.MustCompile("^" + semver.SemverRegexpRaw + "$")
// See https://github.com/hashicorp/go-version/blob/2b13044f5cdd3833370d41ce57d8bf3cec5e62b8/version.go#L61
matches := semverRegexp.FindStringSubmatch(v)
if matches == nil {
return false
}
segmentsStr := strings.Split(matches[1], ".")
segments := make([]int64, len(segmentsStr))
for i, str := range segmentsStr {
val, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return false
}
segments[i] = int64(val)
}
return (len(segments) != 0)
}
func (w *WrappedVersioner) Sort(toSort []string) []string {
if len(toSort) == 0 {
return toSort
}
var versionsMap map[string]string = make(map[string]string)
versionsRaw := []string{}
result := []string{}
for _, v := range toSort {
sanitizedVersion := w.Sanitize(v)
versionsMap[sanitizedVersion] = v
versionsRaw = append(versionsRaw, sanitizedVersion)
}
versions := make([]*semver.Version, len(versionsRaw))
// Check if all of them are semver, otherwise we cannot do a good comparison
allSemverCompliant := true
for _, raw := range versionsRaw {
if !w.IsSemver(raw) {
allSemverCompliant = false
}
}
if allSemverCompliant {
for i, raw := range versionsRaw {
if w.IsSemver(raw) { // Make sure we include only semver, or go-version will panic
v, _ := semver.NewVersion(raw)
versions[i] = v
}
}
// Try first semver sorting
sort.Sort(semver.Collection(versions))
if len(versions) > 0 {
for _, v := range versions {
result = append(result, versionsMap[v.Original()])
}
return result
}
}
// Try with debian sorting
vs := make([]debversion.Version, len(versionsRaw))
for i, r := range versionsRaw {
v, _ := debversion.NewVersion(r)
vs[i] = v
}
sort.Slice(vs, func(i, j int) bool {
return vs[i].LessThan(vs[j])
})
for _, v := range vs {
result = append(result, versionsMap[v.String()])
}
return result
}

View File

@ -0,0 +1,32 @@
// Copyright © 2019 Ettore Di Giacinto <mudler@gentoo.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 version_test
import (
"testing"
. "github.com/mudler/luet/cmd"
config "github.com/mudler/luet/pkg/config"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestVersioner(t *testing.T) {
RegisterFailHandler(Fail)
LoadConfig(config.LuetCfg)
RunSpecs(t, "Versioner Suite")
}

View File

@ -0,0 +1,82 @@
// Copyright © 2019 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 version_test
import (
. "github.com/mudler/luet/pkg/versioner"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Versioner", func() {
Context("Invalid version", func() {
versioner := DefaultVersioner()
It("Sanitize", func() {
sanitized := versioner.Sanitize("foo_bar")
Expect(sanitized).Should(Equal("foo-bar"))
})
})
Context("valid version", func() {
versioner := DefaultVersioner()
It("Validate", func() {
err := versioner.Validate("1.0")
Expect(err).ShouldNot(HaveOccurred())
})
})
Context("invalid version", func() {
versioner := DefaultVersioner()
It("Validate", func() {
err := versioner.Validate("1.0_##")
Expect(err).Should(HaveOccurred())
})
})
Context("Sorting", func() {
versioner := DefaultVersioner()
It("finds the correct ordering", func() {
sorted := versioner.Sort([]string{"1.0", "0.1"})
Expect(sorted).Should(Equal([]string{"0.1", "1.0"}))
})
})
Context("Sorting with invalid characters", func() {
versioner := DefaultVersioner()
It("finds the correct ordering", func() {
sorted := versioner.Sort([]string{"1.0_1", "0.1"})
Expect(sorted).Should(Equal([]string{"0.1", "1.0_1"}))
})
})
Context("Complex Sorting", func() {
versioner := DefaultVersioner()
It("finds the correct ordering", func() {
sorted := versioner.Sort([]string{"1.0", "0.1", "0.22", "1.1", "1.9", "1.10", "11.1"})
Expect(sorted).Should(Equal([]string{"0.1", "0.22", "1.0", "1.1", "1.9", "1.10", "11.1"}))
})
})
// from: https://github.com/knqyf263/go-deb-version/blob/master/version_test.go#L8
Context("Debian Sorting", func() {
versioner := DefaultVersioner()
It("finds the correct ordering", func() {
sorted := versioner.Sort([]string{"2:7.4.052-1ubuntu3.1", "2:7.4.052-1ubuntu1", "2:7.4.052-1ubuntu2", "2:7.4.052-1ubuntu3"})
Expect(sorted).Should(Equal([]string{"2:7.4.052-1ubuntu1", "2:7.4.052-1ubuntu2", "2:7.4.052-1ubuntu3", "2:7.4.052-1ubuntu3.1"}))
})
})
})

View File

@ -0,0 +1 @@
image: "alpine"

View File

@ -0,0 +1,8 @@
labels: null
category: dev-libs
conflicts: null
id: 0
license: LGPL-2.1+
name: libsigc++-2
version: "2.10.1+1"

View File

@ -0,0 +1 @@
image: "alpine"

View File

@ -0,0 +1,7 @@
category: media-libs
conflicts: null
id: 0
license: LGPL-2.1
name: libsndfile
#version: 1.0.29+1
version: 1.0.29+pre2_p20191024.1

View File

@ -0,0 +1,85 @@
#!/bin/bash
export LUET_NOLOCK=true
oneTimeSetUp() {
export tmpdir="$(mktemp -d)"
}
oneTimeTearDown() {
rm -rf "$tmpdir"
}
testBuild() {
mkdir $tmpdir/testbuild
luet build --tree "$ROOT_DIR/tests/fixtures/versioning" --destination $tmpdir/testbuild --compression gzip --all
buildst=$?
assertEquals 'builds successfully' "0" "$buildst"
luet build --tree "$ROOT_DIR/tests/fixtures/versioning" --destination $tmpdir/testbuild --compression gzip media-libs/libsndfile
buildst=$?
assertEquals 'builds successfully' "0" "$buildst"
luet build --tree "$ROOT_DIR/tests/fixtures/versioning" --destination $tmpdir/testbuild --compression gzip '>=dev-libs/libsigc++-2-0'
buildst=$?
assertEquals 'builds successfully' "0" "$buildst"
}
testRepo() {
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/versioning" \
--output $tmpdir/testbuild \
--packages $tmpdir/testbuild \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type disk > /dev/null
createst=$?
assertEquals 'create repo successfully' "0" "$createst"
assertTrue 'create repository' "[ -e '$tmpdir/testbuild/repository.yaml' ]"
}
testConfig() {
mkdir $tmpdir/testrootfs
cat <<EOF > $tmpdir/luet.yaml
general:
debug: true
system:
rootfs: $tmpdir/testrootfs
database_path: "/"
database_engine: "boltdb"
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "0" "$res"
}
testInstall() {
luet install --config $tmpdir/luet.yaml media-libs/libsndfile
installst=$?
assertEquals 'install test successfully' "0" "$installst"
}
testInstall2() {
luet install --config $tmpdir/luet.yaml '>=dev-libs/libsigc++-2-0'
installst=$?
assertEquals 'install test successfully' "0" "$installst"
}
testCleanup() {
luet cleanup --config $tmpdir/luet.yaml
installst=$?
assertEquals 'install test successfully' "0" "$installst"
}
# Load shUnit2.
. "$ROOT_DIR/tests/integration/shunit2"/shunit2

View File

@ -56,7 +56,7 @@ const (
const (
RegexCatString = `(^[a-z]+[0-9]*[a-z]*[-]*[a-z]+[0-9]*[a-z]*|^virtual)`
RegexPkgNameString = `([a-zA-Z]*[0-9a-zA-Z\.\-_]*[a-zA-Z0-9]+|[a-zA-Z]+[+]+)`
RegexPkgNameString = `([a-zA-Z]*[0-9a-zA-Z\.\-_]*[a-zA-Z0-9]+|[a-zA-Z\-]+[+]+[-]+[0-9a-zA-Z\.]*|[a-zA-Z\-]+[+]+)`
)
type GentooPackage struct {

24
vendor/github.com/knqyf263/go-deb-version/.gitignore generated vendored Normal file
View File

@ -0,0 +1,24 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

10
vendor/github.com/knqyf263/go-deb-version/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,10 @@
language: go
go:
- 1.7
- 1.8
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken ca4cRbwqOXDZBv39XjjxoXDDUnwEA7klw

21
vendor/github.com/knqyf263/go-deb-version/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Teppei Fukuda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

72
vendor/github.com/knqyf263/go-deb-version/README.md generated vendored Normal file
View File

@ -0,0 +1,72 @@
# go-deb-version
[![Build Status](https://travis-ci.org/knqyf263/go-deb-version.svg?branch=master)](https://travis-ci.org/knqyf263/go-deb-version)
[![Coverage Status](https://coveralls.io/repos/github/knqyf263/go-deb-version/badge.svg)](https://coveralls.io/github/knqyf263/go-deb-version)
[![Go Report Card](https://goreportcard.com/badge/github.com/knqyf263/go-deb-version)](https://goreportcard.com/report/github.com/knqyf263/go-deb-version)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/knqyf263/go-deb-version/blob/master/LICENSE)
A Go library for parsing package versions
go-deb-version is a library for parsing and comparing versions
Versions used with go-deb-version must follow [deb-version](http://man.he.net/man5/deb-version) (ex. 2:6.0-9ubuntu1)
The implementation is based on [Debian Policy Manual](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version)
OS: Debian, Ubnutu
# Installation and Usage
Installation can be done with a normal go get:
```
$ go get github.com/knqyf263/go-deb-version
```
## Version Parsing and Comparison
```
import "github.com/knqyf263/go-deb-version"
v1, err := version.NewVersion("2:6.0-9")
v2, err := version.NewVersion("2:6.0-9ubuntu1")
// Comparison example. There is also GreaterThan, Equal.
if v1.LessThan(v2) {
fmt.Printf("%s is less than %s", v1, v2)
}
```
## Version Sorting
```
raw := []string{"7.4.052-1ubuntu3.1", "7.4.052-1ubuntu3", "7.1-022+1ubuntu1", "7.1.291-1", "7.3.000+hg~ee53a39d5896-1"}
vs := make([]version.Version, len(raw))
for i, r := range raw {
v, _ := version.NewVersion(r)
vs[i] = v
}
sort.Slice(vs, func(i, j int) bool {
return vs[i].LessThan(vs[j])
})
```
# Contribute
1. fork a repository: github.com/knqyf263/go-deb-version to github.com/you/repo
2. get original code: `go get github.com/knqyf263/go-deb-version`
3. work on original code
4. add remote to your repo: git remote add myfork https://github.com/you/repo.git
5. push your changes: git push myfork
6. create a new Pull Request
- see [GitHub and Go: forking, pull requests, and go-getting](http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html)
----
# License
MIT
# Author
Teppei Fukuda

267
vendor/github.com/knqyf263/go-deb-version/version.go generated vendored Normal file
View File

@ -0,0 +1,267 @@
package version
import (
"errors"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"unicode"
)
type defaultNumSlice []int
// get function returns 0, if the slice does not have the specified index.
func (n defaultNumSlice) get(i int) int {
if len(n) > i {
return n[i]
}
return 0
}
type defaultStringSlice []string
// get function returns "", if the slice does not have the specified index.
func (s defaultStringSlice) get(i int) string {
if len(s) > i {
return s[i]
}
return ""
}
// Version represents a package version (http://man.he.net/man5/deb-version).
type Version struct {
epoch int
upstreamVersion string
debianRevision string
}
var (
digitRegexp = regexp.MustCompile(`[0-9]+`)
nonDigitRegexp = regexp.MustCompile(`[^0-9]+`)
)
// NewVersion returns a parsed version
func NewVersion(ver string) (version Version, err error) {
// Trim space
ver = strings.TrimSpace(ver)
// Parse epoch
splitted := strings.SplitN(ver, ":", 2)
if len(splitted) == 1 {
version.epoch = 0
ver = splitted[0]
} else {
version.epoch, err = strconv.Atoi(splitted[0])
if err != nil {
return Version{}, fmt.Errorf("epoch parse error: %v", err)
}
if version.epoch < 0 {
return Version{}, errors.New("epoch is negative")
}
ver = splitted[1]
}
// Parse upstream_version and debian_revision
index := strings.LastIndex(ver, "-")
if index >= 0 {
version.upstreamVersion = ver[:index]
version.debianRevision = ver[index+1:]
} else {
version.upstreamVersion = ver
}
// Verify upstream_version is valid
err = verifyUpstreamVersion(version.upstreamVersion)
if err != nil {
return Version{}, err
}
// Verify debian_revision is valid
err = verifyDebianRevision(version.debianRevision)
if err != nil {
return Version{}, err
}
return version, nil
}
func verifyUpstreamVersion(str string) error {
if len(str) == 0 {
return errors.New("upstream_version is empty")
}
// The upstream-version should start with a digit
if !unicode.IsDigit(rune(str[0])) {
return errors.New("upstream_version must start with digit")
}
// The upstream-version may contain only alphanumerics("A-Za-z0-9") and the characters .+-:~
allowedSymbols := ".-+~:_"
for _, s := range str {
if !unicode.IsDigit(s) && !unicode.IsLetter(s) && !strings.ContainsRune(allowedSymbols, s) {
return errors.New("upstream_version includes invalid character")
}
}
return nil
}
func verifyDebianRevision(str string) error {
// The debian-revision may contain only alphanumerics and the characters +.~
allowedSymbols := "+.~_"
for _, s := range str {
if !unicode.IsDigit(s) && !unicode.IsLetter(s) && !strings.ContainsRune(allowedSymbols, s) {
return errors.New("debian_revision includes invalid character")
}
}
return nil
}
// Valid validates the version
func Valid(ver string) bool {
_, err := NewVersion(ver)
return err == nil
}
// Equal returns whether this version is equal with another version.
func (v1 *Version) Equal(v2 Version) bool {
return v1.Compare(v2) == 0
}
// GreaterThan returns whether this version is greater than another version.
func (v1 *Version) GreaterThan(v2 Version) bool {
return v1.Compare(v2) > 0
}
// LessThan returns whether this version is less than another version.
func (v1 Version) LessThan(v2 Version) bool {
return v1.Compare(v2) < 0
}
// Compare returns an integer comparing two version according to deb-version.
// The result will be 0 if v1==v2, -1 if v1 < v2, and +1 if v1 > v2.
func (v1 Version) Compare(v2 Version) int {
// Equal
if reflect.DeepEqual(v1, v2) {
return 0
}
// Compare epochs
if v1.epoch > v2.epoch {
return 1
} else if v1.epoch < v2.epoch {
return -1
}
// Compare version
ret := compare(v1.upstreamVersion, v2.upstreamVersion)
if ret != 0 {
return ret
}
//Compare debian_revision
return compare(v1.debianRevision, v2.debianRevision)
}
// String returns the full version string
func (v1 Version) String() string {
version := ""
if v1.epoch > 0 {
version += fmt.Sprintf("%d:", v1.epoch)
}
version += v1.upstreamVersion
if v1.debianRevision != "" {
version += fmt.Sprintf("-%s", v1.debianRevision)
}
return version
}
func compare(v1, v2 string) int {
// Equal
if v1 == v2 {
return 0
}
// Extract digit strings and non-digit strings
numbers1, strings1 := extract(v1)
numbers2, strings2 := extract(v2)
if len(v1) > 0 && unicode.IsDigit(rune(v1[0])) {
strings1 = append([]string{""}, strings1...)
}
if len(v2) > 0 && unicode.IsDigit(rune(v2[0])) {
strings2 = append([]string{""}, strings2...)
}
for i := 0; ; i++ {
// Compare non-digit strings
diff := compareString(strings1.get(i), strings2.get(i))
if diff != 0 {
return diff
}
// Compare digit strings
diff = numbers1.get(i) - numbers2.get(i)
if diff != 0 {
return diff
}
}
}
func compareString(s1, s2 string) int {
if s1 == s2 {
return 0
}
for i := 0; ; i++ {
a := 0
if i < len(s1) {
a = order(rune(s1[i]))
}
b := 0
if i < len(s2) {
b = order(rune(s2[i]))
}
if a != b {
return a - b
}
}
}
// order function returns the number corresponding to rune
func order(r rune) int {
// all the letters sort earlier than all the non-letters
if unicode.IsLetter(r) {
return int(r)
}
// a tilde sorts before anything
if r == '~' {
return -1
}
return int(r) + 256
}
func extract(version string) (defaultNumSlice, defaultStringSlice) {
numbers := digitRegexp.FindAllString(version, -1)
var dnum defaultNumSlice
for _, number := range numbers {
n, _ := strconv.Atoi(number)
dnum = append(dnum, n)
}
s := nonDigitRegexp.FindAllString(version, -1)
return dnum, defaultStringSlice(s)
}

4
vendor/modules.txt vendored
View File

@ -23,7 +23,7 @@ github.com/Microsoft/hcsshim/internal/longpath
github.com/Microsoft/hcsshim/internal/safefile
# github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
github.com/Nvveen/Gotty
# github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1
# github.com/Sabayon/pkgs-checker v0.6.2-0.20200404093625-076438c31739
github.com/Sabayon/pkgs-checker/pkg/gentoo
# github.com/apex/log v1.1.1
github.com/apex/log
@ -141,6 +141,8 @@ github.com/klauspost/compress/flate
github.com/klauspost/cpuid
# github.com/klauspost/pgzip v1.2.1
github.com/klauspost/pgzip
# github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/knqyf263/go-deb-version
# github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/konsorten/go-windows-terminal-sequences
# github.com/kyokomi/emoji v2.1.0+incompatible