Compare commits

..

9 Commits

Author SHA1 Message Date
Ettore Di Giacinto
94f692266c Tag 0.11.3 2021-03-06 20:36:37 +01:00
Ettore Di Giacinto
c13a2174c4 Try to chown after copy 2021-03-06 18:49:14 +01:00
Ettore Di Giacinto
f07cf6c245 Add tests for file search 2021-03-06 18:49:14 +01:00
Ettore Di Giacinto
515017cabd ci: login with sudo -E 2021-03-06 16:52:20 +01:00
Ettore Di Giacinto
0bfb33db92 Allow to set db/rootfs from CLI in cleanup 2021-03-06 11:28:39 +01:00
Ettore Di Giacinto
c9c24dd174 Add integration test 2021-03-06 10:41:15 +01:00
Ettore Di Giacinto
194cfda8a4 Pass by the cli args to the underlying system struct
We didn't set previously what we catched from CLI. Note, this is a
temporary solution until we refactor the cli code

Fixes #186
2021-03-06 10:21:49 +01:00
Ettore Di Giacinto
233429bbeb Allow to search by file
Also make possible to retrieve the artifact when searching for matches
between repositories list. This made possible to show the package list
when calling `luet search`.
2021-02-28 18:42:58 +01:00
Ettore Di Giacinto
d84f6b31fd Add database get command 2021-02-28 18:42:16 +01:00
25 changed files with 921 additions and 196 deletions

View File

@@ -14,7 +14,7 @@ jobs:
- name: setup-docker - name: setup-docker
uses: docker-practice/actions-setup-docker@0.0.1 uses: docker-practice/actions-setup-docker@0.0.1
- name: Login to quay - name: Login to quay
run: echo ${{ secrets.DOCKER_TESTING_PASSWORD }} | sudo docker login -u ${{ secrets.DOCKER_TESTING_USERNAME }} --password-stdin quay.io run: echo ${{ secrets.DOCKER_TESTING_PASSWORD }} | sudo -E docker login -u ${{ secrets.DOCKER_TESTING_USERNAME }} --password-stdin quay.io
- name: Install deps - name: Install deps
run: | run: |
sudo apt-get install -y upx && sudo -E env "PATH=$PATH" make deps sudo apt-get install -y upx && sudo -E env "PATH=$PATH" make deps

View File

@@ -20,6 +20,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
. "github.com/mudler/luet/pkg/config"
config "github.com/mudler/luet/pkg/config" config "github.com/mudler/luet/pkg/config"
"github.com/mudler/luet/pkg/helpers" "github.com/mudler/luet/pkg/helpers"
. "github.com/mudler/luet/pkg/logger" . "github.com/mudler/luet/pkg/logger"
@@ -31,13 +32,24 @@ var cleanupCmd = &cobra.Command{
Use: "cleanup", Use: "cleanup",
Short: "Clean packages cache.", Short: "Clean packages cache.",
Long: `remove downloaded packages tarballs and clean cache directory`, Long: `remove downloaded packages tarballs and clean cache directory`,
PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("installed", cmd.Flags().Lookup("installed"))
},
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var cleaned int = 0 var cleaned int = 0
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := config.LuetCfg.Viper.GetString("system.rootfs")
engine := config.LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
// Check if cache dir exists // Check if cache dir exists
if helpers.Exists(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) { if helpers.Exists(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) {
files, err := ioutil.ReadDir(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) files, err := ioutil.ReadDir(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath())
if err != nil { if err != nil {
Fatal("Error on read cachedir ", err.Error()) Fatal("Error on read cachedir ", err.Error())
} }
@@ -47,12 +59,12 @@ var cleanupCmd = &cobra.Command{
continue continue
} }
if config.LuetCfg.GetGeneral().Debug { if LuetCfg.GetGeneral().Debug {
Info("Removing ", file.Name()) Info("Removing ", file.Name())
} }
err := os.RemoveAll( err := os.RemoveAll(
filepath.Join(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath(), file.Name())) filepath.Join(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath(), file.Name()))
if err != nil { if err != nil {
Fatal("Error on removing", file.Name()) Fatal("Error on removing", file.Name())
} }
@@ -66,5 +78,8 @@ var cleanupCmd = &cobra.Command{
} }
func init() { func init() {
cleanupCmd.Flags().String("system-dbpath", "", "System db path")
cleanupCmd.Flags().String("system-target", "", "System rootpath")
cleanupCmd.Flags().String("system-engine", "", "System DB engine")
RootCmd.AddCommand(cleanupCmd) RootCmd.AddCommand(cleanupCmd)
} }

View File

@@ -36,6 +36,7 @@ func init() {
databaseGroupCmd.AddCommand( databaseGroupCmd.AddCommand(
NewDatabaseCreateCommand(), NewDatabaseCreateCommand(),
NewDatabaseGetCommand(),
NewDatabaseRemoveCommand(), NewDatabaseRemoveCommand(),
) )
} }

View File

@@ -46,10 +46,19 @@ For reference, inspect a "metadata.yaml" file generated while running "luet buil
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
systemDB := LuetCfg.GetSystemDB() systemDB := LuetCfg.GetSystemDB()
for _, a := range args { for _, a := range args {
@@ -77,5 +86,9 @@ For reference, inspect a "metadata.yaml" file generated while running "luet buil
}, },
} }
ans.Flags().String("system-dbpath", "", "System db path")
ans.Flags().String("system-target", "", "System rootpath")
ans.Flags().String("system-engine", "", "System DB engine")
return ans return ans
} }

95
cmd/database/get.go Normal file
View File

