Re: Profile support in apt
- To: deity@lists.debian.org, wookey@wookware.org
- Subject: Re: Profile support in apt
- From: "Johannes Schauer" <j.schauer@email.de>
- Date: Tue, 11 Feb 2014 12:39:29 +0100
- Message-id: <[🔎] 20140211113929.3663.64977@hoothoot>
- In-reply-to: <20130130124635.GA18508@debian.org>
- References: <20130128174718.GB5031@stoneboat.aleph1.co.uk> <CAN3veRfHbO8o4krFbiZM7DK5ZypQdn84YAjMmZO+NrarUzfu6A@mail.gmail.com> <20130129173755.GA31359@hoothoot> <CAAZ6_fBnJmiJvUXRsZ4dSY_YThBnTFOM1PZRtz1hF+dzxyddrA@mail.gmail.com> <20130130084553.GA879@hoothoot> <20130130124635.GA18508@debian.org>
Hi,
Quoting Julian Andres Klode (2013-01-30 12:57:18)
> DEP-11 plans to make '<' and '>' basically part of the package name and use
> that for more complex provides; not knowing the use in multi-arch (I forgot
> it). So the extended architecture syntax seems better in my opinion; as it
> does not conflict with that stuff.
for the better or worse, the <!profile.stage1> syntax was accepted in dpkg
1.17.2. Looking at http://dep.debian.net/deps/ it seems that DEP-11 has been
removed?
I prepared a patch which adds the current implementation of build profiles in
dpkg to apt.
Please have a look.
cheers, josch
From ba8f96524716973d13d53d02cbc08c597338da39 Mon Sep 17 00:00:00 2001
From: josch <j.schauer@email.de>
Date: Tue, 11 Feb 2014 12:36:23 +0100
Subject: [PATCH] Support for build-profiles through APT::Build-Profiles
---
apt-pkg/deb/deblistparser.cc | 89 ++++++++++++++++++++++++++++++++++++++--
apt-pkg/deb/deblistparser.h | 3 +-
apt-pkg/deb/debsrcrecords.cc | 2 +-
doc/apt.conf.5.xml | 7 ++++
test/libapt/parsedepends_test.cc | 88 +++++++++++++++++++++++++++------------
5 files changed, 157 insertions(+), 32 deletions(-)
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 68d544e..432ce7a 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -477,7 +477,8 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
const char *debListParser::ParseDepends(const char *Start,const char *Stop,
string &Package,string &Ver,
unsigned int &Op, bool const &ParseArchFlags,
- bool const &StripMultiArch)
+ bool const &StripMultiArch,
+ bool const &ParseProfilesFlags)
{
// Strip off leading space
for (;Start != Stop && isspace(*Start) != 0; Start++);
@@ -485,7 +486,8 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
// Parse off the package name
const char *I = Start;
for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
- *I != ',' && *I != '|' && *I != '[' && *I != ']'; I++);
+ *I != ',' && *I != '|' && *I != '[' && *I != ']' &&
+ *I != '<' && *I != '>'; I++);
// Malformed, no '('
if (I != Stop && *I == ')')
@@ -602,6 +604,87 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
for (;I != Stop && isspace(*I) != 0; I++);
}
+ if (ParseProfilesFlags == true)
+ {
+ std::vector<string> profiles;
+
+ // accept non-list order as override setting
+ string const overrideProfiles = _config->Find("APT::Build-Profiles", "");
+
+ if (overrideProfiles.empty() == false)
+ profiles.push_back(overrideProfiles);
+
+ std::vector<string> p = _config->FindVector("APT::Build-Profiles");
+ profiles.insert(profiles.end(), p.begin(), p.end());
+
+ // Parse a build profile
+ if (I != Stop && *I == '<')
+ {
+ ++I;
+ // malformed
+ if (unlikely(I == Stop))
+ return 0;
+
+ const char *End = I;
+ bool Found = false;
+ bool NegProfiles = false;
+ while (I != Stop)
+ {
+ // look for whitespace or ending '>'
+ for (;End != Stop && !isspace(*End) && *End != '>'; ++End);
+
+ if (unlikely(End == Stop))
+ return 0;
+
+ if (*I == '!')
+ {
+ NegProfiles = true;
+ ++I;
+ }
+
+ std::string profile(I, End);
+
+ std::string prefix = "profile.";
+ // only support for "profile" prefix
+ if (profile.size() <= prefix.size() ||
+ profile.substr(0, prefix.size()) != prefix) {
+ // wrong prefix, so fast-forward to the end of the wildcards
+ for (; End != Stop && *End != '>'; ++End);
+ } else {
+ // get the name of the profile
+ profile = profile.substr(prefix.size());
+
+ if (profile.empty() == false && profiles.empty() == false &&
+ std::find(profiles.begin(), profiles.end(), profile) != profiles.end())
+ {
+ Found = true;
+ if (I[-1] != '!')
+ NegProfiles = false;
+ // we found a match, so fast-forward to the end of the wildcards
+ for (; End != Stop && *End != '>'; ++End);
+ }
+ }
+
+ if (*End++ == '>') {
+ I = End;
+ break;
+ }
+
+ I = End;
+ for (;I != Stop && isspace(*I) != 0; I++);
+ }
+
+ if (NegProfiles == true)
+ Found = !Found;
+
+ if (Found == false)
+ Package = ""; /* not for this profile */
+ }
+
+ // Skip whitespace
+ for (;I != Stop && isspace(*I) != 0; I++);
+ }
+
if (I != Stop && *I == '|')
Op |= pkgCache::Dep::Or;
@@ -635,7 +718,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
string Version;
unsigned int Op;
- Start = ParseDepends(Start, Stop, Package, Version, Op, false, false);
+ Start = ParseDepends(Start, Stop, Package, Version, Op, false, false, false);
if (Start == 0)
return _error->Error("Problem parsing dependency %s",Tag);
size_t const found = Package.rfind(':');
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 386d291..fff4d00 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -76,7 +76,8 @@ class debListParser : public pkgCacheGenerator::ListParser
static const char *ParseDepends(const char *Start,const char *Stop,
std::string &Package,std::string &Ver,unsigned int &Op,
bool const &ParseArchFlags = false,
- bool const &StripMultiArch = true);
+ bool const &StripMultiArch = true,
+ bool const &ParseProfileFlags = false);
static const char *ConvertRelation(const char *I,unsigned int &Op);
debListParser(FileFd *File, std::string const &Arch = "");
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index ce55ccd..90182b4 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -90,7 +90,7 @@ bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDe
while (1)
{
Start = debListParser::ParseDepends(Start, Stop,
- rec.Package,rec.Version,rec.Op,true, StripMultiArch);
+ rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
if (Start == 0)
return _error->Error("Problem parsing dependency: %s", fields[I]);
diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml
index bfc43ba..ea87e23 100644
--- a/doc/apt.conf.5.xml
+++ b/doc/apt.conf.5.xml
@@ -177,6 +177,13 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
</para></listitem>
</varlistentry>
+ <varlistentry><term><option>Build-Profiles</option></term>
+ <listitem><para>
+ All enabled build profiles for source package builds. By default this
+ list is empty.
+ </para></listitem>
+ </varlistentry>
+
<varlistentry><term><option>Default-Release</option></term>
<listitem><para>Default release to install packages from if more than one
version is available. Contains release name, codename or release version. Examples: 'stable', 'testing',
diff --git a/test/libapt/parsedepends_test.cc b/test/libapt/parsedepends_test.cc
index e950162..288c117 100644
--- a/test/libapt/parsedepends_test.cc
+++ b/test/libapt/parsedepends_test.cc
@@ -10,7 +10,9 @@ int main(int argc,char *argv[]) {
unsigned int Null = 0;
bool StripMultiArch = true;
bool ParseArchFlags = false;
+ bool ParseProfilesFlags = false;
_config->Set("APT::Architecture","amd64");
+ _config->Set("APT::Build-Profiles","stage1");
const char* Depends =
"debhelper:any (>= 5.0), "
@@ -27,6 +29,9 @@ int main(int argc,char *argv[]) {
"os-for-me [ linux-any ], "
"cpu-not-for-me [ any-armel ], "
"os-not-for-me [ kfreebsd-any ], "
+ "not-in-stage1 <!profile.stage1>, "
+ "not-in-stage1-or-nodoc <!profile.nodoc !profile.stage1>, "
+ "only-in-stage1 <profile.stage1>, "
"overlord-dev:any (= 7.15.3~) | overlord-dev:native (>> 7.15.5), "
;
@@ -39,7 +44,7 @@ test:
const char* Start = Depends;
const char* End = Depends + strlen(Depends);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("debhelper", Package);
else
@@ -47,7 +52,7 @@ test:
equals("5.0", Version);
equals(Null | pkgCache::Dep::GreaterEq, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("libdb-dev", Package);
else
@@ -55,7 +60,7 @@ test:
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("gettext", Package);
else
@@ -63,7 +68,7 @@ test:
equals("0.12", Version);
equals(Null | pkgCache::Dep::LessEq, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("libcurl4-gnutls-dev", Package);
else
@@ -71,104 +76,131 @@ test:
equals("", Version);
equals(Null | pkgCache::Dep::Or, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("libcurl3-gnutls-dev", Package);
equals("7.15.5", Version);
equals(Null | pkgCache::Dep::Greater, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("debiandoc-sgml", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("apt", Package);
equals("0.7.25", Version);
equals(Null | pkgCache::Dep::GreaterEq, Op);
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("", Package); // not-for-me
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("only-for-me", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("any-for-me", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("not-for-darwin", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("cpu-for-me", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("os-for-me", Package);
equals("", Version);
equals(Null | pkgCache::Dep::NoOp, Op);
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("", Package); // cpu-not-for-me
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
if (ParseArchFlags == true) {
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
equals("", Package); // os-not-for-me
} else {
- equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
Start = strstr(Start, ",");
Start++;
}
- Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ if (ParseProfilesFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
+ equals("", Package); // not-in-stage1
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseProfilesFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
+ equals("", Package); // not-in-stage1-or-in-nodoc
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseProfilesFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
+ equals("only-in-stage1", Package);
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("overlord-dev", Package);
else
@@ -176,7 +208,7 @@ test:
equals("7.15.3~", Version);
equals(Null | pkgCache::Dep::Equals | pkgCache::Dep::Or, Op);
- debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseProfilesFlags);
if (StripMultiArch == true)
equals("overlord-dev", Package);
else
@@ -185,11 +217,13 @@ test:
equals(Null | pkgCache::Dep::Greater, Op);
if (StripMultiArch == false)
- ParseArchFlags = true;
+ if (ParseArchFlags == false)
+ ParseProfilesFlags = !ParseProfilesFlags;
+ ParseArchFlags = !ParseArchFlags;
StripMultiArch = !StripMultiArch;
runner++;
- if (runner < 4)
+ if (runner < 8)
goto test; // this is the prove: tests are really evil ;)
return 0;
--
1.8.5.3
Reply to: