repos / dbin

📦 Poor man's package manager.
git clone https://github.com/xplshn/dbin.git

xplshn  ·  2025-08-13

findURL.go

Go
  1package main
  2
  3import (
  4	"fmt"
  5	"path/filepath"
  6	"strings"
  7
  8	"github.com/zeebo/errs"
  9)
 10
 11func findMatchingBins(bEntry binaryEntry, uRepoIndex []binaryEntry) []binaryEntry {
 12	var matchingBins []binaryEntry
 13
 14	for _, bin := range uRepoIndex {
 15		// Match based on the format hierarchy: name#id:version@repo, name#id@repo, name#id:version, name#id, name@repo, name
 16		matches := false
 17		if bin.Name == bEntry.Name {
 18			// name#id:version@repo
 19			if bEntry.PkgID != "" && bEntry.Version != "" && bEntry.Repository.Name != "" {
 20				if bin.PkgID == bEntry.PkgID && (bin.Version == bEntry.Version || hasMatchingSnapshot(&bin, bEntry.Version)) && bin.Repository.Name == bEntry.Repository.Name {
 21					matches = true
 22				}
 23				// name#id:version
 24			} else if bEntry.PkgID != "" && bEntry.Version != "" && bEntry.Repository.Name == "" {
 25				if bin.PkgID == bEntry.PkgID && (bin.Version == bEntry.Version || hasMatchingSnapshot(&bin, bEntry.Version)) {
 26					matches = true
 27				}
 28				// name#id@repo
 29			} else if bEntry.PkgID != "" && bEntry.Repository.Name != "" && bEntry.Version == "" {
 30				if bin.PkgID == bEntry.PkgID && bin.Repository.Name == bEntry.Repository.Name {
 31					matches = true
 32				}
 33				// name#id
 34			} else if bEntry.PkgID != "" && bEntry.Version == "" && bEntry.Repository.Name == "" {
 35				if bin.PkgID == bEntry.PkgID {
 36					matches = true
 37				}
 38				// name@repo
 39			} else if bEntry.PkgID == "" && bEntry.Repository.Name != "" && bEntry.Version == "" {
 40				if bin.Repository.Name == bEntry.Repository.Name {
 41					matches = true
 42				}
 43				// name
 44			} else if bEntry.PkgID == "" && bEntry.Version == "" && bEntry.Repository.Name == "" {
 45				matches = true
 46			}
 47		}
 48
 49		if matches {
 50			matchingBins = append(matchingBins, bin)
 51		}
 52	}
 53
 54	return matchingBins
 55}
 56
 57// Helper function to check if a snapshot matches the requested version or commit, and if so, modify the DownloadURL
 58func hasMatchingSnapshot(bin *binaryEntry, version string) bool {
 59	if !strings.HasPrefix(bin.DownloadURL, "oci://") {
 60		return false
 61	}
 62
 63	// First, check all snapshot commits
 64	for _, snap := range bin.Snapshots {
 65		if version == snap.Commit {
 66			// Modify the URL to use the snapshot's commit for OCI URLs
 67			idx := strings.LastIndex(bin.DownloadURL, ":")
 68			if idx != -1 {
 69				bin.DownloadURL = bin.DownloadURL[:idx+1] + snap.Commit
 70				bin.Bsum = "!no_check"
 71				bin.Version = snap.Version
 72			}
 73			return true
 74		}
 75	}
 76
 77	// Then, check all snapshot versions
 78	for _, snap := range bin.Snapshots {
 79		if version == snap.Version {
 80			// Modify the URL to use the snapshot's commit for OCI URLs
 81			idx := strings.LastIndex(bin.DownloadURL, ":")
 82			if idx != -1 {
 83				bin.DownloadURL = bin.DownloadURL[:idx+1] + snap.Commit
 84				bin.Bsum = "!no_check"
 85				bin.Version = snap.Version
 86			}
 87			return true
 88		}
 89	}
 90	return false
 91}
 92
 93func findURL(bEntries []binaryEntry, uRepoIndex []binaryEntry, config *config) ([]binaryEntry, error) {
 94	// Check for duplicate names in bEntries
 95	nameCount := make(map[string]int)
 96	for _, bEntry := range bEntries {
 97		nameCount[bEntry.Name]++
 98		if nameCount[bEntry.Name] > 1 {
 99			return nil, errs.New("duplicate binary name '%s' provided in input", bEntry.Name)
100		}
101	}
102
103	var results []binaryEntry
104	var allErrors []error
105	allFailed := true
106
107	for _, bEntry := range bEntries {
108		if bEntry.Bsum == "!no_check" {
109			results = append(results, bEntry)
110			if verbosityLevel >= extraVerbose {
111				fmt.Printf("\033[2K\rSkipping resolution for \"%s\" (its Bsum was marked as \"!no_check\" by stringToBinaryEntry())\n", bEntry.Name)
112			}
113			allFailed = false
114			continue
115		} else {
116			// Check if the binary is installed and update bEntry with installed metadata if available
117					if instBEntry := bEntryOfinstalledBinary(filepath.Join(config.InstallDir, bEntry.Name)); instBEntry.Name != "" {
118						if bEntry.PkgID == "" {
119							bEntry.PkgID = instBEntry.PkgID
120						}
121						if bEntry.Version == "" {
122							bEntry.Version = instBEntry.Version
123						}
124						if bEntry.Repository.Name == "" {
125							bEntry.Repository.Name = instBEntry.Repository.Name
126						}
127					}
128
129					matchingBins := findMatchingBins(bEntry, uRepoIndex)
130
131					if len(matchingBins) == 0 {
132						results = append(results, binaryEntry{
133							Name:        bEntry.Name,
134							DownloadURL: "!not_found",
135							Bsum:        "!no_check",
136						})
137						allErrors = append(allErrors, fmt.Errorf("didn't find download URL for [%s]", parseBinaryEntry(bEntry, false)))
138						continue
139					}
140
141					allFailed = false
142
143					// If a repository is specified, select the binary from that repository
144					if bEntry.Repository.Name != "" {
145						for _, bin := range matchingBins {
146							if bin.Repository.Name == bEntry.Repository.Name {
147								results = append(results, bin)
148								if verbosityLevel >= extraVerbose {
149									fmt.Printf("\033[2K\rFound \"%s\" with id=%s version=%s repo=%s\n", bEntry.Name, bin.PkgID, bin.Version, bin.Repository.Name)
150								}
151								break
152							}
153						}
154						// If no match with the specified repo, add an error
155						if len(results) == len(bEntries)-1 {
156							results = append(results, binaryEntry{
157								Name:        bEntry.Name,
158								DownloadURL: "!not_found",
159								Bsum:        "!no_check",
160							})
161							allErrors = append(allErrors, fmt.Errorf("no binary found for [%s] in repository %s", parseBinaryEntry(bEntry, false), bEntry.Repository.Name))
162						}
163						continue
164					}
165
166					// If no repository is specified, include the first matching binary
167					results = append(results, matchingBins[0])
168					if verbosityLevel >= extraVerbose {
169						fmt.Printf("\033[2K\rFound \"%s\" with id=%s version=%s repo=%s\n", bEntry.Name, matchingBins[0].PkgID, matchingBins[0].Version, matchingBins[0].Repository.Name)
170					}
171				}
172		}
173
174	if allFailed {
175		var errorMessages []string
176		for _, e := range allErrors {
177			errorMessages = append(errorMessages, e.Error())
178		}
179		return nil, errs.New(ternary(len(bEntries) != 1, "no valid download URLs found for any of the requested binaries.\n%s\n", "%s\n"), strings.Join(errorMessages, "\n"))
180	}
181
182	return results, nil
183}