@@ -0,0 +1,95 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.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_database
import (
"fmt"
helpers "github.com/mudler/luet/cmd/helpers"
"gopkg.in/yaml.v2"
. "github.com/mudler/luet/pkg/config"
"github.com/spf13/cobra"
)
func NewDatabaseGetCommand() *cobra.Command {
var c = &cobra.Command{
Use: "get <package>",
Short: "Get a package in the system DB as yaml",
Long: `Get a package in the system database in the YAML format:
$ luet database get system/foo
To return also files:
$ luet database get --files system/foo`,
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
},
Run: func(cmd *cobra.Command, args []string) {
showFiles, _ := cmd.Flags().GetBool("files")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
systemDB := LuetCfg.GetSystemDB()
for _, a := range args {
pack, err := helpers.ParsePackageStr(a)
if err != nil {
continue
}
ps, err := systemDB.FindPackages(pack)
if err != nil {
continue
}
for _, p := range ps {
y, err := p.Yaml()
if err != nil {
continue
}
fmt.Println(string(y))
if showFiles {
files, err := systemDB.GetPackageFiles(p)
if err != nil {
continue
}
b, err := yaml.Marshal(files)
if err != nil {
continue
}
fmt.Println("files:\n" + string(b))
}
}
}
},
}
c.Flags().Bool("files", false, "Show package files.")
c.Flags().String("system-dbpath", "", "System db path")
c.Flags().String("system-target", "", "System rootpath")
c.Flags().String("system-engine", "", "System DB engine")
return c
}

View File

@@ -38,9 +38,18 @@ This commands takes multiple packages as arguments and prunes their entries from
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
systemDB := LuetCfg.GetSystemDB() systemDB := LuetCfg.GetSystemDB()
for _, a := range args { for _, a := range args {
@@ -60,6 +69,9 @@ This commands takes multiple packages as arguments and prunes their entries from
}, },
} }
ans.Flags().String("system-dbpath", "", "System db path")
ans.Flags().String("system-target", "", "System rootpath")
ans.Flags().String("system-engine", "", "System DB engine")
return ans return ans
} }

View File

@@ -15,8 +15,6 @@
package cmd package cmd
import ( import (
"os"
installer "github.com/mudler/luet/pkg/installer" installer "github.com/mudler/luet/pkg/installer"
"github.com/mudler/luet/pkg/solver" "github.com/mudler/luet/pkg/solver"
@@ -51,6 +49,7 @@ To force install a package:
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type")) LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type"))
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount")) LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate")) LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
@@ -91,6 +90,14 @@ To force install a package:
concurrent, _ := cmd.Flags().GetBool("solver-concurrent") concurrent, _ := cmd.Flags().GetBool("solver-concurrent")
yes := LuetCfg.Viper.GetBool("yes") yes := LuetCfg.Viper.GetBool("yes")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
LuetCfg.GetSolverOptions().Type = stype LuetCfg.GetSolverOptions().Type = stype
LuetCfg.GetSolverOptions().LearnRate = float32(rate) LuetCfg.GetSolverOptions().LearnRate = float32(rate)
LuetCfg.GetSolverOptions().Discount = float32(discount) LuetCfg.GetSolverOptions().Discount = float32(discount)
@@ -127,12 +134,10 @@ To force install a package:
} }
func init() { func init() {
path, err := os.Getwd() installCmd.Flags().String("system-dbpath", "", "System db path")
if err != nil { installCmd.Flags().String("system-target", "", "System rootpath")
Fatal(err) installCmd.Flags().String("system-engine", "", "System DB engine")
}
installCmd.Flags().String("system-dbpath", path, "System db path")
installCmd.Flags().String("system-target", path, "System rootpath")
installCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") installCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )")
installCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") installCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
installCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") installCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")

View File

@@ -15,8 +15,6 @@
package cmd package cmd
import ( import (
"os"
installer "github.com/mudler/luet/pkg/installer" installer "github.com/mudler/luet/pkg/installer"
. "github.com/mudler/luet/pkg/config" . "github.com/mudler/luet/pkg/config"
@@ -31,6 +29,7 @@ var reclaimCmd = &cobra.Command{
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force")) LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force"))
}, },
Long: `Reclaim tries to find association between packages in the online repositories and the system one. Long: `Reclaim tries to find association between packages in the online repositories and the system one.
@@ -40,6 +39,13 @@ var reclaimCmd = &cobra.Command{
It scans the target file system, and if finds a match with a package available in the repositories, it marks as installed in the system database. It scans the target file system, and if finds a match with a package available in the repositories, it marks as installed in the system database.
`, `,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
// This shouldn't be necessary, but we need to unmarshal the repositories to a concrete struct, thus we need to port them back to the Repositories type // This shouldn't be necessary, but we need to unmarshal the repositories to a concrete struct, thus we need to port them back to the Repositories type
repos := installer.Repositories{} repos := installer.Repositories{}
@@ -71,12 +77,11 @@ It scans the target file system, and if finds a match with a package available i
} }
func init() { func init() {
path, err := os.Getwd()
if err != nil { reclaimCmd.Flags().String("system-dbpath", "", "System db path")
Fatal(err) reclaimCmd.Flags().String("system-target", "", "System rootpath")
} reclaimCmd.Flags().String("system-engine", "", "System DB engine")
reclaimCmd.Flags().String("system-dbpath", path, "System db path")
reclaimCmd.Flags().String("system-target", path, "System rootpath")
reclaimCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)") reclaimCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)")
RootCmd.AddCommand(reclaimCmd) RootCmd.AddCommand(reclaimCmd)

View File

