Compare commits

..

35 Commits
0.6.4 ... 0.7

Author SHA1 Message Date
Ettore Di Giacinto
3c5e144b8d Tag 0.7 2020-03-21 21:39:12 +01:00
Ettore Di Giacinto
44aa69928a Merge pull request #69 from mudler/add-pkg-labels
Added `labels` to package definition
2020-03-21 21:37:42 +01:00
Daniele Rondina
c7652c8a70 Added labels to package definition
* cmd/search: Add support for search of the packages
  with a specific label.

* review Search method of Repositories for permit
  different search modes.

* labels are k/v attributes and could be matched
  through label key (with HasLabel method) or through
  regex that use "$key" + "=" + "$value"
2020-03-21 19:24:27 +01:00
Ettore Di Giacinto
fab2d21ac1 Drop unused function 2020-03-19 22:39:22 +01:00
Ettore Di Giacinto
487239334f Treat base case with same algorithm of dependencies 2020-03-19 22:37:39 +01:00
Ettore Di Giacinto
69477a0c36 Make uniform build of seeds and packages 2020-03-19 22:34:26 +01:00
Ettore Di Giacinto
67362a3bc1 Drop unused condition 2020-03-19 22:29:34 +01:00
Ettore Di Giacinto
302d18e749 Tag the target image with the computed hash 2020-03-19 22:28:33 +01:00
geaaru
9047e13d21 Merge pull request #68 from mudler/tree-bump
Tree bump
2020-03-16 22:57:14 +01:00
Daniele Rondina
0249c0fa4a version: Add temporary workaround for handle build string with _ 2020-03-16 22:18:48 +01:00
Daniele Rondina
fc40c770ab Add 'tree bump' command 2020-03-16 22:18:48 +01:00
Ettore Di Giacinto
4357ee45e9 Drop unused functions in package 2020-03-16 18:08:46 +01:00
Daniele Rondina
6ce9a86245 Update vendor github.com/Sabayon/pkgs-checker@b6efed54b4b1 2020-03-16 00:37:31 +01:00
Daniele Rondina
853a1995b4 cmd/tree/validate: Now support multiple tree paths 2020-03-15 19:16:22 +01:00
Daniele Rondina
039b77fdfd cmd/tree/validate: Add counter of broken deps 2020-03-15 17:40:20 +01:00
Ettore Di Giacinto
050d9b3095 Adapt to image based on debian instead of alpine for fixture 2020-03-15 15:30:27 +01:00
Ettore Di Giacinto
4985ff7b5a Use standard golang image for fixture (alpine doesn't contain gcc) 2020-03-15 15:42:24 +01:00
Ettore Di Giacinto
6f138811dd Make recipes idempotent, allowing to load multiple trees 2020-03-15 13:31:12 +01:00
Daniele Rondina
f02c54a274 cmd/tree/validate: Improve scripting integration 2020-03-14 17:38:57 +01:00
Daniele Rondina
d6182cba3b Add cli command 'tree validate' 2020-03-14 11:14:14 +01:00
Daniele Rondina
bc5c0fa0cf cmd/tree/pkglist: Cleanup code 2020-03-14 11:14:14 +01:00
Ettore Di Giacinto
dc64dbff75 Don't try to solve finalizers with --nodeps 2020-03-13 19:32:00 +01:00
Daniele Rondina
a94e430a3b cmd/tree/pkglist: Add --matches/-m flag 2020-03-13 18:08:49 +01:00
Daniele Rondina
93f8f0dd0f solver: Add category to tests 2020-03-12 00:26:53 +01:00
Daniele Rondina
7bdcc72dd3 Update vendor github.com/Sabayon/pkgs-checker@f4e0aec412f0 2020-03-11 08:38:15 +01:00
Daniele Rondina
e47c07d438 Update vendor github.com/Sabayon/pkgs-checker@935615ba9d27 2020-03-10 09:12:22 +01:00
Daniele Rondina
6fc5d1a97b Upgrade vendor github.com/Sabayon/pkgs-checker@v0.6.1 2020-03-09 23:35:01 +01:00
Daniele Rondina
f4a5a97cff tree/compiler_recipe: Return right error message 2020-03-08 16:28:12 +01:00
Daniele Rondina
8c972403a3 tree/compiler_recipe: Handle invalid tree path
If instead of abs path is used bash annotation
now return an error related to wrong directory
supply.
2020-03-08 15:47:40 +01:00
Daniele Rondina
82a17a1a22 Drop cfgFile print to improve bash integration 2020-03-08 00:13:45 +01:00
Daniele Rondina
17238d187a Change 'Skip dir' message to debug 2020-03-08 00:07:20 +01:00
Daniele Rondina
ad011e937f cmd/tree/pkglist: Fix init of regExcludes 2020-03-06 17:54:26 +01:00
Daniele Rondina
25c796c430 Add 'tree pkglist' command cli 2020-03-06 17:51:04 +01:00
Daniele Rondina
df5499393f --verbose/-v is now --debug/-d 2020-03-06 16:53:36 +01:00
Ettore Di Giacinto
026ddf6fc9 Add dev version tag 2020-03-05 18:37:16 +01:00
33 changed files with 1190 additions and 230 deletions

View File

@@ -37,7 +37,7 @@ var cfgFile string
var Verbose bool
const (
LuetCLIVersion = "0.6.4"
LuetCLIVersion = "0.7"
LuetEnvPrefix = "LUET"
)
@@ -122,7 +122,7 @@ func init() {
cobra.OnInitialize(initConfig)
pflags := RootCmd.PersistentFlags()
pflags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.luet.yaml)")
pflags.BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
pflags.BoolP("debug", "d", false, "verbose output")
pflags.Bool("fatal", false, "Enables Warnings to exit")
u, err := user.Current()
@@ -137,7 +137,7 @@ func init() {
pflags.Int("concurrency", runtime.NumCPU(), "Concurrency")
config.LuetCfg.Viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner"))
config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("verbose"))
config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("debug"))
config.LuetCfg.Viper.BindPFlag("general.concurrency", pflags.Lookup("concurrency"))
config.LuetCfg.Viper.BindPFlag("general.fatal_warnings", pflags.Lookup("fatal"))
}
@@ -154,7 +154,6 @@ func initConfig() {
viper.SetConfigType("yaml")
viper.SetConfigName(".luet") // name of config file (without extension)
if cfgFile != "" { // enable ability to specify config file via flag
Info(">>> cfgFile: ", cfgFile)
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath(dir)

View File

@@ -17,7 +17,6 @@ package cmd
import (
"os"
"path/filepath"
"regexp"
. "github.com/mudler/luet/pkg/config"
installer "github.com/mudler/luet/pkg/installer"
@@ -51,6 +50,8 @@ var searchCmd = &cobra.Command{
discount := LuetCfg.Viper.GetFloat64("solver.discount")
rate := LuetCfg.Viper.GetFloat64("solver.rate")
attempts := LuetCfg.Viper.GetInt("solver.max_attempts")
searchWithLabel, _ := cmd.Flags().GetBool("by-label")
searchWithLabelMatch, _ := cmd.Flags().GetBool("by-label-regex")
LuetCfg.GetSolverOptions().Type = stype
LuetCfg.GetSolverOptions().LearnRate = float32(rate)
@@ -70,8 +71,12 @@ var searchCmd = &cobra.Command{
repos = append(repos, r)
}
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{Concurrency: LuetCfg.GetGeneral().Concurrency, SolverOptions: *LuetCfg.GetSolverOptions()})
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: LuetCfg.GetGeneral().Concurrency,
SolverOptions: *LuetCfg.GetSolverOptions(),
},
)
inst.Repositories(repos)
synced, err := inst.SyncRepositories(false)
if err != nil {
@@ -80,7 +85,14 @@ var searchCmd = &cobra.Command{
Info("--- Search results: ---")
matches := synced.Search(args[0])
matches := []installer.PackageMatch{}
if searchWithLabel {
matches = synced.SearchLabel(args[0])
} else if searchWithLabelMatch {
matches = synced.SearchLabelMatch(args[0])
} else {
matches = synced.Search(args[0])
}
for _, m := range matches {
Info(":package:", m.Package.GetCategory(), m.Package.GetName(),
m.Package.GetVersion(), "repository:", m.Repo.GetName())
@@ -94,14 +106,25 @@ var searchCmd = &cobra.Command{
systemDB = pkg.NewInMemoryDatabase(true)
}
system := &installer.System{Database: systemDB, Target: LuetCfg.GetSystem().Rootfs}
var term = regexp.MustCompile(args[0])
for _, k := range system.Database.GetPackages() {
pack, err := system.Database.GetPackage(k)
if err == nil && term.MatchString(pack.GetName()) {
Info(":package:", pack.GetCategory(), pack.GetName(), pack.GetVersion())
}
var err error
iMatches := []pkg.Package{}
if searchWithLabel {
iMatches, err = system.Database.FindPackageLabel(args[0])
} else if searchWithLabelMatch {
iMatches, err = system.Database.FindPackageLabelMatch(args[0])
} else {
iMatches, err = system.Database.FindPackageMatch(args[0])
}
if err != nil {
Fatal("Error: " + err.Error())
}
for _, pack := range iMatches {
Info(":package:", pack.GetCategory(), pack.GetName(), pack.GetVersion())
}
}
},
@@ -119,5 +142,7 @@ func init() {
searchCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
searchCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
searchCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
searchCmd.Flags().Bool("by-label", false, "Search packages through label")
searchCmd.Flags().Bool("by-label-regex", false, "Search packages through label regex")
RootCmd.AddCommand(searchCmd)
}

38
cmd/tree.go Normal file
View File

@@ -0,0 +1,38 @@
// Copyright © 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 cmd
import (
. "github.com/mudler/luet/cmd/tree"
"github.com/spf13/cobra"
)
var treeGroupCmd = &cobra.Command{
Use: "tree [command] [OPTIONS]",
Short: "Tree operations",
}
func init() {
RootCmd.AddCommand(treeGroupCmd)
treeGroupCmd.AddCommand(
NewTreePkglistCommand(),
NewTreeValidateCommand(),
NewTreeBumpCommand(),
)
}

67
cmd/tree/bump.go Normal file
View File

@@ -0,0 +1,67 @@
// Copyright © 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 cmd_tree
import (
"fmt"
//"os"
//"sort"
. "github.com/mudler/luet/pkg/logger"
tree "github.com/mudler/luet/pkg/tree"
"github.com/spf13/cobra"
)
func NewTreeBumpCommand() *cobra.Command {
var ans = &cobra.Command{
Use: "bump [OPTIONS]",
Short: "Bump a new package build version.",
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
df, _ := cmd.Flags().GetString("definition-file")
if df == "" {
Fatal("Mandatory definition.yaml path missing.")
}
},
Run: func(cmd *cobra.Command, args []string) {
spec, _ := cmd.Flags().GetString("definition-file")
pack, err := tree.ReadDefinitionFile(spec)
if err != nil {
Fatal(err.Error())
}
// Retrieve version build section with Gentoo parser
err = pack.BumpBuildVersion()
if err != nil {
Fatal("Error on increment build version: " + err.Error())
}
err = tree.WriteDefinitionFile(&pack, spec)
if err != nil {
Fatal("Error on write definition file: " + err.Error())
}
fmt.Printf("Bumped package %s/%s-%s.\n", pack.Category, pack.Name, pack.Version)
},
}
ans.Flags().StringP("definition-file", "f", "", "Path of the definition to bump.")
return ans
}

140
cmd/tree/pkglist.go Normal file
View File

@@ -0,0 +1,140 @@
// Copyright © 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 cmd_tree
import (
"fmt"
"sort"
//. "github.com/mudler/luet/pkg/config"
helpers "github.com/mudler/luet/pkg/helpers"
. "github.com/mudler/luet/pkg/logger"
pkg "github.com/mudler/luet/pkg/package"
tree "github.com/mudler/luet/pkg/tree"
"github.com/spf13/cobra"
)
func pkgDetail(pkg pkg.Package) string {
ans := fmt.Sprintf(`
@@ Package: %s/%s-%s
Description: %s
License: %s`,
pkg.GetCategory(), pkg.GetName(), pkg.GetVersion(),
pkg.GetDescription(), pkg.GetLicense())
for idx, u := range pkg.GetURI() {
if idx == 0 {
ans += fmt.Sprintf(" URLs: %s", u)
} else {
ans += fmt.Sprintf(" %s", u)
}
}
return ans
}
func NewTreePkglistCommand() *cobra.Command {
var excludes []string
var matches []string
var ans = &cobra.Command{
Use: "pkglist [OPTIONS]",
Short: "List of the packages found in tree.",
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
t, _ := cmd.Flags().GetString("tree")
if t == "" {
Fatal("Mandatory tree param missing.")
}
},
Run: func(cmd *cobra.Command, args []string) {
treePath, _ := cmd.Flags().GetString("tree")
verbose, _ := cmd.Flags().GetBool("verbose")
full, _ := cmd.Flags().GetBool("full")
reciper := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false))
err := reciper.Load(treePath)
if err != nil {
Fatal("Error on load tree ", err)
}
regExcludes, err := helpers.CreateRegexArray(excludes)
if err != nil {
Fatal(err.Error())
}
regMatches, err := helpers.CreateRegexArray(matches)
if err != nil {
Fatal(err.Error())
}
plist := make([]string, 0)
for _, p := range reciper.GetDatabase().World() {
pkgstr := ""
addPkg := true
if full {
pkgstr = pkgDetail(p)
} else if verbose {
pkgstr = fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(), p.GetVersion())
} else {
pkgstr = fmt.Sprintf("%s/%s", p.GetCategory(), p.GetName())
}
if len(matches) > 0 {
matched := false
for _, rgx := range regMatches {
if rgx.MatchString(pkgstr) {
matched = true
break
}
}
if !matched {
addPkg = false
}
}
if len(excludes) > 0 && addPkg {
for _, rgx := range regExcludes {
if rgx.MatchString(pkgstr) {
addPkg = false
break
}
}
}
if addPkg {
plist = append(plist, pkgstr)
}
}
sort.Strings(plist)
for _, p := range plist {
fmt.Println(p)
}
},
}
ans.Flags().BoolP("verbose", "v", false, "Add package version")
ans.Flags().BoolP("full", "f", false, "Show package detail")
ans.Flags().StringP("tree", "t", "", "Path of the tree to use.")
ans.Flags().StringSliceVarP(&matches, "matches", "m", []string{},
"Include only matched packages from list. (Use string as regex).")
ans.Flags().StringSliceVarP(&excludes, "exclude", "e", []string{},
"Exclude matched packages from list. (Use string as regex).")
return ans
}

