Compare commits
10 Commits
5085981f52
...
1329109810
Author | SHA1 | Date | |
---|---|---|---|
1329109810 | |||
4a8c4e22ec | |||
eb8db1bc99 | |||
4f1eeeb11d | |||
2e416b9e6f | |||
d8a42c780d | |||
b1bb8de661 | |||
c425b263fe | |||
5776784021 | |||
903c7dce3e |
@ -45,7 +45,7 @@ You can remove an installed package by typing the following
|
|||||||
bpm remove package_name
|
bpm remove package_name
|
||||||
```
|
```
|
||||||
|
|
||||||
To remove all unused dependencies try using the cleanup command
|
To remove all unused dependencies and clean cached files try using the cleanup command
|
||||||
```sh
|
```sh
|
||||||
bpm cleanup
|
bpm cleanup
|
||||||
```
|
```
|
||||||
|
162
src/bpm/main.go
162
src/bpm/main.go
@ -42,7 +42,11 @@ var doCleanup = false
|
|||||||
var showRepoInfo = false
|
var showRepoInfo = false
|
||||||
var installSrcPkgDepends = false
|
var installSrcPkgDepends = false
|
||||||
var skipChecks = false
|
var skipChecks = false
|
||||||
var outputFilename = ""
|
var outputDirectory = ""
|
||||||
|
var cleanupDependencies = false
|
||||||
|
var cleanupCompilationFiles = false
|
||||||
|
var cleanupCompiledPackages = false
|
||||||
|
var cleanupFetchedPackages = false
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := bpmlib.ReadConfig()
|
err := bpmlib.ReadConfig()
|
||||||
@ -456,51 +460,58 @@ func resolveCommand() {
|
|||||||
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read local databases
|
err := bpmlib.CleanupCache(rootDir, cleanupCompilationFiles, cleanupCompiledPackages, cleanupFetchedPackages, verbose)
|
||||||
err := bpmlib.ReadLocalDatabases()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not read local databases: %s", err)
|
log.Fatalf("Error: could not complete cache cleanup: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create cleanup operation
|
if cleanupDependencies {
|
||||||
operation, err := bpmlib.CleanupPackages(rootDir, verbose)
|
// Read local databases
|
||||||
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
err := bpmlib.ReadLocalDatabases()
|
||||||
log.Fatalf("Error: %s", err)
|
if err != nil {
|
||||||
} else if err != nil {
|
log.Fatalf("Error: could not read local databases: %s", err)
|
||||||
log.Fatalf("Error: could not setup operation: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit if operation contains no actions
|
|
||||||
if len(operation.Actions) == 0 {
|
|
||||||
fmt.Println("No action needs to be taken")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show operation summary
|
|
||||||
operation.ShowOperationSummary()
|
|
||||||
|
|
||||||
// Confirmation Prompt
|
|
||||||
if !yesAll {
|
|
||||||
fmt.Printf("Are you sure you wish to remove all %d packages? [y\\N] ", len(operation.Actions))
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
|
||||||
text, _ := reader.ReadString('\n')
|
|
||||||
if strings.TrimSpace(strings.ToLower(text)) != "y" && strings.TrimSpace(strings.ToLower(text)) != "yes" {
|
|
||||||
fmt.Println("Cancelling package removal...")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Execute operation
|
// Create cleanup operation
|
||||||
err = operation.Execute(verbose, force)
|
operation, err := bpmlib.CleanupPackages(rootDir, verbose)
|
||||||
if err != nil {
|
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
||||||
log.Fatalf("Error: could not complete operation: %s\n", err)
|
log.Fatalf("Error: %s", err)
|
||||||
}
|
} else if err != nil {
|
||||||
|
log.Fatalf("Error: could not setup operation: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Executing hooks
|
// Exit if operation contains no actions
|
||||||
fmt.Println("Running hooks...")
|
if len(operation.Actions) == 0 {
|
||||||
err = operation.RunHooks(verbose)
|
fmt.Println("No action needs to be taken")
|
||||||
if err != nil {
|
return
|
||||||
log.Fatalf("Error: could not run hooks: %s\n", err)
|
}
|
||||||
|
|
||||||
|
// Show operation summary
|
||||||
|
operation.ShowOperationSummary()
|
||||||
|
|
||||||
|
// Confirmation Prompt
|
||||||
|
if !yesAll {
|
||||||
|
fmt.Printf("Are you sure you wish to remove all %d packages? [y\\N] ", len(operation.Actions))
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
text, _ := reader.ReadString('\n')
|
||||||
|
if strings.TrimSpace(strings.ToLower(text)) != "y" && strings.TrimSpace(strings.ToLower(text)) != "yes" {
|
||||||
|
fmt.Println("Cancelling package removal...")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute operation
|
||||||
|
err = operation.Execute(verbose, force)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not complete operation: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executing hooks
|
||||||
|
fmt.Println("Running hooks...")
|
||||||
|
err = operation.RunHooks(verbose)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not run hooks: %s\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case file:
|
case file:
|
||||||
files := subcommandArgs
|
files := subcommandArgs
|
||||||
@ -609,7 +620,9 @@ func resolveCommand() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run 'bpm install' using the set privilege escalator command
|
// Run 'bpm install' using the set privilege escalator command
|
||||||
cmd := exec.Command(bpmlib.BPMConfig.PrivilegeEscalatorCmd, executable, "install", "--installation-reason=dependency", strings.Join(unmetDepends, " "))
|
args := []string{executable, "install", "--installation-reason=dependency"}
|
||||||
|
args = append(args, unmetDepends...)
|
||||||
|
cmd := exec.Command(bpmlib.BPMConfig.PrivilegeEscalatorCmd, args...)
|
||||||
if yesAll {
|
if yesAll {
|
||||||
cmd.Args = slices.Insert(cmd.Args, 3, "-y")
|
cmd.Args = slices.Insert(cmd.Args, 3, "-y")
|
||||||
}
|
}
|
||||||
@ -642,36 +655,40 @@ func resolveCommand() {
|
|||||||
log.Fatalf("Error: could not get user home directory: %s", err)
|
log.Fatalf("Error: could not get user home directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim output filename
|
// Trim output directory
|
||||||
outputFilename = strings.TrimSpace(outputFilename)
|
outputDirectory = strings.TrimSpace(outputDirectory)
|
||||||
if outputFilename != "/" {
|
if outputDirectory != "/" {
|
||||||
outputFilename = strings.TrimSuffix(outputFilename, "/")
|
outputDirectory = strings.TrimSuffix(outputDirectory, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set output filename if empty
|
// Set output directory if empty
|
||||||
if outputFilename == "" {
|
if outputDirectory == "" {
|
||||||
outputFilename = path.Join(workdir, fmt.Sprintf("%s-%s-%d.bpm", bpmpkg.PkgInfo.Name, bpmpkg.PkgInfo.Version, bpmpkg.PkgInfo.Revision))
|
outputDirectory = workdir
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace first tilde with user home directory
|
// Replace first tilde with user home directory
|
||||||
if strings.Split(outputFilename, "/")[0] == "~" {
|
if strings.Split(outputDirectory, "/")[0] == "~" {
|
||||||
outputFilename = strings.Replace(outputFilename, "~", homedir, 1)
|
outputDirectory = strings.Replace(outputDirectory, "~", homedir, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepend current working directory to output filename if not an absolute path
|
// Prepend current working directory to output directory if not an absolute path
|
||||||
if outputFilename != "" && !strings.HasPrefix(outputFilename, "/") {
|
if outputDirectory != "" && !strings.HasPrefix(outputDirectory, "/") {
|
||||||
outputFilename = filepath.Join(workdir, outputFilename)
|
outputDirectory = filepath.Join(workdir, outputDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean path
|
// Clean path
|
||||||
path.Clean(outputFilename)
|
path.Clean(outputDirectory)
|
||||||
|
|
||||||
// Append archive filename if path is set to a directory
|
// Ensure output directory exists and is a directory
|
||||||
if stat, err := os.Stat(outputFilename); err == nil && stat.IsDir() {
|
stat, err := os.Stat(outputDirectory)
|
||||||
outputFilename = path.Join(outputFilename, fmt.Sprintf("%s-%s-%d.bpm", bpmpkg.PkgInfo.Name, bpmpkg.PkgInfo.Version, bpmpkg.PkgInfo.Revision))
|
if err != nil {
|
||||||
|
log.Fatalf("Error: could not stat output directory (%s): %s", outputDirectory, err)
|
||||||
|
}
|
||||||
|
if !stat.IsDir() {
|
||||||
|
log.Fatalf("Error: output directory (%s) is not a directory", outputDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
outputBpmPackages, err := bpmlib.CompileSourcePackage(sourcePackage, outputFilename, skipChecks)
|
outputBpmPackages, err := bpmlib.CompileSourcePackage(sourcePackage, outputDirectory, skipChecks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not compile source package (%s): %s", sourcePackage, err)
|
log.Fatalf("Error: could not compile source package (%s): %s", sourcePackage, err)
|
||||||
}
|
}
|
||||||
@ -725,12 +742,11 @@ func printHelp() {
|
|||||||
fmt.Println(" -c lists the amount of installed packages")
|
fmt.Println(" -c lists the amount of installed packages")
|
||||||
fmt.Println(" -n lists only the names of installed packages")
|
fmt.Println(" -n lists only the names of installed packages")
|
||||||
fmt.Println("-> bpm search <search terms...> | Searches for packages through declared repositories")
|
fmt.Println("-> bpm search <search terms...> | Searches for packages through declared repositories")
|
||||||
fmt.Println("-> bpm install [-R, -v, -y, -f, -o, -c, -b, -k, --reinstall, --reinstall-all, --no-optional, --installation-reason] <packages...> | installs the following files")
|
fmt.Println("-> bpm install [-R, -v, -y, -f, --reinstall, --reinstall-all, --no-optional, --installation-reason] <packages...> | installs the following files")
|
||||||
fmt.Println(" -R=<path> lets you define the root path which will be used")
|
fmt.Println(" -R=<path> lets you define the root path which will be used")
|
||||||
fmt.Println(" -v Show additional information about what BPM is doing")
|
fmt.Println(" -v Show additional information about what BPM is doing")
|
||||||
fmt.Println(" -y skips the confirmation prompt")
|
fmt.Println(" -y skips the confirmation prompt")
|
||||||
fmt.Println(" -f skips dependency, conflict and architecture checking")
|
fmt.Println(" -f skips dependency, conflict and architecture checking")
|
||||||
fmt.Println(" -k keeps the compilation directory created by BPM after source package installation")
|
|
||||||
fmt.Println(" --reinstall Reinstalls packages even if they do not have a newer version available")
|
fmt.Println(" --reinstall Reinstalls packages even if they do not have a newer version available")
|
||||||
fmt.Println(" --reinstall-all Same as --reinstall but also reinstalls dependencies")
|
fmt.Println(" --reinstall-all Same as --reinstall but also reinstalls dependencies")
|
||||||
fmt.Println(" --no-optional Prevents installation of optional dependencies")
|
fmt.Println(" --no-optional Prevents installation of optional dependencies")
|
||||||
@ -752,17 +768,21 @@ func printHelp() {
|
|||||||
fmt.Println(" -y skips the confirmation prompt")
|
fmt.Println(" -y skips the confirmation prompt")
|
||||||
fmt.Println(" --unused removes only packages that aren't required as dependencies by other packages")
|
fmt.Println(" --unused removes only packages that aren't required as dependencies by other packages")
|
||||||
fmt.Println(" --cleanup performs a dependency cleanup")
|
fmt.Println(" --cleanup performs a dependency cleanup")
|
||||||
fmt.Println("-> bpm cleanup [-R, -v, -y] | remove all unused dependency packages")
|
fmt.Println("-> bpm cleanup [-R, -v, -y, --depends, --compilation-files, --compiled-pkgs, --fetched-pkgs] | remove all unused dependencies and cache directories")
|
||||||
fmt.Println(" -v Show additional information about what BPM is doing")
|
fmt.Println(" -v Show additional information about what BPM is doing")
|
||||||
fmt.Println(" -R=<path> lets you define the root path which will be used")
|
fmt.Println(" -R=<path> lets you define the root path which will be used")
|
||||||
fmt.Println(" -y skips the confirmation prompt")
|
fmt.Println(" -y skips the confirmation prompt")
|
||||||
|
fmt.Println(" --depends performs a dependency cleanup")
|
||||||
|
fmt.Println(" --compilation-files performs a cleanup of compilation files")
|
||||||
|
fmt.Println(" --compiled-pkgs performs a cleanup of compilation compiled binary packages")
|
||||||
|
fmt.Println(" --fetched-pkgs performs a cleanup of fetched packages from repositories")
|
||||||
fmt.Println("-> bpm file [-R] <files...> | shows what packages the following packages are managed by")
|
fmt.Println("-> bpm file [-R] <files...> | shows what packages the following packages are managed by")
|
||||||
fmt.Println(" -R=<root_path> lets you define the root path which will be used")
|
fmt.Println(" -R=<root_path> lets you define the root path which will be used")
|
||||||
fmt.Println("-> bpm compile [-d, -s, -o] <source packages...> | Compile source BPM package")
|
fmt.Println("-> bpm compile [-d, -s, -o] <source packages...> | Compile source BPM package")
|
||||||
fmt.Println(" -v Show additional information about what BPM is doing")
|
fmt.Println(" -v Show additional information about what BPM is doing")
|
||||||
fmt.Println(" -d installs required dependencies for package compilation")
|
fmt.Println(" -d installs required dependencies for package compilation")
|
||||||
fmt.Println(" -s skips the check function in source.sh scripts")
|
fmt.Println(" -s skips the check function in source.sh scripts")
|
||||||
fmt.Println(" -o sets output filename")
|
fmt.Println(" -o sets output directory")
|
||||||
fmt.Println(" -y skips the confirmation prompt")
|
fmt.Println(" -y skips the confirmation prompt")
|
||||||
|
|
||||||
fmt.Println("\033[1m----------------\033[0m")
|
fmt.Println("\033[1m----------------\033[0m")
|
||||||
@ -818,6 +838,10 @@ func resolveFlags() {
|
|||||||
cleanupFlagSet.StringVar(&rootDir, "R", "/", "Set the destination root")
|
cleanupFlagSet.StringVar(&rootDir, "R", "/", "Set the destination root")
|
||||||
cleanupFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
|
cleanupFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
|
||||||
cleanupFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
|
cleanupFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
|
||||||
|
cleanupFlagSet.BoolVar(&cleanupDependencies, "depends", false, "Perform a dependency cleanup")
|
||||||
|
cleanupFlagSet.BoolVar(&cleanupCompilationFiles, "compilation-files", false, "Perform a cleanup of compilation files")
|
||||||
|
cleanupFlagSet.BoolVar(&cleanupCompiledPackages, "compiled-pkgs", false, "Perform a cleanup of compilation compiled binary packages")
|
||||||
|
cleanupFlagSet.BoolVar(&cleanupFetchedPackages, "fetched-pkgs", false, "Perform a cleanup of fetched packages from repositories")
|
||||||
cleanupFlagSet.Usage = printHelp
|
cleanupFlagSet.Usage = printHelp
|
||||||
// File flags
|
// File flags
|
||||||
fileFlagSet := flag.NewFlagSet("Remove flags", flag.ExitOnError)
|
fileFlagSet := flag.NewFlagSet("Remove flags", flag.ExitOnError)
|
||||||
@ -827,7 +851,7 @@ func resolveFlags() {
|
|||||||
compileFlagSet := flag.NewFlagSet("Compile flags", flag.ExitOnError)
|
compileFlagSet := flag.NewFlagSet("Compile flags", flag.ExitOnError)
|
||||||
compileFlagSet.BoolVar(&installSrcPkgDepends, "d", false, "Install required dependencies for package compilation")
|
compileFlagSet.BoolVar(&installSrcPkgDepends, "d", false, "Install required dependencies for package compilation")
|
||||||
compileFlagSet.BoolVar(&skipChecks, "s", false, "Skip the check function in source.sh scripts")
|
compileFlagSet.BoolVar(&skipChecks, "s", false, "Skip the check function in source.sh scripts")
|
||||||
compileFlagSet.StringVar(&outputFilename, "o", "", "Set output filename")
|
compileFlagSet.StringVar(&outputDirectory, "o", "", "Set output directory")
|
||||||
compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
|
compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
|
||||||
compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
|
compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
|
||||||
|
|
||||||
@ -873,6 +897,18 @@ func resolveFlags() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
subcommandArgs = removeFlagSet.Args()
|
subcommandArgs = removeFlagSet.Args()
|
||||||
|
} else if getCommandType() == cleanup {
|
||||||
|
err := cleanupFlagSet.Parse(subcommandArgs)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !cleanupDependencies && !cleanupCompilationFiles && !cleanupCompiledPackages && !cleanupFetchedPackages {
|
||||||
|
cleanupDependencies = true
|
||||||
|
cleanupCompilationFiles = true
|
||||||
|
cleanupCompiledPackages = true
|
||||||
|
cleanupFetchedPackages = true
|
||||||
|
}
|
||||||
|
subcommandArgs = cleanupFlagSet.Args()
|
||||||
} else if getCommandType() == file {
|
} else if getCommandType() == file {
|
||||||
err := fileFlagSet.Parse(subcommandArgs)
|
err := fileFlagSet.Parse(subcommandArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
var rootCompilationUID = "65534"
|
var rootCompilationUID = "65534"
|
||||||
var rootCompilationGID = "65534"
|
var rootCompilationGID = "65534"
|
||||||
|
|
||||||
func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks bool) (outputBpmPackages map[string]string, err error) {
|
func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bool) (outputBpmPackages map[string]string, err error) {
|
||||||
// Initialize map
|
// Initialize map
|
||||||
outputBpmPackages = make(map[string]string)
|
outputBpmPackages = make(map[string]string)
|
||||||
|
|
||||||
@ -60,7 +60,13 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
gid = os.Getgid()
|
gid = os.Getgid()
|
||||||
}
|
}
|
||||||
|
|
||||||
tempDirectory := path.Join(homeDir, ".cache/bpm/compilation/", bpmpkg.PkgInfo.Name)
|
// Set temporary directory
|
||||||
|
var tempDirectory string
|
||||||
|
if os.Getuid() == 0 {
|
||||||
|
tempDirectory = path.Join("/var/cache/bpm/compilation/", bpmpkg.PkgInfo.Name)
|
||||||
|
} else {
|
||||||
|
tempDirectory = path.Join(homeDir, ".cache/bpm/compilation/", bpmpkg.PkgInfo.Name)
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure temporary directory does not exist
|
// Ensure temporary directory does not exist
|
||||||
if _, err := os.Stat(tempDirectory); err == nil {
|
if _, err := os.Stat(tempDirectory); err == nil {
|
||||||
@ -144,8 +150,10 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
if os.Getuid() == 0 {
|
||||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -163,29 +171,27 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
if os.Getuid() == 0 {
|
||||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable that will be used later
|
|
||||||
isSplitPkg := true
|
|
||||||
|
|
||||||
// Get all packages to compile
|
// Get all packages to compile
|
||||||
packagesToCompile := bpmpkg.PkgInfo.SplitPackages
|
packagesToCompile := bpmpkg.PkgInfo.SplitPackages
|
||||||
if len(packagesToCompile) == 0 {
|
if !bpmpkg.PkgInfo.IsSplitPackage() {
|
||||||
packagesToCompile = append(packagesToCompile, bpmpkg.PkgInfo)
|
packagesToCompile = append(packagesToCompile, bpmpkg.PkgInfo)
|
||||||
isSplitPkg = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile each package
|
// Compile each package
|
||||||
for _, pkg := range packagesToCompile {
|
for _, pkg := range packagesToCompile {
|
||||||
// Get package function name
|
// Get package function name
|
||||||
packageFunctionName := "package"
|
packageFunctionName := "package"
|
||||||
if isSplitPkg {
|
if bpmpkg.PkgInfo.IsSplitPackage() {
|
||||||
packageFunctionName = "package_" + pkg.Name
|
packageFunctionName = "package_" + pkg.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +227,10 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
if os.Getuid() == 0 {
|
||||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -234,36 +242,17 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
if os.Getuid() == 0 {
|
||||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("files.tar.gz archive could not be created: %s", err)
|
return nil, fmt.Errorf("files.tar.gz archive could not be created: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone source package info
|
// Clone source package info
|
||||||
var pkgInfo PackageInfo
|
pkgInfo := *pkg
|
||||||
if !isSplitPkg {
|
|
||||||
pkgInfo = *bpmpkg.PkgInfo
|
|
||||||
} else {
|
|
||||||
pkgInfo = *pkg
|
|
||||||
|
|
||||||
// Ensure required fields are set
|
|
||||||
if strings.TrimSpace(pkgInfo.Name) == "" {
|
|
||||||
return nil, fmt.Errorf("split package name is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy data from main source package
|
|
||||||
if pkgInfo.Description == "" {
|
|
||||||
pkgInfo.Description = bpmpkg.PkgInfo.Description
|
|
||||||
}
|
|
||||||
pkgInfo.Version = bpmpkg.PkgInfo.Version
|
|
||||||
pkgInfo.Revision = bpmpkg.PkgInfo.Revision
|
|
||||||
pkgInfo.Url = bpmpkg.PkgInfo.Url
|
|
||||||
if pkgInfo.License == "" {
|
|
||||||
pkgInfo.License = bpmpkg.PkgInfo.License
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set package type to binary
|
// Set package type to binary
|
||||||
pkgInfo.Type = "binary"
|
pkgInfo.Type = "binary"
|
||||||
@ -313,8 +302,10 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd.Env = append(env, "CURRENT_DIR="+currentDir)
|
cmd.Env = append(env, "CURRENT_DIR="+currentDir)
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
if os.Getuid() == 0 {
|
||||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("BPM archive could not be created: %s", err)
|
return nil, fmt.Errorf("BPM archive could not be created: %s", err)
|
||||||
@ -326,16 +317,8 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set output filename if split package
|
// Set output filename
|
||||||
if len(bpmpkg.PkgInfo.SplitPackages) != 1 {
|
outputFilename := path.Join(outputDirectory, fmt.Sprintf("%s-%s-%d-%s.bpm", pkgInfo.Name, pkgInfo.Version, pkgInfo.Revision, pkgInfo.Arch))
|
||||||
// Get current working directory
|
|
||||||
workdir, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not get working directory: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
outputFilename = path.Join(workdir, fmt.Sprintf("%s-%s-%d.bpm", pkgInfo.Name, pkgInfo.Version, pkgInfo.Revision))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move final BPM archive
|
// Move final BPM archive
|
||||||
err = os.Rename(path.Join(tempDirectory, "final-archive.bpm"), outputFilename)
|
err = os.Rename(path.Join(tempDirectory, "final-archive.bpm"), outputFilename)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
|
|||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
ForceInstallationReason: installationReason,
|
ForceInstallationReason: installationReason,
|
||||||
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve packages
|
// Resolve packages
|
||||||
@ -35,12 +37,25 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not read package: %s", err)
|
return nil, fmt.Errorf("could not read package: %s", err)
|
||||||
}
|
}
|
||||||
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() {
|
|
||||||
|
if bpmpkg.PkgInfo.Type == "source" && bpmpkg.PkgInfo.IsSplitPackage() {
|
||||||
|
for _, splitPkg := range bpmpkg.PkgInfo.SplitPackages {
|
||||||
|
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(splitPkg.Name, rootDir) && GetPackageInfo(splitPkg.Name, rootDir).GetFullVersion() == splitPkg.GetFullVersion() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
operation.AppendAction(&InstallPackageAction{
|
||||||
|
File: pkg,
|
||||||
|
IsDependency: false,
|
||||||
|
BpmPackage: bpmpkg,
|
||||||
|
SplitPackageToInstall: splitPkg.Name,
|
||||||
|
})
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if bpmpkg.PkgInfo.Type == "source" && len(bpmpkg.PkgInfo.SplitPackages) != 0 {
|
if reinstallMethod == ReinstallMethodNone && IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() {
|
||||||
return nil, fmt.Errorf("direct source package installation has not been implemented")
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
operation.AppendAction(&InstallPackageAction{
|
operation.AppendAction(&InstallPackageAction{
|
||||||
@ -69,10 +84,6 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Info.Type == "source" && len(entry.Info.SplitPackages) != 0 {
|
|
||||||
return nil, fmt.Errorf("direct source package installation has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
operation.AppendAction(&FetchPackageAction{
|
operation.AppendAction(&FetchPackageAction{
|
||||||
IsDependency: false,
|
IsDependency: false,
|
||||||
RepositoryEntry: entry,
|
RepositoryEntry: entry,
|
||||||
@ -128,6 +139,7 @@ func RemovePackages(rootDir string, removeUnusedPackagesOnly, cleanupDependencie
|
|||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for packages
|
// Search for packages
|
||||||
@ -164,6 +176,7 @@ func CleanupPackages(rootDir string, verbose bool) (operation *BPMOperation, err
|
|||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do package cleanup
|
// Do package cleanup
|
||||||
@ -175,6 +188,88 @@ func CleanupPackages(rootDir string, verbose bool) (operation *BPMOperation, err
|
|||||||
return operation, nil
|
return operation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CleanupCache(rootDir string, cleanupCompilationFiles, cleanupCompiledPackages, cleanupFetchedPackages, verbose bool) error {
|
||||||
|
if cleanupCompilationFiles {
|
||||||
|
globalCompilationCacheDir := path.Join(rootDir, "var/cache/bpm/compilation")
|
||||||
|
|
||||||
|
// Ensure path exists and is a directory
|
||||||
|
if stat, err := os.Stat(globalCompilationCacheDir); err == nil && stat.IsDir() {
|
||||||
|
// Delete directory
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Removing directory (%s)\n", globalCompilationCacheDir)
|
||||||
|
}
|
||||||
|
err = os.RemoveAll(globalCompilationCacheDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get home directories of users in root directory
|
||||||
|
homeDirs, err := os.ReadDir(path.Join(rootDir, "home"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all home directories
|
||||||
|
for _, homeDir := range homeDirs {
|
||||||
|
// Skip if not a directory
|
||||||
|
if !homeDir.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
localCompilationDir := path.Join(rootDir, "home", homeDir.Name(), ".cache/bpm/compilation")
|
||||||
|
|
||||||
|
// Ensure path exists and is a directory
|
||||||
|
if stat, err := os.Stat(localCompilationDir); err != nil || !stat.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete directory
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Removing directory (%s)\n", localCompilationDir)
|
||||||
|
}
|
||||||
|
err = os.RemoveAll(localCompilationDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cleanupCompiledPackages {
|
||||||
|
dirToRemove := path.Join(rootDir, "var/cache/bpm/compiled")
|
||||||
|
|
||||||
|
// Ensure path exists and is a directory
|
||||||
|
if stat, err := os.Stat(dirToRemove); err == nil && stat.IsDir() {
|
||||||
|
// Delete directory
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Removing directory (%s)\n", dirToRemove)
|
||||||
|
}
|
||||||
|
err = os.RemoveAll(dirToRemove)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cleanupFetchedPackages {
|
||||||
|
dirToRemove := path.Join(rootDir, "var/cache/bpm/fetched")
|
||||||
|
|
||||||
|
// Ensure path exists and is a directory
|
||||||
|
if stat, err := os.Stat(dirToRemove); err == nil && stat.IsDir() {
|
||||||
|
// Delete directory
|
||||||
|
if verbose {
|
||||||
|
log.Printf("Removing directory (%s)\n", dirToRemove)
|
||||||
|
}
|
||||||
|
err = os.RemoveAll(dirToRemove)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdatePackages fetches the newest versions of all installed packages from
|
// UpdatePackages fetches the newest versions of all installed packages from
|
||||||
func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) {
|
func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) {
|
||||||
// Sync repositories
|
// Sync repositories
|
||||||
@ -206,6 +301,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
|
|||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
ForceInstallationReason: InstallationReasonUnknown,
|
ForceInstallationReason: InstallationReasonUnknown,
|
||||||
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for packages
|
// Search for packages
|
||||||
|
@ -16,6 +16,7 @@ type BPMOperation struct {
|
|||||||
Changes map[string]string
|
Changes map[string]string
|
||||||
RootDir string
|
RootDir string
|
||||||
ForceInstallationReason InstallationReason
|
ForceInstallationReason InstallationReason
|
||||||
|
compiledPackages map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
|
func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
|
||||||
@ -337,6 +338,9 @@ func (operation *BPMOperation) ShowOperationSummary() {
|
|||||||
var pkgInfo *PackageInfo
|
var pkgInfo *PackageInfo
|
||||||
if value.GetActionType() == "install" {
|
if value.GetActionType() == "install" {
|
||||||
pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
|
pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
|
||||||
|
if value.(*InstallPackageAction).SplitPackageToInstall != "" {
|
||||||
|
pkgInfo = pkgInfo.GetSplitPackageInfo(value.(*InstallPackageAction).SplitPackageToInstall)
|
||||||
|
}
|
||||||
} else if value.GetActionType() == "fetch" {
|
} else if value.GetActionType() == "fetch" {
|
||||||
pkgInfo = value.(*FetchPackageAction).RepositoryEntry.Info
|
pkgInfo = value.(*FetchPackageAction).RepositoryEntry.Info
|
||||||
} else {
|
} else {
|
||||||
@ -409,30 +413,68 @@ func (operation *BPMOperation) RunHooks(verbose bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *BPMOperation) Execute(verbose, force bool) error {
|
func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
||||||
// Fetch packages from repositories
|
// Fetch packages from repositories
|
||||||
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
||||||
return action.GetActionType() == "fetch"
|
return action.GetActionType() == "fetch"
|
||||||
}) {
|
}) {
|
||||||
fmt.Println("Fetching packages from available repositories...")
|
fmt.Println("Fetching packages from available repositories...")
|
||||||
|
|
||||||
|
// Create map for fetched packages
|
||||||
|
fetchedPackages := make(map[string]string)
|
||||||
|
|
||||||
for i, action := range operation.Actions {
|
for i, action := range operation.Actions {
|
||||||
if action.GetActionType() != "fetch" {
|
if action.GetActionType() != "fetch" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get repository entry
|
||||||
entry := action.(*FetchPackageAction).RepositoryEntry
|
entry := action.(*FetchPackageAction).RepositoryEntry
|
||||||
fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name)
|
|
||||||
if err != nil {
|
// Create bpmpkg variable
|
||||||
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
var bpmpkg *BPMPackage
|
||||||
|
|
||||||
|
// Check if package has already been fetched from download link
|
||||||
|
if _, ok := fetchedPackages[entry.Download]; !ok {
|
||||||
|
// Fetch package from repository
|
||||||
|
fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read fetched package
|
||||||
|
bpmpkg, err = ReadPackage(fetchedPackage)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add fetched package to map
|
||||||
|
fetchedPackages[entry.Download] = fetchedPackage
|
||||||
|
|
||||||
|
fmt.Printf("Package (%s) was successfully fetched!\n", entry.Info.Name)
|
||||||
|
} else {
|
||||||
|
// Read fetched package
|
||||||
|
bpmpkg, err = ReadPackage(fetchedPackages[entry.Download])
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("could not read package (%s): %s\n", entry.Info.Name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Package (%s) was successfully fetched!\n", entry.Info.Name)
|
||||||
}
|
}
|
||||||
bpmpkg, err := ReadPackage(fetchedPackage)
|
|
||||||
if err != nil {
|
if bpmpkg.PkgInfo.IsSplitPackage() {
|
||||||
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
operation.Actions[i] = &InstallPackageAction{
|
||||||
}
|
File: fetchedPackages[entry.Download],
|
||||||
fmt.Printf("Package (%s) was successfully fetched!\n", bpmpkg.PkgInfo.Name)
|
IsDependency: action.(*FetchPackageAction).IsDependency,
|
||||||
operation.Actions[i] = &InstallPackageAction{
|
BpmPackage: bpmpkg,
|
||||||
File: fetchedPackage,
|
SplitPackageToInstall: entry.Info.Name,
|
||||||
IsDependency: action.(*FetchPackageAction).IsDependency,
|
}
|
||||||
BpmPackage: bpmpkg,
|
} else {
|
||||||
|
operation.Actions[i] = &InstallPackageAction{
|
||||||
|
File: fetchedPackages[entry.Download],
|
||||||
|
IsDependency: action.(*FetchPackageAction).IsDependency,
|
||||||
|
BpmPackage: bpmpkg,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,9 +515,8 @@ func (operation *BPMOperation) Execute(verbose, force bool) error {
|
|||||||
|
|
||||||
// Compile package if type is 'source'
|
// Compile package if type is 'source'
|
||||||
if bpmpkg.PkgInfo.Type == "source" {
|
if bpmpkg.PkgInfo.Type == "source" {
|
||||||
// Get path to compiled package directory and output filename
|
// Get path to compiled package directory
|
||||||
compiledDir := path.Join(operation.RootDir, "/var/lib/bpm/compiled/")
|
compiledDir := path.Join(operation.RootDir, "/var/cache/bpm/compiled/")
|
||||||
outputFilename := path.Join(compiledDir, fmt.Sprintf("%s-%s-%d.bpm", bpmpkg.PkgInfo.Name, bpmpkg.PkgInfo.Version, bpmpkg.PkgInfo.Revision))
|
|
||||||
|
|
||||||
// Create compiled package directory if not exists
|
// Create compiled package directory if not exists
|
||||||
if _, err := os.Stat(compiledDir); err != nil {
|
if _, err := os.Stat(compiledDir); err != nil {
|
||||||
@ -485,15 +526,28 @@ func (operation *BPMOperation) Execute(verbose, force bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile source package
|
// Get package name to install
|
||||||
outputBpmPackages, err := CompileSourcePackage(value.File, outputFilename, false)
|
pkgNameToInstall := bpmpkg.PkgInfo.Name
|
||||||
if err != nil {
|
if bpmpkg.PkgInfo.IsSplitPackage() {
|
||||||
return fmt.Errorf("could not compile source package (%s): %s\n", value.File, err)
|
pkgNameToInstall = value.SplitPackageToInstall
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile source package if not compiled already
|
||||||
|
if _, ok := operation.compiledPackages[pkgNameToInstall]; !ok {
|
||||||
|
outputBpmPackages, err := CompileSourcePackage(value.File, compiledDir, false)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not compile source package (%s): %s\n", value.File, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add compiled packages to slice
|
||||||
|
for pkgName, pkgFile := range outputBpmPackages {
|
||||||
|
operation.compiledPackages[pkgName] = pkgFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set values
|
// Set values
|
||||||
fileToInstall = outputBpmPackages[bpmpkg.PkgInfo.Name]
|
fileToInstall = operation.compiledPackages[pkgNameToInstall]
|
||||||
bpmpkg, err = ReadPackage(outputFilename)
|
bpmpkg, err = ReadPackage(fileToInstall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not read package (%s): %s\n", fileToInstall, err)
|
return fmt.Errorf("could not read package (%s): %s\n", fileToInstall, err)
|
||||||
}
|
}
|
||||||
@ -531,9 +585,10 @@ type OperationAction interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InstallPackageAction struct {
|
type InstallPackageAction struct {
|
||||||
File string
|
File string
|
||||||
IsDependency bool
|
IsDependency bool
|
||||||
BpmPackage *BPMPackage
|
SplitPackageToInstall string
|
||||||
|
BpmPackage *BPMPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (action *InstallPackageAction) GetActionType() string {
|
func (action *InstallPackageAction) GetActionType() string {
|
||||||
|
@ -70,6 +70,25 @@ func (pkgInfo *PackageInfo) GetFullVersion() string {
|
|||||||
return pkgInfo.Version + "-" + strconv.Itoa(pkgInfo.Revision)
|
return pkgInfo.Version + "-" + strconv.Itoa(pkgInfo.Revision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pkgInfo *PackageInfo) IsSplitPackage() bool {
|
||||||
|
// Return false if not a source package
|
||||||
|
if pkgInfo.Type != "source" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(pkgInfo.SplitPackages) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pkgInfo *PackageInfo) GetSplitPackageInfo(splitPkg string) *PackageInfo {
|
||||||
|
for _, splitPkgInfo := range pkgInfo.SplitPackages {
|
||||||
|
if splitPkgInfo.Name == splitPkg {
|
||||||
|
return splitPkgInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type InstallationReason string
|
type InstallationReason string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -149,7 +168,6 @@ func ReadPackage(filename string) (*BPMPackage, error) {
|
|||||||
var pkgFiles []*PackageFileEntry
|
var pkgFiles []*PackageFileEntry
|
||||||
|
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
fmt.Println("a")
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +406,7 @@ func executePackageScripts(filename, rootDir string, operation packageOperation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
||||||
pkgInfo := PackageInfo{
|
pkgInfo := &PackageInfo{
|
||||||
Name: "",
|
Name: "",
|
||||||
Description: "",
|
Description: "",
|
||||||
Version: "",
|
Version: "",
|
||||||
@ -410,6 +428,8 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure required fields are set properly
|
||||||
if pkgInfo.Name == "" {
|
if pkgInfo.Name == "" {
|
||||||
return nil, errors.New("this package contains no name")
|
return nil, errors.New("this package contains no name")
|
||||||
} else if pkgInfo.Description == "" {
|
} else if pkgInfo.Description == "" {
|
||||||
@ -423,10 +443,46 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
|||||||
} else if pkgInfo.Type == "" {
|
} else if pkgInfo.Type == "" {
|
||||||
return nil, errors.New("this package contains no type")
|
return nil, errors.New("this package contains no type")
|
||||||
}
|
}
|
||||||
for i := 0; i < len(pkgInfo.Keep); i++ {
|
for _, val := range pkgInfo.Keep {
|
||||||
pkgInfo.Keep[i] = strings.TrimPrefix(pkgInfo.Keep[i], "/")
|
if strings.HasPrefix(val, "/") {
|
||||||
|
return nil, fmt.Errorf("cannot keep file (%s) after update because it starts with a slash", val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &pkgInfo, nil
|
|
||||||
|
// Setup split package information
|
||||||
|
for i, splitPkg := range pkgInfo.SplitPackages {
|
||||||
|
// Ensure split package contains a name and one that is different from the main package name
|
||||||
|
if splitPkg.Name == "" || splitPkg.Name == pkgInfo.Name {
|
||||||
|
return nil, fmt.Errorf("invalid split package name: %s", splitPkg.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn split package into json data
|
||||||
|
splitPkgJson, err := yaml.Marshal(splitPkg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone all main package fields onto split package
|
||||||
|
pkgInfoClone := *pkgInfo
|
||||||
|
pkgInfo.SplitPackages[i] = &pkgInfoClone
|
||||||
|
|
||||||
|
// Set make depends and split package field of split package to nil
|
||||||
|
pkgInfo.SplitPackages[i].MakeDepends = nil
|
||||||
|
pkgInfo.SplitPackages[i].SplitPackages = nil
|
||||||
|
|
||||||
|
// Unmarshal json data back to struct
|
||||||
|
err = yaml.Unmarshal(splitPkgJson, &pkgInfo.SplitPackages[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force set split package version, revision and URL
|
||||||
|
pkgInfo.SplitPackages[i].Version = pkgInfo.Version
|
||||||
|
pkgInfo.SplitPackages[i].Revision = pkgInfo.Revision
|
||||||
|
pkgInfo.SplitPackages[i].Url = pkgInfo.Url
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkgInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, pkgInfo *PackageInfo, rootDir string) string {
|
func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, pkgInfo *PackageInfo, rootDir string) string {
|
||||||
|
@ -73,10 +73,56 @@ func (repo *Repository) ReadLocalDatabase() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range entry.Info.Provides {
|
// Create repository entries
|
||||||
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name)
|
if entry.Info.IsSplitPackage() {
|
||||||
|
for _, splitPkg := range entry.Info.SplitPackages {
|
||||||
|
// Turn split package into json data
|
||||||
|
splitPkgJson, err := yaml.Marshal(splitPkg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone all main package fields onto split package
|
||||||
|
splitPkgClone := *entry.Info
|
||||||
|
|
||||||
|
// Set split package field of split package to nil
|
||||||
|
splitPkgClone.SplitPackages = nil
|
||||||
|
|
||||||
|
// Unmarshal json data back to struct
|
||||||
|
err = yaml.Unmarshal(splitPkgJson, &splitPkgClone)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force set split package version, revision and URL
|
||||||
|
splitPkgClone.Version = entry.Info.Version
|
||||||
|
splitPkgClone.Revision = entry.Info.Revision
|
||||||
|
splitPkgClone.Url = entry.Info.Url
|
||||||
|
|
||||||
|
// Create entry for split package
|
||||||
|
repo.Entries[splitPkg.Name] = &RepositoryEntry{
|
||||||
|
Info: &splitPkgClone,
|
||||||
|
Download: entry.Download,
|
||||||
|
DownloadSize: entry.DownloadSize,
|
||||||
|
InstalledSize: 0,
|
||||||
|
Repository: repo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add virtual packages to repository
|
||||||
|
for _, p := range splitPkg.Provides {
|
||||||
|
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], splitPkg.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create entry for package
|
||||||
|
repo.Entries[entry.Info.Name] = &entry
|
||||||
|
|
||||||
|
// Add virtual packages to repository
|
||||||
|
for _, p := range entry.Info.Provides {
|
||||||
|
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
repo.Entries[entry.Info.Name] = &entry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -220,16 +266,16 @@ func (repo *Repository) FetchPackage(pkg string) (string, error) {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
err = os.MkdirAll("/var/cache/bpm/packages/", 0755)
|
err = os.MkdirAll("/var/cache/bpm/fetched/", 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
out, err := os.Create("/var/cache/bpm/packages/" + path.Base(entry.Download))
|
out, err := os.Create("/var/cache/bpm/fetched/" + path.Base(entry.Download))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer out.Close()
|
defer out.Close()
|
||||||
|
|
||||||
_, err = io.Copy(out, resp.Body)
|
_, err = io.Copy(out, resp.Body)
|
||||||
return "/var/cache/bpm/packages/" + path.Base(entry.Download), nil
|
return "/var/cache/bpm/fetched/" + path.Base(entry.Download), nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user