-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
73 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,92 @@ | ||
// remove.go // This file implements the functionality of "remove" //> | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"sync" | ||
|
||
"github.com/pkg/xattr" | ||
) | ||
|
||
// removeCommand handles the removal of one or more binaries based on the verbosity level. | ||
// removeCommand handles the overall flow, passing binaries to removeBinaries and ensuring tracker cleanup. | ||
func removeCommand(binaries []string, installDir, trackerFile string, verbosityLevel Verbosity) error { | ||
if len(binaries) == 1 { | ||
err := removeBinary(binaries[0], installDir, verbosityLevel) | ||
if err != nil { | ||
return err | ||
} | ||
} else if len(binaries) > 1 { | ||
// Remove duplicates before processing | ||
binaries = removeDuplicates(binaries) | ||
err := multipleRemove(binaries, installDir, verbosityLevel) | ||
if err != nil { | ||
return err | ||
} | ||
// Call removeBinaries to handle the actual removal process | ||
err := removeBinaries(removeDuplicates(binaries), installDir, verbosityLevel) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Cleanup the tracker file after removal | ||
err := cleanupTrackerFile(trackerFile, installDir) | ||
// Cleanup the tracker file after all binaries are removed | ||
err = cleanupTrackerFile(trackerFile, installDir) | ||
if err != nil { | ||
return fmt.Errorf("error cleaning up tracker file: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// removeBinary removes a single binary and logs the operation based on verbosity level. | ||
func removeBinary(binaryName, installDir string, verbosityLevel Verbosity) error { | ||
installPath := filepath.Join(installDir, filepath.Base(binaryName)) | ||
err := os.Remove(installPath) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
if verbosityLevel >= normalVerbosity { | ||
fmt.Fprintf(os.Stderr, "Warning: '%s' does not exist in %s\n", binaryName, installDir) | ||
} | ||
} else { | ||
if verbosityLevel >= silentVerbosityWithErrors { | ||
fmt.Fprintf(os.Stderr, "error: failed to remove '%s' from %s. %v\n", binaryName, installDir, err) | ||
} | ||
return err | ||
// removeBinaries processes each binary, removing only those that pass validation. | ||
func removeBinaries(binaries []string, installDir string, verbosityLevel Verbosity) error { | ||
var wg sync.WaitGroup | ||
var removeErrors []string | ||
var mutex sync.Mutex | ||
|
||
// Inline function to check if a binary is ours | ||
validate := func(file string) bool { | ||
if isSymlink(file) { | ||
return false | ||
} | ||
} else if verbosityLevel <= extraVerbose { | ||
fmt.Printf("'%s' removed from %s\n", binaryName, installDir) | ||
managedBy, err := xattr.Get(file, "user.ManagedBy") | ||
if err != nil || string(managedBy) != "dbin" { | ||
return false | ||
} | ||
return true | ||
} | ||
return nil | ||
} | ||
|
||
// multipleRemove removes multiple binaries and logs the operations based on verbosity level. | ||
func multipleRemove(binaries []string, installDir string, verbosityLevel Verbosity) error { | ||
// Loop over the binaries and remove the valid ones | ||
for _, binaryName := range binaries { | ||
if err := removeBinary(binaryName, installDir, verbosityLevel); err != nil { | ||
return err | ||
} | ||
wg.Add(1) | ||
go func(binaryName string) { | ||
defer wg.Done() | ||
|
||
installPath := filepath.Join(installDir, filepath.Base(binaryName)) | ||
|
||
if !validate(installPath) { | ||
if verbosityLevel >= normalVerbosity { | ||
fmt.Fprintf(os.Stderr, "Skipping '%s': it was not installed by dbin\n", binaryName) | ||
} | ||
return | ||
} | ||
|
||
err := os.Remove(installPath) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
if verbosityLevel >= normalVerbosity { | ||
fmt.Fprintf(os.Stderr, "Warning: '%s' does not exist in %s\n", binaryName, installDir) | ||
} | ||
} else { | ||
if verbosityLevel >= silentVerbosityWithErrors { | ||
fmt.Fprintf(os.Stderr, "error: failed to remove '%s' from %s. %v\n", binaryName, installDir, err) | ||
} | ||
// Add error to the list in a thread-safe way, i guess | ||
mutex.Lock() | ||
removeErrors = append(removeErrors, fmt.Sprintf("failed to remove '%s' from %s: %v", binaryName, installDir, err)) | ||
mutex.Unlock() | ||
} | ||
} else if verbosityLevel <= extraVerbose { | ||
fmt.Printf("'%s' removed from %s\n", binaryName, installDir) | ||
} | ||
}(binaryName) | ||
} | ||
|
||
// Wait for all goroutines to finish | ||
wg.Wait() | ||
|
||
// Return concatenated errors if any occurred | ||
if len(removeErrors) > 0 { | ||
return fmt.Errorf(strings.Join(removeErrors, "\n")) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters