7 Commits
4 changed files with 86 additions and 64 deletions
+54 -33
View File
@@ -93,7 +93,7 @@ func main() {
currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package removal")
currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts")
currentFlagSet.BoolP("unused", "u", false, "Remove packages only if they are not required as dependencies")
currentFlagSet.BoolP("cleanup", "c", false, "Additionally remove all unused dependencies")
currentFlagSet.BoolP("cleanup", "n", false, "Additionally remove all unused dependencies")
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Remove the specified packages", os.Args[2:])
removePackages()
@@ -103,6 +103,8 @@ func main() {
currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory")
currentFlagSet.BoolP("verbose", "v", false, "Show additional information about the current operation")
currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package cleanup")
currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts")
currentFlagSet.BoolP("all", "a", false, "Perform all types of cleanup")
currentFlagSet.BoolP("depends", "d", false, "Perform a dependency cleanup")
currentFlagSet.BoolP("make-depends", "m", false, "Perform a make dependency cleanup")
currentFlagSet.BoolP("compilation-files", "c", false, "Perform a cleanup of compilation files")
@@ -506,10 +508,6 @@ func removePackages() {
// Get packages
packages := currentFlagSet.Args()
if len(packages) == 0 {
fmt.Println("No packages were given to remove")
return
}
// Check for required permissions
if os.Getuid() != 0 {
@@ -592,6 +590,7 @@ func doCleanup() {
verbose, _ := currentFlagSet.GetBool("verbose")
force, _ := currentFlagSet.GetBool("force")
yesAll, _ := currentFlagSet.GetBool("yes")
all, _ := currentFlagSet.GetBool("all")
cleanupDepends, _ := currentFlagSet.GetBool("depends")
cleanupMakeDepends, _ := currentFlagSet.GetBool("make-depends")
cleanupCompilationFiles, _ := currentFlagSet.GetBool("compilation-files")
@@ -599,7 +598,13 @@ func doCleanup() {
cleanupFetchedPackages, _ := currentFlagSet.GetBool("fetched-packages")
// Set default behaviour
if !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") && !isFlagSet(currentFlagSet, "compilation-files") && !isFlagSet(currentFlagSet, "binary-packages") && !isFlagSet(currentFlagSet, "fetched-packages") {
if all {
cleanupDepends = true
cleanupMakeDepends = bpmlib.MainBPMConfig.CleanupMakeDependencies
cleanupCompilationFiles = true
cleanupBinaryPackages = true
cleanupFetchedPackages = true
} else if !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") && !isFlagSet(currentFlagSet, "compilation-files") && !isFlagSet(currentFlagSet, "binary-packages") && !isFlagSet(currentFlagSet, "fetched-packages") {
cleanupDepends = true
cleanupMakeDepends = bpmlib.MainBPMConfig.CleanupMakeDependencies
cleanupCompilationFiles = false
@@ -1044,9 +1049,39 @@ func compilePackage() {
}
}
// Setup cleanup function
cleanupFunc := func() {
if installSrcPkgDepends && len(unmetDepends) > 0 {
// Get path to current executable
executable, err := os.Executable()
if err != nil {
log.Printf("Warning: could not get path to executable: %s\n", err)
}
// Run 'bpm cleanup' using the set privilege escalator command
cmd := exec.Command(bpmlib.CompilationBPMConfig.PrivilegeEscalatorCmd, executable, "cleanup")
if yesAll {
cmd.Args = slices.Insert(cmd.Args, 3, "-y")
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if verbose {
fmt.Println("Running command: " + cmd.String())
}
err = cmd.Run()
if err != nil {
log.Printf("Warning: dependency cleanup command failed: %s\n", err)
}
}
}
// Get current working directory
workdir, err := os.Getwd()
if err != nil {
// Remove unused packages
cleanupFunc()
log.Printf("Error: could not get working directory: %s", err)
exitCode = 1
return
@@ -1055,6 +1090,9 @@ func compilePackage() {
// Get user home directory
homedir, err := os.UserHomeDir()
if err != nil {
// Remove unused packages
cleanupFunc()
log.Printf("Error: could not get user home directory: %s", err)
exitCode = 1
return
@@ -1087,11 +1125,17 @@ func compilePackage() {
// Ensure output directory exists and is a directory
stat, err := os.Stat(outputDirectory)
if err != nil {
// Remove unused packages
cleanupFunc()
log.Printf("Error: could not stat output directory (%s): %s", outputDirectory, err)
exitCode = 1
return
}
if !stat.IsDir() {
// Remove unused packages
cleanupFunc()
log.Printf("Error: output directory (%s) is not a directory", outputDirectory)
exitCode = 1
return
@@ -1099,6 +1143,9 @@ func compilePackage() {
outputBpmPackages, err := bpmlib.CompileSourcePackage(sourcePackage, outputDirectory, skipChecks)
if err != nil {
// Remove unused packages
cleanupFunc()
log.Printf("Error: could not compile source package (%s): %s", sourcePackage, err)
exitCode = 1
return
@@ -1119,33 +1166,7 @@ func compilePackage() {
}
// Remove unused packages
if installSrcPkgDepends && len(unmetDepends) > 0 {
// Get path to current executable
executable, err := os.Executable()
if err != nil {
log.Printf("Error: could not get path to executable: %s\n", err)
exitCode = 1
return
}
// Run 'bpm cleanup' using the set privilege escalator command
cmd := exec.Command(bpmlib.CompilationBPMConfig.PrivilegeEscalatorCmd, executable, "cleanup")
if yesAll {
cmd.Args = slices.Insert(cmd.Args, 3, "-y")
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if verbose {
fmt.Println("Running command: " + cmd.String())
}
err = cmd.Run()
if err != nil {
log.Printf("Error: dependency cleanup command failed: %s\n", err)
exitCode = 1
return
}
}
cleanupFunc()
}
}
+24 -23
View File
@@ -132,7 +132,6 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
env = append(env, "HOME="+tempDirectory)
env = append(env, "BPM_WORKDIR="+tempDirectory)
env = append(env, "BPM_SOURCE="+path.Join(tempDirectory, "source"))
env = append(env, "BPM_OUTPUT="+path.Join(tempDirectory, "output"))
env = append(env, "BPM_PKG_NAME="+bpmpkg.PkgInfo.Name)
env = append(env, "BPM_PKG_VERSION="+bpmpkg.PkgInfo.Version)
env = append(env, "BPM_PKG_REVISION="+strconv.Itoa(bpmpkg.PkgInfo.Revision))
@@ -188,6 +187,21 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
packagesToCompile = append(packagesToCompile, bpmpkg.PkgInfo)
}
// Create output directories for each package
for _, pkg := range packagesToCompile {
// Create new output directory
err = os.Mkdir(path.Join(tempDirectory, "output_"+pkg.Name), 0755)
if err != nil {
return nil, err
}
// Change output directory owner
err = os.Chown(path.Join(tempDirectory, "output_"+pkg.Name), uid, gid)
if err != nil {
return nil, err
}
}
// Compile each package
for _, pkg := range packagesToCompile {
// Get package function name
@@ -196,26 +210,6 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
packageFunctionName = "package_" + pkg.Name
}
// Remove output directory if it already exists
if _, err := os.Stat(path.Join(tempDirectory, "output")); err == nil {
err := os.RemoveAll(path.Join(tempDirectory, "output"))
if err != nil {
return nil, err
}
}
// Create new output directory
err = os.Mkdir(path.Join(tempDirectory, "output"), 0755)
if err != nil {
return nil, err
}
// Change output directory owner
err = os.Chown(path.Join(tempDirectory, "output"), uid, gid)
if err != nil {
return nil, err
}
// Execute package function in source.sh script and generate package file list
cmd = exec.Command("bash", "-c",
"set -a\n"+ // Source and export functions and variables in source.sh script
@@ -224,10 +218,11 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
"echo \"Running "+packageFunctionName+"() function\"\n"+
"( cd \"$BPM_SOURCE\" && fakeroot -s \"$BPM_WORKDIR\"/fakeroot_file bash -e -c '"+packageFunctionName+"' ) || exit 1\n"+ // Run package() function
"fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file find \"$BPM_OUTPUT\" -mindepth 1 -printf \"%P %#m %U %G %s\\n\" > \"$BPM_WORKDIR\"/pkg.files") // Create package file list
cmd.Dir = tempDirectory
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = env
cmd.Env = append(env, "BPM_OUTPUT="+path.Join(tempDirectory, "output_"+pkg.Name))
if os.Getuid() == 0 {
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
@@ -238,7 +233,7 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
}
// Create gzip-compressed archive for the package files
cmd = exec.Command("bash", "-c", "find output -printf \"%P\\n\" | fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file tar -czf files.tar.gz --no-recursion -C output -T -")
cmd = exec.Command("bash", "-c", fmt.Sprintf("find %s -printf \"%%P\\n\" | fakeroot -i %s/fakeroot_file tar -czf files.tar.gz --no-recursion -C %s -T -", "output_"+pkg.Name, tempDirectory, "output_"+pkg.Name))
cmd.Dir = tempDirectory
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@@ -330,6 +325,12 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
return nil, err
}
// Remove output directory
err = os.RemoveAll(path.Join(tempDirectory, "output_"+pkg.Name))
if err != nil {
return nil, err
}
outputBpmPackages[pkgInfo.Name] = outputFilename
}
+7 -7
View File
@@ -31,7 +31,7 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalD
}) {
allDepends = append(allDepends, pkgInstallationReason{
PkgName: depend,
InstallationReason: InstallationReasonDependency,
InstallationReason: InstallationReasonManual,
})
}
}
@@ -51,23 +51,23 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalD
return allDepends
}
func (pkgInfo *PackageInfo) GetAllDependencies(includeMakeDepends, includeOptionalDepends bool, rootDir string) (resolved []string) {
func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeMakeDepends bool, rootDir string) (resolved []string) {
// Initialize slices
resolved = make([]string, 0)
unresolved := make([]string, 0)
// Call unexported function
pkgInfo.getAllDependencies(&resolved, &unresolved, includeMakeDepends, includeOptionalDepends, rootDir)
pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeMakeDepends, rootDir)
return resolved
}
func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[]string, includeMakeDepends, includeOptionalDepends bool, rootDir string) {
func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeMakeDepends bool, rootDir string) {
// Add current package name to unresolved slice
*unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies
for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, includeOptionalDepends) {
for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, false) {
depend := pkgIR.PkgName
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
@@ -86,7 +86,7 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
dependInfo := GetPackageInfo(depend, rootDir)
if dependInfo != nil {
dependInfo.getAllDependencies(resolved, unresolved, includeMakeDepends, includeOptionalDepends, rootDir)
dependInfo.getDependenciesRecursive(resolved, unresolved, includeMakeDepends, rootDir)
}
}
}
@@ -155,7 +155,7 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
}
// Resolve the dependencies of this dependency
resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, false, ignoreInstalled, verbose, rootDir)
// Move dependency from the unresolved slice to the resolved slice
if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
+1 -1
View File
@@ -230,7 +230,7 @@ func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
}
keepPackages = append(keepPackages, pkg.Name)
resolved := pkg.GetAllDependencies(!cleanupMakeDepends, true, operation.RootDir)
resolved := pkg.GetDependenciesRecursive(!cleanupMakeDepends, operation.RootDir)
for _, value := range resolved {
if !slices.Contains(keepPackages, value) {
keepPackages = append(keepPackages, value)