mirror of
https://github.com/mudler/luet.git
synced 2025-08-29 12:13:09 +00:00
commit
c2beab64cb
@ -46,7 +46,7 @@ var installCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
Long: `Install packages in parallel`,
|
Long: `Install packages in parallel`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
var toInstall []pkg.Package
|
var toInstall pkg.Packages
|
||||||
var systemDB pkg.PackageDatabase
|
var systemDB pkg.PackageDatabase
|
||||||
|
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
|
@ -94,6 +94,7 @@ func LoadConfig(c *config.LuetConfig) error {
|
|||||||
func Execute() {
|
func Execute() {
|
||||||
|
|
||||||
if os.Getenv("LUET_NOLOCK") != "true" {
|
if os.Getenv("LUET_NOLOCK") != "true" {
|
||||||
|
if len(os.Args) > 1 {
|
||||||
for _, lockedCmd := range LockedCommands {
|
for _, lockedCmd := range LockedCommands {
|
||||||
if os.Args[1] == lockedCmd {
|
if os.Args[1] == lockedCmd {
|
||||||
s := single.New("luet")
|
s := single.New("luet")
|
||||||
@ -108,6 +109,7 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := RootCmd.Execute(); err != nil {
|
if err := RootCmd.Execute(); err != nil {
|
||||||
if len(os.Args) > 0 {
|
if len(os.Args) > 0 {
|
||||||
|
@ -108,7 +108,7 @@ var searchCmd = &cobra.Command{
|
|||||||
system := &installer.System{Database: systemDB, Target: LuetCfg.GetSystem().Rootfs}
|
system := &installer.System{Database: systemDB, Target: LuetCfg.GetSystem().Rootfs}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
iMatches := []pkg.Package{}
|
iMatches := pkg.Packages{}
|
||||||
if searchWithLabel {
|
if searchWithLabel {
|
||||||
iMatches, err = system.Database.FindPackageLabel(args[0])
|
iMatches, err = system.Database.FindPackageLabel(args[0])
|
||||||
} else if searchWithLabelMatch {
|
} else if searchWithLabelMatch {
|
||||||
|
@ -41,6 +41,7 @@ func NewTreeBumpCommand() *cobra.Command {
|
|||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
spec, _ := cmd.Flags().GetString("definition-file")
|
spec, _ := cmd.Flags().GetString("definition-file")
|
||||||
|
toStdout, _ := cmd.Flags().GetBool("to-stdout")
|
||||||
pack, err := tree.ReadDefinitionFile(spec)
|
pack, err := tree.ReadDefinitionFile(spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(err.Error())
|
Fatal(err.Error())
|
||||||
@ -52,16 +53,26 @@ func NewTreeBumpCommand() *cobra.Command {
|
|||||||
Fatal("Error on increment build version: " + err.Error())
|
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)
|
err = tree.WriteDefinitionFile(&pack, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal("Error on write definition file: " + err.Error())
|
Fatal("Error on write definition file: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Bumped package %s/%s-%s.\n", pack.Category, pack.Name, pack.Version)
|
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().StringP("definition-file", "f", "", "Path of the definition to bump.")
|
||||||
|
ans.Flags().BoolP("to-stdout", "o", false, "Bump package to output.")
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,34 @@ func NewTreeValidateCommand() *cobra.Command {
|
|||||||
|
|
||||||
for _, p := range reciper.GetDatabase().World() {
|
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(),
|
pkgstr := fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(),
|
||||||
p.GetVersion())
|
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.")
|
Info("Checking package "+fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(), p.GetVersion()), "with", len(p.GetRequires()), "dependencies.")
|
||||||
|
|
||||||
for _, r := range p.GetRequires() {
|
all := p.GetRequires()
|
||||||
|
all = append(all, p.GetConflicts()...)
|
||||||
deps, err := reciper.GetDatabase().FindPackages(
|
for _, r := range all {
|
||||||
|
var deps pkg.Packages
|
||||||
|
var err error
|
||||||
|
if r.IsSelector() {
|
||||||
|
deps, err = reciper.GetDatabase().FindPackages(
|
||||||
&pkg.DefaultPackage{
|
&pkg.DefaultPackage{
|
||||||
Name: r.GetName(),
|
Name: r.GetName(),
|
||||||
Category: r.GetCategory(),
|
Category: r.GetCategory(),
|
||||||
Version: r.GetVersion(),
|
Version: r.GetVersion(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
deps = append(deps, r)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil || len(deps) < 1 {
|
if err != nil || len(deps) < 1 {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -154,7 +189,11 @@ func NewTreeValidateCommand() *cobra.Command {
|
|||||||
|
|
||||||
if withSolver {
|
if withSolver {
|
||||||
Spinner(32)
|
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()
|
SpinnerStop()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
6
go.mod
6
go.mod
@ -4,8 +4,7 @@ go 1.12
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/DataDog/zstd v1.4.4 // indirect
|
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.20200404093625-076438c31739
|
||||||
github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1
|
|
||||||
github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154
|
github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154
|
||||||
github.com/briandowns/spinner v1.7.0
|
github.com/briandowns/spinner v1.7.0
|
||||||
github.com/cavaliercoder/grab v2.0.0+incompatible
|
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/docker/docker v0.7.3-0.20180827131323-0c5f8d2b9b23
|
||||||
github.com/ecooper/qlearning v0.0.0-20160612200101-3075011a69fd
|
github.com/ecooper/qlearning v0.0.0-20160612200101-3075011a69fd
|
||||||
github.com/ghodss/yaml v1.0.0
|
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/hashicorp/go-version v1.2.0
|
||||||
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
|
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
|
||||||
github.com/klauspost/pgzip v1.2.1
|
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/kr/pretty v0.2.0 // indirect
|
||||||
github.com/kyokomi/emoji v2.1.0+incompatible
|
github.com/kyokomi/emoji v2.1.0+incompatible
|
||||||
github.com/logrusorgru/aurora v0.0.0-20190417123914-21d75270181e
|
github.com/logrusorgru/aurora v0.0.0-20190417123914-21d75270181e
|
||||||
github.com/marcsauter/single v0.0.0-20181104081128-f8bf46f26ec0
|
github.com/marcsauter/single v0.0.0-20181104081128-f8bf46f26ec0
|
||||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
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/mudler/docker-companion v0.4.6-0.20191110154655-b8b364100616
|
||||||
github.com/onsi/ginkgo v1.10.1
|
github.com/onsi/ginkgo v1.10.1
|
||||||
github.com/onsi/gomega v1.7.0
|
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/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 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
|
||||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
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 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
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/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.6.2-0.20200404093625-076438c31739 h1:cWiphrLut8a+RNwosFre5j+zWDe1m6y1OpkSzn5bu1w=
|
||||||
github.com/Sabayon/pkgs-checker v0.4.2-0.20200101193228-1d500105afb7/go.mod h1:GFGM6ZzSE5owdGgjLnulj0+Vt9UTd5LFGmB2AOVPYrE=
|
github.com/Sabayon/pkgs-checker v0.6.2-0.20200404093625-076438c31739/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/Sereal/Sereal v0.0.0-20181211220259-509a78ddbda3 h1:Xu7z47ZiE/J+sKXHZMGxEor/oY2q6dq51fkO0JqdSwY=
|
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/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=
|
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 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/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/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 h1:HO63LCf9kTXQgUnlvFeS2qSDQhZ/cLP8DAJO89CythY=
|
||||||
github.com/crillab/gophersat v1.1.9-0.20200211102949-9a8bf7f2f0a3/go.mod h1:S91tHga1PCZzYhCkStwZAhvp1rCc+zqtSi55I+vDWGc=
|
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=
|
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.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
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-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.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.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
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/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
|
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
|
||||||
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
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.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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
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-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/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/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"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")
|
return []compiler.ArtifactLayer{}, errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdiffs) // clean up
|
defer os.RemoveAll(tmpdiffs) // clean up
|
||||||
|
var errorBuffer bytes.Buffer
|
||||||
|
|
||||||
diffargs := []string{"diff", fromImage, toImage, "-v", "error", "-q", "--type=file", "-j", "-n", "-c", tmpdiffs}
|
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 {
|
if err != nil {
|
||||||
return []compiler.ArtifactLayer{}, errors.Wrap(err, "Failed Resolving layer diffs: "+string(out))
|
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))
|
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)
|
summary := compiler.ComputeArtifactLayerSummary(diffs)
|
||||||
for _, l := range summary.Layers {
|
for _, l := range summary.Layers {
|
||||||
Debug(fmt.Sprintf("Diff %s -> %s: add %d (%d bytes), del %d (%d bytes), change %d (%d bytes)",
|
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())
|
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 {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "While computing a solution for "+p.GetPackage().HumanReadableString())
|
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{}
|
assertions := solver.PackagesAssertions{}
|
||||||
for _, assertion := range dependencies { //highly dependent on the order
|
for _, assertion := range dependencies { //highly dependent on the order
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
_gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
_gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
|
version "github.com/mudler/luet/pkg/versioner"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateRegexArray(rgx []string) ([]*regexp.Regexp, error) {
|
func CreateRegexArray(rgx []string) ([]*regexp.Regexp, error) {
|
||||||
@ -53,14 +54,14 @@ func ParsePackageStr(p string) (*pkg.DefaultPackage, error) {
|
|||||||
pkgVersion := ""
|
pkgVersion := ""
|
||||||
if gp.VersionBuild != "" {
|
if gp.VersionBuild != "" {
|
||||||
pkgVersion = fmt.Sprintf("%s%s%s+%s",
|
pkgVersion = fmt.Sprintf("%s%s%s+%s",
|
||||||
pkg.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
|
version.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
|
||||||
gp.Version,
|
gp.Version,
|
||||||
gp.VersionSuffix,
|
gp.VersionSuffix,
|
||||||
gp.VersionBuild,
|
gp.VersionBuild,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
pkgVersion = fmt.Sprintf("%s%s%s",
|
pkgVersion = fmt.Sprintf("%s%s%s",
|
||||||
pkg.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
|
version.PkgSelectorConditionFromInt(gp.Condition.Int()).String(),
|
||||||
gp.Version,
|
gp.Version,
|
||||||
gp.VersionSuffix,
|
gp.VersionSuffix,
|
||||||
)
|
)
|
||||||
|
@ -74,7 +74,7 @@ func (l *LuetInstaller) Upgrade(s *System) error {
|
|||||||
return errors.Wrap(err, "Failed solving solution for upgrade")
|
return errors.Wrap(err, "Failed solving solution for upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
toInstall := []pkg.Package{}
|
toInstall := pkg.Packages{}
|
||||||
for _, assertion := range solution {
|
for _, assertion := range solution {
|
||||||
// Be sure to filter from solutions packages already installed in the system
|
// Be sure to filter from solutions packages already installed in the system
|
||||||
if _, err := s.Database.FindPackage(assertion.Package); err != nil && assertion.Value {
|
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
|
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)
|
syncedRepos, err := l.SyncRepositories(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -115,7 +115,7 @@ func (l *LuetInstaller) Swap(toRemove []pkg.Package, toInstall []pkg.Package, s
|
|||||||
return l.swap(syncedRepos, toRemove, toInstall, 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
|
// First match packages against repositories by priority
|
||||||
allRepos := pkg.NewInMemoryDatabase(false)
|
allRepos := pkg.NewInMemoryDatabase(false)
|
||||||
syncedRepos.SyncDatabase(allRepos)
|
syncedRepos.SyncDatabase(allRepos)
|
||||||
@ -153,7 +153,7 @@ func (l *LuetInstaller) swap(syncedRepos Repositories, toRemove []pkg.Package, t
|
|||||||
return l.install(syncedRepos, toInstall, s)
|
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)
|
syncedRepos, err := l.SyncRepositories(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -161,7 +161,7 @@ func (l *LuetInstaller) Install(cp []pkg.Package, s *System, downloadOnly bool)
|
|||||||
return l.install(syncedRepos, cp, s)
|
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{}
|
toDownload := map[string]ArtifactMatch{}
|
||||||
|
|
||||||
// FIXME: This can be optimized. We don't need to re-match this to the repository
|
// 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
|
// Gathers things to download
|
||||||
for _, currentPack := range cp {
|
for _, currentPack := range cp {
|
||||||
matches := syncedRepos.PackageMatches([]pkg.Package{currentPack})
|
matches := syncedRepos.PackageMatches(pkg.Packages{currentPack})
|
||||||
if len(matches) == 0 {
|
if len(matches) == 0 {
|
||||||
return errors.New("Failed matching solutions against repository for " + currentPack.HumanReadableString() + " where are definitions coming from?!")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *System) error {
|
func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *System) error {
|
||||||
var p []pkg.Package
|
var p pkg.Packages
|
||||||
|
|
||||||
// Check if the package is installed first
|
// Check if the package is installed first
|
||||||
for _, pi := range cp {
|
for _, pi := range cp {
|
||||||
@ -237,7 +237,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
|
|||||||
syncedRepos.SyncDatabase(allRepos)
|
syncedRepos.SyncDatabase(allRepos)
|
||||||
p = syncedRepos.ResolveSelectors(p)
|
p = syncedRepos.ResolveSelectors(p)
|
||||||
toInstall := map[string]ArtifactMatch{}
|
toInstall := map[string]ArtifactMatch{}
|
||||||
var packagesToInstall []pkg.Package
|
var packagesToInstall pkg.Packages
|
||||||
var err error
|
var err error
|
||||||
var solution solver.PackagesAssertions
|
var solution solver.PackagesAssertions
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
|
|||||||
|
|
||||||
// Gathers things to install
|
// Gathers things to install
|
||||||
for _, currentPack := range packagesToInstall {
|
for _, currentPack := range packagesToInstall {
|
||||||
matches := syncedRepos.PackageMatches([]pkg.Package{currentPack})
|
matches := syncedRepos.PackageMatches(pkg.Packages{currentPack})
|
||||||
if len(matches) == 0 {
|
if len(matches) == 0 {
|
||||||
return errors.New("Failed matching solutions against repository for " + currentPack.HumanReadableString() + " where are definitions coming from?!")
|
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
|
// TODO: Lower those errors as warning
|
||||||
for _, w := range p {
|
for _, w := range p {
|
||||||
// Finalizers needs to run in order and in sequence.
|
// 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:
|
ORDER:
|
||||||
for _, ass := range ordered {
|
for _, ass := range ordered {
|
||||||
if ass.Value {
|
if ass.Value {
|
||||||
|
@ -23,12 +23,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Installer interface {
|
type Installer interface {
|
||||||
Install([]pkg.Package, *System, bool) error
|
Install(pkg.Packages, *System, bool) error
|
||||||
Uninstall(pkg.Package, *System) error
|
Uninstall(pkg.Package, *System) error
|
||||||
Upgrade(s *System) error
|
Upgrade(s *System) error
|
||||||
Repositories([]Repository)
|
Repositories([]Repository)
|
||||||
SyncRepositories(bool) (Repositories, error)
|
SyncRepositories(bool) (Repositories, error)
|
||||||
Swap([]pkg.Package, []pkg.Package, *System) error
|
Swap(pkg.Packages, pkg.Packages, *System) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
|
@ -701,9 +701,9 @@ func (r Repositories) Less(i, j int) bool {
|
|||||||
return r[i].GetPriority() < r[j].GetPriority()
|
return r[i].GetPriority() < r[j].GetPriority()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Repositories) World() []pkg.Package {
|
func (r Repositories) World() pkg.Packages {
|
||||||
cache := map[string]pkg.Package{}
|
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
|
// 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.
|
// 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
|
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
|
// 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
|
// 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)
|
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
|
// If a selector is given, get the best from each repo
|
||||||
sort.Sort(re) // respect prio
|
sort.Sort(re) // respect prio
|
||||||
var matches []pkg.Package
|
var matches pkg.Packages
|
||||||
PACKAGE:
|
PACKAGE:
|
||||||
for _, pack := range p {
|
for _, pack := range p {
|
||||||
REPOSITORY:
|
REPOSITORY:
|
||||||
@ -798,7 +798,7 @@ func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
for _, r := range re {
|
for _, r := range re {
|
||||||
var repoMatches []pkg.Package
|
var repoMatches pkg.Packages
|
||||||
|
|
||||||
switch o.Mode {
|
switch o.Mode {
|
||||||
case SRegexPkg:
|
case SRegexPkg:
|
||||||
|
@ -9,6 +9,6 @@ type System struct {
|
|||||||
Target string
|
Target string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *System) World() ([]pkg.Package, error) {
|
func (s *System) World() (pkg.Packages, error) {
|
||||||
return s.Database.World(), nil
|
return s.Database.World(), nil
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ type PackageSet interface {
|
|||||||
GetPackage(ID string) (Package, error)
|
GetPackage(ID string) (Package, error)
|
||||||
Clean() error
|
Clean() error
|
||||||
FindPackage(Package) (Package, error)
|
FindPackage(Package) (Package, error)
|
||||||
FindPackages(p Package) ([]Package, error)
|
FindPackages(p Package) (Packages, error)
|
||||||
UpdatePackage(p Package) error
|
UpdatePackage(p Package) error
|
||||||
GetAllPackages(packages chan Package) error
|
GetAllPackages(packages chan Package) error
|
||||||
RemovePackage(Package) error
|
RemovePackage(Package) error
|
||||||
@ -41,13 +41,13 @@ type PackageSet interface {
|
|||||||
GetPackageFiles(Package) ([]string, error)
|
GetPackageFiles(Package) ([]string, error)
|
||||||
SetPackageFiles(*PackageFile) error
|
SetPackageFiles(*PackageFile) error
|
||||||
RemovePackageFiles(Package) error
|
RemovePackageFiles(Package) error
|
||||||
FindPackageVersions(p Package) ([]Package, error)
|
FindPackageVersions(p Package) (Packages, error)
|
||||||
World() []Package
|
World() Packages
|
||||||
|
|
||||||
FindPackageCandidate(p Package) (Package, error)
|
FindPackageCandidate(p Package) (Package, error)
|
||||||
FindPackageLabel(labelKey string) ([]Package, error)
|
FindPackageLabel(labelKey string) (Packages, error)
|
||||||
FindPackageLabelMatch(pattern string) ([]Package, error)
|
FindPackageLabelMatch(pattern string) (Packages, error)
|
||||||
FindPackageMatch(pattern string) ([]Package, error)
|
FindPackageMatch(pattern string) (Packages, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PackageFile struct {
|
type PackageFile struct {
|
||||||
|
@ -233,7 +233,7 @@ func (db *BoltDatabase) getProvide(p Package) (Package, error) {
|
|||||||
|
|
||||||
for ve, _ := range versions {
|
for ve, _ := range versions {
|
||||||
|
|
||||||
match, err := p.VersionMatchSelector(ve)
|
match, err := p.VersionMatchSelector(ve, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error on match version")
|
return nil, errors.Wrap(err, "Error on match version")
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ func (db *BoltDatabase) RemovePackage(p Package) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *BoltDatabase) World() []Package {
|
func (db *BoltDatabase) World() Packages {
|
||||||
|
|
||||||
var all []Package
|
var all []Package
|
||||||
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
// 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)
|
all = append(all, pack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return all
|
return Packages(all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
|
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 {
|
if err != nil || len(packages) == 0 {
|
||||||
required = p
|
required = p
|
||||||
} else {
|
} else {
|
||||||
required = Best(packages)
|
required = packages.Best(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
return required, 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)
|
// FindPackages return the list of the packages beloging to cat/name (any versions in requested range)
|
||||||
// FIXME: Optimize, see inmemorydb
|
// 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
|
// Provides: Treat as the replaced package here
|
||||||
if provided, err := db.getProvide(p); err == nil {
|
if provided, err := db.getProvide(p); err == nil {
|
||||||
p = provided
|
p = provided
|
||||||
@ -362,7 +362,7 @@ func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
match, err := p.SelectorMatchVersion(w.GetVersion())
|
match, err := p.SelectorMatchVersion(w.GetVersion(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error on match selector")
|
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)
|
versionsInWorld = append(versionsInWorld, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return versionsInWorld, nil
|
return Packages(versionsInWorld), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindPackageVersions return the list of the packages beloging to cat/name
|
// 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
|
var versionsInWorld []Package
|
||||||
for _, w := range db.World() {
|
for _, w := range db.World() {
|
||||||
if w.GetName() != p.GetName() || w.GetCategory() != p.GetCategory() {
|
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)
|
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
|
var ans []Package
|
||||||
|
|
||||||
for _, k := range db.GetPackages() {
|
for _, k := range db.GetPackages() {
|
||||||
@ -398,10 +398,10 @@ func (db *BoltDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
|
|||||||
ans = append(ans, pack)
|
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
|
var ans []Package
|
||||||
|
|
||||||
re := regexp.MustCompile(pattern)
|
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
|
var ans []Package
|
||||||
|
|
||||||
re := regexp.MustCompile(pattern)
|
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 {
|
for ve, _ := range versions {
|
||||||
|
|
||||||
match, err := p.VersionMatchSelector(ve)
|
match, err := p.VersionMatchSelector(ve, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error on match version")
|
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
|
// 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()]
|
versions, ok := db.CacheNoVersion[p.GetPackageName()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("No versions found for package")
|
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)
|
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)
|
// 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
|
// Provides: Treat as the replaced package here
|
||||||
if provided, err := db.getProvide(p); err == nil {
|
if provided, err := db.getProvide(p); err == nil {
|
||||||
@ -252,7 +252,7 @@ func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
|
|||||||
}
|
}
|
||||||
var versionsInWorld []Package
|
var versionsInWorld []Package
|
||||||
for ve, _ := range versions {
|
for ve, _ := range versions {
|
||||||
match, err := p.SelectorMatchVersion(ve)
|
match, err := p.SelectorMatchVersion(ve, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error on match selector")
|
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)
|
versionsInWorld = append(versionsInWorld, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return versionsInWorld, nil
|
return Packages(versionsInWorld), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *InMemoryDatabase) UpdatePackage(p Package) error {
|
func (db *InMemoryDatabase) UpdatePackage(p Package) error {
|
||||||
@ -327,7 +327,7 @@ func (db *InMemoryDatabase) RemovePackage(p Package) error {
|
|||||||
delete(db.Database, p.GetFingerPrint())
|
delete(db.Database, p.GetFingerPrint())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (db *InMemoryDatabase) World() []Package {
|
func (db *InMemoryDatabase) World() Packages {
|
||||||
var all []Package
|
var all []Package
|
||||||
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
// FIXME: This should all be locked in the db - for now forbid the solver to be run in threads.
|
||||||
for _, k := range db.GetPackages() {
|
for _, k := range db.GetPackages() {
|
||||||
@ -336,7 +336,7 @@ func (db *InMemoryDatabase) World() []Package {
|
|||||||
all = append(all, pack)
|
all = append(all, pack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return all
|
return Packages(all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *InMemoryDatabase) FindPackageCandidate(p Package) (Package, error) {
|
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 {
|
if err != nil || len(packages) == 0 {
|
||||||
required = p
|
required = p
|
||||||
} else {
|
} else {
|
||||||
required = Best(packages)
|
required = packages.Best(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
return required, 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
|
var ans []Package
|
||||||
|
|
||||||
for _, k := range db.GetPackages() {
|
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
|
var ans []Package
|
||||||
|
|
||||||
re := regexp.MustCompile(pattern)
|
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
|
var ans []Package
|
||||||
|
|
||||||
re := regexp.MustCompile(pattern)
|
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"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
||||||
"github.com/crillab/gophersat/bf"
|
"github.com/crillab/gophersat/bf"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
version "github.com/hashicorp/go-version"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
|
version "github.com/mudler/luet/pkg/versioner"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,15 +46,15 @@ type Package interface {
|
|||||||
GetPackageName() string
|
GetPackageName() string
|
||||||
Requires([]*DefaultPackage) Package
|
Requires([]*DefaultPackage) Package
|
||||||
Conflicts([]*DefaultPackage) Package
|
Conflicts([]*DefaultPackage) Package
|
||||||
Revdeps(PackageDatabase) []Package
|
Revdeps(PackageDatabase) Packages
|
||||||
LabelDeps(PackageDatabase, string) []Package
|
LabelDeps(PackageDatabase, string) Packages
|
||||||
|
|
||||||
GetProvides() []*DefaultPackage
|
GetProvides() []*DefaultPackage
|
||||||
SetProvides([]*DefaultPackage) Package
|
SetProvides([]*DefaultPackage) Package
|
||||||
|
|
||||||
GetRequires() []*DefaultPackage
|
GetRequires() []*DefaultPackage
|
||||||
GetConflicts() []*DefaultPackage
|
GetConflicts() []*DefaultPackage
|
||||||
Expand(PackageDatabase) ([]Package, error)
|
Expand(PackageDatabase) (Packages, error)
|
||||||
SetCategory(string)
|
SetCategory(string)
|
||||||
|
|
||||||
GetName() string
|
GetName() string
|
||||||
@ -92,8 +91,8 @@ type Package interface {
|
|||||||
MatchLabel(*regexp.Regexp) bool
|
MatchLabel(*regexp.Regexp) bool
|
||||||
|
|
||||||
IsSelector() bool
|
IsSelector() bool
|
||||||
VersionMatchSelector(string) (bool, error)
|
VersionMatchSelector(string, version.Versioner) (bool, error)
|
||||||
SelectorMatchVersion(string) (bool, error)
|
SelectorMatchVersion(string, version.Versioner) (bool, error)
|
||||||
|
|
||||||
String() string
|
String() string
|
||||||
HumanReadableString() string
|
HumanReadableString() string
|
||||||
@ -104,10 +103,12 @@ type Tree interface {
|
|||||||
GetPackageSet() PackageDatabase
|
GetPackageSet() PackageDatabase
|
||||||
Prelude() string // A tree might have a prelude to be able to consume a tree
|
Prelude() string // A tree might have a prelude to be able to consume a tree
|
||||||
SetPackageSet(s PackageDatabase)
|
SetPackageSet(s PackageDatabase)
|
||||||
World() ([]Package, error)
|
World() (Packages, error)
|
||||||
FindPackage(Package) (Package, error)
|
FindPackage(Package) (Package, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Packages []Package
|
||||||
|
|
||||||
// >> Unmarshallers
|
// >> Unmarshallers
|
||||||
// DefaultPackageFromYaml decodes a package from yaml bytes
|
// DefaultPackageFromYaml decodes a package from yaml bytes
|
||||||
func DefaultPackageFromYaml(yml []byte) (DefaultPackage, error) {
|
func DefaultPackageFromYaml(yml []byte) (DefaultPackage, error) {
|
||||||
@ -378,15 +379,15 @@ func (p *DefaultPackage) Matches(m Package) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error) {
|
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) (Packages, error) {
|
||||||
var versionsInWorld []Package
|
var versionsInWorld Packages
|
||||||
|
|
||||||
all, err := definitiondb.FindPackages(p)
|
all, err := definitiondb.FindPackages(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, w := range all {
|
for _, w := range all {
|
||||||
match, err := p.SelectorMatchVersion(w.GetVersion())
|
match, err := p.SelectorMatchVersion(w.GetVersion(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -398,8 +399,8 @@ func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error)
|
|||||||
return versionsInWorld, nil
|
return versionsInWorld, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) []Package {
|
func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) Packages {
|
||||||
var versionsInWorld []Package
|
var versionsInWorld Packages
|
||||||
for _, w := range definitiondb.World() {
|
for _, w := range definitiondb.World() {
|
||||||
if w.Matches(p) {
|
if w.Matches(p) {
|
||||||
continue
|
continue
|
||||||
@ -415,8 +416,8 @@ func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) []Package {
|
|||||||
return versionsInWorld
|
return versionsInWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) []Package {
|
func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) Packages {
|
||||||
var pkgsWithLabelInWorld []Package
|
var pkgsWithLabelInWorld Packages
|
||||||
// TODO: check if integrate some index to improve
|
// TODO: check if integrate some index to improve
|
||||||
// research instead of iterate all list.
|
// research instead of iterate all list.
|
||||||
for _, w := range definitiondb.World() {
|
for _, w := range definitiondb.World() {
|
||||||
@ -458,7 +459,13 @@ func (pack *DefaultPackage) RequiresContains(definitiondb PackageDatabase, s Pac
|
|||||||
return false, nil
|
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)
|
var versionsMap map[string]Package = make(map[string]Package)
|
||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
panic("Best needs a list with elements")
|
panic("Best needs a list with elements")
|
||||||
@ -469,17 +476,9 @@ func Best(set []Package) Package {
|
|||||||
versionsRaw = append(versionsRaw, p.GetVersion())
|
versionsRaw = append(versionsRaw, p.GetVersion())
|
||||||
versionsMap[p.GetVersion()] = p
|
versionsMap[p.GetVersion()] = p
|
||||||
}
|
}
|
||||||
|
sorted := v.Sort(versionsRaw)
|
||||||
|
|
||||||
versions := make([]*version.Version, len(versionsRaw))
|
return versionsMap[sorted[len(sorted)-1]]
|
||||||
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()]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db PackageDatabase) ([]bf.Formula, error) {
|
func (pack *DefaultPackage) BuildFormula(definitiondb PackageDatabase, db PackageDatabase) ([]bf.Formula, error) {
|
||||||
@ -750,3 +749,22 @@ end:
|
|||||||
|
|
||||||
return nil
|
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).To(ContainElement(a1))
|
||||||
Expect(lst).ToNot(ContainElement(a01))
|
Expect(lst).ToNot(ContainElement(a01))
|
||||||
Expect(len(lst)).To(Equal(2))
|
Expect(len(lst)).To(Equal(2))
|
||||||
p := Best(lst)
|
p := lst.Best(nil)
|
||||||
Expect(p).To(Equal(a11))
|
Expect(p).To(Equal(a11))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
toposort "github.com/philopon/go-toposort"
|
toposort "github.com/philopon/go-toposort"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/stevenle/topsort"
|
"github.com/stevenle/topsort"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ func (assertions PackagesAssertions) Search(f string) *PackageAssert {
|
|||||||
return nil
|
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{}
|
orderedAssertions := PackagesAssertions{}
|
||||||
unorderedAssertions := PackagesAssertions{}
|
unorderedAssertions := PackagesAssertions{}
|
||||||
@ -191,19 +192,19 @@ func (assertions PackagesAssertions) Order(definitiondb pkg.PackageDatabase, fin
|
|||||||
}
|
}
|
||||||
result, err := graph.TopSort(fingerprint)
|
result, err := graph.TopSort(fingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil, errors.Wrap(err, "fail on sorting "+fingerprint)
|
||||||
}
|
}
|
||||||
for _, res := range result {
|
for _, res := range result {
|
||||||
a, ok := tmpMap[res]
|
a, ok := tmpMap[res]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("fail looking for " + res)
|
return nil, errors.New("fail looking for " + res)
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
orderedAssertions = append(orderedAssertions, a)
|
orderedAssertions = append(orderedAssertions, a)
|
||||||
// orderedAssertions = append(PackagesAssertions{a}, orderedAssertions...) // push upfront
|
// orderedAssertions = append(PackagesAssertions{a}, orderedAssertions...) // push upfront
|
||||||
}
|
}
|
||||||
//helpers.ReverseAny(orderedAssertions)
|
//helpers.ReverseAny(orderedAssertions)
|
||||||
return orderedAssertions
|
return orderedAssertions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (assertions PackagesAssertions) Explain() string {
|
func (assertions PackagesAssertions) Explain() string {
|
||||||
|
@ -72,7 +72,8 @@ var _ = Describe("Decoder", func() {
|
|||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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(len(solution)).To(Equal(6))
|
||||||
Expect(solution[0].Package.GetName()).To(Equal("G"))
|
Expect(solution[0].Package.GetName()).To(Equal("G"))
|
||||||
Expect(solution[1].Package.GetName()).To(Equal("H"))
|
Expect(solution[1].Package.GetName()).To(Equal("H"))
|
||||||
@ -188,7 +189,8 @@ var _ = Describe("Decoder", func() {
|
|||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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(len(solution)).To(Equal(6))
|
||||||
Expect(solution[0].Package.GetName()).To(Equal("G"))
|
Expect(solution[0].Package.GetName()).To(Equal("G"))
|
||||||
Expect(solution[1].Package.GetName()).To(Equal("H"))
|
Expect(solution[1].Package.GetName()).To(Equal("H"))
|
||||||
@ -206,7 +208,8 @@ var _ = Describe("Decoder", func() {
|
|||||||
|
|
||||||
Expect(len(solution)).To(Equal(6))
|
Expect(len(solution)).To(Equal(6))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
solution = solution.Order(dbDefinitions, B.GetFingerPrint())
|
solution, err = solution.Order(dbDefinitions, B.GetFingerPrint())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
hash2 := solution.AssertionHash()
|
hash2 := solution.AssertionHash()
|
||||||
|
|
||||||
// Expect(len(solution)).To(Equal(6))
|
// Expect(len(solution)).To(Equal(6))
|
||||||
@ -243,7 +246,11 @@ var _ = Describe("Decoder", func() {
|
|||||||
|
|
||||||
solution2, err := s.Install([]pkg.Package{Z})
|
solution2, err := s.Install([]pkg.Package{Z})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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() {
|
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})
|
solution2, err := s.Install([]pkg.Package{Z})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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
|
Solver PackageSolver
|
||||||
Formula bf.Formula
|
Formula bf.Formula
|
||||||
|
|
||||||
Targets []pkg.Package
|
Targets pkg.Packages
|
||||||
Current []pkg.Package
|
Current pkg.Packages
|
||||||
|
|
||||||
observedDelta int
|
observedDelta int
|
||||||
observedDeltaChoice []pkg.Package
|
observedDeltaChoice pkg.Packages
|
||||||
|
|
||||||
Agent *qlearning.SimpleAgent
|
Agent *qlearning.SimpleAgent
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ func (resolver *QLearningResolver) Try(c Choice) error {
|
|||||||
packtoAdd := pkg.FromString(pack)
|
packtoAdd := pkg.FromString(pack)
|
||||||
resolver.Attempted[pack+strconv.Itoa(int(c.Action))] = true // increase the count
|
resolver.Attempted[pack+strconv.Itoa(int(c.Action))] = true // increase the count
|
||||||
s, _ := resolver.Solver.(*Solver)
|
s, _ := resolver.Solver.(*Solver)
|
||||||
var filtered []pkg.Package
|
var filtered pkg.Packages
|
||||||
|
|
||||||
switch c.Action {
|
switch c.Action {
|
||||||
case ActionAdded:
|
case ActionAdded:
|
||||||
|
@ -27,12 +27,12 @@ import (
|
|||||||
// PackageSolver is an interface to a generic package solving algorithm
|
// PackageSolver is an interface to a generic package solving algorithm
|
||||||
type PackageSolver interface {
|
type PackageSolver interface {
|
||||||
SetDefinitionDatabase(pkg.PackageDatabase)
|
SetDefinitionDatabase(pkg.PackageDatabase)
|
||||||
Install(p []pkg.Package) (PackagesAssertions, error)
|
Install(p pkg.Packages) (PackagesAssertions, error)
|
||||||
Uninstall(candidate pkg.Package, checkconflicts bool) ([]pkg.Package, error)
|
Uninstall(candidate pkg.Package, checkconflicts bool) (pkg.Packages, error)
|
||||||
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
ConflictsWithInstalled(p pkg.Package) (bool, error)
|
||||||
ConflictsWith(p pkg.Package, ls []pkg.Package) (bool, error)
|
ConflictsWith(p pkg.Package, ls pkg.Packages) (bool, error)
|
||||||
World() []pkg.Package
|
World() pkg.Packages
|
||||||
Upgrade(checkconflicts bool) ([]pkg.Package, PackagesAssertions, error)
|
Upgrade(checkconflicts bool) (pkg.Packages, PackagesAssertions, error)
|
||||||
|
|
||||||
SetResolver(PackageResolver)
|
SetResolver(PackageResolver)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ type PackageSolver interface {
|
|||||||
type Solver struct {
|
type Solver struct {
|
||||||
DefinitionDatabase pkg.PackageDatabase
|
DefinitionDatabase pkg.PackageDatabase
|
||||||
SolverDatabase pkg.PackageDatabase
|
SolverDatabase pkg.PackageDatabase
|
||||||
Wanted []pkg.Package
|
Wanted pkg.Packages
|
||||||
InstalledDatabase pkg.PackageDatabase
|
InstalledDatabase pkg.PackageDatabase
|
||||||
|
|
||||||
Resolver PackageResolver
|
Resolver PackageResolver
|
||||||
@ -72,11 +72,11 @@ func (s *Solver) SetResolver(r PackageResolver) {
|
|||||||
s.Resolver = r
|
s.Resolver = r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) World() []pkg.Package {
|
func (s *Solver) World() pkg.Packages {
|
||||||
return s.DefinitionDatabase.World()
|
return s.DefinitionDatabase.World()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) Installed() []pkg.Package {
|
func (s *Solver) Installed() pkg.Packages {
|
||||||
|
|
||||||
return s.InstalledDatabase.World()
|
return s.InstalledDatabase.World()
|
||||||
}
|
}
|
||||||
@ -130,8 +130,8 @@ func (s *Solver) BuildWorld(includeInstalled bool) (bf.Formula, error) {
|
|||||||
return bf.And(formulas...), nil
|
return bf.And(formulas...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Package, error) {
|
func (s *Solver) getList(db pkg.PackageDatabase, lsp pkg.Packages) (pkg.Packages, error) {
|
||||||
var ls []pkg.Package
|
var ls pkg.Packages
|
||||||
|
|
||||||
for _, pp := range lsp {
|
for _, pp := range lsp {
|
||||||
cp, err := db.FindPackage(pp)
|
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 {
|
if err != nil || len(packages) == 0 {
|
||||||
cp = pp
|
cp = pp
|
||||||
} else {
|
} else {
|
||||||
cp = pkg.Best(packages)
|
cp = packages.Best(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ls = append(ls, cp)
|
ls = append(ls, cp)
|
||||||
@ -149,7 +149,7 @@ func (s *Solver) getList(db pkg.PackageDatabase, lsp []pkg.Package) ([]pkg.Packa
|
|||||||
return ls, nil
|
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)
|
p, err := s.DefinitionDatabase.FindPackage(pack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = pack //Relax search, otherwise we cannot compute solutions for packages not in definitions
|
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())
|
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..
|
// First get candidates that needs to be upgraded..
|
||||||
|
|
||||||
toUninstall := []pkg.Package{}
|
toUninstall := pkg.Packages{}
|
||||||
toInstall := []pkg.Package{}
|
toInstall := pkg.Packages{}
|
||||||
|
|
||||||
availableCache := map[string][]pkg.Package{}
|
availableCache := map[string]pkg.Packages{}
|
||||||
for _, p := range s.DefinitionDatabase.World() {
|
for _, p := range s.DefinitionDatabase.World() {
|
||||||
// Each one, should be expanded
|
// Each one, should be expanded
|
||||||
availableCache[p.GetName()+p.GetCategory()] = append(availableCache[p.GetName()+p.GetCategory()], p)
|
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)
|
installedcopy.CreatePackage(p)
|
||||||
packages, ok := availableCache[p.GetName()+p.GetCategory()]
|
packages, ok := availableCache[p.GetName()+p.GetCategory()]
|
||||||
if ok && len(packages) != 0 {
|
if ok && len(packages) != 0 {
|
||||||
best := pkg.Best(packages)
|
best := packages.Best(nil)
|
||||||
if best.GetVersion() != p.GetVersion() {
|
if best.GetVersion() != p.GetVersion() {
|
||||||
toUninstall = append(toUninstall, p)
|
toUninstall = append(toUninstall, p)
|
||||||
toInstall = append(toInstall, best)
|
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
|
// 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.
|
// in order to purge the candidate. Returns error if unsat.
|
||||||
func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) ([]pkg.Package, error) {
|
func (s *Solver) Uninstall(c pkg.Package, checkconflicts bool) (pkg.Packages, error) {
|
||||||
var res []pkg.Package
|
var res pkg.Packages
|
||||||
candidate, err := s.InstalledDatabase.FindPackage(c)
|
candidate, err := s.InstalledDatabase.FindPackage(c)
|
||||||
if err != nil {
|
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 {
|
if err != nil || len(packages) == 0 {
|
||||||
candidate = c
|
candidate = c
|
||||||
} else {
|
} else {
|
||||||
candidate = pkg.Best(packages)
|
candidate = packages.Best(nil)
|
||||||
}
|
}
|
||||||
//Relax search, otherwise we cannot compute solutions for packages not in definitions
|
//Relax search, otherwise we cannot compute solutions for packages not in definitions
|
||||||
// return nil, errors.Wrap(err, "Package not found between installed")
|
// return nil, errors.Wrap(err, "Package not found between installed")
|
||||||
}
|
}
|
||||||
// Build a fake "Installed" - Candidate and its requires tree
|
// Build a fake "Installed" - Candidate and its requires tree
|
||||||
var InstalledMinusCandidate []pkg.Package
|
var InstalledMinusCandidate pkg.Packages
|
||||||
|
|
||||||
// TODO: Can be optimized
|
// TODO: Can be optimized
|
||||||
for _, i := range s.Installed() {
|
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 := NewSolver(pkg.NewInMemoryDatabase(false), s.DefinitionDatabase, pkg.NewInMemoryDatabase(false))
|
||||||
s2.SetResolver(s.Resolver)
|
s2.SetResolver(s.Resolver)
|
||||||
// Get the requirements to install the candidate
|
// Get the requirements to install the candidate
|
||||||
asserts, err := s2.Install([]pkg.Package{candidate})
|
asserts, err := s2.Install(pkg.Packages{candidate})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// 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
|
// 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)
|
coll, err := s.getList(s.DefinitionDatabase, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -882,7 +882,7 @@ var _ = Describe("Solver", func() {
|
|||||||
Expect(lst).To(ContainElement(a03))
|
Expect(lst).To(ContainElement(a03))
|
||||||
Expect(lst).ToNot(ContainElement(old))
|
Expect(lst).ToNot(ContainElement(old))
|
||||||
Expect(len(lst)).To(Equal(5))
|
Expect(len(lst)).To(Equal(5))
|
||||||
p := pkg.Best(lst)
|
p := lst.Best(nil)
|
||||||
Expect(p).To(Equal(a03))
|
Expect(p).To(Equal(a03))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -50,7 +50,7 @@ type GentooBuilder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EbuildParser interface {
|
type EbuildParser interface {
|
||||||
ScanEbuild(string) ([]pkg.Package, error)
|
ScanEbuild(string) (pkg.Packages, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gb *GentooBuilder) scanEbuild(path string, db pkg.PackageDatabase) error {
|
func (gb *GentooBuilder) scanEbuild(path string, db pkg.PackageDatabase) error {
|
||||||
|
@ -27,8 +27,8 @@ import (
|
|||||||
type FakeParser struct {
|
type FakeParser struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeParser) ScanEbuild(path string) ([]pkg.Package, error) {
|
func (f *FakeParser) ScanEbuild(path string) (pkg.Packages, error) {
|
||||||
return []pkg.Package{&pkg.DefaultPackage{Name: path}}, nil
|
return pkg.Packages{&pkg.DefaultPackage{Name: path}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("GentooBuilder", func() {
|
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.
|
// 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)
|
Debug("Starting parsing of ebuild", path)
|
||||||
|
|
||||||
pkgstr := filepath.Base(path)
|
pkgstr := filepath.Base(path)
|
||||||
@ -332,7 +332,7 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
|
|||||||
|
|
||||||
gp, err := _gentoo.ParsePackageStr(pkgstr)
|
gp, err := _gentoo.ParsePackageStr(pkgstr)
|
||||||
if err != nil {
|
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{
|
pack := &pkg.DefaultPackage{
|
||||||
@ -350,7 +350,7 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
|
|||||||
vars, err := SourceFile(timeout, path, gp)
|
vars, err := SourceFile(timeout, path, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Error("Error on source file ", pack.Name, ": ", err)
|
Error("Error on source file ", pack.Name, ": ", err)
|
||||||
return []pkg.Package{}, err
|
return pkg.Packages{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle this a bit better
|
// TODO: Handle this a bit better
|
||||||
@ -405,8 +405,8 @@ func (ep *SimpleEbuildParser) ScanEbuild(path string) ([]pkg.Package, error) {
|
|||||||
gRDEPEND, err := ParseRDEPEND(rdepend.String())
|
gRDEPEND, err := ParseRDEPEND(rdepend.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warning("Error on parsing RDEPEND for package ", pack.Category+"/"+pack.Name, err)
|
Warning("Error on parsing RDEPEND for package ", pack.Category+"/"+pack.Name, err)
|
||||||
return []pkg.Package{pack}, nil
|
return pkg.Packages{pack}, nil
|
||||||
// return []pkg.Package{}, err
|
// return pkg.Packages{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pack.PackageConflicts = []*pkg.DefaultPackage{}
|
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))
|
Debug("Finished processing ebuild", path, "deps ", len(pack.PackageRequires))
|
||||||
|
|
||||||
//TODO: Deps and conflicts
|
//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})
|
solution, err := s.Install([]pkg.Package{pack})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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].Package.GetName()).To(Equal("a"))
|
||||||
Expect(solution[0].Value).To(BeFalse())
|
Expect(solution[0].Value).To(BeFalse())
|
||||||
@ -137,7 +138,8 @@ var _ = Describe("Tree", func() {
|
|||||||
solution, err := s.Install([]pkg.Package{Dd})
|
solution, err := s.Install([]pkg.Package{Dd})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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"})
|
pack, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "a", Category: "test", Version: "1.0"})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
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
|
// You should have received a copy of the GNU General Public License along
|
||||||
// with this program; if not, see <http://www.gnu.org/licenses/>.
|
// with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package pkg
|
package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
version "github.com/hashicorp/go-version"
|
semver "github.com/hashicorp/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package Selector Condition
|
// Package Selector Condition
|
||||||
@ -162,7 +161,7 @@ func ParseVersion(v string) (PkgVersionSelector, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if build number is present
|
// Check if build number is present
|
||||||
buildIdx := strings.Index(v, "+")
|
buildIdx := strings.LastIndex(v, "+")
|
||||||
buildVersion := ""
|
buildVersion := ""
|
||||||
if buildIdx > 0 {
|
if buildIdx > 0 {
|
||||||
// <pre-release> ::= <dot-separated pre-release identifiers>
|
// <pre-release> ::= <dot-separated pre-release identifiers>
|
||||||
@ -252,8 +251,8 @@ func ParseVersion(v string) (PkgVersionSelector, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
|
func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
|
||||||
var v1 *version.Version = nil
|
var v1 *semver.Version = nil
|
||||||
var v2 *version.Version = nil
|
var v2 *semver.Version = nil
|
||||||
var ans bool
|
var ans bool
|
||||||
var err error
|
var err error
|
||||||
var sanitizedSelectorVersion, sanitizedIVersion string
|
var sanitizedSelectorVersion, sanitizedIVersion string
|
||||||
@ -262,14 +261,14 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
|
|||||||
// TODO: This is temporary!. I promise it.
|
// TODO: This is temporary!. I promise it.
|
||||||
sanitizedSelectorVersion = strings.ReplaceAll(selector.Version, "_", "-")
|
sanitizedSelectorVersion = strings.ReplaceAll(selector.Version, "_", "-")
|
||||||
|
|
||||||
v1, err = version.NewVersion(sanitizedSelectorVersion)
|
v1, err = semver.NewVersion(sanitizedSelectorVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if i.Version != "" {
|
if i.Version != "" {
|
||||||
sanitizedIVersion = strings.ReplaceAll(i.Version, "_", "-")
|
sanitizedIVersion = strings.ReplaceAll(i.Version, "_", "-")
|
||||||
v2, err = version.NewVersion(sanitizedIVersion)
|
v2, err = semver.NewVersion(sanitizedIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -307,7 +306,7 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
|
|||||||
segments[len(segments)-1]++
|
segments[len(segments)-1]++
|
||||||
}
|
}
|
||||||
nextVersion := strings.Trim(strings.Replace(fmt.Sprint(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),
|
fmt.Sprintf(">= %s, < %s", sanitizedSelectorVersion, nextVersion),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -335,35 +334,3 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
|
|||||||
|
|
||||||
return ans, nil
|
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
|
// You should have received a copy of the GNU General Public License along
|
||||||
// with this program; if not, see <http://www.gnu.org/licenses/>.
|
// with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package pkg_test
|
package version_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
|
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/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "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 (
|
const (
|
||||||
RegexCatString = `(^[a-z]+[0-9]*[a-z]*[-]*[a-z]+[0-9]*[a-z]*|^virtual)`
|
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 {
|
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/Microsoft/hcsshim/internal/safefile
|
||||||
# github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
|
# github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
|
||||||
github.com/Nvveen/Gotty
|
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/Sabayon/pkgs-checker/pkg/gentoo
|
||||||
# github.com/apex/log v1.1.1
|
# github.com/apex/log v1.1.1
|
||||||
github.com/apex/log
|
github.com/apex/log
|
||||||
@ -141,6 +141,8 @@ github.com/klauspost/compress/flate
|
|||||||
github.com/klauspost/cpuid
|
github.com/klauspost/cpuid
|
||||||
# github.com/klauspost/pgzip v1.2.1
|
# github.com/klauspost/pgzip v1.2.1
|
||||||
github.com/klauspost/pgzip
|
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 v1.0.2
|
||||||
github.com/konsorten/go-windows-terminal-sequences
|
github.com/konsorten/go-windows-terminal-sequences
|
||||||
# github.com/kyokomi/emoji v2.1.0+incompatible
|
# github.com/kyokomi/emoji v2.1.0+incompatible
|
||||||
|
Loading…
Reference in New Issue
Block a user