212
cmd/tree/validate.go Normal file
View File

@@ -0,0 +1,212 @@
// Copyright © 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 cmd_tree
import (
"fmt"
"os"
"sort"
//. "github.com/mudler/luet/pkg/config"
helpers "github.com/mudler/luet/pkg/helpers"
. "github.com/mudler/luet/pkg/logger"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
tree "github.com/mudler/luet/pkg/tree"
"github.com/spf13/cobra"
)
func NewTreeValidateCommand() *cobra.Command {
var excludes []string
var matches []string
var treePaths []string
var ans = &cobra.Command{
Use: "validate [OPTIONS]",
Short: "Validate a tree or a list of packages",
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
if len(treePaths) < 1 {
Fatal("Mandatory tree param missing.")
}
},
Run: func(cmd *cobra.Command, args []string) {
var depSolver solver.PackageSolver
var errstr string
errors := make([]string, 0)
brokenPkgs := 0
brokenDeps := 0
withSolver, _ := cmd.Flags().GetBool("with-solver")
reciper := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false))
for _, treePath := range treePaths {
err := reciper.Load(treePath)
if err != nil {
Fatal("Error on load tree ", err)
}
}
emptyInstallationDb := pkg.NewInMemoryDatabase(false)
if withSolver {
depSolver = solver.NewSolver(pkg.NewInMemoryDatabase(false),
reciper.GetDatabase(),
emptyInstallationDb)
}
regExcludes, err := helpers.CreateRegexArray(excludes)
if err != nil {
Fatal(err.Error())
}
regMatches, err := helpers.CreateRegexArray(matches)
if err != nil {
Fatal(err.Error())
}
for _, p := range reciper.GetDatabase().World() {
pkgstr := fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(),
p.GetVersion())
validpkg := true
if len(matches) > 0 {
matched := false
for _, rgx := range regMatches {
if rgx.MatchString(pkgstr) {
matched = true
break
}
}
if !matched {
continue
}
}
if len(excludes) > 0 {
excluded := false
for _, rgx := range regExcludes {
if rgx.MatchString(pkgstr) {
excluded = true
break
}
}
if excluded {
continue
}
}
Info("Checking package "+fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(), p.GetVersion()), "with", len(p.GetRequires()), "dependencies.")
for _, r := range p.GetRequires() {
deps, err := reciper.GetDatabase().FindPackages(
&pkg.DefaultPackage{
Name: r.GetName(),
Category: r.GetCategory(),
Version: r.GetVersion(),
},
)
if err != nil || len(deps) < 1 {
if err != nil {
errstr = err.Error()
} else {
errstr = "No packages"
}
Error(fmt.Sprintf("%s/%s-%s: Broken Dep %s/%s-%s - %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
r.GetCategory(), r.GetName(), r.GetVersion(),
errstr,
))
errors = append(errors,
fmt.Sprintf("%s/%s-%s: Broken Dep %s/%s-%s - %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
r.GetCategory(), r.GetName(), r.GetVersion(),
errstr))
brokenDeps++
validpkg = false
} else {
Debug("Find packages for dep",
fmt.Sprintf("%s/%s-%s", r.GetCategory(), r.GetName(), r.GetVersion()))
if withSolver {
Spinner(32)
_, err := depSolver.Install([]pkg.Package{r})
SpinnerStop()
if err != nil {
Error(fmt.Sprintf("%s/%s-%s: solver broken for dep %s/%s-%s - %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
r.GetCategory(), r.GetName(), r.GetVersion(),
err.Error(),
))
errors = append(errors,
fmt.Sprintf("%s/%s-%s: solver broken for Dep %s/%s-%s - %s",
p.GetCategory(), p.GetName(), p.GetVersion(),
r.GetCategory(), r.GetName(), r.GetVersion(),
err.Error()))
brokenDeps++
validpkg = false
}
}
}
}
if !validpkg {
brokenPkgs++
}
}
sort.Strings(errors)
for _, e := range errors {
fmt.Println(e)
}
fmt.Println("Broken packages:", brokenPkgs, "(", brokenDeps, "deps ).")
if brokenPkgs > 0 {
os.Exit(1)
} else {
os.Exit(0)
}
},
}
ans.Flags().BoolP("with-solver", "s", false,
"Enable check of requires also with solver.")
ans.Flags().StringSliceVarP(&treePaths, "tree", "t", []string{},
"Path of the tree to use.")
ans.Flags().StringSliceVarP(&excludes, "exclude", "e", []string{},
"Exclude matched packages from analysis. (Use string as regex).")
ans.Flags().StringSliceVarP(&matches, "matches", "m", []string{},
"Analyze only matched packages. (Use string as regex).")
return ans
}

