Skip to content

Commit 76dba2d

Browse files
committed
♻️ Synced dbin 📦 <-- 1.6: fix remove.go ⌚
1 parent edf806b commit 76dba2d

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

remove.go

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,18 @@ func removeBinaries(config *config, bEntries []binaryEntry) error {
4343
go func(bEntry binaryEntry) {
4444
defer wg.Done()
4545

46-
installPath := filepath.Join(installDir, filepath.Base(bEntry.Name))
47-
licensePath := filepath.Join(config.LicenseDir, fmt.Sprintf("%s_LICENSE", parseBinaryEntry(bEntry, false)))
48-
49-
trackedBEntry, err := readEmbeddedBEntry(installPath)
46+
// Try to find the binary by name or by matching user.FullName
47+
binaryPath, trackedBEntry, err := findBinaryByNameOrFullName(installDir, bEntry.Name)
5048
if err != nil {
5149
if verbosityLevel >= normalVerbosity {
52-
fmt.Fprintf(os.Stderr, "Warning: Failed to retrieve full name for '%s'. Skipping removal because this program may not have been installed by dbin.\n", parseBinaryEntry(bEntry, true))
50+
fmt.Fprintf(os.Stderr, "Warning: '%s' does not exist or was not installed by dbin: %v\n", bEntry.Name, err)
5351
}
5452
return
5553
}
5654

57-
if filepath.Base(bEntry.Name) != filepath.Base(trackedBEntry.Name) {
58-
installPath = filepath.Join(installDir, filepath.Base(trackedBEntry.Name))
59-
licensePath = filepath.Join(config.LicenseDir, fmt.Sprintf("%s_LICENSE", filepath.Base(parseBinaryEntry(trackedBEntry, false))))
60-
}
55+
licensePath := filepath.Join(config.LicenseDir, fmt.Sprintf("%s_LICENSE", filepath.Base(parseBinaryEntry(trackedBEntry, false))))
6156

62-
if !fileExists(installPath) {
57+
if !fileExists(binaryPath) {
6358
if verbosityLevel >= normalVerbosity {
6459
fmt.Fprintf(os.Stderr, "Warning: '%s' does not exist in %s\n", bEntry.Name, installDir)
6560
}
@@ -68,25 +63,25 @@ func removeBinaries(config *config, bEntries []binaryEntry) error {
6863

6964
if trackedBEntry.PkgID == "" {
7065
if verbosityLevel >= normalVerbosity {
71-
fmt.Fprintf(os.Stderr, "Skipping '%s': it was not installed by dbin\n", bEntry.Name)
66+
fmt.Fprintf(os.Stderr, "Warning: '%s' was not installed by dbin\n", bEntry.Name)
7267
}
7368
return
7469
}
7570

76-
if err := runDeintegrationHooks(config, installPath); err != nil {
71+
if err := runDeintegrationHooks(config, binaryPath); err != nil {
7772
if verbosityLevel >= silentVerbosityWithErrors {
78-
fmt.Fprintf(os.Stderr, "%s\n", err)
73+
fmt.Fprintf(os.Stderr, "Error running deintegration hooks for '%s': %v\n", bEntry.Name, err)
7974
}
8075
mutex.Lock()
8176
removeErrors = append(removeErrors, err.Error())
8277
mutex.Unlock()
8378
return
8479
}
8580

86-
err = os.Remove(installPath)
81+
err = os.Remove(binaryPath)
8782
if err != nil {
8883
if verbosityLevel >= silentVerbosityWithErrors {
89-
fmt.Fprintf(os.Stderr, "failed to remove '%s' from %s. %v\n", bEntry.Name, installDir, err)
84+
fmt.Fprintf(os.Stderr, "Failed to remove '%s' from %s: %v\n", bEntry.Name, installDir, err)
9085
}
9186
mutex.Lock()
9287
removeErrors = append(removeErrors, fmt.Sprintf("failed to remove '%s' from %s: %v", bEntry.Name, installDir, err))
@@ -119,6 +114,50 @@ func removeBinaries(config *config, bEntries []binaryEntry) error {
119114
return nil
120115
}
121116

117+
// findBinaryByNameOrFullName searches for a binary in installDir by its name or by matching the user.FullName xattr.
118+
func findBinaryByNameOrFullName(installDir, name string) (string, binaryEntry, error) {
119+
// First, try direct path
120+
binaryPath := filepath.Join(installDir, filepath.Base(name))
121+
if fileExists(binaryPath) {
122+
trackedBEntry, err := readEmbeddedBEntry(binaryPath)
123+
if err == nil && trackedBEntry.Name != "" {
124+
return binaryPath, trackedBEntry, nil
125+
}
126+
}
127+
128+
// If direct path fails, scan directory for matching user.FullName
129+
entries, err := os.ReadDir(installDir)
130+
if err != nil {
131+
return "", binaryEntry{}, errFileAccess.Wrap(err)
132+
}
133+
134+
// Normalize the input name for comparison
135+
inputBEntry := stringToBinaryEntry(name)
136+
inputFullName := parseBinaryEntry(inputBEntry, false)
137+
138+
for _, entry := range entries {
139+
if entry.IsDir() {
140+
continue
141+
}
142+
binaryPath = filepath.Join(installDir, entry.Name())
143+
if !isExecutable(binaryPath) || isSymlink(binaryPath) {
144+
continue
145+
}
146+
147+
trackedBEntry, err := readEmbeddedBEntry(binaryPath)
148+
if err != nil || trackedBEntry.Name == "" {
149+
continue
150+
}
151+
152+
trackedFullName := parseBinaryEntry(trackedBEntry, false)
153+
if trackedFullName == inputFullName || trackedBEntry.Name == filepath.Base(name) {
154+
return binaryPath, trackedBEntry, nil
155+
}
156+
}
157+
158+
return "", binaryEntry{}, errFileNotFound.New("binary '%s' not found in %s", name, installDir)
159+
}
160+
122161
func runDeintegrationHooks(config *config, binaryPath string) error {
123162
if config.UseIntegrationHooks {
124163
ext := filepath.Ext(binaryPath)

repoIndexFile.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ type binaryEntry struct {
3030
Snapshots []snapshot `json:"snapshots,omitempty" `
3131
Rank uint16 `json:"rank,omitempty" `
3232
WebManifest string `json:"web_manifest,omitempty"`
33+
// specific to `dbin`'s internal needs:
34+
binaryPath string `json:"-"`
3335
Repository repository
3436
}

utility.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var (
4141

4242
const (
4343
blueColor = "\x1b[0;34m"
44+
yellowColor = "\x1b[0;33m"
4445
cyanColor = "\x1b[0;36m"
4546
intenseBlackColor = "\x1b[0;90m"
4647
blueBgWhiteFg = "\x1b[48;5;4m"
@@ -360,7 +361,10 @@ func readEmbeddedBEntry(binaryPath string) (binaryEntry, error) {
360361
return binaryEntry{}, errXAttr.New("xattr: user.FullName attribute not found for binary: %s", binaryPath)
361362
}
362363

363-
return stringToBinaryEntry(string(fullName)), nil
364+
bEntry := stringToBinaryEntry(string(fullName))
365+
bEntry.binaryPath = binaryPath
366+
367+
return bEntry, nil
364368
}
365369

366370
func accessCachedOrFetch(url, filename string, cfg *config, syncInterval time.Duration) ([]byte, error) {

0 commit comments

Comments
 (0)