@@ -15,8 +15,6 @@
package cmd package cmd
import ( import (
"os"
installer "github.com/mudler/luet/pkg/installer" installer "github.com/mudler/luet/pkg/installer"
"github.com/mudler/luet/pkg/solver" "github.com/mudler/luet/pkg/solver"
@@ -38,6 +36,7 @@ var replaceCmd = &cobra.Command{
`, `,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) LuetCfg.Viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) LuetCfg.Viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target"))
LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type")) LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type"))
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount")) LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
@@ -64,6 +63,13 @@ var replaceCmd = &cobra.Command{
onlydeps := LuetCfg.Viper.GetBool("onlydeps") onlydeps := LuetCfg.Viper.GetBool("onlydeps")
concurrent, _ := cmd.Flags().GetBool("solver-concurrent") concurrent, _ := cmd.Flags().GetBool("solver-concurrent")
yes := LuetCfg.Viper.GetBool("yes") yes := LuetCfg.Viper.GetBool("yes")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
for _, a := range args { for _, a := range args {
pack, err := helpers.ParsePackageStr(a) pack, err := helpers.ParsePackageStr(a)
@@ -127,12 +133,11 @@ var replaceCmd = &cobra.Command{
} }
func init() { func init() {
path, err := os.Getwd()
if err != nil { replaceCmd.Flags().String("system-dbpath", "", "System db path")
Fatal(err) replaceCmd.Flags().String("system-target", "", "System rootpath")
} replaceCmd.Flags().String("system-engine", "", "System DB engine")
replaceCmd.Flags().String("system-dbpath", path, "System db path")
replaceCmd.Flags().String("system-target", path, "System rootpath")
replaceCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") replaceCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )")
replaceCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") replaceCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
replaceCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") replaceCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")

View File

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

View File

@@ -16,7 +16,6 @@ package cmd
import ( import (
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
@@ -30,12 +29,13 @@ import (
) )
type PackageResult struct { type PackageResult struct {
Name string `json:"name"` Name string `json:"name"`
Category string `json:"category"` Category string `json:"category"`
Version string `json:"version"` Version string `json:"version"`
Repository string `json:"repository"` Repository string `json:"repository"`
Target string `json:"target"` Target string `json:"target"`
Hidden bool `json:"hidden"` Hidden bool `json:"hidden"`
Files []string `json:"files"`
} }
type Results struct { type Results struct {
@@ -64,6 +64,205 @@ func packageToList(l list.Writer, repo string, p pkg.Package) {
l.UnIndent() l.UnIndent()
} }
func searchLocally(term string, l list.Writer, t table.Writer, label, labelMatch, revdeps, hidden bool) Results {
var results Results
system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs}
var err error
iMatches := pkg.Packages{}
if label {
iMatches, err = system.Database.FindPackageLabel(term)
} else if labelMatch {
iMatches, err = system.Database.FindPackageLabelMatch(term)
} else {
iMatches, err = system.Database.FindPackageMatch(term)
}
if err != nil {
Fatal("Error: " + err.Error())
}
for _, pack := range iMatches {
if !revdeps {
if !pack.IsHidden() || pack.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
f, _ := system.Database.GetPackageFiles(pack)
results.Packages = append(results.Packages,
PackageResult{
Name: pack.GetName(),
Version: pack.GetVersion(),
Category: pack.GetCategory(),
Repository: "system",
Hidden: pack.IsHidden(),
Files: f,
})
}
} else {
packs, _ := system.Database.GetRevdeps(pack)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
f, _ := system.Database.GetPackageFiles(revdep)
results.Packages = append(results.Packages,
PackageResult{
Name: revdep.GetName(),
Version: revdep.GetVersion(),
Category: revdep.GetCategory(),
Repository: "system",
Hidden: revdep.IsHidden(),
Files: f,
})
}
}
}
}
return results
}
func searchOnline(term string, l list.Writer, t table.Writer, label, labelMatch, revdeps, hidden bool) Results {
var results Results
repos := installer.Repositories{}
for _, repo := range LuetCfg.SystemRepositories {
if !repo.Enable {
continue
}
r := installer.NewSystemRepository(repo)
repos = append(repos, r)
}
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: LuetCfg.GetGeneral().Concurrency,
SolverOptions: *LuetCfg.GetSolverOptions(),
},
)
inst.Repositories(repos)
synced, err := inst.SyncRepositories(false)
if err != nil {
Fatal("Error: " + err.Error())
}
Info("--- Search results (" + term + "): ---")
matches := []installer.PackageMatch{}
if label {
matches = synced.SearchLabel(term)
} else if labelMatch {
matches = synced.SearchLabelMatch(term)
} else {
matches = synced.Search(term)
}
for _, m := range matches {
if !revdeps {
if !m.Package.IsHidden() || m.Package.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
packageToList(l, m.Repo.GetName(), m.Package)
results.Packages = append(results.Packages,
PackageResult{
Name: m.Package.GetName(),
Version: m.Package.GetVersion(),
Category: m.Package.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: m.Package.IsHidden(),
Files: m.Artifact.GetFiles(),
})
}
} else {
packs, _ := m.Repo.GetTree().GetDatabase().GetRevdeps(m.Package)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), revdep))
packageToList(l, m.Repo.GetName(), revdep)
results.Packages = append(results.Packages,
PackageResult{
Name: revdep.GetName(),
Version: revdep.GetVersion(),
Category: revdep.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: revdep.IsHidden(),
Files: m.Artifact.GetFiles(),
})
}
}
}
}
return results
}
func searchLocalFiles(term string, l list.Writer, t table.Writer) Results {
var results Results
Info("--- Search results (" + term + "): ---")
matches, _ := LuetCfg.GetSystemDB().FindPackageByFile(term)
for _, pack := range matches {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
f, _ := LuetCfg.GetSystemDB().GetPackageFiles(pack)
results.Packages = append(results.Packages,
PackageResult{
Name: pack.GetName(),
Version: pack.GetVersion(),
Category: pack.GetCategory(),
Repository: "system",
Hidden: pack.IsHidden(),
Files: f,
})
}
return results
}
func searchFiles(term string, l list.Writer, t table.Writer) Results {
var results Results
repos := installer.Repositories{}
for _, repo := range LuetCfg.SystemRepositories {
if !repo.Enable {
continue
}
r := installer.NewSystemRepository(repo)
repos = append(repos, r)
}
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: LuetCfg.GetGeneral().Concurrency,
SolverOptions: *LuetCfg.GetSolverOptions(),
},
)
inst.Repositories(repos)
synced, err := inst.SyncRepositories(false)
if err != nil {
Fatal("Error: " + err.Error())
}
Info("--- Search results (" + term + "): ---")
matches := []installer.PackageMatch{}
matches = synced.SearchPackages(term, installer.FileSearch)
for _, m := range matches {
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
packageToList(l, m.Repo.GetName(), m.Package)
results.Packages = append(results.Packages,
PackageResult{
Name: m.Package.GetName(),
Version: m.Package.GetVersion(),
Category: m.Package.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: m.Package.IsHidden(),
Files: m.Artifact.GetFiles(),
})
}
return results
}
var searchCmd = &cobra.Command{ var searchCmd = &cobra.Command{
Use: "search <term>", Use: "search <term>",
Short: "Search packages", Short: "Search packages",
@@ -107,6 +306,7 @@ Search can also return results in the terminal in different ways: as terminal ou
LuetCfg.Viper.BindPFlag("installed", cmd.Flags().Lookup("installed")) LuetCfg.Viper.BindPFlag("installed", cmd.Flags().Lookup("installed"))
LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type")) LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type"))
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount")) LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate")) LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts")) LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts"))
}, },
@@ -128,7 +328,14 @@ Search can also return results in the terminal in different ways: as terminal ou
searchWithLabelMatch, _ := cmd.Flags().GetBool("by-label-regex") searchWithLabelMatch, _ := cmd.Flags().GetBool("by-label-regex")
revdeps, _ := cmd.Flags().GetBool("revdeps") revdeps, _ := cmd.Flags().GetBool("revdeps")
tableMode, _ := cmd.Flags().GetBool("table") tableMode, _ := cmd.Flags().GetBool("table")
files, _ := cmd.Flags().GetBool("files")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
out, _ := cmd.Flags().GetString("output") out, _ := cmd.Flags().GetString("output")
if out != "terminal" { if out != "terminal" {
LuetCfg.GetLogging().SetLogLevel("error") LuetCfg.GetLogging().SetLogLevel("error")
@@ -144,121 +351,15 @@ Search can also return results in the terminal in different ways: as terminal ou
t.AppendHeader(rows) t.AppendHeader(rows)
Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
if !installed { switch {
case files && installed:
repos := installer.Repositories{} results = searchLocalFiles(args[0], l, t)
for _, repo := range LuetCfg.SystemRepositories { case files && !installed:
if !repo.Enable { results = searchFiles(args[0], l, t)
continue case !installed:
} results = searchOnline(args[0], l, t, searchWithLabel, searchWithLabelMatch, revdeps, hidden)
r := installer.NewSystemRepository(repo) default:
repos = append(repos, r) results = searchLocally(args[0], l, t, searchWithLabel, searchWithLabelMatch, revdeps, hidden)
}
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: LuetCfg.GetGeneral().Concurrency,
SolverOptions: *LuetCfg.GetSolverOptions(),
},
)
inst.Repositories(repos)
synced, err := inst.SyncRepositories(false)
if err != nil {
Fatal("Error: " + err.Error())
}
Info("--- Search results (" + 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 {
if !revdeps {
if !m.Package.IsHidden() || m.Package.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
packageToList(l, m.Repo.GetName(), m.Package)
results.Packages = append(results.Packages,
PackageResult{
Name: m.Package.GetName(),
Version: m.Package.GetVersion(),
Category: m.Package.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: m.Package.IsHidden(),
})
}
} else {
packs, _ := m.Repo.GetTree().GetDatabase().GetRevdeps(m.Package)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), revdep))
packageToList(l, m.Repo.GetName(), revdep)
results.Packages = append(results.Packages,
PackageResult{
Name: revdep.GetName(),
Version: revdep.GetVersion(),
Category: revdep.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: revdep.IsHidden(),
})
}
}
}
}
} else {
system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs}
var err error
iMatches := pkg.Packages{}
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 {
if !revdeps {
if !pack.IsHidden() || pack.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
results.Packages = append(results.Packages,
PackageResult{
Name: pack.GetName(),
Version: pack.GetVersion(),
Category: pack.GetCategory(),
Repository: "system",
Hidden: pack.IsHidden(),
})
}
} else {
packs, _ := system.Database.GetRevdeps(pack)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
results.Packages = append(results.Packages,
PackageResult{
Name: revdep.GetName(),
Version: revdep.GetVersion(),
Category: revdep.GetCategory(),
Repository: "system",
Hidden: revdep.IsHidden(),
})
}
}
}
}
} }
t.AppendFooter(rows) t.AppendFooter(rows)
@@ -292,12 +393,10 @@ Search can also return results in the terminal in different ways: as terminal ou
} }
func init() { func init() {
path, err := os.Getwd() searchCmd.Flags().String("system-dbpath", "", "System db path")
if err != nil { searchCmd.Flags().String("system-target", "", "System rootpath")
Fatal(err) searchCmd.Flags().String("system-engine", "", "System DB engine")
}
searchCmd.Flags().String("system-dbpath", path, "System db path")
searchCmd.Flags().String("system-target", path, "System rootpath")
searchCmd.Flags().Bool("installed", false, "Search between system packages") searchCmd.Flags().Bool("installed", false, "Search between system packages")
searchCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") searchCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )")
searchCmd.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )") searchCmd.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )")
@@ -309,6 +408,7 @@ func init() {
searchCmd.Flags().Bool("revdeps", false, "Search package reverse dependencies") searchCmd.Flags().Bool("revdeps", false, "Search package reverse dependencies")
searchCmd.Flags().Bool("hidden", false, "Include hidden packages") searchCmd.Flags().Bool("hidden", false, "Include hidden packages")
searchCmd.Flags().Bool("table", false, "show output in a table (wider screens)") searchCmd.Flags().Bool("table", false, "show output in a table (wider screens)")
searchCmd.Flags().Bool("files", false, "Search between packages files")
RootCmd.AddCommand(searchCmd) RootCmd.AddCommand(searchCmd)
} }

View File

@@ -15,8 +15,6 @@
package cmd package cmd
import ( import (
"os"
helpers "github.com/mudler/luet/cmd/helpers" helpers "github.com/mudler/luet/cmd/helpers"
. "github.com/mudler/luet/pkg/config" . "github.com/mudler/luet/pkg/config"
installer "github.com/mudler/luet/pkg/installer" installer "github.com/mudler/luet/pkg/installer"
@@ -42,6 +40,7 @@ var uninstallCmd = &cobra.Command{
LuetCfg.Viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps")) LuetCfg.Viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps"))
LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force")) LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force"))
LuetCfg.Viper.BindPFlag("yes", cmd.Flags().Lookup("yes")) LuetCfg.Viper.BindPFlag("yes", cmd.Flags().Lookup("yes"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
toRemove := []pkg.Package{} toRemove := []pkg.Package{}
@@ -65,6 +64,13 @@ var uninstallCmd = &cobra.Command{
fullClean, _ := cmd.Flags().GetBool("full-clean") fullClean, _ := cmd.Flags().GetBool("full-clean")
concurrent, _ := cmd.Flags().GetBool("solver-concurrent") concurrent, _ := cmd.Flags().GetBool("solver-concurrent")
yes := LuetCfg.Viper.GetBool("yes") yes := LuetCfg.Viper.GetBool("yes")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
LuetCfg.GetSolverOptions().Type = stype LuetCfg.GetSolverOptions().Type = stype
LuetCfg.GetSolverOptions().LearnRate = float32(rate) LuetCfg.GetSolverOptions().LearnRate = float32(rate)
@@ -101,12 +107,11 @@ var uninstallCmd = &cobra.Command{
} }
func init() { func init() {
path, err := os.Getwd()
if err != nil { uninstallCmd.Flags().String("system-dbpath", "", "System db path")
Fatal(err) uninstallCmd.Flags().String("system-target", "", "System rootpath")
} uninstallCmd.Flags().String("system-engine", "", "System DB engine")
uninstallCmd.Flags().String("system-dbpath", path, "System db path")
uninstallCmd.Flags().String("system-target", path, "System rootpath")
uninstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") uninstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )")
uninstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") uninstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
uninstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") uninstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")

View File

@@ -15,8 +15,6 @@
package cmd package cmd
import ( import (
"os"
. "github.com/mudler/luet/pkg/config" . "github.com/mudler/luet/pkg/config"
installer "github.com/mudler/luet/pkg/installer" installer "github.com/mudler/luet/pkg/installer"
. "github.com/mudler/luet/pkg/logger" . "github.com/mudler/luet/pkg/logger"
@@ -38,6 +36,7 @@ var upgradeCmd = &cobra.Command{
LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts")) LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts"))
LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force")) LuetCfg.Viper.BindPFlag("force", cmd.Flags().Lookup("force"))
LuetCfg.Viper.BindPFlag("yes", cmd.Flags().Lookup("yes")) LuetCfg.Viper.BindPFlag("yes", cmd.Flags().Lookup("yes"))
LuetCfg.Viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
}, },
Long: `Upgrades packages in parallel`, Long: `Upgrades packages in parallel`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
@@ -64,7 +63,13 @@ var upgradeCmd = &cobra.Command{
sync, _ := cmd.Flags().GetBool("sync") sync, _ := cmd.Flags().GetBool("sync")
concurrent, _ := cmd.Flags().GetBool("solver-concurrent") concurrent, _ := cmd.Flags().GetBool("solver-concurrent")
yes := LuetCfg.Viper.GetBool("yes") yes := LuetCfg.Viper.GetBool("yes")
dbpath := LuetCfg.Viper.GetString("system.database_path")
rootfs := LuetCfg.Viper.GetString("system.rootfs")
engine := LuetCfg.Viper.GetString("system.database_engine")
LuetCfg.System.DatabaseEngine = engine
LuetCfg.System.DatabasePath = dbpath
LuetCfg.System.Rootfs = rootfs
LuetCfg.GetSolverOptions().Type = stype LuetCfg.GetSolverOptions().Type = stype
LuetCfg.GetSolverOptions().LearnRate = float32(rate) LuetCfg.GetSolverOptions().LearnRate = float32(rate)
LuetCfg.GetSolverOptions().Discount = float32(discount) LuetCfg.GetSolverOptions().Discount = float32(discount)
@@ -102,12 +107,10 @@ var upgradeCmd = &cobra.Command{
} }
func init() { func init() {
path, err := os.Getwd() upgradeCmd.Flags().String("system-dbpath", "", "System db path")
if err != nil { upgradeCmd.Flags().String("system-target", "", "System rootpath")
Fatal(err) upgradeCmd.Flags().String("system-engine", "", "System DB engine")
}
upgradeCmd.Flags().String("system-dbpath", path, "System db path")
upgradeCmd.Flags().String("system-target", path, "System rootpath")
upgradeCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") upgradeCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )")
upgradeCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") upgradeCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
upgradeCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") upgradeCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")

View File

@@ -16,6 +16,7 @@
package helpers package helpers
import ( import (
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -172,9 +173,18 @@ func CopyFile(src, dst string) (err error) {
return nil return nil
} }
return copy.Copy(src, dst, copy.Options{ err = copy.Copy(src, dst, copy.Options{
Sync: true, Sync: true,
OnSymlink: func(string) copy.SymlinkAction { return copy.Shallow }}) OnSymlink: func(string) copy.SymlinkAction { return copy.Shallow }})
if err != nil {
return err
}
if stat, ok := fi.Sys().(*syscall.Stat_t); ok {
if err := os.Chown(dst, int(stat.Uid), int(stat.Gid)); err != nil {
fmt.Println("failed chowning", dst, err.Error())
}
}
return err
} }
func IsDirectory(path string) (bool, error) { func IsDirectory(path string) (bool, error) {

View File

@@ -74,4 +74,6 @@ type Repository interface {
Serialize() (*LuetSystemRepositoryMetadata, LuetSystemRepositorySerialized) Serialize() (*LuetSystemRepositoryMetadata, LuetSystemRepositorySerialized)
GetBackend() compiler.CompilerBackend GetBackend() compiler.CompilerBackend
SetBackend(b compiler.CompilerBackend) SetBackend(b compiler.CompilerBackend)
FileSearch(pattern string) (pkg.Packages, error)
SearchArtefact(p pkg.Package) (compiler.Artifact, error)
} }

View File

@@ -21,6 +21,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@@ -86,17 +87,17 @@ type LuetSystemRepositoryMetadata struct {
Index []*compiler.PackageArtifact `json:"index,omitempty"` Index []*compiler.PackageArtifact `json:"index,omitempty"`
} }
type LuetSearchModeType string type LuetSearchModeType int
const ( const (
SLabel LuetSearchModeType = "label" SLabel = iota
SRegexPkg LuetSearchModeType = "regexPkg" SRegexPkg = iota
SRegexLabel LuetSearchModeType = "regexLabel" SRegexLabel = iota
FileSearch = iota
) )
type LuetSearchOpts struct { type LuetSearchOpts struct {
Pattern string Mode LuetSearchModeType
Mode LuetSearchModeType
} }
func NewLuetSystemRepositoryMetadata(file string, removeFile bool) (*LuetSystemRepositoryMetadata, error) { func NewLuetSystemRepositoryMetadata(file string, removeFile bool) (*LuetSystemRepositoryMetadata, error) {
@@ -406,6 +407,25 @@ func (r *LuetSystemRepository) SetPriority(n int) {
r.LuetRepository.Priority = n r.LuetRepository.Priority = n
} }
// FileSearch search a pattern among the artifacts in a repository
func (r *LuetSystemRepository) FileSearch(pattern string) (pkg.Packages, error) {
var matches pkg.Packages
reg, err := regexp.Compile(pattern)
if err != nil {
return matches, err
}
ARTIFACT:
for _, a := range r.GetIndex() {
for _, f := range a.GetFiles() {
if reg.MatchString(f) {
matches = append(matches, a.GetCompileSpec().GetPackage())
continue ARTIFACT
}
}
}
return matches, nil
}
func (r *LuetSystemRepository) GetName() string { func (r *LuetSystemRepository) GetName() string {
return r.LuetRepository.Name return r.LuetRepository.Name
} }
@@ -881,6 +901,16 @@ func (r *LuetSystemRepository) Client() Client {
return nil return nil
} }
func (r *LuetSystemRepository) SearchArtefact(p pkg.Package) (compiler.Artifact, error) {
for _, a := range r.GetIndex() {
if a.GetCompileSpec().GetPackage().Matches(p) {
return a, nil
}
}
return nil, errors.New("Not found")
}
func (r *LuetSystemRepository) Sync(force bool) (Repository, error) { func (r *LuetSystemRepository) Sync(force bool) (Repository, error) {
var repoUpdated bool = false var repoUpdated bool = false
var treefs, metafs string var treefs, metafs string
@@ -1129,8 +1159,9 @@ func (r Repositories) SyncDatabase(d pkg.PackageDatabase) {
} }
type PackageMatch struct { type PackageMatch struct {
Repo Repository Repo Repository
Package pkg.Package Artifact compiler.Artifact
Package pkg.Package
} }
func (re Repositories) PackageMatches(p pkg.Packages) []PackageMatch { func (re Repositories) PackageMatches(p pkg.Packages) []PackageMatch {
@@ -1182,7 +1213,7 @@ PACKAGE:
} }
func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch { func (re Repositories) SearchPackages(p string, t LuetSearchModeType) []PackageMatch {
sort.Sort(re) sort.Sort(re)
var matches []PackageMatch var matches []PackageMatch
var err error var err error
@@ -1190,18 +1221,21 @@ func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch
for _, r := range re { for _, r := range re {
var repoMatches pkg.Packages var repoMatches pkg.Packages
switch o.Mode { switch t {
case SRegexPkg: case SRegexPkg:
repoMatches, err = r.GetTree().GetDatabase().FindPackageMatch(p) repoMatches, err = r.GetTree().GetDatabase().FindPackageMatch(p)
case SLabel: case SLabel:
repoMatches, err = r.GetTree().GetDatabase().FindPackageLabel(p) repoMatches, err = r.GetTree().GetDatabase().FindPackageLabel(p)
case SRegexLabel: case SRegexLabel:
repoMatches, err = r.GetTree().GetDatabase().FindPackageLabelMatch(p) repoMatches, err = r.GetTree().GetDatabase().FindPackageLabelMatch(p)
case FileSearch:
repoMatches, err = r.FileSearch(p)
} }
if err == nil && len(repoMatches) > 0 { if err == nil && len(repoMatches) > 0 {
for _, pack := range repoMatches { for _, pack := range repoMatches {
matches = append(matches, PackageMatch{Package: pack, Repo: r}) a, _ := r.SearchArtefact(pack)
matches = append(matches, PackageMatch{Package: pack, Repo: r, Artifact: a})
} }
} }
} }
@@ -1210,13 +1244,13 @@ func (re Repositories) SearchPackages(p string, o LuetSearchOpts) []PackageMatch
} }
func (re Repositories) SearchLabelMatch(s string) []PackageMatch { func (re Repositories) SearchLabelMatch(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SRegexLabel}) return re.SearchPackages(s, SRegexLabel)
} }
func (re Repositories) SearchLabel(s string) []PackageMatch { func (re Repositories) SearchLabel(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SLabel}) return re.SearchPackages(s, SLabel)
} }
func (re Repositories) Search(s string) []PackageMatch { func (re Repositories) Search(s string) []PackageMatch {
return re.SearchPackages(s, LuetSearchOpts{Pattern: s, Mode: SRegexPkg}) return re.SearchPackages(s, SRegexPkg)
} }

View File

@@ -392,5 +392,80 @@ urls:
Expect(string(content)).To(Equal("")) Expect(string(content)).To(Equal(""))
}) })
It("Searches files", func() {
repos := Repositories{
&LuetSystemRepository{
Index: compiler.ArtifactIndex{
&compiler.PackageArtifact{
CompileSpec: &compiler.LuetCompilationSpec{
Package: &pkg.DefaultPackage{},
},
Path: "bar",
Files: []string{"boo"},
},
&compiler.PackageArtifact{
Path: "d",
Files: []string{"baz"},
},
},
},
}
matches := repos.SearchPackages("bo", FileSearch)
Expect(len(matches)).To(Equal(1))
Expect(matches[0].Artifact.GetPath()).To(Equal("bar"))
})
It("Searches packages", func() {
repo := &LuetSystemRepository{
Index: compiler.ArtifactIndex{
&compiler.PackageArtifact{
Path: "foo",
CompileSpec: &compiler.LuetCompilationSpec{
Package: &pkg.DefaultPackage{
Name: "foo",
Category: "bar",
Version: "1.0",
},
},
},
&compiler.PackageArtifact{
Path: "baz",
CompileSpec: &compiler.LuetCompilationSpec{
Package: &pkg.DefaultPackage{
Name: "foo",
Category: "baz",
Version: "1.0",
},
},
},
},
}
a, err := repo.SearchArtefact(&pkg.DefaultPackage{
Name: "foo",
Category: "baz",
Version: "1.0",
})
Expect(err).ToNot(HaveOccurred())
Expect(a.GetPath()).To(Equal("baz"))
a, err = repo.SearchArtefact(&pkg.DefaultPackage{
Name: "foo",
Category: "bar",
Version: "1.0",
})
Expect(err).ToNot(HaveOccurred())
Expect(a.GetPath()).To(Equal("foo"))
// Doesn't exist. so must fail
_, err = repo.SearchArtefact(&pkg.DefaultPackage{
Name: "foo",
Category: "bar",
Version: "1.1",
})
Expect(err).To(HaveOccurred())
})
}) })
}) })