3
go.mod
View File

@@ -5,7 +5,7 @@ go 1.12
require (
github.com/DataDog/zstd v1.4.4 // indirect
github.com/MottainaiCI/simplestreams-builder v0.0.0-20190710131531-efb382161f56 // indirect
github.com/Sabayon/pkgs-checker v0.5.1-0.20200221202320-073693f2c657
github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1
github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154
github.com/briandowns/spinner v1.7.0
github.com/cavaliercoder/grab v2.0.0+incompatible
@@ -22,6 +22,7 @@ require (
github.com/logrusorgru/aurora v0.0.0-20190417123914-21d75270181e
github.com/marcsauter/single v0.0.0-20181104081128-f8bf46f26ec0
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mudler/docker-companion v0.4.6-0.20191110154655-b8b364100616
github.com/onsi/ginkgo v1.10.1
github.com/onsi/gomega v1.7.0

10
go.sum
View File

@@ -19,6 +19,14 @@ github.com/Sabayon/pkgs-checker v0.4.2-0.20200101193228-1d500105afb7/go.mod h1:G
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/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -177,6 +185,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=

View File

@@ -429,82 +429,6 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
return artifact, nil
}
func (cs *LuetCompiler) packageFromImage(p CompilationSpec, tag string, keepPermissions, keepImg bool, concurrency int) (Artifact, error) {
if !cs.Clean {
if art, err := LoadArtifactFromYaml(p); err == nil {
Debug("Artifact reloaded. Skipping build")
return art, err
}
}
pkgTag := ":package: " + p.GetPackage().HumanReadableString()
Info(pkgTag, " 🍩 Build starts 🔨 🔨 🔨 ")
builderOpts := CompilerBackendOptions{
ImageName: p.GetImage(),
Destination: p.Rel(p.GetPackage().GetFingerPrint() + ".image.tar"),
}
err := cs.Backend.DownloadImage(builderOpts)
if err != nil {
return nil, errors.Wrap(err, "Could not download image")
}
if tag != "" {
err = cs.Backend.CopyImage(p.GetImage(), tag)
if err != nil {
return nil, errors.Wrap(err, "Could not download image")
}
}
err = cs.Backend.ExportImage(builderOpts)
if err != nil {
return nil, errors.Wrap(err, "Could not export image")
}
if !cs.Options.KeepImageExport {
defer os.Remove(builderOpts.Destination)
}
rootfs, err := ioutil.TempDir(p.GetOutputPath(), "rootfs")
if err != nil {
return nil, errors.Wrap(err, "Could not create tempdir")
}
defer os.RemoveAll(rootfs) // clean up
// TODO: Compression and such
err = cs.Backend.ExtractRootfs(CompilerBackendOptions{
ImageName: p.GetImage(),
SourcePath: builderOpts.Destination, Destination: rootfs}, keepPermissions)
if err != nil {
return nil, errors.Wrap(err, "Could not extract rootfs")
}
artifact := NewPackageArtifact(p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar"))
artifact.SetCompileSpec(p)
artifact.SetCompressionType(cs.CompressionType)
err = artifact.Compress(rootfs, concurrency)
if err != nil {
return nil, errors.Wrap(err, "Error met while creating package archive")
}
if !keepImg {
// We keep them around, so to not reload them from the tar (which should be the "correct way") and we automatically share the same layers
// TODO: Handle caching and optionally do not remove things
err = cs.Backend.RemoveImage(builderOpts)
if err != nil {
Warning("Could not remove image ", builderOpts.ImageName)
// return nil, errors.Wrap(err, "Could not remove image")
}
}
Info(pkgTag, " :white_check_mark: Done")
err = artifact.WriteYaml(p.GetOutputPath())
if err != nil {
return artifact, err
}
return artifact, nil
}
func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssertions, error) {
s := solver.NewResolver(pkg.NewInMemoryDatabase(false), cs.Database, pkg.NewInMemoryDatabase(false), cs.Options.SolverOptions.Resolver())
@@ -550,14 +474,13 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
return nil, errors.New("Package " + p.GetPackage().GetFingerPrint() + "with no deps and no seed image supplied, bailing out")
}
targetAssertion := p.GetSourceAssertion().Search(p.GetPackage().GetFingerPrint())
targetPackageHash := cs.ImageRepository + ":" + targetAssertion.Hash.PackageHash
// - If image is set we just generate a plain dockerfile
// Treat last case (easier) first. The image is provided and we just compute a plain dockerfile with the images listed as above
if p.GetImage() != "" {
if p.ImageUnpack() { // If it is just an entire image, create a package from it
return cs.packageFromImage(p, "", keepPermissions, cs.KeepImg, concurrency)
}
return cs.compileWithImage(p.GetImage(), "", "", concurrency, keepPermissions, cs.KeepImg, p)
return cs.compileWithImage(p.GetImage(), "", targetPackageHash, concurrency, keepPermissions, cs.KeepImg, p)
}
// - If image is not set, we read a base_image. Then we will build one image from it to kick-off our build based
@@ -595,20 +518,6 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
lastHash = currentPackageImageHash
if compileSpec.GetImage() != "" {
// TODO: Refactor this
if compileSpec.ImageUnpack() { // If it is just an entire image, create a package from it
if compileSpec.GetImage() == "" {
return nil, errors.New("No image defined for package: " + assertion.Package.HumanReadableString())
}
Info(pkgTag, ":whale: Sourcing package from image", compileSpec.GetImage())
artifact, err := cs.packageFromImage(compileSpec, currentPackageImageHash, keepPermissions, cs.KeepImg, concurrency)
if err != nil {
return nil, errors.Wrap(err, "Failed compiling "+compileSpec.GetPackage().HumanReadableString())
}
departifacts = append(departifacts, artifact)
continue
}
Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from image")
artifact, err := cs.compileWithImage(compileSpec.GetImage(), buildImageHash, currentPackageImageHash, concurrency, keepPermissions, cs.KeepImg, compileSpec)
if err != nil {
@@ -636,7 +545,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
if !cs.Options.OnlyDeps {
Info(":package:", p.GetPackage().HumanReadableString(), ":cyclone: Building package target from:", lastHash)
artifact, err := cs.compileWithImage(lastHash, "", "", concurrency, keepPermissions, cs.KeepImg, p)
artifact, err := cs.compileWithImage(lastHash, "", targetPackageHash, concurrency, keepPermissions, cs.KeepImg, p)
if err != nil {
return artifact, err
}

View File

@@ -17,12 +17,29 @@
package helpers
import (
"errors"
"fmt"
"regexp"
_gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
pkg "github.com/mudler/luet/pkg/package"
)
func CreateRegexArray(rgx []string) ([]*regexp.Regexp, error) {
ans := make([]*regexp.Regexp, len(rgx))
if len(rgx) > 0 {
for idx, reg := range rgx {
re := regexp.MustCompile(reg)
if re == nil {
return nil, errors.New("Invalid regex " + reg + "!")
}
ans[idx] = re
}
}
return ans, nil
}
func ParsePackageStr(p string) (*pkg.DefaultPackage, error) {
gp, err := _gentoo.ParsePackageStr(p)
if err != nil {

View File

@@ -337,45 +337,72 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp []pkg.Package, s *S
}
executedFinalizer := map[string]bool{}
// TODO: Lower those errors as warning
for _, w := range p {
// Finalizers needs to run in order and in sequence.
ordered := solution.Order(allRepos, w.GetFingerPrint())
ORDER:
for _, ass := range ordered {
if ass.Value {
if !l.Options.NoDeps {
// TODO: Lower those errors as warning
for _, w := range p {
// Finalizers needs to run in order and in sequence.
ordered := solution.Order(allRepos, w.GetFingerPrint())
ORDER:
for _, ass := range ordered {
if ass.Value {
installed, ok := toInstall[ass.Package.GetFingerPrint()]
if !ok {
// It was a dep already installed in the system, so we can skip it safely
continue ORDER
}
treePackage, err := installed.Repository.GetTree().GetDatabase().FindPackage(ass.Package)
if err != nil {
return errors.Wrap(err, "Error getting package "+ass.Package.HumanReadableString())
}
if helpers.Exists(treePackage.Rel(tree.FinalizerFile)) {
Info("Executing finalizer for " + ass.Package.HumanReadableString())
finalizerRaw, err := ioutil.ReadFile(treePackage.Rel(tree.FinalizerFile))
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error reading file "+treePackage.Rel(tree.FinalizerFile))
installed, ok := toInstall[ass.Package.GetFingerPrint()]
if !ok {
// It was a dep already installed in the system, so we can skip it safely
continue ORDER
}
if _, exists := executedFinalizer[ass.Package.GetFingerPrint()]; !exists {
finalizer, err := NewLuetFinalizerFromYaml(finalizerRaw)
treePackage, err := installed.Repository.GetTree().GetDatabase().FindPackage(ass.Package)
if err != nil {
return errors.Wrap(err, "Error getting package "+ass.Package.HumanReadableString())
}
if helpers.Exists(treePackage.Rel(tree.FinalizerFile)) {
Info("Executing finalizer for " + ass.Package.HumanReadableString())
finalizerRaw, err := ioutil.ReadFile(treePackage.Rel(tree.FinalizerFile))
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error reading finalizer "+treePackage.Rel(tree.FinalizerFile))
return errors.Wrap(err, "Error reading file "+treePackage.Rel(tree.FinalizerFile))
}
err = finalizer.RunInstall()
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error executing install finalizer "+treePackage.Rel(tree.FinalizerFile))
if _, exists := executedFinalizer[ass.Package.GetFingerPrint()]; !exists {
finalizer, err := NewLuetFinalizerFromYaml(finalizerRaw)
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error reading finalizer "+treePackage.Rel(tree.FinalizerFile))
}
err = finalizer.RunInstall()
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error executing install finalizer "+treePackage.Rel(tree.FinalizerFile))
}
executedFinalizer[ass.Package.GetFingerPrint()] = true
}
executedFinalizer[ass.Package.GetFingerPrint()] = true
}
}
}
}
}
} else {
for _, c := range toInstall {
treePackage, err := c.Repository.GetTree().GetDatabase().FindPackage(c.Package)
if err != nil {
return errors.Wrap(err, "Error getting package "+c.Package.HumanReadableString())
}
if helpers.Exists(treePackage.Rel(tree.FinalizerFile)) {
Info("Executing finalizer for " + c.Package.HumanReadableString())
finalizerRaw, err := ioutil.ReadFile(treePackage.Rel(tree.FinalizerFile))
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error reading file "+treePackage.Rel(tree.FinalizerFile))
}
if _, exists := executedFinalizer[c.Package.GetFingerPrint()]; !exists {
finalizer, err := NewLuetFinalizerFromYaml(finalizerRaw)
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error reading finalizer "+treePackage.Rel(tree.FinalizerFile))
}
err = finalizer.RunInstall()
if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error executing install finalizer "+treePackage.Rel(tree.FinalizerFile))
}
executedFinalizer[c.Package.GetFingerPrint()] = true
}
}
}
}
return nil

View File

@@ -21,7 +21,6 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
@@ -69,6 +68,19 @@ type LuetSystemRepositorySerialized struct {
TreeChecksums compiler.Checksums `json:"treechecksums"`
}
type LuetSearchModeType string
const (
SLabel LuetSearchModeType = "label"
SRegexPkg LuetSearchModeType = "regexPkg"
SRegexLabel LuetSearchModeType = "regexLabel"
)
type LuetSearchOpts struct {
Pattern string
Mode LuetSearchModeType
}
func GenerateRepository(name, descr, t string, urls []string, priority int, src, treeDir string, db pkg.PackageDatabase) (Repository, error) {
art, err := buildPackageIndex(src)
@@ -554,14 +566,24 @@ PACKAGE:
}
func (re Repositories) Search(s string) []PackageMatch {
func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch {
sort.Sort(re)
var term = regexp.MustCompile(s)
var matches []PackageMatch
var err error
for _, r := range re {
for _, pack := range r.GetTree().GetDatabase().World() {
if term.MatchString(pack.GetName()) {
var repoMatches []pkg.Package
if o.Mode == SRegexPkg {
repoMatches, err = r.GetTree().GetDatabase().FindPackageMatch(p)
} else if o.Mode == SLabel {
repoMatches, err = r.GetTree().GetDatabase().FindPackageLabel(p)
} else if o.Mode == SRegexLabel {
repoMatches, err = r.GetTree().GetDatabase().FindPackageLabelMatch(p)
}
if err == nil && len(repoMatches) > 0 {
for _, pack := range repoMatches {
matches = append(matches, PackageMatch{Package: pack, Repo: r})
}
}
@@ -569,3 +591,15 @@ func (re Repositories) Search(s string) []PackageMatch {
return matches
}
func (re Repositories) SearchLabelMatch(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SRegexLabel})
}
func (re Repositories) SearchLabel(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SLabel})
}
func (re Repositories) Search(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SRegexPkg})
}

View File

@@ -45,6 +45,9 @@ type PackageSet interface {
World() []Package
FindPackageCandidate(p Package) (Package, error)
FindPackageLabel(labelKey string) ([]Package, error)
FindPackageLabelMatch(pattern string) ([]Package, error)
FindPackageMatch(pattern string) ([]Package, error)
}
type PackageFile struct {

View File

@@ -18,6 +18,7 @@ package pkg
import (
"encoding/base64"
"os"
"regexp"
"strconv"
"sync"
"time"
@@ -384,3 +385,61 @@ func (db *BoltDatabase) FindPackageVersions(p Package) ([]Package, error) {
}
return versionsInWorld, nil
}
func (db *BoltDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
var ans []Package
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if pack.HasLabel(labelKey) {
ans = append(ans, pack)
}
}
return ans, nil
}
func (db *BoltDatabase) FindPackageLabelMatch(pattern string) ([]Package, error) {
var ans []Package
re := regexp.MustCompile(pattern)
if re == nil {
return nil, errors.New("Invalid regex " + pattern + "!")
}
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if pack.MatchLabel(re) {
ans = append(ans, pack)
}
}
return ans, nil
}
func (db *BoltDatabase) FindPackageMatch(pattern string) ([]Package, error) {
var ans []Package
re := regexp.MustCompile(pattern)
if re == nil {
return nil, errors.New("Invalid regex " + pattern + "!")
}
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if re.MatchString(pack.GetCategory() + pack.GetName()) {
ans = append(ans, pack)
}
}
return ans, nil
}

