mirror of
https://github.com/mudler/luet.git
synced 2025-08-28 11:50:37 +00:00
commit
c2beab64cb
@ -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 {
|
||||
|
22
cmd/root.go
22
cmd/root.go
@ -94,17 +94,19 @@ func LoadConfig(c *config.LuetConfig) error {
|
||||
func Execute() {
|
||||
|
||||
if os.Getenv("LUET_NOLOCK") != "true" {
|
||||
for _, lockedCmd := range LockedCommands {
|
||||
if os.Args[1] == lockedCmd {
|
||||
s := single.New("luet")
|
||||
if err := s.CheckLock(); err != nil && err == single.ErrAlreadyRunning {
|
||||
Fatal("another instance of the app is already running, exiting")
|
||||
} else if err != nil {
|
||||
// Another error occurred, might be worth handling it as well
|
||||
Fatal("failed to acquire exclusive app lock:", err.Error())
|
||||
if len(os.Args) > 1 {
|
||||
for _, lockedCmd := range LockedCommands {
|
||||
if os.Args[1] == lockedCmd {
|
||||
s := single.New("luet")
|
||||
if err := s.CheckLock(); err != nil && err == single.ErrAlreadyRunning {
|
||||
Fatal("another instance of the app is already running, exiting")
|
||||
} else if err != nil {
|
||||
// Another error occurred, might be worth handling it as well
|
||||
Fatal("failed to acquire exclusive app lock:", err.Error())
|
||||
}
|
||||
defer s.TryUnlock()
|
||||
break
|
||||
}
|
||||
defer s.TryUnlock()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
err = tree.WriteDefinitionFile(&pack, spec)
|
||||
if err != nil {
|
||||
Fatal("Error on write definition file: " + err.Error())
|
||||
}
|
||||
if toStdout {
|
||||
data, err := pack.Yaml()
|
||||
if err != nil {
|
||||
Fatal("Error on yaml conversion: " + err.Error())
|
||||
}
|
||||
fmt.Println(string(data))
|
||||
} else {
|
||||
|
||||
fmt.Printf("Bumped package %s/%s-%s.\n", pack.Category, pack.Name, pack.Version)
|
||||
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
|
||||
}
|
||||
|
@ -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(
|
||||
&pkg.DefaultPackage{
|
||||
Name: r.GetName(),
|
||||
Category: r.GetCategory(),
|
||||
Version: r.GetVersion(),
|
||||
},
|
||||
)
|
||||
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
6
go.mod
@ -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
25
go.sum
@ -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=
|
||||
|
@ -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)",
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
})
|
||||
})
|
||||
|
@ -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 {
|
||||
|
@ -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()))
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
})
|
||||
})
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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())
|
||||
|
||||
|
27
pkg/versioner/interface.go
Normal file
27
pkg/versioner/interface.go
Normal 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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
148
pkg/versioner/versioner.go
Normal 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
|
||||
}
|
32
pkg/versioner/versioner_suite_test.go
Normal file
32
pkg/versioner/versioner_suite_test.go
Normal 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")
|
||||
}
|
82
pkg/versioner/versioner_test.go
Normal file
82
pkg/versioner/versioner_test.go
Normal 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"}))
|
||||
})
|
||||
})
|
||||
})
|
1
tests/fixtures/versioning/libsigc++-2/build.yaml
vendored
Normal file
1
tests/fixtures/versioning/libsigc++-2/build.yaml
vendored
Normal file
@ -0,0 +1 @@
|
||||
image: "alpine"
|
8
tests/fixtures/versioning/libsigc++-2/definition.yaml
vendored
Normal file
8
tests/fixtures/versioning/libsigc++-2/definition.yaml
vendored
Normal 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"
|
1
tests/fixtures/versioning/libsndfile/build.yaml
vendored
Normal file
1
tests/fixtures/versioning/libsndfile/build.yaml
vendored
Normal file
@ -0,0 +1 @@
|
||||
image: "alpine"
|
7
tests/fixtures/versioning/libsndfile/definition.yaml
vendored
Normal file
7
tests/fixtures/versioning/libsndfile/definition.yaml
vendored
Normal 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
|
85
tests/integration/08_versioning.sh
Executable file
85
tests/integration/08_versioning.sh
Executable 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
|
2
vendor/github.com/Sabayon/pkgs-checker/pkg/gentoo/pkg.go
generated
vendored
2
vendor/github.com/Sabayon/pkgs-checker/pkg/gentoo/pkg.go
generated
vendored
@ -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
24
vendor/github.com/knqyf263/go-deb-version/.gitignore
generated
vendored
Normal 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
10
vendor/github.com/knqyf263/go-deb-version/.travis.yml
generated
vendored
Normal 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
21
vendor/github.com/knqyf263/go-deb-version/LICENSE
generated
vendored
Normal 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
72
vendor/github.com/knqyf263/go-deb-version/README.md
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# go-deb-version
|
||||
|
||||
[](https://travis-ci.org/knqyf263/go-deb-version)
|
||||
[](https://coveralls.io/github/knqyf263/go-deb-version)
|
||||
[](https://goreportcard.com/report/github.com/knqyf263/go-deb-version)
|
||||
[](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
267
vendor/github.com/knqyf263/go-deb-version/version.go
generated
vendored
Normal 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
4
vendor/modules.txt
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user