View File

@@ -52,6 +52,7 @@ type PackageSet interface {
FindPackageLabel(labelKey string) (Packages, error) FindPackageLabel(labelKey string) (Packages, error)
FindPackageLabelMatch(pattern string) (Packages, error) FindPackageLabelMatch(pattern string) (Packages, error)
FindPackageMatch(pattern string) (Packages, error) FindPackageMatch(pattern string) (Packages, error)
FindPackageByFile(pattern string) (Packages, error)
} }
type PackageFile struct { type PackageFile struct {

View File

@@ -436,9 +436,9 @@ func (db *BoltDatabase) FindPackageLabel(labelKey string) (Packages, error) {
func (db *BoltDatabase) FindPackageLabelMatch(pattern string) (Packages, error) { func (db *BoltDatabase) FindPackageLabelMatch(pattern string) (Packages, error) {
var ans []Package var ans []Package
re := regexp.MustCompile(pattern) re, err := regexp.Compile(pattern)
if re == nil { if err != nil {
return nil, errors.New("Invalid regex " + pattern + "!") return nil, errors.Wrap(err, "Invalid regex "+pattern+"!")
} }
for _, pack := range db.World() { for _, pack := range db.World() {
@@ -450,12 +450,15 @@ func (db *BoltDatabase) FindPackageLabelMatch(pattern string) (Packages, error)
return Packages(ans), nil return Packages(ans), nil
} }
func (db *BoltDatabase) FindPackageByFile(pattern string) (Packages, error) {
return findPackageByFile(db, pattern)
}
func (db *BoltDatabase) FindPackageMatch(pattern string) (Packages, error) { func (db *BoltDatabase) FindPackageMatch(pattern string) (Packages, error) {
var ans []Package var ans []Package
re := regexp.MustCompile(pattern) re, err := regexp.Compile(pattern)
if re == nil { if err != nil {
return nil, errors.New("Invalid regex " + pattern + "!") return nil, errors.Wrap(err, "Invalid regex "+pattern+"!")
} }
for _, pack := range db.World() { for _, pack := range db.World() {

View File

@@ -57,6 +57,31 @@ var _ = Describe("BoltDB Database", func() {
}) })
It("Find package files", func() {
a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
a1 := NewPackage("A", "1.1", []*DefaultPackage{}, []*DefaultPackage{})
a3 := NewPackage("A", "1.3", []*DefaultPackage{}, []*DefaultPackage{})
_, err := db.CreatePackage(a)
Expect(err).ToNot(HaveOccurred())
_, err = db.CreatePackage(a1)
Expect(err).ToNot(HaveOccurred())
_, err = db.CreatePackage(a3)
Expect(err).ToNot(HaveOccurred())
err = db.SetPackageFiles(&PackageFile{PackageFingerprint: a.GetFingerPrint(), Files: []string{"foo"}})
Expect(err).ToNot(HaveOccurred())
err = db.SetPackageFiles(&PackageFile{PackageFingerprint: a1.GetFingerPrint(), Files: []string{"bar"}})
Expect(err).ToNot(HaveOccurred())
pack, err := db.FindPackageByFile("fo")
Expect(err).ToNot(HaveOccurred())
Expect(len(pack)).To(Equal(1))
Expect(pack[0]).To(Equal(a))
})
It("Expands correctly", func() { It("Expands correctly", func() {
a := NewPackage("A", ">=1.0", []*DefaultPackage{}, []*DefaultPackage{}) a := NewPackage("A", ">=1.0", []*DefaultPackage{}, []*DefaultPackage{})

View File

@@ -15,7 +15,11 @@
package pkg package pkg
import "github.com/pkg/errors" import (
"regexp"
"github.com/pkg/errors"
)
func clone(src, dst PackageDatabase) error { func clone(src, dst PackageDatabase) error {
for _, i := range src.World() { for _, i := range src.World() {
@@ -36,3 +40,29 @@ func copy(src PackageDatabase) (PackageDatabase, error) {
return dst, nil return dst, nil
} }
func findPackageByFile(db PackageDatabase, pattern string) (Packages, error) {
var ans []Package
re, err := regexp.Compile(pattern)
if err != nil {
return nil, errors.Wrap(err, "Invalid regex "+pattern+"!")
}
PACKAGE:
for _, pack := range db.World() {
files, err := db.GetPackageFiles(pack)
if err == nil {
for _, f := range files {
if re.MatchString(f) {
ans = append(ans, pack)
continue PACKAGE
}
}
}
}
return Packages(ans), nil
}

View File

@@ -560,3 +560,7 @@ func (db *InMemoryDatabase) FindPackageMatch(pattern string) (Packages, error) {
return Packages(ans), nil return Packages(ans), nil
} }
func (db *InMemoryDatabase) FindPackageByFile(pattern string) (Packages, error) {
return findPackageByFile(db, pattern)
}

View File

@@ -77,6 +77,32 @@ var _ = Describe("Database", func() {
}) })
It("Find package files", func() {
db := NewInMemoryDatabase(false)
a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})
a1 := NewPackage("A", "1.1", []*DefaultPackage{}, []*DefaultPackage{})
a3 := NewPackage("A", "1.3", []*DefaultPackage{}, []*DefaultPackage{})
_, err := db.CreatePackage(a)
Expect(err).ToNot(HaveOccurred())
_, err = db.CreatePackage(a1)
Expect(err).ToNot(HaveOccurred())
_, err = db.CreatePackage(a3)
Expect(err).ToNot(HaveOccurred())
err = db.SetPackageFiles(&PackageFile{PackageFingerprint: a.GetFingerPrint(), Files: []string{"foo"}})
Expect(err).ToNot(HaveOccurred())
err = db.SetPackageFiles(&PackageFile{PackageFingerprint: a1.GetFingerPrint(), Files: []string{"bar"}})
Expect(err).ToNot(HaveOccurred())
pack, err := db.FindPackageByFile("fo")
Expect(err).ToNot(HaveOccurred())
Expect(len(pack)).To(Equal(1))
Expect(pack[0]).To(Equal(a))
})
It("Find specific package candidate", func() { It("Find specific package candidate", func() {
db := NewInMemoryDatabase(false) db := NewInMemoryDatabase(false)
a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{}) a := NewPackage("A", "1.0", []*DefaultPackage{}, []*DefaultPackage{})

128
tests/integration/01_rootfs.sh Executable file
View File

@@ -0,0 +1,128 @@
#!/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/buildableseed" --destination $tmpdir/testbuild --compression gzip test/c > /dev/null
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package dep B' "[ -e '$tmpdir/testbuild/b-test-1.0.package.tar.gz' ]"
assertTrue 'create package' "[ -e '$tmpdir/testbuild/c-test-1.0.package.tar.gz' ]"
}
testRepo() {
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/buildableseed" \
--output $tmpdir/testbuild \
--packages $tmpdir/testbuild \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type disk > /dev/null
createst=$?
assertEquals 'create repo successfully' "$createst" "0"
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_engine: "memory"
config_from_host: true
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "$res" "0"
}
testInstall() {
luet install -y --config $tmpdir/luet.yaml test/c
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package installed' "[ -e '$tmpdir/testrootfs/c' ]"
}
testCleanup() {
luet cleanup --config $tmpdir/luet.yaml
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package cleaned' "[ ! -e '$tmpdir/testrootfs/packages/c-test-1.0.package.tar.gz' ]"
}
testInstall2() {
luet install -y --config $tmpdir/luet.yaml --system-target $tmpdir/foo test/c
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'db not created' "[ ! -e '$tmpdir/foo/var/cache/luet/luet.db' ]"
assertTrue 'package installed' "[ -e '$tmpdir/foo/c' ]"
}
testCleanup2() {
luet cleanup --config $tmpdir/luet.yaml --system-target $tmpdir/foo
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package cleaned' "[ ! -e '$tmpdir/foo/packages/c-test-1.0.package.tar.gz' ]"
}
testInstall3() {
cat <<EOF > $tmpdir/luet2.yaml
general:
debug: true
config_from_host: true
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet install -y --config $tmpdir/luet2.yaml --system-target $tmpdir/baz test/c
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package installed' "[ -e '$tmpdir/baz/c' ]"
}
testCleanup3() {
luet cleanup --config $tmpdir/luet2.yaml --system-target $tmpdir/baz
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package cleaned' "[ ! -e '$tmpdir/baz/packages/c-test-1.0.package.tar.gz' ]"
}
testInstall4() {
luet install -y --config $tmpdir/luet2.yaml --system-target $tmpdir/bad --system-engine boltdb test/c
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package installed' "[ -e '$tmpdir/bad/c' ]"
assertTrue 'db created' "[ -d '$tmpdir/bad/var/cache/luet' ]"
}
testCleanup4() {
luet cleanup --config $tmpdir/luet2.yaml --system-target $tmpdir/bad --system-engine boltdb
installst=$?
assertEquals 'install test successfully' "$installst" "0"
assertTrue 'package cleaned' "[ ! -e '$tmpdir/bad/packages/c-test-1.0.package.tar.gz' ]"
}
# Load shUnit2.
. "$ROOT_DIR/tests/integration/shunit2"/shunit2

View File

@@ -0,0 +1,128 @@
#!/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/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/b@1.0
buildst=$?
assertTrue 'create package B 1.0' "[ -e '$tmpdir/testbuild/b-test-1.0.package.tar.gz' ]"
assertEquals 'builds successfully' "$buildst" "0"
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/b@1.1
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package B 1.1' "[ -e '$tmpdir/testbuild/b-test-1.1.package.tar.gz' ]"
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/a@1.0
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package A 1.0' "[ -e '$tmpdir/testbuild/a-test-1.0.package.tar.gz' ]"
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/a@1.1
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package A 1.1' "[ -e '$tmpdir/testbuild/a-test-1.1.package.tar.gz' ]"
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/a@1.2
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package A 1.2' "[ -e '$tmpdir/testbuild/a-test-1.2.package.tar.gz' ]"
luet build --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" --destination $tmpdir/testbuild --compression gzip test/c@1.0
buildst=$?
assertEquals 'builds successfully' "$buildst" "0"
assertTrue 'create package C 1.0' "[ -e '$tmpdir/testbuild/c-test-1.0.package.tar.gz' ]"
}
testRepo() {
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/upgrade_integration" \
--output $tmpdir/testbuild \
--packages $tmpdir/testbuild \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type disk
createst=$?
assertEquals 'create repo successfully' "$createst" "0"
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"
config_from_host: true
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "$res" "0"
}
testSearch() {
installed=$(luet --config $tmpdir/luet.yaml search --files testaa)
searchst=$?
assertEquals 'search exists successfully' "$searchst" "0"
assertContains 'contains test/a-1.0' "$installed" 'test/a-1.0'
}
testGetSearchLocal() {
luet install -y --config $tmpdir/luet.yaml test/a@1.0
assertTrue 'package installed A' "[ -e '$tmpdir/testrootfs/testaa' ]"
installst=$?
assertEquals 'install test successfully' "$installst" "0"
installed=$(luet --config $tmpdir/luet.yaml database get --files test/a@1.0)
searchst=$?
assertEquals 'search exists successfully' "$searchst" "0"
assertContains 'contains file' "$installed" 'testaa'
installed=$(luet --config $tmpdir/luet.yaml database get test/a@1.0)
searchst=$?
assertEquals 'search exists successfully' "$searchst" "0"
assertNotContains 'contains file' "$installed" 'testaa'
installed=$(luet --config $tmpdir/luet.yaml search --installed --files testaa)
searchst=$?
assertEquals 'search exists successfully' "$searchst" "0"
assertContains 'contains test/a-1.1' "$installed" 'test/a-1.0'
installed=$(luet --config $tmpdir/luet.yaml search --installed --files foo)
searchst=$?
assertEquals 'search exists successfully' "$searchst" "0"
assertNotContains 'contains test/a-1.1' "$installed" 'test/a-1.0'
}
# Load shUnit2.
. "$ROOT_DIR/tests/integration/shunit2"/shunit2