Added deletion of packages
This commit is contained in:
parent
7b0aba2ad7
commit
39f15e7e1e
5 changed files with 1116 additions and 438 deletions
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "Launch Package",
|
|
||||||
"type": "go",
|
|
||||||
"request": "launch",
|
|
||||||
"mode": "auto",
|
|
||||||
"program": "${fileDirname}",
|
|
||||||
"args": [],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
BIN
cmd/cmd
BIN
cmd/cmd
Binary file not shown.
399
cmd/main.go
399
cmd/main.go
|
@ -6,27 +6,39 @@ import (
|
||||||
"eon/common"
|
"eon/common"
|
||||||
"eon/lib"
|
"eon/lib"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/term"
|
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"regexp"
|
"golang.org/x/sys/unix"
|
||||||
"strings"
|
"golang.org/x/term"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = &common.DefaultLogger
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
fmt.Println("Usage: eon <list/info/install/remove/clean/repo/help> [args]")
|
fmt.Println("Usage: eon <list/info/install/remove/clean/repo/help> [args]")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := &common.DefaultLogger
|
||||||
|
|
||||||
|
for i, arg := range os.Args {
|
||||||
|
if arg == "--help" || arg == "-h" || (i != 1 && arg == "help") {
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "To ask for help, use 'eon help <list/info/install/remove/clean/repo/help>', not --help, -h, or eon <command> help.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
switch os.Args[1] {
|
switch os.Args[1] {
|
||||||
case "help":
|
case "help":
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
|
@ -35,11 +47,11 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
switch os.Args[2] {
|
switch os.Args[2] {
|
||||||
case "list":
|
case "list":
|
||||||
fmt.Println("Usage: eon list (remote/local)")
|
fmt.Println("Usage: eon list (repo/local)")
|
||||||
fmt.Println("- remote: lists packages available in the repositories.")
|
fmt.Println("- repo: lists packages available in repositories.")
|
||||||
fmt.Println("- local: lists installed packages.")
|
fmt.Println("- local: lists installed packages.")
|
||||||
case "info":
|
case "info":
|
||||||
fmt.Println("Usage: eon info <package>")
|
fmt.Println("Usage: eon info <package> [(repo/local)] [<repository>]")
|
||||||
fmt.Println("Shows information about a package.")
|
fmt.Println("Shows information about a package.")
|
||||||
case "install":
|
case "install":
|
||||||
fmt.Println("Usage: eon install <package> [<repository>]")
|
fmt.Println("Usage: eon install <package> [<repository>]")
|
||||||
|
@ -51,9 +63,9 @@ func main() {
|
||||||
fmt.Println("Usage: eon clean")
|
fmt.Println("Usage: eon clean")
|
||||||
fmt.Println("Removes unused dependencies.")
|
fmt.Println("Removes unused dependencies.")
|
||||||
case "repo":
|
case "repo":
|
||||||
fmt.Println("Usage: eon repo (add/remove/list)")
|
fmt.Println("Usage: eon repo (add/del/list)")
|
||||||
fmt.Println("- add <url>: adds a repository.")
|
fmt.Println("- add <url>: adds a repository.")
|
||||||
fmt.Println("- remove <url>: removes a repository.")
|
fmt.Println("- del <name>: removes a repository.")
|
||||||
fmt.Println("- list: lists repositories.")
|
fmt.Println("- list: lists repositories.")
|
||||||
case "help":
|
case "help":
|
||||||
fmt.Println("Usage: eon help (list/info/install/remove/clean/repo/help) [args]")
|
fmt.Println("Usage: eon help (list/info/install/remove/clean/repo/help) [args]")
|
||||||
|
@ -65,6 +77,7 @@ func main() {
|
||||||
}
|
}
|
||||||
case "install":
|
case "install":
|
||||||
var forceMode bool
|
var forceMode bool
|
||||||
|
var yesMode bool
|
||||||
var inMemoryMode bool
|
var inMemoryMode bool
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Usage: eon install <package>")
|
fmt.Println("Usage: eon install <package>")
|
||||||
|
@ -103,6 +116,8 @@ func main() {
|
||||||
forceMode = true
|
forceMode = true
|
||||||
case "--optimizeForSpeed", "-O":
|
case "--optimizeForSpeed", "-O":
|
||||||
inMemoryMode = true
|
inMemoryMode = true
|
||||||
|
case "--yes", "-y":
|
||||||
|
yesMode = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,18 +141,27 @@ func main() {
|
||||||
var epkList []common.InstallPackage
|
var epkList []common.InstallPackage
|
||||||
var skipEpkList [][]string
|
var skipEpkList [][]string
|
||||||
var dependencies int
|
var dependencies int
|
||||||
|
|
||||||
|
localPackageListIteration:
|
||||||
for _, pkg := range localPackageList {
|
for _, pkg := range localPackageList {
|
||||||
|
// Check if the package is already in epkList.
|
||||||
|
for _, epk := range epkList {
|
||||||
|
if epk.EPKPreMap.DisplayData.Name == pkg {
|
||||||
|
continue localPackageListIteration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
epkFile, err := os.Open(pkg)
|
epkFile, err := os.Open(pkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to open package: " + err.Error()))
|
fmt.Println(color.RedString("Failed to open package: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var displayData lib.EPKPreMap
|
var preMap lib.EPKPreMap
|
||||||
var vagueErr error
|
var vagueErr error
|
||||||
var epkBytes bytes.Buffer
|
var epkBytes bytes.Buffer
|
||||||
if !inMemoryMode {
|
if !inMemoryMode {
|
||||||
displayData, err, vagueErr = lib.PreMapEPK(lib.StreamOrBytes{FileStream: epkFile, IsFileStream: true}, fileInfos[pkg].Size())
|
preMap, err, vagueErr = lib.PreMapEPK(lib.StreamOrBytes{FileStream: epkFile, IsFileStream: true}, fileInfos[pkg].Size())
|
||||||
} else {
|
} else {
|
||||||
_, err = io.Copy(bufio.NewWriter(&epkBytes), epkFile)
|
_, err = io.Copy(bufio.NewWriter(&epkBytes), epkFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -149,15 +173,29 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.HiYellowString("Failed to close package file: " + err.Error() + ", memory leak possible."))
|
fmt.Println(color.HiYellowString("Failed to close package file: " + err.Error() + ", memory leak possible."))
|
||||||
}
|
}
|
||||||
displayData, err, vagueErr = lib.PreMapEPK(lib.StreamOrBytes{Bytes: epkBytes.Bytes()}, fileInfos[pkg].Size())
|
preMap, err, vagueErr = lib.PreMapEPK(lib.StreamOrBytes{Bytes: epkBytes.Bytes()}, fileInfos[pkg].Size())
|
||||||
}
|
}
|
||||||
if err != nil || vagueErr != nil {
|
if err != nil || vagueErr != nil {
|
||||||
common.PreMapEPKHandleError(err, vagueErr, logger)
|
common.PreMapEPKHandleError(err, vagueErr, logger)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the architecture is supported.
|
||||||
|
var uts unix.Utsname
|
||||||
|
err = unix.Uname(&uts)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to get system architecture: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the architecture is supported.
|
||||||
|
if preMap.DisplayData.Architecture != "noarch" || preMap.DisplayData.Architecture != string(uts.Machine[:]) {
|
||||||
|
fmt.Println(color.RedString("Package architecture not supported: " + preMap.DisplayData.Architecture))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
var installPackage common.InstallPackage
|
var installPackage common.InstallPackage
|
||||||
installPackage.EPKPreMap = &displayData
|
installPackage.EPKPreMap = &preMap
|
||||||
installPackage.Url = ""
|
installPackage.Url = ""
|
||||||
installPackage.Priority = 0
|
installPackage.Priority = 0
|
||||||
installPackage.IsRemote = false
|
installPackage.IsRemote = false
|
||||||
|
@ -174,21 +212,23 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
installPackage.Repository = lib.Repository{Name: "Local file"}
|
installPackage.Repository = lib.Repository{Name: "Local file"}
|
||||||
displayData.IsUpgrade = true
|
preMap.IsUpgrade = true
|
||||||
|
|
||||||
version, exists, err := common.DefaultCheckEPKInDB(displayData.Name)
|
version, exists, err := common.DefaultCheckEPKInDB(preMap.DisplayData.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to check for package in database: " + err.Error()))
|
fmt.Println(color.RedString("Failed to check for package in database: " + err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
if version.Compare(&displayData.Version) != -1 {
|
if version.Compare(&preMap.DisplayData.Version) != -1 {
|
||||||
if !forceMode {
|
if !forceMode {
|
||||||
skipEpk := []string{displayData.Name, displayData.Architecture, displayData.Version.String(), "Local file", humanize.BigIBytes(displayData.DecompressedSize), "Skip"}
|
skipEpk := []string{preMap.DisplayData.Name, preMap.DisplayData.Architecture, preMap.DisplayData.Version.String(), "Local file", humanize.BigIBytes(preMap.DisplayData.DecompressedSize), "Skip"}
|
||||||
skipEpkList = append(skipEpkList, skipEpk)
|
skipEpkList = append(skipEpkList, skipEpk)
|
||||||
} else {
|
} else {
|
||||||
installPackage.IsForced = true
|
installPackage.IsForced = true
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -198,7 +238,9 @@ func main() {
|
||||||
epkList = append(epkList, installPackage)
|
epkList = append(epkList, installPackage)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -208,8 +250,10 @@ func main() {
|
||||||
epkList = append(epkList, installPackage)
|
epkList = append(epkList, installPackage)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayData.IsUpgrade = false
|
preMap.IsUpgrade = false
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, installPackage, 0, []lib.RemoteEPK{}, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -220,7 +264,15 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repoPackageListIteration:
|
||||||
for _, pkg := range repoPackageList {
|
for _, pkg := range repoPackageList {
|
||||||
|
// Check if the package is already in epkList.
|
||||||
|
for _, epk := range epkList {
|
||||||
|
if epk.EPKPreMap.DisplayData.Name == pkg {
|
||||||
|
continue repoPackageListIteration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the package is already installed.
|
// Check if the package is already installed.
|
||||||
version, exists, err := common.DefaultCheckEPKInDB(pkg)
|
version, exists, err := common.DefaultCheckEPKInDB(pkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -237,13 +289,20 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
epkExists := false
|
||||||
for _, epk := range remoteEpkList {
|
for _, epk := range remoteEpkList {
|
||||||
if epk.Name == pkg {
|
if epk.Name == pkg {
|
||||||
remoteEPK = epk
|
remoteEPK = epk
|
||||||
|
epkExists = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !epkExists {
|
||||||
|
fmt.Println(color.RedString("Package not found: " + pkg))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the download URL
|
// Calculate the download URL
|
||||||
epkDownloadUrl, err := url.JoinPath(remoteEPK.Repository.URL, remoteEPK.Path)
|
epkDownloadUrl, err := url.JoinPath(remoteEPK.Repository.URL, remoteEPK.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -253,15 +312,15 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-map the EPK
|
// Pre-map the EPK
|
||||||
displayData, err, vagueErr := lib.PreMapRemoteEPK(remoteEPK, logger)
|
preMap, err, vagueErr := lib.PreMapRemoteEPK(remoteEPK, logger)
|
||||||
if err != nil || vagueErr != nil {
|
if err != nil || vagueErr != nil {
|
||||||
common.PreMapEPKHandleError(err, vagueErr, logger)
|
common.PreMapRemoteEPKHandleError(err, vagueErr, logger)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map the data we have
|
// Map the data we have
|
||||||
epkEntry.Priority = 0
|
epkEntry.Priority = 0
|
||||||
epkEntry.EPKPreMap = &displayData
|
epkEntry.EPKPreMap = &preMap
|
||||||
epkEntry.Url = epkDownloadUrl
|
epkEntry.Url = epkDownloadUrl
|
||||||
epkEntry.IsRemote = true
|
epkEntry.IsRemote = true
|
||||||
epkEntry.Repository = remoteEPK.Repository
|
epkEntry.Repository = remoteEPK.Repository
|
||||||
|
@ -287,7 +346,7 @@ func main() {
|
||||||
contentLength.SetString(epkBytes.Header.Get("Content-Length"), 10)
|
contentLength.SetString(epkBytes.Header.Get("Content-Length"), 10)
|
||||||
|
|
||||||
// Print that we are downloading the package
|
// Print that we are downloading the package
|
||||||
fmt.Println("\nDownloading package: " + displayData.Name + " (" + humanize.BigIBytes(contentLength) + ")")
|
fmt.Println("\nDownloading package: " + preMap.DisplayData.Name + " (" + humanize.BigIBytes(contentLength) + ")")
|
||||||
|
|
||||||
// Hide the cursor for reasons explained below.
|
// Hide the cursor for reasons explained below.
|
||||||
fmt.Print("\033[?25l")
|
fmt.Print("\033[?25l")
|
||||||
|
@ -331,15 +390,17 @@ func main() {
|
||||||
|
|
||||||
// Make decisions on what happens if the package is already installed.
|
// Make decisions on what happens if the package is already installed.
|
||||||
if exists {
|
if exists {
|
||||||
if version.Compare(&displayData.Version) != -1 {
|
if version.Compare(&preMap.DisplayData.Version) != -1 {
|
||||||
// If the version is the same or newer, skip the package.
|
// If the version is the same or newer, skip the package.
|
||||||
if !forceMode {
|
if !forceMode {
|
||||||
skipEpkList = append(skipEpkList, []string{displayData.Name, displayData.Architecture, displayData.Version.String(), remoteEPK.Repository.Name, humanize.BigIBytes(displayData.DecompressedSize), "Skip"})
|
skipEpkList = append(skipEpkList, []string{preMap.DisplayData.Name, preMap.DisplayData.Architecture, preMap.DisplayData.Version.String(), remoteEPK.Repository.Name, humanize.BigIBytes(preMap.DisplayData.DecompressedSize), "Skip"})
|
||||||
} else {
|
} else {
|
||||||
// If the version is the same or newer, but the user wants to force the installation, install it.
|
// If the version is the same or newer, but the user wants to force the installation, install it.
|
||||||
epkEntry.IsForced = true
|
epkEntry.IsForced = true
|
||||||
// We can let it use our remoteEPKList to save a SQL query.
|
// We can let it use our remoteEPKList to save a SQL query.
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -351,7 +412,9 @@ func main() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the version is older, install it.
|
// If the version is older, install it.
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -362,7 +425,9 @@ func main() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the package is not installed, install it.
|
// If the package is not installed, install it.
|
||||||
addedDeps, err := common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, &epkList, logger)
|
var emptyList []string
|
||||||
|
var addedDeps int
|
||||||
|
epkList, addedDeps, err = common.HandleDependencies(dependencies, epkEntry, 0, remoteEpkList, common.DefaultListRemotePackagesInDB, epkList, &emptyList, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
fmt.Println(color.RedString("Failed to handle dependencies: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -373,6 +438,14 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort the list of packages to install by priority, then alphabetically.
|
||||||
|
sort.Slice(epkList, func(i, j int) bool {
|
||||||
|
if epkList[i].Priority == epkList[j].Priority {
|
||||||
|
return epkList[i].EPKPreMap.DisplayData.Name < epkList[j].EPKPreMap.DisplayData.Name
|
||||||
|
}
|
||||||
|
return epkList[i].Priority > epkList[j].Priority
|
||||||
|
})
|
||||||
|
|
||||||
// Give the summary of the installation.
|
// Give the summary of the installation.
|
||||||
fmt.Println("\nThe following packages will be installed:")
|
fmt.Println("\nThe following packages will be installed:")
|
||||||
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
||||||
|
@ -407,15 +480,15 @@ func main() {
|
||||||
|
|
||||||
for _, pkg := range epkList {
|
for _, pkg := range epkList {
|
||||||
finalisedList := make([]string, 6)
|
finalisedList := make([]string, 6)
|
||||||
finalisedList[0] = pkg.EPKPreMap.Name
|
finalisedList[0] = pkg.EPKPreMap.DisplayData.Name
|
||||||
finalisedList[1] = pkg.EPKPreMap.Architecture
|
finalisedList[1] = pkg.EPKPreMap.DisplayData.Architecture
|
||||||
finalisedList[2] = pkg.EPKPreMap.Version.String()
|
finalisedList[2] = pkg.EPKPreMap.DisplayData.Version.String()
|
||||||
if !pkg.IsRemote {
|
if !pkg.IsRemote {
|
||||||
finalisedList[3] = "Local file"
|
finalisedList[3] = "Local file"
|
||||||
} else {
|
} else {
|
||||||
finalisedList[3] = pkg.Repository.Name
|
finalisedList[3] = pkg.Repository.Name
|
||||||
}
|
}
|
||||||
finalisedList[4] = humanize.BigIBytes(pkg.EPKPreMap.DecompressedSize)
|
finalisedList[4] = humanize.BigIBytes(pkg.EPKPreMap.DisplayData.DecompressedSize)
|
||||||
if pkg.IsForced {
|
if pkg.IsForced {
|
||||||
finalisedList[5] = "Forced installation"
|
finalisedList[5] = "Forced installation"
|
||||||
} else if pkg.EPKPreMap.IsUpgrade {
|
} else if pkg.EPKPreMap.IsUpgrade {
|
||||||
|
@ -436,13 +509,16 @@ func main() {
|
||||||
fmt.Println("\nInstalling " + humanize.Comma(int64(len(epkList))) + " packages, of which " + humanize.Comma(int64(dependencies)) + " are dependencies.")
|
fmt.Println("\nInstalling " + humanize.Comma(int64(len(epkList))) + " packages, of which " + humanize.Comma(int64(dependencies)) + " are dependencies.")
|
||||||
fmt.Println("Total download size: " + humanize.BigIBytes(common.GetTotalSize(epkList)))
|
fmt.Println("Total download size: " + humanize.BigIBytes(common.GetTotalSize(epkList)))
|
||||||
fmt.Println("Total installed size: " + humanize.BigIBytes(common.GetTotalInstalledSize(epkList)) + "\n")
|
fmt.Println("Total installed size: " + humanize.BigIBytes(common.GetTotalInstalledSize(epkList)) + "\n")
|
||||||
response := logger.LogFunc(lib.Log{
|
var response string
|
||||||
|
if !yesMode {
|
||||||
|
response = logger.LogFunc(lib.Log{
|
||||||
Level: "INFO",
|
Level: "INFO",
|
||||||
Content: "Proceed with installation (y/n)?",
|
Content: "Proceed with installation (y/n)?",
|
||||||
Prompt: true,
|
Prompt: true,
|
||||||
PlaySound: true,
|
PlaySound: true,
|
||||||
})
|
})
|
||||||
if strings.ToLower(response) == "y" {
|
}
|
||||||
|
if strings.ToLower(response) == "y" || yesMode {
|
||||||
// We hide the cursor because it makes the progress bar look weird and other package managers hide
|
// We hide the cursor because it makes the progress bar look weird and other package managers hide
|
||||||
// it during installation. For some reason, it builds suspense. Or it does with me anyway, when
|
// it during installation. For some reason, it builds suspense. Or it does with me anyway, when
|
||||||
// a program hides the cursor, it makes me think twice than to Ctrl+C it :P
|
// a program hides the cursor, it makes me think twice than to Ctrl+C it :P
|
||||||
|
@ -450,10 +526,78 @@ func main() {
|
||||||
fmt.Print("\033[?25l")
|
fmt.Print("\033[?25l")
|
||||||
// Time to install things.
|
// Time to install things.
|
||||||
for _, installPackage := range epkList {
|
for _, installPackage := range epkList {
|
||||||
|
if installPackage.IsRemote {
|
||||||
|
if !inMemoryMode {
|
||||||
|
// Set the package stream to the URL.
|
||||||
|
installPackage.StreamOrBytes.IsURL = true
|
||||||
|
installPackage.StreamOrBytes.IsRemote = true
|
||||||
|
installPackage.StreamOrBytes.RepositoryName = installPackage.Repository.Name
|
||||||
|
installPackage.StreamOrBytes.IsFileStream = false
|
||||||
|
installPackage.StreamOrBytes.URL = installPackage.Url
|
||||||
|
} else {
|
||||||
|
// Download the entire EPK into memory
|
||||||
|
epkBytes, err := http.Get(installPackage.Url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to download package: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if epkBytes.StatusCode != 200 {
|
||||||
|
fmt.Println(color.RedString("Failed to download package: " + epkBytes.Status))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start streaming the package into a buffer
|
||||||
|
contentLength := new(big.Int).SetBytes([]byte(epkBytes.Header.Get("Content-Length")))
|
||||||
|
fmt.Println("\nDownloading package: " + installPackage.EPKPreMap.DisplayData.Name + " (" + humanize.BigIBytes(contentLength) + ")")
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
_, err = io.Copy(&lib.ProgressWriter{
|
||||||
|
Logger: logger,
|
||||||
|
Total: contentLength,
|
||||||
|
Writer: &buffer,
|
||||||
|
}, epkBytes.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to read package into memory: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the progress to 100%
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "PROGRESS",
|
||||||
|
Progress: big.NewInt(1),
|
||||||
|
Total: big.NewInt(1),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close the response body
|
||||||
|
err = epkBytes.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.HiYellowString("Failed to close response body: " + err.Error() + ", memory leak possible."))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Package downloaded")
|
||||||
|
|
||||||
|
// Set the buffer as the bytes
|
||||||
|
installPackage.StreamOrBytes.Bytes = buffer.Bytes()
|
||||||
|
installPackage.StreamOrBytes.IsURL = false
|
||||||
|
installPackage.StreamOrBytes.IsRemote = true
|
||||||
|
installPackage.StreamOrBytes.RepositoryName = installPackage.Repository.Name
|
||||||
|
installPackage.StreamOrBytes.IsFileStream = false
|
||||||
|
}
|
||||||
|
}
|
||||||
// Map the EPK metadata.
|
// Map the EPK metadata.
|
||||||
metadata, err, vagueErr := lib.FullyMapMetadata(installPackage.StreamOrBytes,
|
metadata, err, vagueErr := lib.FullyMapMetadata(installPackage.StreamOrBytes,
|
||||||
installPackage.EPKPreMap, common.DefaultGetFingerprintFromDB,
|
installPackage.EPKPreMap, common.DefaultGetFingerprintFromDB,
|
||||||
common.DefaultAddFingerprintToDB, logger)
|
common.DefaultAddFingerprintToDB, func(*lib.Logger) {
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "WARN",
|
||||||
|
Content: "This server does not support range requests. Please use the -O flag to " +
|
||||||
|
"enable in memory mode, or contact the server administrator to use a web server " +
|
||||||
|
"that supports range requests, such as Apache or Nginx. The speed of download " +
|
||||||
|
"is considerably slowed, as we need to discard bytes since we can only read " +
|
||||||
|
"sequentially.",
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
}, logger)
|
||||||
if err != nil || vagueErr != nil {
|
if err != nil || vagueErr != nil {
|
||||||
common.FullyMapMetadataHandleError(err, vagueErr, logger)
|
common.FullyMapMetadataHandleError(err, vagueErr, logger)
|
||||||
}
|
}
|
||||||
|
@ -464,7 +608,7 @@ func main() {
|
||||||
common.InstallEPKHandleError(tempDir, err, vagueErr, logger)
|
common.InstallEPKHandleError(tempDir, err, vagueErr, logger)
|
||||||
}
|
}
|
||||||
// Done!
|
// Done!
|
||||||
fmt.Println("Installed package: " + installPackage.EPKPreMap.Name)
|
fmt.Println("Installed package: " + installPackage.EPKPreMap.DisplayData.Name)
|
||||||
}
|
}
|
||||||
// We show the cursor again because we're done with the progress bar.
|
// We show the cursor again because we're done with the progress bar.
|
||||||
fmt.Print("\033[?25h")
|
fmt.Print("\033[?25h")
|
||||||
|
@ -486,7 +630,7 @@ func main() {
|
||||||
}
|
}
|
||||||
case "repo":
|
case "repo":
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Usage: eon repo (add/remove/list)")
|
fmt.Println("Usage: eon repo (add/del/list)")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,9 +652,9 @@ func main() {
|
||||||
fmt.Println("Added repository " + repoName + " to the database.")
|
fmt.Println("Added repository " + repoName + " to the database.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "remove":
|
case "del":
|
||||||
if len(os.Args) < 4 {
|
if len(os.Args) < 4 {
|
||||||
fmt.Println("Usage: eon repo remove <name>")
|
fmt.Println("Usage: eon repo del <name>")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
err := common.EstablishDBConnection(logger)
|
err := common.EstablishDBConnection(logger)
|
||||||
|
@ -539,7 +683,174 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Repositories:")
|
fmt.Println("Repositories:")
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
fmt.Println("\n" + repo.Name + ":\n" + " " + repo.Description + "\n URL: " + repo.URL + "\n Owner: " + repo.Owner)
|
fmt.Println("\n" + repo.Name + ":\n" + "- " + repo.Description + "\n- URL: " + repo.URL + "\n- Owner: " + repo.Owner)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "remove":
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
fmt.Println("Usage: eon remove <package>")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err := common.EstablishDBConnection(logger)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to establish a connection to the database: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Create a map of all installed packages, to minimise the database queries later.
|
||||||
|
epkMap, decompressedSizeMap, repositoryMap, _, err := common.DefaultListEPKsInDB()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to list installed packages: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Create a list of packages to remove.
|
||||||
|
var packageRemoveList []common.RemovePackage
|
||||||
|
for _, pkg := range os.Args[2:] {
|
||||||
|
var removePackage common.RemovePackage
|
||||||
|
_, exists, err := common.DefaultCheckEPKInDB(pkg)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to check for package in database: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
fmt.Println(color.RedString("Package not found: " + pkg))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Search to see if it's parent is still installed.
|
||||||
|
for _, epk := range epkMap {
|
||||||
|
for _, dep := range epk.Dependencies {
|
||||||
|
if dep == os.Args[2] {
|
||||||
|
// First, check if it's in the list of packages to remove.
|
||||||
|
var found bool
|
||||||
|
for _, epkName := range os.Args[2:] {
|
||||||
|
if epkName == epk.Name {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
fmt.Println(color.RedString("Package " + pkg + " is a dependency of another package (" + epk.Name + ") and cannot be removed."))
|
||||||
|
os.Exit(1)
|
||||||
|
} else {
|
||||||
|
// It is in the list of packages to remove, we need to set this package's priority higher.
|
||||||
|
removePackage.Priority++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add it to the list of packages to remove.
|
||||||
|
removePackage.Name = pkg
|
||||||
|
removePackage.DisplayData = epkMap[pkg]
|
||||||
|
packageRemoveList = append(packageRemoveList, removePackage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(packageRemoveList) > 0 {
|
||||||
|
// First, re-order the packageRemoveList by priority, then alphabetically.
|
||||||
|
sort.Slice(packageRemoveList, func(i, j int) bool {
|
||||||
|
if packageRemoveList[i].Priority == packageRemoveList[j].Priority {
|
||||||
|
return packageRemoveList[i].Name < packageRemoveList[j].Name
|
||||||
|
}
|
||||||
|
return packageRemoveList[i].Priority > packageRemoveList[j].Priority
|
||||||
|
})
|
||||||
|
|
||||||
|
// Print the packages that will be removed.
|
||||||
|
fmt.Println("The following packages will be removed:")
|
||||||
|
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to get terminal width: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if width < 42 {
|
||||||
|
fmt.Println(color.RedString("Terminal too small. Minimum required width: 42 characters."))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for range width {
|
||||||
|
fmt.Print("=")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
tableList := []string{"Package", "Architecture", "Version", "Repository", "Installed Size", "Action"}
|
||||||
|
maxSize := width / 6
|
||||||
|
for _, item := range tableList {
|
||||||
|
common.PrintWithEvenPadding(item, maxSize)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
for range width {
|
||||||
|
fmt.Print("=")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
for _, pkg := range packageRemoveList {
|
||||||
|
finalisedList := make([]string, 6)
|
||||||
|
finalisedList[0] = pkg.Name
|
||||||
|
finalisedList[1] = pkg.DisplayData.Architecture
|
||||||
|
finalisedList[2] = pkg.DisplayData.Version.String()
|
||||||
|
finalisedList[3] = repositoryMap[pkg.Name].Name
|
||||||
|
finalisedList[4] = humanize.BigIBytes(decompressedSizeMap[pkg.Name])
|
||||||
|
finalisedList[5] = "Remove"
|
||||||
|
for _, item := range finalisedList {
|
||||||
|
common.PrintWithEvenPadding(item, maxSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for range width {
|
||||||
|
fmt.Print("=")
|
||||||
|
}
|
||||||
|
fmt.Println("Transaction Summary")
|
||||||
|
fmt.Println("\nRemoving " + humanize.Comma(int64(len(packageRemoveList))) + " packages.")
|
||||||
|
space := new(big.Int)
|
||||||
|
for _, pkg := range packageRemoveList {
|
||||||
|
space = new(big.Int).Add(space, decompressedSizeMap[pkg.Name])
|
||||||
|
}
|
||||||
|
fmt.Println("Total reclaimed space: " + humanize.BigIBytes(space) + "\n")
|
||||||
|
response := logger.LogFunc(lib.Log{
|
||||||
|
Level: "INFO",
|
||||||
|
Content: "Proceed with removal (y/n)?",
|
||||||
|
Prompt: true,
|
||||||
|
})
|
||||||
|
if strings.ToLower(response) == "y" {
|
||||||
|
for _, pkg := range packageRemoveList {
|
||||||
|
err, vagueErr := lib.RemoveEPK(pkg.Name, common.DefaultRemoveEPKFromDB, common.DefaultGetEPKRemoveInfoFromDB, logger)
|
||||||
|
if err != nil || vagueErr != nil {
|
||||||
|
common.RemoveEPKHandleError(err, vagueErr, logger)
|
||||||
|
fmt.Println(color.RedString("Failed to remove package: " + vagueErr.Error() + err.Error()))
|
||||||
|
}
|
||||||
|
fmt.Println("Removed package: " + pkg.Name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("Removal cancelled.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "list":
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
fmt.Println("Usage: eon list (remote/local)")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := common.EstablishDBConnection(logger)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to establish a connection to the database: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[2] {
|
||||||
|
case "remote":
|
||||||
|
remoteEpkList, err := common.DefaultListRemotePackagesInDB()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(color.RedString("Failed to list remote packages: " + err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if len(remoteEpkList) == 0 {
|
||||||
|
fmt.Println("No remote packages.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Remote packages:")
|
||||||
|
for _, epk := range remoteEpkList {
|
||||||
|
fmt.Println("\n" + epk.Name + ":\n" +
|
||||||
|
"- " + epk.Description +
|
||||||
|
"\n- Author: " + epk.Author +
|
||||||
|
"\n- Size to download: " + humanize.Bytes(uint64(epk.CompressedSize)) +
|
||||||
|
"\n- Version: " + epk.Version.String() +
|
||||||
|
"\n- Architecture: " + epk.Architecture +
|
||||||
|
"\n- Repository: " + epk.Repository.Name)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
475
common/main.go
475
common/main.go
|
@ -1,25 +1,27 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"eon/lib"
|
"eon/lib"
|
||||||
"math"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"plugin"
|
"plugin"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/binary"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
|
|
||||||
|
@ -39,6 +41,12 @@ type InstallPackage struct {
|
||||||
Repository lib.Repository
|
Repository lib.Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RemovePackage struct {
|
||||||
|
Name string
|
||||||
|
Priority int
|
||||||
|
DisplayData lib.DisplayData
|
||||||
|
}
|
||||||
|
|
||||||
type PluginInfo struct {
|
type PluginInfo struct {
|
||||||
Name string
|
Name string
|
||||||
HasErrHandler bool
|
HasErrHandler bool
|
||||||
|
@ -53,7 +61,7 @@ type Plugin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var conn *sql.DB
|
var conn *sql.DB
|
||||||
var dbVersion = semver.MustParse("1.0.0-beta.3")
|
var dbVersion = semver.MustParse("1.0.0-beta.4")
|
||||||
|
|
||||||
var DefaultLogger = lib.Logger{
|
var DefaultLogger = lib.Logger{
|
||||||
LogFunc: func(log lib.Log) string {
|
LogFunc: func(log lib.Log) string {
|
||||||
|
@ -83,7 +91,7 @@ var DefaultLogger = lib.Logger{
|
||||||
// Get the terminal width so we can calculate the width of the progress bar.
|
// Get the terminal width so we can calculate the width of the progress bar.
|
||||||
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to get terminal width: " + err.Error()))
|
fmt.Println(color.RedString("Could not get terminal width: " + err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
// Calculate the percentage in text form.
|
// Calculate the percentage in text form.
|
||||||
|
@ -123,13 +131,13 @@ var DefaultLogger = lib.Logger{
|
||||||
}
|
}
|
||||||
if log.Prompt {
|
if log.Prompt {
|
||||||
fmt.Print(": ")
|
fmt.Print(": ")
|
||||||
var userInput string
|
reader := bufio.NewReader(os.Stdin)
|
||||||
_, err := fmt.Scanln(&userInput)
|
userInput, err := reader.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("Failed to read input: " + err.Error()))
|
fmt.Println(color.RedString("[FATAL]"), "Could not read user input:", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
return userInput
|
return userInput[:len(userInput)-1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
@ -185,45 +193,44 @@ var TimeMagnitudes = []humanize.RelTimeMagnitude{
|
||||||
// End of Expat / MIT licensed code
|
// End of Expat / MIT licensed code
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleDependencies(previousDeps int, targetEPK InstallPackage, parentPriority int, epkList []lib.RemoteEPK, ListRemotePackagesInDB func() ([]lib.RemoteEPK, error), InstallPackageList *[]InstallPackage, logger *lib.Logger) (int, error) {
|
func HandleDependencies(previousDeps int, targetEPK InstallPackage, parentPriority int, epkList []lib.RemoteEPK, ListRemotePackagesInDB func() ([]lib.RemoteEPK, error), InstallPackageList []InstallPackage, previousPackages *[]string, logger *lib.Logger) ([]InstallPackage, int, error) {
|
||||||
// Iterate through the dependencies of the target EPK.
|
// Iterate through the dependencies of the target EPK.
|
||||||
dependencyLoop:
|
dependencyLoop:
|
||||||
for _, dependency := range targetEPK.EPKPreMap.Dependencies {
|
for _, dependency := range targetEPK.EPKPreMap.DisplayData.Dependencies {
|
||||||
// Check if the dependency is already in the list of EPKs to install.
|
// Check if the dependency is already in the list of EPKs to install.
|
||||||
for iterator, epk := range *InstallPackageList {
|
for iterator, epk := range InstallPackageList {
|
||||||
if epk.EPKPreMap.Name == dependency {
|
if epk.EPKPreMap.DisplayData.Name == dependency {
|
||||||
// The dependency is already in the list of EPKs to install, check for its dependencies.
|
// The dependency is already in the list of EPKs to install, check for its dependencies.
|
||||||
if len(epk.EPKPreMap.Dependencies) == 0 || epk.EPKPreMap.Dependencies == nil {
|
if len(epk.EPKPreMap.DisplayData.Dependencies) == 0 || epk.EPKPreMap.DisplayData.Dependencies == nil {
|
||||||
// All dependencies are handled - change the priority and continue with the next dependency.
|
// All dependencies are handled - change the priority and continue with the next dependency.
|
||||||
epk.Priority = parentPriority + 1
|
epk.Priority = parentPriority + 1
|
||||||
currentInstallPackageList := *InstallPackageList
|
InstallPackageList[iterator] = epk
|
||||||
currentInstallPackageList[iterator] = epk
|
|
||||||
InstallPackageList = ¤tInstallPackageList
|
|
||||||
continue dependencyLoop
|
continue dependencyLoop
|
||||||
} else {
|
} else {
|
||||||
// Check if it's a circular dependency.
|
// Check if it's a circular dependency.
|
||||||
for _, epk := range *InstallPackageList {
|
for _, epk := range *previousPackages {
|
||||||
if epk.EPKPreMap.Name == targetEPK.EPKPreMap.Name {
|
if epk == targetEPK.EPKPreMap.DisplayData.Name {
|
||||||
// We have a circular dependency. Crash immediately.
|
// We have a circular dependency. Crash immediately.
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Circular dependency detected: " + targetEPK.EPKPreMap.Name + " -> " + dependency + " -> " + targetEPK.EPKPreMap.Name,
|
Content: "Circular dependency detected: " + targetEPK.EPKPreMap.DisplayData.Name + " -> " + dependency + " -> " + targetEPK.EPKPreMap.DisplayData.Name,
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add the dependency to the list of previous packages.
|
||||||
|
*previousPackages = append(*previousPackages, targetEPK.EPKPreMap.DisplayData.Name)
|
||||||
// Recursively handle dependencies.
|
// Recursively handle dependencies.
|
||||||
addedDeps, err := HandleDependencies(previousDeps, epk, parentPriority+1, epkList, ListRemotePackagesInDB, InstallPackageList, logger)
|
installedPackage, addedDeps, err := HandleDependencies(previousDeps, epk, parentPriority+1, epkList, ListRemotePackagesInDB, InstallPackageList, previousPackages, logger)
|
||||||
|
InstallPackageList = installedPackage
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, 0, err
|
||||||
} else {
|
} else {
|
||||||
// Add the dependencies to the total number of dependencies.
|
// Add the dependencies to the total number of dependencies.
|
||||||
previousDeps += addedDeps
|
previousDeps += addedDeps
|
||||||
// All dependencies are now handled - change the priority and continue with the next dependency.
|
// All dependencies are now handled - change the priority and continue with the next dependency.
|
||||||
epk.Priority = parentPriority + 1
|
epk.Priority = parentPriority + 1
|
||||||
currentInstallPackageList := *InstallPackageList
|
InstallPackageList[iterator] = epk
|
||||||
currentInstallPackageList[iterator] = epk
|
|
||||||
InstallPackageList = ¤tInstallPackageList
|
|
||||||
continue dependencyLoop
|
continue dependencyLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,14 +242,14 @@ dependencyLoop:
|
||||||
var err error
|
var err error
|
||||||
epkList, err = ListRemotePackagesInDB()
|
epkList, err = ListRemotePackagesInDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we already have the EPK installed.
|
// Check if we already have the EPK installed.
|
||||||
version, exists, err := DefaultCheckEPKInDB(dependency)
|
version, exists, err := DefaultCheckEPKInDB(dependency)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteEPK lib.RemoteEPK
|
var remoteEPK lib.RemoteEPK
|
||||||
|
@ -270,7 +277,7 @@ dependencyLoop:
|
||||||
}
|
}
|
||||||
// If the dependency doesn't exist, crash.
|
// If the dependency doesn't exist, crash.
|
||||||
if !dependencyExists {
|
if !dependencyExists {
|
||||||
return 0, errors.New("dependency " + dependency + " does not exist")
|
return nil, 0, errors.New("dependency " + dependency + " does not exist")
|
||||||
}
|
}
|
||||||
// Increase the dependency's priority.
|
// Increase the dependency's priority.
|
||||||
epkEntry.Priority = parentPriority + 1
|
epkEntry.Priority = parentPriority + 1
|
||||||
|
@ -279,7 +286,7 @@ dependencyLoop:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to join URL path: " + err.Error(),
|
Content: "Could not join URL path: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -289,7 +296,7 @@ dependencyLoop:
|
||||||
// Map the EPKs display data.
|
// Map the EPKs display data.
|
||||||
epkPreMap, err, vagueErr := lib.PreMapRemoteEPK(remoteEPK, logger)
|
epkPreMap, err, vagueErr := lib.PreMapRemoteEPK(remoteEPK, logger)
|
||||||
if err != nil || vagueErr != nil {
|
if err != nil || vagueErr != nil {
|
||||||
return 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
// Set the EPKs display data.
|
// Set the EPKs display data.
|
||||||
epkEntry.EPKPreMap = &epkPreMap
|
epkEntry.EPKPreMap = &epkPreMap
|
||||||
|
@ -304,40 +311,42 @@ dependencyLoop:
|
||||||
// Check if the dependency has dependencies, and if so, recursively handle them.
|
// Check if the dependency has dependencies, and if so, recursively handle them.
|
||||||
if !(len(remoteEPK.Dependencies) == 0 || remoteEPK.Dependencies == nil) {
|
if !(len(remoteEPK.Dependencies) == 0 || remoteEPK.Dependencies == nil) {
|
||||||
// Check if it's a circular dependency.
|
// Check if it's a circular dependency.
|
||||||
for _, epk := range *InstallPackageList {
|
for _, epk := range *previousPackages {
|
||||||
if epk.EPKPreMap.Name == targetEPK.EPKPreMap.Name {
|
if epk == targetEPK.EPKPreMap.DisplayData.Name {
|
||||||
// We have a circular dependency. Crash immediately.
|
// We have a circular dependency. Crash immediately.
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Circular dependency detected: " + targetEPK.EPKPreMap.Name + " -> " + dependency + " -> " + targetEPK.EPKPreMap.Name,
|
Content: "Circular dependency detected: " + targetEPK.EPKPreMap.DisplayData.Name + " -> " + dependency + " -> " + targetEPK.EPKPreMap.DisplayData.Name,
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add the dependency to the list of previous packages.
|
||||||
|
*previousPackages = append(*previousPackages, epkEntry.EPKPreMap.DisplayData.Name)
|
||||||
// Recursively handle dependencies.
|
// Recursively handle dependencies.
|
||||||
addedDeps, err := HandleDependencies(previousDeps, epkEntry, epkEntry.Priority+1, epkList, ListRemotePackagesInDB, InstallPackageList, logger)
|
installPackages, addedDeps, err := HandleDependencies(previousDeps, epkEntry, epkEntry.Priority+1, epkList, ListRemotePackagesInDB, InstallPackageList, previousPackages, logger)
|
||||||
|
InstallPackageList = installPackages
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the dependencies to the total number of dependencies.
|
// Add the dependencies to the total number of dependencies.
|
||||||
previousDeps += addedDeps
|
previousDeps += addedDeps
|
||||||
}
|
}
|
||||||
// All dependencies are now handled - continue with the next dependency.
|
// All dependencies are now handled - continue with the next dependency.
|
||||||
currentInstallPackageList := append(*InstallPackageList, epkEntry)
|
InstallPackageList = append(InstallPackageList, epkEntry)
|
||||||
InstallPackageList = ¤tInstallPackageList
|
|
||||||
previousDeps++
|
previousDeps++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reach this point, all dependencies have been handled.
|
// If we reach this point, all dependencies have been handled.
|
||||||
return previousDeps, nil
|
return InstallPackageList, previousDeps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTotalSize(InstallPackageList []InstallPackage) *big.Int {
|
func GetTotalSize(InstallPackageList []InstallPackage) *big.Int {
|
||||||
totalSize := new(big.Int)
|
totalSize := new(big.Int)
|
||||||
for _, epk := range InstallPackageList {
|
for _, epk := range InstallPackageList {
|
||||||
totalSize.Add(totalSize, big.NewInt(epk.EPKPreMap.Size))
|
totalSize.Add(totalSize, big.NewInt(epk.EPKPreMap.DisplayData.Size))
|
||||||
}
|
}
|
||||||
return totalSize
|
return totalSize
|
||||||
}
|
}
|
||||||
|
@ -346,7 +355,7 @@ func GetTotalInstalledSize(InstallPackageList []InstallPackage) *big.Int {
|
||||||
totalSize := new(big.Int)
|
totalSize := new(big.Int)
|
||||||
for _, epk := range InstallPackageList {
|
for _, epk := range InstallPackageList {
|
||||||
if !epk.IsRemote {
|
if !epk.IsRemote {
|
||||||
totalSize.Add(totalSize, epk.EPKPreMap.DecompressedSize)
|
totalSize.Add(totalSize, epk.EPKPreMap.DisplayData.DecompressedSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalSize
|
return totalSize
|
||||||
|
@ -492,7 +501,7 @@ func InitDB(conn *sql.DB) error {
|
||||||
|
|
||||||
// Huge query moment. This is way too big to read comfortably, but too bad! It breaks the Jetbrains SQL formatter if
|
// Huge query moment. This is way too big to read comfortably, but too bad! It breaks the Jetbrains SQL formatter if
|
||||||
// I break it into multiple lines.
|
// I break it into multiple lines.
|
||||||
_, err = conn.Exec("CREATE TABLE packages (name TEXT NOT NULL UNIQUE, description TEXT NOT NULL, longDescription TEXT NOT NULL, version TEXT NOT NULL, author TEXT NOT NULL, license TEXT NOT NULL, architecture TEXT NOT NULL, size INTEGER NOT NULL, dependencies TEXT NOT NULL, removeScript TEXT NOT NULL, hasRemoveScript BOOLEAN NOT NULL, isDependency BOOLEAN NOT NULL DEFAULT false, repository TEXT)")
|
_, err = conn.Exec("CREATE TABLE packages (name TEXT NOT NULL UNIQUE, description TEXT NOT NULL, longDescription TEXT NOT NULL, version TEXT NOT NULL, author TEXT NOT NULL, license TEXT NOT NULL, architecture TEXT NOT NULL, size INTEGER NOT NULL, dependencies TEXT NOT NULL, removeScript TEXT NOT NULL, hasRemoveScript BOOLEAN NOT NULL, isDependency BOOLEAN NOT NULL DEFAULT false, repository TEXT, installedPaths TEXT)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -590,7 +599,7 @@ func EstablishDBConnection(logger *lib.Logger) error {
|
||||||
} else {
|
} else {
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "The database is corrupted and cannot be used. Please reset the database.",
|
Content: "The database is corrupted and could not be used. Please reset the database.",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -598,7 +607,7 @@ func EstablishDBConnection(logger *lib.Logger) error {
|
||||||
} else {
|
} else {
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "The database is corrupted and cannot be used. Please reset the database.",
|
Content: "The database is corrupted and could not be used. Please reset the database.",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -645,7 +654,7 @@ func EstablishDBConnection(logger *lib.Logger) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultAddEPKToDB(metadata *lib.Metadata, removeScript []byte, dependency bool, hasRemoveScript bool, size int64, repository ...string) error {
|
func DefaultAddEPKToDB(metadata *lib.Metadata, installedPaths []string, removeScript []byte, dependency bool, hasRemoveScript bool, size int64, repository ...string) error {
|
||||||
// If it already exists, delete it. This may happen in a force-install scenario.
|
// If it already exists, delete it. This may happen in a force-install scenario.
|
||||||
_, err := conn.Exec("DELETE FROM packages WHERE name = ?", metadata.Name)
|
_, err := conn.Exec("DELETE FROM packages WHERE name = ?", metadata.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -663,6 +672,13 @@ func DefaultAddEPKToDB(metadata *lib.Metadata, removeScript []byte, dependency b
|
||||||
dependencies = "[]"
|
dependencies = "[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var installedPathsString string
|
||||||
|
if len(installedPaths) > 0 {
|
||||||
|
installedPathsString = "[" + strings.Join(installedPaths, ", ") + "]"
|
||||||
|
} else {
|
||||||
|
installedPathsString = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
// Another fat unreadable line so Jetbrains doesn't break the SQL formatter. Too bad!
|
// Another fat unreadable line so Jetbrains doesn't break the SQL formatter. Too bad!
|
||||||
// But seriously though why doesn't Jetbrains support this? It's literally their own IDE which tells me to not make
|
// But seriously though why doesn't Jetbrains support this? It's literally their own IDE which tells me to not make
|
||||||
// super-long lines, but then doesn't support it.
|
// super-long lines, but then doesn't support it.
|
||||||
|
@ -671,14 +687,15 @@ func DefaultAddEPKToDB(metadata *lib.Metadata, removeScript []byte, dependency b
|
||||||
// Not that I'm complaining or anything.
|
// Not that I'm complaining or anything.
|
||||||
// - Arzumify
|
// - Arzumify
|
||||||
if len(repository) > 0 {
|
if len(repository) > 0 {
|
||||||
_, err = conn.Exec("INSERT INTO packages (name, description, longDescription, version, author, license, architecture, size, dependencies, removeScript, hasRemoveScript, isDependency, repository) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
_, err = conn.Exec("INSERT INTO packages (name, description, longDescription, version, author, license, architecture, size, dependencies, removeScript, hasRemoveScript, isDependency, repository, installedPaths) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
metadata.Name, metadata.Description, metadata.LongDescription, metadata.Version.String(), metadata.Author,
|
metadata.Name, metadata.Description, metadata.LongDescription, metadata.Version.String(), metadata.Author,
|
||||||
metadata.License, metadata.Architecture, size, dependencies, string(removeScript), hasRemoveScript, dependency,
|
metadata.License, metadata.Architecture, size, dependencies, string(removeScript), hasRemoveScript, dependency,
|
||||||
repository[0])
|
repository[0], installedPathsString)
|
||||||
} else {
|
} else {
|
||||||
_, err = conn.Exec("INSERT INTO packages (name, description, longDescription, version, author, license, architecture, size, dependencies, removeScript, hasRemoveScript, isDependency) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
_, err = conn.Exec("INSERT INTO packages (name, description, longDescription, version, author, license, architecture, size, dependencies, removeScript, hasRemoveScript, isDependency, installedPaths) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
metadata.Name, metadata.Description, metadata.LongDescription, metadata.Version.String(), metadata.Author,
|
metadata.Name, metadata.Description, metadata.LongDescription, metadata.Version.String(), metadata.Author,
|
||||||
metadata.License, metadata.Architecture, size, dependencies, string(removeScript), hasRemoveScript, dependency)
|
metadata.License, metadata.Architecture, size, dependencies, string(removeScript), hasRemoveScript, dependency,
|
||||||
|
installedPathsString)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -712,32 +729,111 @@ func DefaultCheckEPKInDB(name string) (*semver.Version, bool, error) {
|
||||||
return version, true, nil
|
return version, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultGetEPKFromDB(name string) (lib.Metadata, string, bool, bool, int64, error) {
|
func DefaultGetEPKFromDB(name string) (lib.Metadata, string, bool, bool, int64, string, []string, error) {
|
||||||
var metadata lib.Metadata
|
var metadata lib.Metadata
|
||||||
var removeScript string
|
var removeScript string
|
||||||
var dependency bool
|
var dependency bool
|
||||||
var versionString string
|
var versionString string
|
||||||
var dependencies string
|
var dependencies string
|
||||||
var hasRemoveScript bool
|
var hasRemoveScript bool
|
||||||
|
var repository string
|
||||||
|
var installedPaths string
|
||||||
var size int64
|
var size int64
|
||||||
err := conn.QueryRow("SELECT name, description, longDescription, version, author, license, architecture, size, "+
|
err := conn.QueryRow("SELECT description, longDescription, version, author, license, architecture, size, "+
|
||||||
"dependencies, removeScript, hasRemoveScript, isDependency FROM packages WHERE name = ?", name).Scan(
|
"dependencies, removeScript, hasRemoveScript, isDependency, repository, installedPaths FROM packages WHERE name = ?",
|
||||||
&metadata.Name, &metadata.Description, &metadata.LongDescription, &versionString, &metadata.Author,
|
name).Scan(&metadata.Description, &metadata.LongDescription, &versionString, &metadata.Author,
|
||||||
&metadata.License, &metadata.Architecture, &size, &dependencies, &removeScript, &hasRemoveScript,
|
&metadata.License, &metadata.Architecture, &size, &dependencies, &removeScript, &hasRemoveScript,
|
||||||
&dependency)
|
&dependency, &repository, &installedPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lib.Metadata{}, "", false, false, 0, err
|
return lib.Metadata{}, "", false, false, 0, "", nil, err
|
||||||
}
|
}
|
||||||
// This is the world's most basic JSON unmarshaller :P
|
// This is the world's most basic JSON unmarshaller :P
|
||||||
// - Arzumify
|
// - Arzumify
|
||||||
metadata.Dependencies = strings.Split(strings.TrimSuffix(strings.TrimPrefix(dependencies, "["), "]"), ", ")
|
metadata.Dependencies = strings.Split(strings.TrimSuffix(strings.TrimPrefix(dependencies, "["), "]"), ", ")
|
||||||
version, err := semver.NewVersion(versionString)
|
version, err := semver.NewVersion(versionString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lib.Metadata{}, "", false, false, 0, err
|
return lib.Metadata{}, "", false, false, 0, "", nil, err
|
||||||
}
|
}
|
||||||
|
// Also unmarshal the installed paths
|
||||||
|
var installedPathsSlice []string
|
||||||
|
installedPathsSlice = strings.Split(strings.TrimSuffix(strings.TrimPrefix(installedPaths, "["), "]"), ", ")
|
||||||
|
|
||||||
// For some reason NewVersion returns a pointer
|
// For some reason NewVersion returns a pointer
|
||||||
metadata.Version = *version
|
metadata.Version = *version
|
||||||
return metadata, removeScript, dependency, hasRemoveScript, size, nil
|
return metadata, removeScript, dependency, hasRemoveScript, size, repository, installedPathsSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultRemoveEPKFromDB(name string) error {
|
||||||
|
_, err := conn.Exec("DELETE FROM packages WHERE name = ?", name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultListEPKsInDB() (map[string]lib.DisplayData, map[string]*big.Int, map[string]lib.Repository, map[string]int64, error) {
|
||||||
|
rows, err := conn.Query("SELECT name, description, version, author, architecture, size, dependencies, repository FROM packages")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repositoryMap := make(map[string]lib.Repository)
|
||||||
|
repoNameToRepo := make(map[string]lib.Repository)
|
||||||
|
metadataMap := make(map[string]lib.DisplayData)
|
||||||
|
sizes := make(map[string]*big.Int)
|
||||||
|
compressedSizes := make(map[string]int64)
|
||||||
|
for rows.Next() {
|
||||||
|
var metadata lib.DisplayData
|
||||||
|
var size int64
|
||||||
|
var dependencies string
|
||||||
|
var repository string
|
||||||
|
var version string
|
||||||
|
err := rows.Scan(&metadata.Name, &metadata.Description, &version,
|
||||||
|
&metadata.Author, &metadata.Architecture, &size, &dependencies, &repository)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
}
|
||||||
|
semVer, err := semver.NewVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
}
|
||||||
|
// Stupid pointer
|
||||||
|
metadata.Version = *semVer
|
||||||
|
metadata.Dependencies = strings.Split(strings.TrimSuffix(strings.TrimPrefix(dependencies, "["), "]"), ", ")
|
||||||
|
metadataMap[metadata.Name] = metadata
|
||||||
|
sizes[metadata.Name] = big.NewInt(size)
|
||||||
|
compressedSizes[metadata.Name] = size
|
||||||
|
// Check if the repository is in the repoNameToRepo map
|
||||||
|
_, ok := repoNameToRepo[repository]
|
||||||
|
if !ok {
|
||||||
|
// If it's not, find the repository and add it to the map
|
||||||
|
var repo lib.Repository
|
||||||
|
err := conn.QueryRow("SELECT url, owner, description FROM repositories WHERE name = ?", repository).Scan(&repo.URL, &repo.Owner, &repo.Description)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
}
|
||||||
|
repositoryMap[repository] = repo
|
||||||
|
}
|
||||||
|
// Add the repository to the repository map
|
||||||
|
repositoryMap[metadata.Name] = repoNameToRepo[repository]
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadataMap, sizes, repositoryMap, compressedSizes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultGetEPKRemoveInfoFromDB(name string) (string, []string, error) {
|
||||||
|
var removeScript string
|
||||||
|
var installedPaths string
|
||||||
|
err := conn.QueryRow("SELECT removeScript, installedPaths FROM packages WHERE name = ?", name).Scan(&removeScript, &installedPaths)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal the installed paths
|
||||||
|
var installedPathsSlice []string
|
||||||
|
installedPathsSlice = strings.Split(strings.TrimSuffix(strings.TrimPrefix(installedPaths, "["), "]"), ", ")
|
||||||
|
|
||||||
|
return removeScript, installedPathsSlice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultAddFingerprintToDB(fingerprint []byte, owner string, replace bool) error {
|
func DefaultAddFingerprintToDB(fingerprint []byte, owner string, replace bool) error {
|
||||||
|
@ -781,11 +877,12 @@ func DefaultGetFingerprintFromDB(fingerprint []byte, author string) (bool, bool,
|
||||||
func DefaultAddRepositoryToDB(repository lib.Repository, forceReplace bool) error {
|
func DefaultAddRepositoryToDB(repository lib.Repository, forceReplace bool) error {
|
||||||
if forceReplace {
|
if forceReplace {
|
||||||
// Delete the repository if it already exists. This may happen in a force-install scenario.
|
// Delete the repository if it already exists. This may happen in a force-install scenario.
|
||||||
_, err := conn.Exec("DELETE FROM repositories WHERE name = ?", repository.Name)
|
_, err := conn.Exec("DELETE FROM repositories WHERE name = ? OR url = ?", repository.Name, repository.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := conn.Exec("INSERT INTO repositories (url, name, owner, description) VALUES (?, ?, ?, ?)",
|
_, err := conn.Exec("INSERT INTO repositories (url, name, owner, description) VALUES (?, ?, ?, ?)",
|
||||||
repository.URL, repository.Name, repository.Owner, repository.Description)
|
repository.URL, repository.Name, repository.Owner, repository.Description)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -833,6 +930,7 @@ func DefaultListRepositoriesInDB() ([]lib.Repository, error) {
|
||||||
}
|
}
|
||||||
repositories = append(repositories, lib.Repository{Name: name, URL: repoUrl, Owner: owner, Description: description})
|
repositories = append(repositories, lib.Repository{Name: name, URL: repoUrl, Owner: owner, Description: description})
|
||||||
}
|
}
|
||||||
|
|
||||||
return repositories, nil
|
return repositories, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,7 +974,7 @@ func DefaultRemoveRemotePackageFromDB(name string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultListRemotePackagesInDB() ([]lib.RemoteEPK, error) {
|
func DefaultListRemotePackagesInDB() ([]lib.RemoteEPK, error) {
|
||||||
rows, err := conn.Query("SELECT name, author, description, version, architecture, size, dependencies, path, arch, hash, repository FROM remotePackages")
|
rows, err := conn.Query("SELECT name, author, description, version, architecture, size, dependencies, path, arch, hash, repository FROM remotePackages ORDER BY version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []lib.RemoteEPK{}, err
|
return []lib.RemoteEPK{}, err
|
||||||
}
|
}
|
||||||
|
@ -923,6 +1021,11 @@ func DefaultListRemotePackagesInDB() ([]lib.RemoteEPK, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-sort remotePackages by version, latest first - this stops the package manager from installing older versions.
|
||||||
|
sort.Slice(remotePackages, func(i, j int) bool {
|
||||||
|
return remotePackages[i].Version.GreaterThan(&remotePackages[j].Version)
|
||||||
|
})
|
||||||
|
|
||||||
return remotePackages, nil
|
return remotePackages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,34 +1132,94 @@ func RefreshPackageList(listRepositoriesInDB func() ([]lib.Repository, error), a
|
||||||
// PreMapEPKHandleError handles errors that occur during the mapping of an EPKs display data.
|
// PreMapEPKHandleError handles errors that occur during the mapping of an EPKs display data.
|
||||||
func PreMapEPKHandleError(err error, vagueErr error, logger *lib.Logger) {
|
func PreMapEPKHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(vagueErr, lib.ErrPreMapEPKFailedToReadError):
|
case errors.Is(vagueErr, lib.ErrPreMapEPKCouldNotRead):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to read file: " + err.Error(),
|
Content: "Could not read file: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrPreMapEPKNotEPKError):
|
case errors.Is(vagueErr, lib.ErrPreMapEPKHasNetworkStream):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Network streams are not supported: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapEPKHasNotGotEPKMagic):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "The specified file is not an EPK.",
|
Content: "The specified file is not an EPK.",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrPreMapEPKInvalidEndianError):
|
case errors.Is(vagueErr, lib.ErrPreMapEPKHasInvalidEndian):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "The specified file is corrupted or invalid: invalid endian",
|
Content: "The specified file is corrupted or invalid: invalid endian",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrPreMapEPKCouldNotParseJSONError):
|
case errors.Is(vagueErr, lib.ErrPreMapEPKCouldNotMapJSON):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to parse metadata JSON: " + err.Error(),
|
Content: "Could not map metadata JSON: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrPreMapEPKCouldNotMapJSONError):
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreMapRemoteEPKHandleError handles errors that occur during the mapping of a remote EPKs display data.
|
||||||
|
func PreMapRemoteEPKHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
|
switch {
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotCreateURL):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to map metadata JSON: " + err.Error(),
|
Content: "Could not create URL: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotCreateRequest):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not create request: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotSendRequest):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not send request: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotRead):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not read EPK: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotCloseConnection):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not close connection: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKUnexpectedStatusCode):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Unexpected status code: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapEPKHasNotGotEPKMagic):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "The specified file is not an EPK.",
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKInvalidEndian):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "The specified file is corrupted or invalid: invalid endian",
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrPreMapRemoteEPKCouldNotMapJSON):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not map metadata JSON: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1065,40 +1228,40 @@ func PreMapEPKHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
// FullyMapMetadataHandleError handles errors that occur during the mapping of an EPK file.
|
// FullyMapMetadataHandleError handles errors that occur during the mapping of an EPK file.
|
||||||
func FullyMapMetadataHandleError(err error, vagueErr error, logger *lib.Logger) {
|
func FullyMapMetadataHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataFailedToReadError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotRead):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to read file: " + err.Error(),
|
Content: "Could not read file: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataFailedToJumpError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotJump):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to jump to metadata: " + err.Error(),
|
Content: "Could not jump to metadata: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataFailedToAddFingerprintError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotAddFingerprint):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to add fingerprint to database: " + err.Error(),
|
Content: "Could not add fingerprint to database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataFailedToGetFingerprintError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotGetFingerprint):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to get fingerprint from database: " + err.Error(),
|
Content: "Could not get fingerprint from database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataInvalidSignatureError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataHasInvalidSignature):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "The specified file is corrupted or invalid: signature mismatch",
|
Content: "The specified file is corrupted or invalid: signature mismatch",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotMapJSONError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotMapJSON):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to map metadata JSON: " + err.Error(),
|
Content: "Could not map metadata JSON: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1108,76 +1271,76 @@ func FullyMapMetadataHandleError(err error, vagueErr error, logger *lib.Logger)
|
||||||
func InstallEPKHandleError(tempDir string, err error, vagueErr error, logger *lib.Logger) {
|
func InstallEPKHandleError(tempDir string, err error, vagueErr error, logger *lib.Logger) {
|
||||||
doNotRemoveTempDir := false
|
doNotRemoveTempDir := false
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateTempDirError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateTempDir):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create temporary directory: " + err.Error(),
|
Content: "Could not create temporary directory: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateZStandardReaderError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateZStandardReader):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create ZStandard reader: " + err.Error(),
|
Content: "Could not create ZStandard reader: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotDecompressTarArchiveError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotDecompressTarArchive):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to decompress tar archive: " + err.Error(),
|
Content: "Could not decompress tar archive: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateDirError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateDir):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create directory: " + err.Error(),
|
Content: "Could not create directory: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatDirError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatDir):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "ERROR",
|
Level: "ERROR",
|
||||||
Content: "Could not get file information about directory: " + err.Error(),
|
Content: "Could not get file information about directory: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatFileError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatFile):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "ERROR",
|
Level: "ERROR",
|
||||||
Content: "Could not get file information about file: " + err.Error(),
|
Content: "Could not get file information about file: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateFileError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCreateFile):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create file: " + err.Error(),
|
Content: "Could not create file: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCloseTarReaderError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotCloseTarReader):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to close tar reader: " + err.Error(),
|
Content: "Could not close tar reader: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatHookError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotStatHook):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Could not get file information about hook: " + err.Error(),
|
Content: "Could not get file information about hook: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotRunHookError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotRunHook):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to run hook: " + err.Error(),
|
Content: "Could not run hook: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotAddEPKToDBError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotAddEPKToDB):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to add EPK to database: " + err.Error(),
|
Content: "Could not add EPK to database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotRemoveTempDirError):
|
case errors.Is(vagueErr, lib.ErrInstallEPKCouldNotRemoveTempDir):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "CRITICAL",
|
Level: "CRITICAL",
|
||||||
Content: "Failed to remove temporary directory: " + err.Error() + ", please remove the directory " + tempDir + " manually",
|
Content: "Could not remove temporary directory: " + err.Error() + ", please remove the directory " + tempDir + " manually",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
doNotRemoveTempDir = true
|
doNotRemoveTempDir = true
|
||||||
|
@ -1187,7 +1350,7 @@ func InstallEPKHandleError(tempDir string, err error, vagueErr error, logger *li
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "CRITICAL",
|
Level: "CRITICAL",
|
||||||
Content: "Failed to remove temporary directory: " + err.Error() + ", please remove the directory " + tempDir + " manually",
|
Content: "Could not remove temporary directory: " + err.Error() + ", please remove the directory " + tempDir + " manually",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1196,94 +1359,82 @@ func InstallEPKHandleError(tempDir string, err error, vagueErr error, logger *li
|
||||||
|
|
||||||
func AddRepositoryHandleError(err error, vagueErr error, logger *lib.Logger) {
|
func AddRepositoryHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotCreateRequestError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotCreateRequest):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create request: " + err.Error(),
|
Content: "Could not create request: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotSendRequestError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotSendRequest):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to send request: " + err.Error(),
|
Content: "Could not send request: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryUnexpectedStatusCodeError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryHasUnexpectedStatusCode):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Unexpected status code: " + err.Error(),
|
Content: "Unexpected status code: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotReadResponseError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotReadResponse):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to read response: " + err.Error(),
|
Content: "Could not read response: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryInvalidMagicError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryHasInvalidMagic):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Invalid magic: " + err.Error(),
|
Content: "Invalid magic: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotHashError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotHash):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to copy file to hash: " + err.Error(),
|
Content: "Could not copy file to hash: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryUnmarshalMetadataError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotUnmarshalMetadata):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to unmarshal metadata: " + err.Error(),
|
Content: "Could not unmarshal metadata: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrFullyMapMetadataFailedToGetFingerprintError):
|
case errors.Is(vagueErr, lib.ErrFullyMapMetadataCouldNotGetFingerprint):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to get fingerprint from database: " + err.Error(),
|
Content: "Could not get fingerprint from database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryFailedToAddFingerprintError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotAddFingerprint):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to add fingerprint to database: " + err.Error(),
|
Content: "Could not add fingerprint to database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryInvalidMetadataError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryHasInvalidMetadata):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Invalid metadata: " + err.Error(),
|
Content: "Invalid metadata: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotCreateDirError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotAddPackage):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to create repository directory: " + err.Error(),
|
Content: "Could not add package to database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryCannotStatDirError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryHasRepositoryExists):
|
||||||
logger.LogFunc(lib.Log{
|
|
||||||
Level: "FATAL",
|
|
||||||
Content: "Failed to get file information about repository directory: " + err.Error(),
|
|
||||||
Prompt: false,
|
|
||||||
})
|
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryFailedToAddPackageError):
|
|
||||||
logger.LogFunc(lib.Log{
|
|
||||||
Level: "FATAL",
|
|
||||||
Content: "Failed to add package to database: " + err.Error(),
|
|
||||||
Prompt: false,
|
|
||||||
})
|
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryRepositoryAlreadyExistsError):
|
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Repository already exists",
|
Content: "Repository already exists",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrAddRepositoryFailedToAddRepositoryError):
|
case errors.Is(vagueErr, lib.ErrAddRepositoryCouldNotAddRepository):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to add repository to database: " + err.Error(),
|
Content: "Could not add repository to database: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1292,28 +1443,70 @@ func AddRepositoryHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
|
|
||||||
func RemoveRepositoryHandleError(err error, vagueErr error, logger *lib.Logger) {
|
func RemoveRepositoryHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(vagueErr, lib.ErrRemoveRepositoryDoesNotExistError):
|
case errors.Is(vagueErr, lib.ErrRemoveRepositoryDoesNotExist):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Repository does not exist",
|
Content: "Repository does not exist",
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrRemoveRepositoryCannotFindRepositoryError):
|
case errors.Is(vagueErr, lib.ErrRemoveRepositoryCouldNotFindRepository):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to get file information about repository: " + err.Error(),
|
Content: "Could not get file information about repository: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrRemoveRepositoryCannotRemoveRepositoryError):
|
case errors.Is(vagueErr, lib.ErrRemoveRepositoryCouldNotRemoveRepository):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to remove repository files: " + err.Error(),
|
Content: "Could not remove repository files: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
case errors.Is(vagueErr, lib.ErrRemoveRepositoryFailedToRemoveRepositoryFromDBError):
|
case errors.Is(vagueErr, lib.ErrRemoveRepositoryCouldNotRemoveRepositoryFromDB):
|
||||||
logger.LogFunc(lib.Log{
|
logger.LogFunc(lib.Log{
|
||||||
Level: "FATAL",
|
Level: "FATAL",
|
||||||
Content: "Failed to remove repository from database: " + err.Error(),
|
Content: "Could not remove repository from database: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveEPKHandleError handles errors that occur during the removal of an EPK.
|
||||||
|
func RemoveEPKHandleError(err error, vagueErr error, logger *lib.Logger) {
|
||||||
|
switch {
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotFindEPK):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not get EPK from database: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotCreateTempFile):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not create temporary file: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotWriteTempFile):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not write to temporary file: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotRunRemoveHook):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not run remove hook: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotRemoveEPKFromDB):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not remove EPK from database: " + err.Error(),
|
||||||
|
Prompt: false,
|
||||||
|
})
|
||||||
|
case errors.Is(vagueErr, lib.ErrRemoveEPKCouldNotRemoveFiles):
|
||||||
|
logger.LogFunc(lib.Log{
|
||||||
|
Level: "FATAL",
|
||||||
|
Content: "Could not remove files: " + err.Error(),
|
||||||
Prompt: false,
|
Prompt: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
660
lib/main.go
660
lib/main.go
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue