Compare commits

...

5 Commits
0.7.8 ... 0.7.9

Author SHA1 Message Date
Ettore Di Giacinto
956e55a1d4 Tag 0.7.9 2020-05-19 23:04:28 +02:00
Ettore Di Giacinto
9971fe9f45 Unique hashes for packages without deps 2020-05-18 19:57:01 +02:00
Daniele Rondina
11759f98e0 package/NewPackage: init Labels on AddLabel 2020-05-18 19:51:47 +02:00
Daniele Rondina
cb2ac15de8 package: Fix typo on labels key 2020-05-17 19:17:14 +02:00
Ettore Di Giacinto
c0b432befa Add development version 2020-05-16 22:46:29 +02:00
5 changed files with 165 additions and 5 deletions

View File

@@ -38,7 +38,7 @@ var Verbose bool
var LockedCommands = []string{"install", "uninstall", "upgrade"} var LockedCommands = []string{"install", "uninstall", "upgrade"}
const ( const (
LuetCLIVersion = "0.7.8" LuetCLIVersion = "0.7.9"
LuetEnvPrefix = "LUET" LuetEnvPrefix = "LUET"
) )

View File

@@ -468,7 +468,7 @@ func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssert
nthsolution := dependencies.Cut(assertion.Package) nthsolution := dependencies.Cut(assertion.Package)
assertion.Hash = solver.PackageHash{ assertion.Hash = solver.PackageHash{
BuildHash: nthsolution.Drop(assertion.Package).AssertionHash(), BuildHash: nthsolution.HashFrom(assertion.Package),
PackageHash: nthsolution.AssertionHash(), PackageHash: nthsolution.AssertionHash(),
} }
assertions = append(assertions, assertion) assertions = append(assertions, assertion)

View File