View File

@@ -18,6 +18,7 @@ package pkg
import (
"encoding/base64"
"encoding/json"
"regexp"
"sync"
"github.com/pkg/errors"
@@ -358,3 +359,62 @@ func (db *InMemoryDatabase) FindPackageCandidate(p Package) (Package, error) {
return required, err
}
func (db *InMemoryDatabase) FindPackageLabel(labelKey string) ([]Package, error) {
var ans []Package
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if pack.HasLabel(labelKey) {
ans = append(ans, pack)
}
}
return ans, nil
}
func (db *InMemoryDatabase) FindPackageLabelMatch(pattern string) ([]Package, error) {
var ans []Package
re := regexp.MustCompile(pattern)
if re == nil {
return nil, errors.New("Invalid regex " + pattern + "!")
}
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if pack.MatchLabel(re) {
ans = append(ans, pack)
}
}
return ans, nil
}
func (db *InMemoryDatabase) FindPackageMatch(pattern string) ([]Package, error) {
var ans []Package
re := regexp.MustCompile(pattern)
if re == nil {
return nil, errors.New("Invalid regex " + pattern + "!")
}
for _, k := range db.GetPackages() {
pack, err := db.GetPackage(k)
if err != nil {
return ans, err
}
if re.MatchString(pack.GetCategory() + pack.GetName()) {
ans = append(ans, pack)
}
}
return ans, nil
}

