mirror of
https://github.com/mudler/luet.git
synced 2025-09-02 15:54:39 +00:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
956e55a1d4 | ||
|
9971fe9f45 | ||
|
11759f98e0 | ||
|
cb2ac15de8 | ||
|
c0b432befa |
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
|
@@ -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)))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user