@@ -59,6 +59,7 @@ type Package interface {
SetCategory(string) SetCategory(string)
GetName() string GetName() string
SetName(string)
GetCategory() string GetCategory() string
GetVersion() string GetVersion() string
@@ -98,6 +99,8 @@ type Package interface {
String() string String() string
HumanReadableString() string HumanReadableString() string
HashFingerprint() string HashFingerprint() string
Clone() Package
} }
type Tree interface { type Tree interface {
@@ -163,7 +166,7 @@ type DefaultPackage struct {
Uri []string `json:"uri,omitempty"` Uri []string `json:"uri,omitempty"`
License string `json:"license,omitempty"` License string `json:"license,omitempty"`
Labels map[string]string `json:labels,omitempty` Labels map[string]string `json:"labels,omitempty"` // Affects YAML field names too.
} }
// State represent the package state // State represent the package state
@@ -176,7 +179,7 @@ func NewPackage(name, version string, requires []*DefaultPackage, conflicts []*D
Version: version, Version: version,
PackageRequires: requires, PackageRequires: requires,
PackageConflicts: conflicts, PackageConflicts: conflicts,
Labels: make(map[string]string, 0), Labels: nil,
} }
} }
@@ -287,7 +290,6 @@ func (p *DefaultPackage) Encode(db PackageDatabase) (string, error) {
func (p *DefaultPackage) Yaml() ([]byte, error) { func (p *DefaultPackage) Yaml() ([]byte, error) {
j, err := p.JSON() j, err := p.JSON()
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
} }
y, err := yaml.JSONToYAML(j) y, err := yaml.JSONToYAML(j)
@@ -338,10 +340,18 @@ func (p *DefaultPackage) GetCategory() string {
func (p *DefaultPackage) SetCategory(s string) { func (p *DefaultPackage) SetCategory(s string) {
p.Category = s p.Category = s
} }
func (p *DefaultPackage) SetName(s string) {
p.Name = s
}
func (p *DefaultPackage) GetUses() []string { func (p *DefaultPackage) GetUses() []string {
return p.UseFlags return p.UseFlags
} }
func (p *DefaultPackage) AddLabel(k, v string) { func (p *DefaultPackage) AddLabel(k, v string) {
if p.Labels == nil {
p.Labels = make(map[string]string, 0)
}
p.Labels[k] = v p.Labels[k] = v
} }
func (p *DefaultPackage) GetLabels() map[string]string { func (p *DefaultPackage) GetLabels() map[string]string {

View File

@@ -251,6 +251,34 @@ func (a PackagesAssertions) Less(i, j int) bool {
} }
func (a PackagesAssertions) TrueLen() int {
count := 0
for _, ass := range a {
if ass.Value {
count++
}
}
return count
}
// HashFrom computes the assertion hash From a given package. It drops it from the assertions
// and checks it's not the only one. if it's unique it marks it specially - so the hash
// which is generated is unique for the selected package
func (assertions PackagesAssertions) HashFrom(p pkg.Package) string {
var assertionhash string
// When we don't have any solution to hash for, we need to generate an UUID by ourselves
latestsolution := assertions.Drop(p)
if latestsolution.TrueLen() == 0 {
assertionhash = assertions.Mark(p).AssertionHash()
} else {
assertionhash = latestsolution.AssertionHash()
}
return assertionhash
}
func (assertions PackagesAssertions) AssertionHash() string { func (assertions PackagesAssertions) AssertionHash() string {
var fingerprint string var fingerprint string
for _, assertion := range assertions { // Note: Always order them first! for _, assertion := range assertions { // Note: Always order them first!
@@ -287,3 +315,18 @@ func (assertions PackagesAssertions) Cut(p pkg.Package) PackagesAssertions {
} }
return ass return ass
} }
// Mark returns a new assertion with the package marked
func (assertions PackagesAssertions) Mark(p pkg.Package) PackagesAssertions {
ass := PackagesAssertions{}
for _, a := range assertions {
if a.Package.Matches(p) {
marked := a.Package.Clone()
marked.SetName("@@" + marked.GetName())
a = PackageAssert{Package: marked.(*pkg.DefaultPackage), Value: a.Value, Hash: a.Hash}
}
ass = append(ass, a)
}
return ass
}

View File

@@ -19,6 +19,7 @@ import (
"strconv" "strconv"
pkg "github.com/mudler/luet/pkg/package" pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@@ -283,5 +284,111 @@ var _ = Describe("Decoder", func() {
Expect(orderY.Cut(Y).Drop(Y).AssertionHash()).To(Equal(orderZ.Cut(Z).Drop(Z).AssertionHash())) Expect(orderY.Cut(Y).Drop(Y).AssertionHash()).To(Equal(orderZ.Cut(Z).Drop(Z).AssertionHash()))
}) })
It("HashFrom can be used equally", func() {
X := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
Y := pkg.NewPackage("Y", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
Z := pkg.NewPackage("Z", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
for _, p := range []pkg.Package{X, Y, Z} {
_, err := dbDefinitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
for _, p := range []pkg.Package{} {
_, err := dbInstalled.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
solution, err := s.Install([]pkg.Package{Y})
Expect(err).ToNot(HaveOccurred())
solution2, err := s.Install([]pkg.Package{Z})
Expect(err).ToNot(HaveOccurred())
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(orderY.Cut(Y).HashFrom(Y)).To(Equal(orderZ.Cut(Z).HashFrom(Z)))
})
It("Unique hashes for single packages", func() {
X := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
F := pkg.NewPackage("F", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
for _, p := range []pkg.Package{X, F, D} {
_, err := dbDefinitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
for _, p := range []pkg.Package{} {
_, err := dbInstalled.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
solution, err := s.Install([]pkg.Package{X})
Expect(err).ToNot(HaveOccurred())
solution2, err := s.Install([]pkg.Package{F})
Expect(err).ToNot(HaveOccurred())
solution3, err := s.Install([]pkg.Package{D})
Expect(err).ToNot(HaveOccurred())
Expect(solution.AssertionHash()).ToNot(Equal(solution2.AssertionHash()))
Expect(solution3.AssertionHash()).To(Equal(solution.AssertionHash()))
})
It("Unique hashes for empty assertions", func() {
empty := solver.PackagesAssertions{}
empty2 := solver.PackagesAssertions{}
Expect(empty.AssertionHash()).To(Equal(empty2.AssertionHash()))
})
It("Unique hashes for single packages with HashFrom", func() {
X := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
F := pkg.NewPackage("F", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D := pkg.NewPackage("X", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
Y := pkg.NewPackage("Y", "", []*pkg.DefaultPackage{X}, []*pkg.DefaultPackage{})
empty := solver.PackagesAssertions{}
for _, p := range []pkg.Package{X, F, D, Y} {
_, err := dbDefinitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
for _, p := range []pkg.Package{} {
_, err := dbInstalled.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
solution, err := s.Install([]pkg.Package{X})
Expect(err).ToNot(HaveOccurred())
solution2, err := s.Install([]pkg.Package{F})
Expect(err).ToNot(HaveOccurred())
solution3, err := s.Install([]pkg.Package{D})
Expect(err).ToNot(HaveOccurred())
solution4, err := s.Install([]pkg.Package{Y})
Expect(err).ToNot(HaveOccurred())
Expect(solution.HashFrom(X)).ToNot(Equal(solution2.HashFrom(F)))
Expect(solution3.HashFrom(D)).To(Equal(solution.HashFrom(X)))
Expect(empty.AssertionHash()).ToNot(Equal(solution3.HashFrom(D)))
Expect(empty.AssertionHash()).ToNot(Equal(solution2.HashFrom(F)))
Expect(solution4.Drop(Y).AssertionHash()).To(Equal(solution4.HashFrom(Y)))
})
}) })
}) })