View File

@@ -22,16 +22,17 @@ import (
"fmt"
"io"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
// . "github.com/mudler/luet/pkg/logger"
gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo"
"github.com/crillab/gophersat/bf"
"github.com/ghodss/yaml"
version "github.com/hashicorp/go-version"
"github.com/jinzhu/copier"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
)
// Package is a package interface (TBD)
@@ -47,6 +48,7 @@ type Package interface {
Requires([]*DefaultPackage) Package
Conflicts([]*DefaultPackage) Package
Revdeps(PackageDatabase) []Package
LabelDeps(PackageDatabase, string) []Package
GetProvides() []*DefaultPackage
SetProvides([]*DefaultPackage) Package
@@ -62,7 +64,7 @@ type Package interface {
GetVersion() string
RequiresContains(PackageDatabase, Package) (bool, error)
Matches(m Package) bool
Bigger(m Package) bool
BumpBuildVersion() error
AddUse(use string)
RemoveUse(use string)
@@ -84,6 +86,11 @@ type Package interface {
SetLicense(string)
GetLicense() string
AddLabel(string, string)
GetLabels() map[string]string
HasLabel(string) bool
MatchLabel(*regexp.Regexp) bool
IsSelector() bool
VersionMatchSelector(string) (bool, error)
SelectorMatchVersion(string) (bool, error)
@@ -150,9 +157,11 @@ type DefaultPackage struct {
// Path is set only internally when tree is loaded from disk
Path string `json:"path,omitempty"`
Description string `json:"description"`
Uri []string `json:"uri"`
License string `json:"license"`
Description string `json:"description,omitempty"`
Uri []string `json:"uri,omitempty"`
License string `json:"license,omitempty"`
Labels map[string]string `json:labels,omitempty`
}
// State represent the package state
@@ -160,7 +169,13 @@ type State string
// NewPackage returns a new package
func NewPackage(name, version string, requires []*DefaultPackage, conflicts []*DefaultPackage) *DefaultPackage {
return &DefaultPackage{Name: name, Version: version, PackageRequires: requires, PackageConflicts: conflicts}
return &DefaultPackage{
Name: name,
Version: version,
PackageRequires: requires,
PackageConflicts: conflicts,
Labels: make(map[string]string, 0),
}
}
func (p *DefaultPackage) String() string {
@@ -218,6 +233,28 @@ func (p *DefaultPackage) IsSelector() bool {
return strings.ContainsAny(p.GetVersion(), "<>=")
}
func (p *DefaultPackage) HasLabel(label string) bool {
ans := false
for k, _ := range p.Labels {
if k == label {
ans = true
break
}
}
return ans
}
func (p *DefaultPackage) MatchLabel(r *regexp.Regexp) bool {
ans := false
for k, v := range p.Labels {
if r.MatchString(k + "=" + v) {
ans = true
break
}
}
return ans
}
// AddUse adds a use to a package
func (p *DefaultPackage) AddUse(use string) {
for _, v := range p.UseFlags {
@@ -302,6 +339,12 @@ func (p *DefaultPackage) SetCategory(s string) {
func (p *DefaultPackage) GetUses() []string {
return p.UseFlags
}
func (p *DefaultPackage) AddLabel(k, v string) {
p.Labels[k] = v
}
func (p *DefaultPackage) GetLabels() map[string]string {
return p.Labels
}
func (p *DefaultPackage) GetProvides() []*DefaultPackage {
return p.Provides
}
@@ -334,13 +377,6 @@ func (p *DefaultPackage) Matches(m Package) bool {
}
return false
}
func (p *DefaultPackage) Bigger(m Package) bool {
low := Lower([]Package{p, m})
if low.Matches(m) {
return true
}
return false
}
func (p *DefaultPackage) Expand(definitiondb PackageDatabase) ([]Package, error) {
var versionsInWorld []Package
@@ -379,6 +415,19 @@ func (p *DefaultPackage) Revdeps(definitiondb PackageDatabase) []Package {
return versionsInWorld
}
func (p *DefaultPackage) LabelDeps(definitiondb PackageDatabase, labelKey string) []Package {
var pkgsWithLabelInWorld []Package
// TODO: check if integrate some index to improve
// research instead of iterate all list.
for _, w := range definitiondb.World() {
if w.HasLabel(labelKey) {
pkgsWithLabelInWorld = append(pkgsWithLabelInWorld, w)
}
}
return pkgsWithLabelInWorld
}
func DecodePackage(ID string, db PackageDatabase) (Package, error) {
return db.GetPackage(ID)
}
@@ -408,29 +457,7 @@ func (pack *DefaultPackage) RequiresContains(definitiondb PackageDatabase, s Pac
return false, nil
}
func Lower(set []Package) Package {
var versionsMap map[string]Package = make(map[string]Package)
if len(set) == 0 {
panic("Best needs a list with elements")
}
versionsRaw := []string{}
for _, p := range set {
versionsRaw = append(versionsRaw, p.GetVersion())
versionsMap[p.GetVersion()] = p
}
versions := make([]*version.Version, len(versionsRaw))
for i, raw := range versionsRaw {
v, _ := version.NewVersion(raw)
versions[i] = v
}
// After this, the versions are properly sorted
sort.Sort(version.Collection(versions))
return versionsMap[versions[0].Original()]
}
func Best(set []Package) Package {
var versionsMap map[string]Package = make(map[string]Package)
if len(set) == 0 {
@@ -637,3 +664,89 @@ func (p *DefaultPackage) Explain() {
fmt.Println("====================")
}
func (p *DefaultPackage) BumpBuildVersion() error {
cat := p.Category
if cat == "" {
// Use fake category for parse package
cat = "app"
}
gp, err := gentoo.ParsePackageStr(
fmt.Sprintf("%s/%s-%s", cat,
p.Name, p.GetVersion()))
if err != nil {
return errors.Wrap(err, "Error on parser version")
}
buildPrefix := ""
buildId := 0
if gp.VersionBuild != "" {
// Check if version build is a number
buildId, err = strconv.Atoi(gp.VersionBuild)
if err == nil {
goto end
}
// POST: is not only a number
// TODO: check if there is a better way to handle all use cases.
r1 := regexp.MustCompile(`^r[0-9]*$`)
if r1 == nil {
return errors.New("Error on create regex for -r[0-9]")
}
if r1.MatchString(gp.VersionBuild) {
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "r", ""))
if err == nil {
buildPrefix = "r"
goto end
}
}
p1 := regexp.MustCompile(`^p[0-9]*$`)
if p1 == nil {
return errors.New("Error on create regex for -p[0-9]")
}
if p1.MatchString(gp.VersionBuild) {
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "p", ""))
if err == nil {
buildPrefix = "p"
goto end
}
}
rc1 := regexp.MustCompile(`^rc[0-9]*$`)
if rc1 == nil {
return errors.New("Error on create regex for -rc[0-9]")
}
if rc1.MatchString(gp.VersionBuild) {
buildId, err = strconv.Atoi(strings.ReplaceAll(gp.VersionBuild, "rc", ""))
if err == nil {
buildPrefix = "rc"
goto end
}
}
// Check if version build contains a dot
dotIdx := strings.LastIndex(gp.VersionBuild, ".")
if dotIdx > 0 {
buildPrefix = gp.VersionBuild[0 : dotIdx+1]
bVersion := gp.VersionBuild[dotIdx+1:]
buildId, err = strconv.Atoi(bVersion)
if err == nil {
goto end
}
}
buildPrefix = gp.VersionBuild + "."
buildId = 0
}
end:
buildId++
p.Version = fmt.Sprintf("%s%s+%s%d",
gp.Version, gp.VersionSuffix, buildPrefix, buildId)
return nil
}

View File

@@ -16,6 +16,8 @@
package pkg_test
import (
"regexp"
. "github.com/mudler/luet/pkg/package"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -61,6 +63,34 @@ var _ = Describe("Package", func() {
})
})
Context("Find label on packages", func() {
a := NewPackage("A", ">=1.0", []*DefaultPackage{}, []*DefaultPackage{})
a.AddLabel("project1", "test1")
a.AddLabel("label2", "value1")
b := NewPackage("B", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
b.AddLabel("project2", "test2")
b.AddLabel("label2", "value1")
It("Expands correctly", func() {
var err error
definitions := NewInMemoryDatabase(false)
for _, p := range []Package{a, b} {
_, err = definitions.CreatePackage(p)
Expect(err).ToNot(HaveOccurred())
}
re := regexp.MustCompile("project[0-9][=].*")
Expect(err).ToNot(HaveOccurred())
Expect(re).ToNot(BeNil())
Expect(a.HasLabel("label2")).To(Equal(true))
Expect(a.HasLabel("label3")).To(Equal(false))
Expect(a.HasLabel("project1")).To(Equal(true))
Expect(b.HasLabel("project2")).To(Equal(true))
Expect(b.HasLabel("label2")).To(Equal(true))
Expect(b.MatchLabel(re)).To(Equal(true))
Expect(a.MatchLabel(re)).To(Equal(true))
})
})
Context("Check description", func() {
a := NewPackage("A", ">=1.0", []*DefaultPackage{}, []*DefaultPackage{})
a.SetDescription("Description A")
@@ -252,4 +282,69 @@ var _ = Describe("Package", func() {
Expect(len(a1.GetUses())).To(Equal(0))
})
})
Context("Check Bump build Version", func() {
It("Bump without build version", func() {
a1 := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
err := a1.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(a1.GetVersion()).To(Equal("1.0+1"))
})
It("Bump 2", func() {
p := NewPackage("A", "1.0+1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+2"))
})
It("Bump 3", func() {
p := NewPackage("A", "1.0+100", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+101"))
})
It("Bump 4", func() {
p := NewPackage("A", "1.0+r1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+r2"))
})
It("Bump 5", func() {
p := NewPackage("A", "1.0+p1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+p2"))
})
It("Bump 6", func() {
p := NewPackage("A", "1.0+pre20200315", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+pre20200315.1"))
})
It("Bump 7", func() {
p := NewPackage("A", "1.0+pre20200315.1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+pre20200315.2"))
})
It("Bump 8", func() {
p := NewPackage("A", "1.0+d-r1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+d-r1.1"))
})
It("Bump 9", func() {
p := NewPackage("A", "1.0+p20200315.1", []*DefaultPackage{}, []*DefaultPackage{})
err := p.BumpBuildVersion()
Expect(err).ToNot(HaveOccurred())
Expect(p.GetVersion()).To(Equal("1.0+p20200315.2"))
})
})
})

