summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-08-22 16:10:58 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2024-08-22 16:11:38 +0200
commit67070389f3752f6f23d1fb0c06bd963464aa8bca (patch)
tree02e0e09f6d5a6e1132dab89b154418c3f5be7a7b
parentaccc2f202eabfe472ceae37d9e4f4431a8cc298f (diff)
Implement 'Pin: source-version <foo>'
As wondered about by Paride some minutes ago.
-rw-r--r--apt-pkg/policy.cc2
-rw-r--r--apt-pkg/versionmatch.cc10
-rw-r--r--apt-pkg/versionmatch.h2
-rw-r--r--doc/apt_preferences.5.xml8
-rwxr-xr-xtest/integration/test-policy-pinning17
5 files changed, 36 insertions, 3 deletions
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index b1d8e7223..5d361af1a 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -452,6 +452,8 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
pkgVersionMatch::MatchType Type;
if (stringcasecmp(Start,Word,"version") == 0 && Name.empty() == false)
Type = pkgVersionMatch::Version;
+ else if (stringcasecmp(Start,Word,"source-version") == 0 && Name.empty() == false)
+ Type = pkgVersionMatch::SourceVersion;
else if (stringcasecmp(Start,Word,"release") == 0)
Type = pkgVersionMatch::Release;
else if (stringcasecmp(Start,Word,"origin") == 0)
diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc
index f95232ac3..3af51e40c 100644
--- a/apt-pkg/versionmatch.cc
+++ b/apt-pkg/versionmatch.cc
@@ -42,7 +42,7 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
return;
// Cut up the version representation
- if (Type == Version)
+ if (Type == Version || Type == SourceVersion)
{
if (Data.end()[-1] == '*')
{
@@ -177,6 +177,14 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
/* */
bool pkgVersionMatch::VersionMatches(pkgCache::VerIterator Ver)
{
+ if (Type == SourceVersion)
+ {
+ if (MatchVer(Ver.SourceVerStr(),VerStr,VerPrefixMatch) == true)
+ return true;
+ if (ExpressionMatches(VerStr, Ver.SourceVerStr()) == true)
+ return true;
+ return false;
+ }
if (Type == Version)
{
if (MatchVer(Ver.VerStr(),VerStr,VerPrefixMatch) == true)
diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h
index faf1fd436..abaec08d6 100644
--- a/apt-pkg/versionmatch.h
+++ b/apt-pkg/versionmatch.h
@@ -62,7 +62,7 @@ class APT_PUBLIC pkgVersionMatch
public:
- enum MatchType {None = 0,Version,Release,Origin} Type;
+ enum MatchType {None = 0,Version,Release,Origin, SourceVersion} Type;
bool MatchVer(const char *A,std::string B,bool Prefix) APT_PURE;
static bool ExpressionMatches(const char *pattern, const char *string);
diff --git a/doc/apt_preferences.5.xml b/doc/apt_preferences.5.xml
index 1b38ae1c6..f166acc23 100644
--- a/doc/apt_preferences.5.xml
+++ b/doc/apt_preferences.5.xml
@@ -213,6 +213,14 @@ Package: perl
Pin: version &good-perl;*
Pin-Priority: 1001
</programlisting>
+
+<simpara>Since 2.9.9, you can also pin by a source version:</simpara>
+<programlisting>
+Package: perl
+Pin: source-version &good-perl;*
+Pin-Priority: 1001
+</programlisting>
+
</listitem>
<listitem><simpara>The general form assigns a priority to all of the package versions in a
diff --git a/test/integration/test-policy-pinning b/test/integration/test-policy-pinning
index dc3192fe9..99f193930 100755
--- a/test/integration/test-policy-pinning
+++ b/test/integration/test-policy-pinning
@@ -80,8 +80,9 @@ testglobalpolicy
msgmsg 'Test with specific packages'
+# Yeesh, the XB-Source stuff is hacky, hopefully this won't break.
buildsimplenativepackage "coolstuff" "all" "1.0" "stable"
-buildsimplenativepackage "coolstuff" "all" "2.0~bpo1" "backports"
+buildsimplenativepackage "coolstuff" "all" "2.0~bpo1" "backports" "XB-Source: coolstuff (2.0~bpo1-source-version)"
setupaptarchive
@@ -434,6 +435,20 @@ testsuccessequal "coolstuff:
1.0 500
500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff
+echo "Package: coolstuff
+Pin: source-version 2.0~bpo1-source-version
+Pin-Priority: 1000" > rootdir/etc/apt/preferences
+testsuccessequal "coolstuff:
+ Installed: 2.0~bpo1
+ Candidate: 2.0~bpo1
+ Version table:
+ 2.0~bpo2 100
+ 100 file:${tmppath}/aptarchive backports/main all Packages
+ *** 2.0~bpo1 1000
+ 100 ${tmppath}/rootdir/var/lib/dpkg/status
+ 1.0 500
+ 500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff
+
# Check for 0
echo "Package: coolstuff
Pin: release n=backports