diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2020-01-17 13:18:03 +0100 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2020-01-17 13:24:39 +0100 |
commit | 450af26202424bef33e0c58f3f99dfd0c21e7297 (patch) | |
tree | 633055b6cd785a0211d64767ca90dce50faa6fd9 | |
parent | 8ebabf3d9026d1a738a4e8988e168902af7446e3 (diff) |
policy: Implement pinning by source package
This implements the src: syntax inside policy, allowing you to
pin by source package. This by default only pins the native
architecuture, use src:pkg:any to pin for all architectures
in your cache.
Closes: #166032
-rw-r--r-- | apt-pkg/policy.cc | 57 | ||||
-rw-r--r-- | doc/apt_preferences.5.xml | 21 |
2 files changed, 64 insertions, 14 deletions
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index b9bdfd20f..618e17e0b 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -175,6 +175,11 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, return; } + bool IsSourcePin = APT::String::Startswith(Name, "src:"); + if (IsSourcePin) { + Name = Name.substr(sizeof("src:") - 1); + } + size_t found = Name.rfind(':'); string Arch; if (found != string::npos) { @@ -190,10 +195,11 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G) if (Name != G.Name() && match.ExpressionMatches(Name, G.Name())) { + auto NameToPinFor = IsSourcePin ? string("src:").append(G.Name()) : string(G.Name()); if (Arch.empty() == false) - CreatePin(Type, string(G.Name()).append(":").append(Arch), Data, Priority); + CreatePin(Type, NameToPinFor.append(":").append(Arch), Data, Priority); else - CreatePin(Type, G.Name(), Data, Priority); + CreatePin(Type, NameToPinFor, Data, Priority); } return; } @@ -209,20 +215,19 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, else MatchingArch = Arch; APT::CacheFilter::PackageArchitectureMatchesSpecification pams(MatchingArch); - for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) - { - if (pams(Pkg.Arch()) == false) - continue; - - PkgPin P(Pkg.FullName()); - P.Type = Type; - P.Priority = Priority; - P.Data = Data; - // Find matching version(s) and copy the pin into it - pkgVersionMatch Match(P.Data,P.Type); - for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() != true; ++Ver) + if (IsSourcePin) { + for (pkgCache::VerIterator Ver = Grp.VersionsInSource(); not Ver.end(); Ver = Ver.NextInSource()) { + if (pams(Ver.ParentPkg().Arch()) == false) + continue; + + PkgPin P(Ver.ParentPkg().FullName()); + P.Type = Type; + P.Priority = Priority; + P.Data = Data; + // Find matching version(s) and copy the pin into it + pkgVersionMatch Match(P.Data,P.Type); if (Match.VersionMatches(Ver)) { Pin *VP = VerPins + Ver->ID; if (VP->Type == pkgVersionMatch::None) { @@ -231,6 +236,30 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, } } } + } else { + for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) + { + if (pams(Pkg.Arch()) == false) + continue; + + PkgPin P(Pkg.FullName()); + P.Type = Type; + P.Priority = Priority; + P.Data = Data; + + // Find matching version(s) and copy the pin into it + pkgVersionMatch Match(P.Data,P.Type); + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() != true; ++Ver) + { + if (Match.VersionMatches(Ver)) { + Pin *VP = VerPins + Ver->ID; + if (VP->Type == pkgVersionMatch::None) { + *VP = P; + matched = true; + } + } + } + } } } diff --git a/doc/apt_preferences.5.xml b/doc/apt_preferences.5.xml index cac9a96e1..dacf3dc21 100644 --- a/doc/apt_preferences.5.xml +++ b/doc/apt_preferences.5.xml @@ -303,7 +303,28 @@ a &glob; expression in itself. </para> </refsect2> +<refsect2><title>Pinning by source package</title> +<para>APT supports pinning by source packages. To pin by a source package, +prepend "src:" to the package name.</para> +<para>For example, to pin all binaries produced by the apt source package +of this APT's version to 990, you can do:</para> +<programlisting> +Package: src:apt +Pin: version &apt-product-version; +Pin-Priority: 990 +</programlisting> + +<para>Source package pinning can be combined with regular expressions and +glob patterns, and can also take a binary architecture.</para> +<para>For example, let's pin all binaries for all architectures produced by +any source package containing apt in its name to 990:</para> +<programlisting> +Package: src:*apt*:any +Pin: version * +Pin-Priority: 990 +</programlisting> +</refsect2> |