View File

@@ -256,15 +256,20 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
var v2 *version.Version = nil
var ans bool
var err error
var sanitizedSelectorVersion, sanitizedIVersion string
if selector.Version != "" {
v1, err = version.NewVersion(selector.Version)
// TODO: This is temporary!. I promise it.
sanitizedSelectorVersion = strings.ReplaceAll(selector.Version, "_", "-")
v1, err = version.NewVersion(sanitizedSelectorVersion)
if err != nil {
return false, err
}
}
if i.Version != "" {
v2, err = version.NewVersion(i.Version)
sanitizedIVersion = strings.ReplaceAll(i.Version, "_", "-")
v2, err = version.NewVersion(sanitizedIVersion)
if err != nil {
return false, err
}
@@ -290,7 +295,7 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
// TODO: case of 7.3* where 7.30 is accepted.
if v1 != nil && v2 != nil {
segments := v1.Segments()
n := strings.Count(selector.Version, ".")
n := strings.Count(sanitizedIVersion, ".")
switch n {
case 0:
segments[0]++
@@ -303,7 +308,7 @@ func PackageAdmit(selector, i PkgVersionSelector) (bool, error) {
}
nextVersion := strings.Trim(strings.Replace(fmt.Sprint(segments), " ", ".", -1), "[]")
constraints, err := version.NewConstraint(
fmt.Sprintf(">= %s, < %s", selector.Version, nextVersion),
fmt.Sprintf(">= %s, < %s", sanitizedSelectorVersion, nextVersion),
)
if err != nil {
return false, err

View File

@@ -191,6 +191,17 @@ var _ = Describe("Versions", func() {
})
})
Context("Versions Parser16 - semver", func() {
v, err := ParseVersion("<=1.0.29+pre2_p20191024")
It("ParseVersion10", func() {
var c PkgSelectorCondition = PkgCondLessEqual
Expect(err).Should(BeNil())
Expect(v.Version).Should(Equal("1.0.29+pre2_p20191024"))
Expect(v.VersionSuffix).Should(Equal(""))
Expect(v.Condition).Should(Equal(c))
})
})
Context("Selector1", func() {
v1, err := ParseVersion(">=0.0.20190406.4.9.172-r1")
v2, err2 := ParseVersion("1.0.111")
@@ -275,6 +286,18 @@ var _ = Describe("Versions", func() {
})
})
Context("Selector8", func() {
v1, err := ParseVersion(">=0")
v2, err2 := ParseVersion("1.0.29+pre2_p20191024")
match, err3 := PackageAdmit(v1, v2)
It("Selector8", func() {
Expect(err).Should(BeNil())
Expect(err2).Should(BeNil())
Expect(err3).Should(BeNil())
Expect(match).Should(Equal(true))
})
})
Context("Condition Converter 1", func() {
gp, err := gentoo.ParsePackageStr("=layer/build-1.0")
var cond gentoo.PackageCond = gentoo.PkgCondEqual

View File

@@ -35,7 +35,7 @@ func LoadRepositories(c *LuetConfig) error {
files, err := ioutil.ReadDir(rdir)
if err != nil {
Warning("Skip dir", rdir, ":", err.Error())
Debug("Skip dir", rdir, ":", err.Error())
continue
}

View File

@@ -363,12 +363,19 @@ var _ = Describe("Solver", func() {
It("Selects best version", func() {
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
E.SetCategory("test")
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
C.SetCategory("test")
D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D2.SetCategory("test")
D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D.SetCategory("test")
D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
D1.SetCategory("test")
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{})
B.SetCategory("test")
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{})
A.SetCategory("test")
for _, p := range []pkg.Package{A, B, C, D, D1, D2, E} {
_, err := dbDefinitions.CreatePackage(p)
@@ -397,16 +404,23 @@ var _ = Describe("Solver", func() {
It("Support provides", func() {
E := pkg.NewPackage("E", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
E.SetCategory("test")
C := pkg.NewPackage("C", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
C.SetCategory("test")
D2 := pkg.NewPackage("D", "1.9", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D2.SetCategory("test")
D := pkg.NewPackage("D", "1.8", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
D.SetCategory("test")
D1 := pkg.NewPackage("D", "1.4", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{})
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0"}}, []*pkg.DefaultPackage{})
D1.SetCategory("test")
B := pkg.NewPackage("B", "1.1", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{})
B.SetCategory("test")
A := pkg.NewPackage("A", "", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "D", Version: ">=1.0", Category: "test"}}, []*pkg.DefaultPackage{})
A.SetCategory("test")
D2.SetProvides([]*pkg.DefaultPackage{{Name: "E"}})
A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: ""}}, []*pkg.DefaultPackage{})
D2.SetProvides([]*pkg.DefaultPackage{{Name: "E", Category: "test"}})
A2 := pkg.NewPackage("A", "1.3", []*pkg.DefaultPackage{&pkg.DefaultPackage{Name: "E", Version: "", Category: "test"}}, []*pkg.DefaultPackage{})
A2.SetCategory("test")
for _, p := range []pkg.Package{A, B, C, D, D1, D2, A2, E} {
_, err := dbDefinitions.CreatePackage(p)

View File

@@ -26,5 +26,5 @@ type Builder interface {
GetDatabase() pkg.PackageDatabase
WithDatabase(d pkg.PackageDatabase)
GetSourcePath() string
GetSourcePath() []string
}

View File

@@ -38,6 +38,20 @@ func NewCompilerRecipe(d pkg.PackageDatabase) Builder {
return &CompilerRecipe{Recipe: Recipe{Database: d}}
}
func ReadDefinitionFile(path string) (pkg.DefaultPackage, error) {
empty := pkg.DefaultPackage{}
dat, err := ioutil.ReadFile(path)
if err != nil {
return empty, errors.Wrap(err, "Error reading file "+path)
}
pack, err := pkg.DefaultPackageFromYaml(dat)
if err != nil {
return empty, errors.Wrap(err, "Error reading yaml "+path)
}
return pack, nil
}
// Recipe is the "general" reciper for Trees
type CompilerRecipe struct {
Recipe
@@ -45,7 +59,7 @@ type CompilerRecipe struct {
func (r *CompilerRecipe) Load(path string) error {
r.SourcePath = path
r.SourcePath = append(r.SourcePath, path)
//tmpfile, err := ioutil.TempFile("", "luet")
//if err != nil {
// return err
@@ -56,17 +70,17 @@ func (r *CompilerRecipe) Load(path string) error {
// the function that handles each file or dir
var ff = func(currentpath string, info os.FileInfo, err error) error {
if err != nil {
return errors.Wrap(err, "Error on walk path "+currentpath)
}
if info.Name() != DefinitionFile {
return nil // Skip with no errors
}
dat, err := ioutil.ReadFile(currentpath)
pack, err := ReadDefinitionFile(currentpath)
if err != nil {
return errors.Wrap(err, "Error reading file "+currentpath)
}
pack, err := pkg.DefaultPackageFromYaml(dat)
if err != nil {
return errors.Wrap(err, "Error reading yaml "+currentpath)
return err
}
// Path is set only internally when tree is loaded from disk
pack.SetPath(filepath.Dir(currentpath))
@@ -74,13 +88,17 @@ func (r *CompilerRecipe) Load(path string) error {
// Instead of rdeps, have a different tree for build deps.
compileDefPath := pack.Rel(CompilerDefinitionFile)
if helpers.Exists(compileDefPath) {
dat, err = ioutil.ReadFile(compileDefPath)
dat, err := ioutil.ReadFile(compileDefPath)
if err != nil {
return errors.Wrap(err, "Error reading file "+currentpath)
return errors.Wrap(err,
"Error reading file "+CompilerDefinitionFile+" from "+
filepath.Dir(currentpath))
}
packbuild, err := pkg.DefaultPackageFromYaml(dat)
if err != nil {
return errors.Wrap(err, "Error reading yaml "+currentpath)
return errors.Wrap(err,
"Error reading yaml "+CompilerDefinitionFile+" from "+
filepath.Dir(currentpath))
}
pack.Requires(packbuild.GetRequires())
pack.Conflicts(packbuild.GetConflicts())
@@ -103,4 +121,4 @@ func (r *CompilerRecipe) Load(path string) error {
func (r *CompilerRecipe) GetDatabase() pkg.PackageDatabase { return r.Database }
func (r *CompilerRecipe) WithDatabase(d pkg.PackageDatabase) { r.Database = d }
func (r *CompilerRecipe) GetSourcePath() string { return r.SourcePath }
func (r *CompilerRecipe) GetSourcePath() []string { return r.SourcePath }

View File

@@ -40,7 +40,7 @@ func NewInstallerRecipe(db pkg.PackageDatabase) Builder {
// InstallerRecipe is the "general" reciper for Trees
type InstallerRecipe struct {
SourcePath string
SourcePath []string
Database pkg.PackageDatabase
}
@@ -74,7 +74,7 @@ func (r *InstallerRecipe) Load(path string) error {
// if err != nil {
// return err
// }
r.SourcePath = path
r.SourcePath = append(r.SourcePath, path)
//r.Tree().SetPackageSet(pkg.NewBoltDatabase(tmpfile.Name()))
// TODO: Handle cleaning after? Cleanup implemented in GetPackageSet().Clean()
@@ -114,4 +114,4 @@ func (r *InstallerRecipe) Load(path string) error {
func (r *InstallerRecipe) GetDatabase() pkg.PackageDatabase { return r.Database }
func (r *InstallerRecipe) WithDatabase(d pkg.PackageDatabase) { r.Database = d }
func (r *InstallerRecipe) GetSourcePath() string { return r.SourcePath }
func (r *InstallerRecipe) GetSourcePath() []string { return r.SourcePath }

View File

@@ -37,24 +37,32 @@ func NewGeneralRecipe(db pkg.PackageDatabase) Builder { return &Recipe{Database:
// Recipe is the "general" reciper for Trees
type Recipe struct {
SourcePath string
SourcePath []string
Database pkg.PackageDatabase
}
func (r *Recipe) Save(path string) error {
func WriteDefinitionFile(p pkg.Package, definitionFilePath string) error {
data, err := p.Yaml()
if err != nil {
return err
}
err = ioutil.WriteFile(definitionFilePath, data, 0644)
if err != nil {
return err
}
return nil
}
func (r *Recipe) Save(path string) error {
for _, p := range r.Database.World() {
dir := filepath.Join(path, p.GetCategory(), p.GetName(), p.GetVersion())
os.MkdirAll(dir, os.ModePerm)
data, err := p.Yaml()
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dir, DefinitionFile), data, 0644)
if err != nil {
return err
}
err := WriteDefinitionFile(p, filepath.Join(dir, DefinitionFile))
if err != nil {
return err
}
}
return nil
}
@@ -65,7 +73,7 @@ func (r *Recipe) Load(path string) error {
// if err != nil {
// return err
// }
r.SourcePath = path
r.SourcePath = append(r.SourcePath, path)
if r.Database == nil {
r.Database = pkg.NewInMemoryDatabase(false)
@@ -109,4 +117,4 @@ func (r *Recipe) Load(path string) error {
func (r *Recipe) GetDatabase() pkg.PackageDatabase { return r.Database }
func (r *Recipe) WithDatabase(d pkg.PackageDatabase) { r.Database = d }
func (r *Recipe) GetSourcePath() string { return r.SourcePath }
func (r *Recipe) GetSourcePath() []string { return r.SourcePath }

View File

@@ -96,4 +96,77 @@ var _ = Describe("Tree", func() {
})
})
Context("Multiple trees", func() {
It("Merges", func() {
for index := 0; index < 300; index++ { // Just to make sure we don't have false positives
db := pkg.NewInMemoryDatabase(false)
generalRecipe := NewCompilerRecipe(db)
tmpdir, err := ioutil.TempDir("", "package")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up
err = generalRecipe.Load("../../tests/fixtures/buildableseed")
Expect(err).ToNot(HaveOccurred())
Expect(len(generalRecipe.GetDatabase().World())).To(Equal(4))
err = generalRecipe.Load("../../tests/fixtures/layers")
Expect(err).ToNot(HaveOccurred())
Expect(len(generalRecipe.GetDatabase().World())).To(Equal(6))
extra, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "extra", Category: "layer", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
Expect(extra).ToNot(BeNil())
D, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
Expect(D.GetRequires()[0].GetName()).To(Equal("c"))
CfromD, err := generalRecipe.GetDatabase().FindPackage(D.GetRequires()[0])
Expect(err).ToNot(HaveOccurred())
Expect(len(CfromD.GetRequires()) != 0).To(BeTrue())
Expect(CfromD.GetRequires()[0].GetName()).To(Equal("b"))
s := solver.NewSolver(pkg.NewInMemoryDatabase(false), generalRecipe.GetDatabase(), db)
Dd, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
solution, err := s.Install([]pkg.Package{Dd})
Expect(err).ToNot(HaveOccurred())
solution = solution.Order(generalRecipe.GetDatabase(), Dd.GetFingerPrint())
pack, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "a", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
base, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "base", Category: "layer", Version: "0.2"})
Expect(err).ToNot(HaveOccurred())
Expect(solution).To(ContainElement(solver.PackageAssert{Package: pack.(*pkg.DefaultPackage), Value: false}))
Expect(solution).To(ContainElement(solver.PackageAssert{Package: D.(*pkg.DefaultPackage), Value: true}))
Expect(solution).To(ContainElement(solver.PackageAssert{Package: extra.(*pkg.DefaultPackage), Value: false}))
Expect(solution).To(ContainElement(solver.PackageAssert{Package: base.(*pkg.DefaultPackage), Value: false}))
Expect(len(solution)).To(Equal(6))
}
})
})
Context("Simple tree with labels", func() {
It("Read tree with labels", func() {
db := pkg.NewInMemoryDatabase(false)
generalRecipe := NewCompilerRecipe(db)
err := generalRecipe.Load("../../tests/fixtures/labels")
Expect(err).ToNot(HaveOccurred())
Expect(len(generalRecipe.GetDatabase().World())).To(Equal(1))
pack, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "pkgA", Category: "test", Version: "0.1"})
Expect(err).ToNot(HaveOccurred())
Expect(pack.HasLabel("label1")).To(Equal(true))
Expect(pack.HasLabel("label3")).To(Equal(false))
})
})
})

View File

@@ -0,0 +1,3 @@
image: "alpine"
steps:
- echo "test" > /file1

View File

@@ -0,0 +1,6 @@
category: "test"
name: "pkgA"
version: "0.1"
labels:
label1: "value1"
label2: "value2"

View File

@@ -1,2 +1,2 @@
image: "golang:alpine"
image: "golang"
unpack: true

View File

@@ -3,8 +3,8 @@ requires:
name: "base"
version: "0.1"
prelude:
- apk update
- apk add git
- apt-get update
- apt-get install git
- rm -rf /go/pkg/mod
steps:
- echo test > /extra-layer

View File

@@ -3,7 +3,7 @@ requires:
name: "extra"
version: "0.1"
prelude:
- apk add git
- apt-get install git
- mkdir -p /go/src/github.com/Sabayon/
- git clone https://github.com/Sabayon/pkgs-checker /go/src/github.com/Sabayon/pkgs-checker
steps:

View File

@@ -55,8 +55,8 @@ const (
)
const (
RegexCatString = `(^[a-z]+[0-9]*[a-z]*[-][a-z]+[0-9]*[a-z]*|^virtual)`
RegexPkgNameString = `([a-z]+[0-9a-zA-Z\-[+]*]*[+]*)`
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]+[+]+)`
)
type GentooPackage struct {
@@ -69,6 +69,7 @@ type GentooPackage struct {
Condition PackageCond
Repository string `json:"repository",omitempty"`
UseFlags []string `json:"use_flags",omitempty"`
License string `json:"license",omitempty"`
}
func (p *GentooPackage) String() string {

2
vendor/modules.txt vendored
View File

@@ -23,7 +23,7 @@ github.com/Microsoft/hcsshim/internal/longpath
github.com/Microsoft/hcsshim/internal/safefile
# github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
github.com/Nvveen/Gotty
# github.com/Sabayon/pkgs-checker v0.5.1-0.20200221202320-073693f2c657
# github.com/Sabayon/pkgs-checker v0.6.2-0.20200315232328-b6efed54b4b1
github.com/Sabayon/pkgs-checker/pkg/gentoo
# github.com/apex/log v1.1.1
github.com/apex/log