Fix -with-sources not downloading differently named sources

Such as e.g. downloading 'glibc' when the sources for 'libc6'
are requested.
This commit is contained in:
Gordian Schoenherr
2024-11-26 16:19:46 +09:00
parent 3b785e4165
commit 0c76677b16
3 changed files with 46 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package deb
import (
"fmt"
"regexp"
"sort"
"strings"
@@ -507,12 +508,24 @@ func (l *PackageList) Search(dep Dependency, allMatches bool, searchProvided boo
type FilterOptions struct {
Queries []PackageQuery
WithDependencies bool
WithSources bool // Source packages correspond to binary packages are included
Source *PackageList
DependencyOptions int
Architectures []string
Progress aptly.Progress // set to non-nil to report progress
}
// SourceRegex is a regular expression to match source package names.
// > In a binary package control file [...], the source package name may be followed by a version number in
// > parentheses. This version number may be omitted [...] if it has the same value as the Version field of
// > the binary package in question.
// > [...]
// > Package names (both source and binary, see Package) must consist only of lower case letters (a-z),
// > digits (0-9), plus (+) and minus (-) signs, and periods (.).
// > They must be at least two characters long and must start with an alphanumeric character.
// -- https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-source
var SourceRegex = regexp.MustCompile(`^([a-z0-9][-+.a-z0-9]+)(?:\s+\(([^)]+)\))?$`)
// Filter filters package index by specified queries (ORed together), possibly pulling dependencies
func (l *PackageList) Filter(options FilterOptions) (*PackageList, error) {
if !l.indexed {
@@ -524,6 +537,37 @@ func (l *PackageList) Filter(options FilterOptions) (*PackageList, error) {
for _, query := range options.Queries {
_ = result.Append(query.Query(l))
}
// The above loop already finds source packages that are named equal to their binary package, but we still need
// to account for those that are named differently.
if options.WithSources {
sourceQueries := make([]PackageQuery, 0)
for _, pkg := range result.packages {
if pkg.Source == "" {
continue
}
matches := SourceRegex.FindStringSubmatch(pkg.Source)
if matches == nil {
return nil, fmt.Errorf("invalid Source field: %s", pkg.Source)
}
sourceName := matches[1]
if sourceName == pkg.Name {
continue
}
sourceVersion := pkg.Version
if matches[2] != "" {
sourceVersion = matches[2]
}
sourceQueries = append(sourceQueries, &DependencyQuery{Dependency{
Pkg: sourceName,
Version: sourceVersion,
Relation: VersionEqual,
Architecture: ArchitectureSource,
}})
}
for _, query := range sourceQueries {
_ = result.Append(query.Query(l))
}
}
if options.WithDependencies {
added := result.Len()

View File

@@ -450,7 +450,7 @@ func (p *Package) GetArchitecture() string {
return p.Architecture
}
// GetDependencies compiles list of dependncies by flags from options
// GetDependencies compiles list of dependencies by flags from options
func (p *Package) GetDependencies(options int) (dependencies []string) {
deps := p.Deps()

View File

@@ -600,6 +600,7 @@ func (repo *RemoteRepo) ApplyFilter(dependencyOptions int, filterQuery PackageQu
Queries: []PackageQuery{filterQuery},
WithDependencies: repo.FilterWithDeps,
Source: emptyList,
WithSources: repo.DownloadSources,
DependencyOptions: dependencyOptions,
Architectures: repo.Architectures,
Progress: progress,