Browse Source

bring back deb822 sources.list entries as .sources

Having two different formats in the same file is very dirty and causes
external tools to fail hard trying to parse them. It is probably not a
good idea for them to parse them in the first place, but they do and we
shouldn't break them if there is a better way.

So we solve this issue for now by giving our deb822 format a new
filename extension ".sources" which unsupporting applications are likely
to ignore an can begin gradually moving forward rather than waiting for
the unknown applications to catch up.

Currently and for the forseeable future apt is going to support both
with the same feature set as documented in the manpage, with the
longtime plan of adopting the 'new' format as default, but that is a
long way to go and might get going more from having an easier time
setting options than from us pushing it explicitely.
tags/debian/1.1.exp9
David Kalnischkies 6 years ago
parent
commit
81460e3296
18 changed files with 500 additions and 285 deletions
  1. +2
    -17
      apt-pkg/policy.cc
  2. +114
    -114
      apt-pkg/sourcelist.cc
  3. +8
    -8
      apt-pkg/sourcelist.h
  4. +8
    -0
      apt-pkg/tagfile.cc
  5. +8
    -0
      apt-pkg/tagfile.h
  6. +228
    -109
      doc/sources.list.5.xml
  7. +56
    -19
      test/integration/test-apt-sources-deb822
  8. +9
    -2
      test/libapt/file-helpers.cc
  9. +5
    -10
      test/libapt/sourcelist_test.cc
  10. +7
    -1
      vendor/README
  11. +9
    -0
      vendor/blankon/apt-vendor.ent
  12. +12
    -0
      vendor/debian/apt-vendor.ent
  13. +1
    -2
      vendor/debian/sources.list.in
  14. +6
    -0
      vendor/raspbian/apt-vendor.ent
  15. +7
    -0
      vendor/steamos/apt-vendor.ent
  16. +1
    -3
      vendor/steamos/sources.list.in
  17. +6
    -0
      vendor/tanglu/apt-vendor.ent
  18. +13
    -0
      vendor/ubuntu/apt-vendor.ent

+ 2
- 17
apt-pkg/policy.cc View File

@@ -396,21 +396,6 @@ APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &Fi
return PFPriority[File->ID];
}
/*}}}*/
// PreferenceSection class - Overriding the default TrimRecord method /*{{{*/
// ---------------------------------------------------------------------
/* The preference file is a user generated file so the parser should
therefore be a bit more friendly by allowing comments and new lines
all over the place rather than forcing a special format */
class PreferenceSection : public pkgTagSection
{
void TrimRecord(bool /*BeforeRecord*/, const char* &End)
{
for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
if (Stop[0] == '#')
Stop = (const char*) memchr(Stop,'\n',End-Stop);
}
};
/*}}}*/
// ReadPinDir - Load the pin files from this dir into a Policy /*{{{*/
// ---------------------------------------------------------------------
/* This will load each pin file in the given dir into a Policy. If the
@@ -455,8 +440,8 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
pkgTagFile TF(&Fd);
if (_error->PendingError() == true)
return false;
PreferenceSection Tags;
pkgUserTagSection Tags;
while (TF.Step(Tags) == true)
{
// can happen when there are only comments in a record


+ 114
- 114
apt-pkg/sourcelist.cc View File

@@ -82,15 +82,15 @@ bool pkgSourceList::Type::FixupURI(string &URI) const
return true;
}
/*}}}*/
bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List,
bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List, /*{{{*/
pkgTagSection &Tags,
int i,
unsigned int const i,
FileFd &Fd)
{
map<string, string> Options;

string Enabled = Tags.FindS("Enabled");
if (Enabled.size() > 0 && StringToBool(Enabled) == false)
if (Enabled.empty() == false && StringToBool(Enabled) == false)
return true;

std::map<char const * const, char const * const> mapping;
@@ -115,46 +115,63 @@ bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List,
// now create one item per suite/section
string Suite = Tags.FindS("Suites");
Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture"));
string const Section = Tags.FindS("Sections");
string URIS = Tags.FindS("URIs");
string const Component = Tags.FindS("Components");
string const URIS = Tags.FindS("URIs");

std::vector<std::string> const list_uris = VectorizeString(URIS, ' ');
std::vector<std::string> const list_suite = VectorizeString(Suite, ' ');
std::vector<std::string> const list_comp = VectorizeString(Component, ' ');

if (list_uris.empty())
// TRANSLATOR: %u is a line number, the first %s is a filename of a file with the extension "second %s" and the third %s is a unique identifier for bugreports
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "URI");

std::vector<std::string> list_uris = StringSplit(URIS, " ");
std::vector<std::string> list_dist = StringSplit(Suite, " ");
std::vector<std::string> list_section = StringSplit(Section, " ");
for (std::vector<std::string>::const_iterator U = list_uris.begin();
U != list_uris.end(); ++U)
{
std::string URI = (*U);
if (!FixupURI(URI))
{
_error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str());
return false;
}
std::string URI = *U;
if (U->empty() || FixupURI(URI) == false)
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "URI parse");
if (list_suite.empty())
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "Suite");

for (std::vector<std::string>::const_iterator I = list_dist.begin();
I != list_dist.end(); ++I)
for (std::vector<std::string>::const_iterator S = list_suite.begin();
S != list_suite.end(); ++S)
{
for (std::vector<std::string>::const_iterator J = list_section.begin();
J != list_section.end(); ++J)
{
if (CreateItem(List, URI, (*I), (*J), Options) == false)
{
return false;
}
}
if (S->empty() == false && (*S)[S->size() - 1] == '/')
{
if (list_comp.empty() == false)
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "absolute Suite Component");
if (CreateItem(List, URI, *S, "", Options) == false)
return false;
}
else
{
if (list_comp.empty())
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "Component");

for (std::vector<std::string>::const_iterator C = list_comp.begin();
C != list_comp.end(); ++C)
{
if (CreateItem(List, URI, *S, *C, Options) == false)
{
return false;
}
}
}
}
}
return true;
}

/*}}}*/
// Type::ParseLine - Parse a single line /*{{{*/
// ---------------------------------------------------------------------
/* This is a generic one that is the 'usual' format for sources.list
Weird types may override this. */
bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
const char *Buffer,
unsigned long const &CurLine,
unsigned int const CurLine,
string const &File) const
{
for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
@@ -171,10 +188,10 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
// get one option, e.g. option1=value1
string option;
if (ParseQuoteWord(Buffer,option) == false)
return _error->Error(_("Malformed line %lu in source list %s ([option] unparseable)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] unparseable");

if (option.length() < 3)
return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] too short");

// accept options even if the last has no space before the ]-end marker
if (option.at(option.length()-1) == ']')
@@ -185,16 +202,16 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,

size_t const needle = option.find('=');
if (needle == string::npos)
return _error->Error(_("Malformed line %lu in source list %s ([%s] is not an assignment)"),CurLine,File.c_str(), option.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] not assignment");

string const key = string(option, 0, needle);
string const value = string(option, needle + 1, option.length());

if (key.empty() == true)
return _error->Error(_("Malformed line %lu in source list %s ([%s] has no key)"),CurLine,File.c_str(), option.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] no key");

if (value.empty() == true)
return _error->Error(_("Malformed line %lu in source list %s ([%s] key %s has no value)"),CurLine,File.c_str(),option.c_str(),key.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] no value");

Options[key] = value;
}
@@ -207,33 +224,33 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
string Section;

if (ParseQuoteWord(Buffer,URI) == false)
return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "URI");
if (ParseQuoteWord(Buffer,Dist) == false)
return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "Suite");
if (FixupURI(URI) == false)
return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "URI parse");

// Check for an absolute dists specification.
if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
{
if (ParseQuoteWord(Buffer,Section) == true)
return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "absolute Suite Component");
Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
return CreateItem(List, URI, Dist, Section, Options);
}
// Grab the rest of the dists
if (ParseQuoteWord(Buffer,Section) == false)
return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "Component");
do
{
if (CreateItem(List, URI, Dist, Section, Options) == false)
return false;
}
while (ParseQuoteWord(Buffer,Section) == true);
return true;
}
/*}}}*/
@@ -242,11 +259,6 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
/* */
pkgSourceList::pkgSourceList() : d(NULL)
{
}

pkgSourceList::pkgSourceList(string File) : d(NULL)
{
Read(File);
}
/*}}}*/
// SourceList::~pkgSourceList - Destructor /*{{{*/
@@ -305,7 +317,7 @@ void pkgSourceList::Reset()
// SourceList::Read - Parse the sourcelist file /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgSourceList::Read(string File)
bool pkgSourceList::Read(string const &File)
{
Reset();
return ReadAppend(File);
@@ -314,71 +326,63 @@ bool pkgSourceList::Read(string File)
// SourceList::ReadAppend - Parse a sourcelist file /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgSourceList::ReadAppend(string File)
bool pkgSourceList::ReadAppend(string const &File)
{
if (_config->FindB("APT::Sources::Use-Deb822", false) == true)
{
int lines_parsed =ParseFileDeb822(File);
if (lines_parsed < 0)
return false;
else if (lines_parsed > 0)
return true;
// no lines parsed ... fall through and use old style parser
}
return ParseFileOldStyle(File);
if (flExtension(File) == "sources")
return ParseFileDeb822(File);
else
return ParseFileOldStyle(File);
}

// SourceList::ReadFileOldStyle - Read Traditional style sources.list /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgSourceList::ParseFileOldStyle(string File)
bool pkgSourceList::ParseFileOldStyle(std::string const &File)
{
// Open the stream for reading
ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
if (F.fail() == true)
return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());

// CNC:2003-12-10 - 300 is too short.
char Buffer[1024];

int CurLine = 0;
while (F.eof() == false)
std::string Buffer;
for (unsigned int CurLine = 1; std::getline(F, Buffer); ++CurLine)
{
F.getline(Buffer,sizeof(Buffer));
CurLine++;
_strtabexpand(Buffer,sizeof(Buffer));
if (F.fail() && !F.eof())
return _error->Error(_("Line %u too long in source list %s."),
CurLine,File.c_str());

char *I;
// CNC:2003-02-20 - Do not break if '#' is inside [].
for (I = Buffer; *I != 0 && *I != '#'; I++)
if (*I == '[')
{
char *b_end = strchr(I + 1, ']');
if (b_end != NULL)
I = b_end;
}
*I = 0;
const char *C = _strstrip(Buffer);
// Comment or blank
if (C[0] == '#' || C[0] == 0)
// remove comments
size_t curpos = 0;
while ((curpos = Buffer.find('#', curpos)) != std::string::npos)
{
size_t const openbrackets = std::count(Buffer.begin(), Buffer.begin() + curpos, '[');
size_t const closedbrackets = std::count(Buffer.begin(), Buffer.begin() + curpos, ']');
if (openbrackets > closedbrackets)
{
// a # in an option, unlikely, but oh well, it was supported so stick to it
++curpos;
continue;
}
Buffer.erase(curpos);
break;
}
// remove spaces before/after
curpos = Buffer.find_first_not_of(" \t\r");
if (curpos != 0)
Buffer.erase(0, curpos);
curpos = Buffer.find_last_not_of(" \t\r");
if (curpos != std::string::npos)
Buffer.erase(curpos + 1);

if (Buffer.empty())
continue;
// Grok it
string LineType;
if (ParseQuoteWord(C,LineType) == false)
std::string const LineType = Buffer.substr(0, Buffer.find(' '));
if (LineType.empty() || LineType == Buffer)
return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());

Type *Parse = Type::GetType(LineType.c_str());
if (Parse == 0)
return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
if (Parse->ParseLine(SrcList, C, CurLine, File) == false)
if (Parse->ParseLine(SrcList, Buffer.c_str() + LineType.length(), CurLine, File) == false)
return false;
}
return true;
@@ -387,30 +391,25 @@ bool pkgSourceList::ParseFileOldStyle(string File)
// SourceList::ParseFileDeb822 - Parse deb822 style sources.list /*{{{*/
// ---------------------------------------------------------------------
/* Returns: the number of stanzas parsed*/
int pkgSourceList::ParseFileDeb822(string File)
bool pkgSourceList::ParseFileDeb822(string const &File)
{
pkgTagSection Tags;
unsigned int i=0;
pkgUserTagSection Tags;
unsigned int i = 1;

// see if we can read the file
_error->PushToStack();
FileFd Fd(File, FileFd::ReadOnly);
pkgTagFile Sources(&Fd);
if (_error->PendingError() == true)
{
_error->RevertToStack();
return 0;
}
_error->MergeWithStack();
return _error->Error(_("Malformed stanza %u in source list %s (type)"),i,File.c_str());

// read step by step
while (Sources.Step(Tags) == true)
{
if(!Tags.Exists("Types"))
continue;
if(Tags.Exists("Types") == false)
return _error->Error(_("Malformed stanza %u in source list %s (type)"),i,File.c_str());

string const types = Tags.FindS("Types");
std::vector<std::string> list_types = StringSplit(types, " ");
std::vector<std::string> const list_types = VectorizeString(types, ' ');
for (std::vector<std::string>::const_iterator I = list_types.begin();
I != list_types.end(); ++I)
{
@@ -418,18 +417,16 @@ int pkgSourceList::ParseFileDeb822(string File)
if (Parse == 0)
{
_error->Error(_("Type '%s' is not known on stanza %u in source list %s"), (*I).c_str(),i,Fd.Name().c_str());
return -1;
return false;
}
if (!Parse->ParseStanza(SrcList, Tags, i, Fd))
return -1;
return false;

i++;
++i;
}
}

// we are done, return the number of stanzas read
return i;
return true;
}
/*}}}*/
// SourceList::FindIndex - Get the index associated with a file /*{{{*/
@@ -471,9 +468,12 @@ bool pkgSourceList::GetIndexes(pkgAcquire *Owner, bool GetAll) const
// Based on ReadConfigDir() /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgSourceList::ReadSourceDir(string Dir)
bool pkgSourceList::ReadSourceDir(string const &Dir)
{
vector<string> const List = GetListOfFilesInDir(Dir, "list", true);
std::vector<std::string> ext;
ext.push_back("list");
ext.push_back("sources");
std::vector<std::string> const List = GetListOfFilesInDir(Dir, ext, true);

// Read the files
for (vector<string>::const_iterator I = List.begin(); I != List.end(); ++I)


+ 8
- 8
apt-pkg/sourcelist.h View File

@@ -72,11 +72,11 @@ class pkgSourceList
bool FixupURI(std::string &URI) const;
virtual bool ParseStanza(std::vector<metaIndex *> &List,
pkgTagSection &Tags,
int stanza_n,
unsigned int const stanza_n,
FileFd &Fd);
virtual bool ParseLine(std::vector<metaIndex *> &List,
const char *Buffer,
unsigned long const &CurLine,std::string const &File) const;
unsigned int const CurLine,std::string const &File) const;
virtual bool CreateItem(std::vector<metaIndex *> &List,std::string const &URI,
std::string const &Dist,std::string const &Section,
std::map<std::string, std::string> const &Options) const = 0;
@@ -90,18 +90,19 @@ class pkgSourceList

std::vector<metaIndex *> SrcList;

int ParseFileDeb822(std::string File);
bool ParseFileOldStyle(std::string File);
private:
APT_HIDDEN bool ParseFileDeb822(std::string const &File);
APT_HIDDEN bool ParseFileOldStyle(std::string const &File);

public:

bool ReadMainList();
bool Read(std::string File);
bool Read(std::string const &File);

// CNC:2003-03-03
void Reset();
bool ReadAppend(std::string File);
bool ReadSourceDir(std::string Dir);
bool ReadAppend(std::string const &File);
bool ReadSourceDir(std::string const &Dir);
// List accessors
inline const_iterator begin() const {return SrcList.begin();};
@@ -117,7 +118,6 @@ class pkgSourceList
time_t GetLastModifiedTime();

pkgSourceList();
explicit pkgSourceList(std::string File);
virtual ~pkgSourceList();
};



+ 8
- 0
apt-pkg/tagfile.cc View File

@@ -775,6 +775,14 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v
}
/*}}}*/

void pkgUserTagSection::TrimRecord(bool /*BeforeRecord*/, const char* &End)/*{{{*/
{
for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
if (Stop[0] == '#')
Stop = (const char*) memchr(Stop,'\n',End-Stop);
}
/*}}}*/

#include "tagfile-order.c"

// TFRewrite - Rewrite a control record /*{{{*/


+ 8
- 0
apt-pkg/tagfile.h View File

@@ -142,6 +142,14 @@ class pkgTagSection
bool Write(FileFd &File, char const * const * const Order = NULL, std::vector<Tag> const &Rewrite = std::vector<Tag>()) const;
};


/* For user generated file the parser should be a bit more relaxed in exchange
for being a bit slower to allow comments and new lines all over the place */
class pkgUserTagSection : public pkgTagSection
{
virtual void TrimRecord(bool BeforeRecord, const char* &End);
};

class pkgTagFilePrivate;
class pkgTagFile
{


+ 228
- 109
doc/sources.list.5.xml View File

@@ -31,37 +31,99 @@
<refsect1><title>Description</title>
<para>
The source list <filename>/etc/apt/sources.list</filename> is designed to support
any number of active sources and a variety of source media. The file lists one
source per line, with the most preferred source listed first. The information available
from the configured sources is acquired by <command>apt-get update</command>
(or by an equivalent command from another APT front-end).
</para>
<para>
Each line specifying a source starts with type (e.g. <literal>deb-src</literal>)
followed by options and arguments for this type.
Individual entries cannot be continued onto a following line. Empty lines
are ignored, and a <literal>#</literal> character anywhere on a line marks
the remainder of that line as a comment.
The source list <filename>/etc/apt/sources.list</filename> and the the
files contained in <filename>/etc/apt/sources.list.d/</filename> are
designed to support any number of active sources and a variety of source
media. The files list one source per line (one line style) or contain multiline
stanzas defining one or more sources per stanza (deb822 style), with the
most preferred source listed first. The information available from the
configured sources is acquired by <command>apt-get update</command> (or
by an equivalent command from another APT front-end).
</para>
</refsect1>
<refsect1><title>sources.list.d</title>
<para>The <filename>/etc/apt/sources.list.d</filename> directory provides
a way to add sources.list entries in separate files.
The format is the same as for the regular <filename>sources.list</filename> file.
File names need to end with
<filename>.list</filename> and may only contain letters (a-z and A-Z),
digits (0-9), underscore (_), hyphen (-) and period (.) characters.
Otherwise APT will print a notice that it has ignored a file, unless that
file matches a pattern in the <literal>Dir::Ignore-Files-Silently</literal>
configuration list - in which case it will be silently ignored.</para>
<para>The <filename>/etc/apt/sources.list.d</filename> directory provides
a way to add sources.list entries in separate files.
Two different file formats are allowed as described in the next two sections.
Filenames need to have either the extension <filename>.list</filename> or
<filename>.sources</filename> depending on the contained format.
The filenames may only contain letters (a-z and A-Z),
digits (0-9), underscore (_), hyphen (-) and period (.) characters.
Otherwise APT will print a notice that it has ignored a file, unless that
file matches a pattern in the <literal>Dir::Ignore-Files-Silently</literal>
configuration list - in which case it will be silently ignored.</para>
</refsect1>

<refsect1><title>The deb and deb-src types</title>
<refsect1><title>one line style format</title>
<para>
Files in this format have the extension <filename>.list</filename>.
Each line specifying a source starts with a type (e.g. <literal>deb-src</literal>)
followed by options and arguments for this type.

Individual entries cannot be continued onto a following line. Empty lines
are ignored, and a <literal>#</literal> character anywhere on a line marks
the remainder of that line as a comment. Consequently an entry can be
disabled by commenting out the entire line.

If options should be provided they are separated by spaces and all of
them together are enclosed by square brackets (<literal>[]</literal>)
included in the line after the type separated from it with a space.
If an option allows multiple values these are separated from each other
with a comma (<literal>,</literal>). An option name is separated from its
value(s) by a equal sign (<literal>=</literal>). Multivalue options have
also <literal>-=</literal> and <literal>+=</literal> as separator which
instead of replacing the default with the given value(s) modify the default
value(s) to remove or include the given values.
</para><para>
This is the traditional format and supported by all apt versions.
Note that not all options as described below are supported by all apt versions.
Note also that some older applications parsing this format on its own might not
expect to encounter options as they were uncommon before the introduction of
multi-architecture support.
</para>
</refsect1>

<refsect1><title>deb822 style format</title>
<para>
Files in this format have the extension <filename>.sources</filename>.
The format is similar in syntax to other files used by Debian and its
derivatives, like the metadata itself apt will download from the configured
sources or the <filename>debian/control</filename> file in a Debian source package.

Individual entries are separated by an empty line, additional empty
lines are ignored, and a <literal>#</literal> character at the start of
the line marks the entire line as a comment. An entry can hence be
disabled by commenting out each line belonging to the stanza, but it is
usually easier to add the field "Enabled: no" to the stanza to disable
the entry. Removing the field or setting it to yes reenables it.

Options have the same syntax as every other field: A fieldname separated by
a colon (<literal>:</literal>) and optionally spaces from its value(s).
Note especially that multiple values are separated by spaces, not by
commas as in the one line format. Multivalue fields like <literal>Architectures</literal>
also have <literal>Architectures-Add</literal> and <literal>Architectures-Remove</literal>
to modify the default value rather than replacing it.
</para><para>
This is a new format supported by apt itself since version 1.1. Previous
versions ignore such files with a notice message as described earlier.
It is intended to make this format gradually the default format and
deprecating the previously described one line style format as it is
easier to create, extend and modify by humans and machines alike
especially if a lot of sources and/or options are involved.

Developers who are working with and/or parsing apt sources are highly
encouraged to add support for this format and to contact the APT team
to coordinate and share this work. Users can freely adopt this format
already, but could encounter problems with software not supporting
the format yet.
</para>
</refsect1>

<refsect1><title>The deb and deb-src types: General Format</title>
<para>The <literal>deb</literal> type references a typical two-level Debian
archive, <filename>distribution/component</filename>. The
<literal>distribution</literal> is generally an archive name like
<literal>distribution</literal> is generally a suite name like
<literal>stable</literal> or <literal>testing</literal> or a codename like
<literal>&stable-codename;</literal> or <literal>&testing-codename;</literal>
while component is one of <literal>main</literal>, <literal>contrib</literal> or
@@ -70,42 +132,33 @@
code in the same form as the <literal>deb</literal> type.
A <literal>deb-src</literal> line is required to fetch source indexes.</para>

<para>The format for a <filename>sources.list</filename> entry using the
<para>The format for two one line style entries using the
<literal>deb</literal> and <literal>deb-src</literal> types is:</para>

<literallayout>deb [ options ] uri suite [component1] [component2] [...]</literallayout>
<literallayout>deb [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]</literallayout>

<para>Alternatively a rfc822 style format is also supported:
<para>Alternatively the equivalent entry in deb822 style looks like this:
<literallayout>
Types: deb deb-src
URIs: http://example.com
Suites: stable testing
Sections: component1 component2
Description: short
long long long
[option1]: [option1-value]

Types: deb
URIs: http://another.example.com
Suites: experimental
Sections: component1 component2
Enabled: no
Description: short
long long long
[option1]: [option1-value]
URIs: uri
Suites: suite
Components: [component1] [component2] [...]
option1: value1
option2: value2
</literallayout>
</para>

<para>The URI for the <literal>deb</literal> type must specify the base of the
Debian distribution, from which APT will find the information it needs.
<literal>suite</literal> can specify an exact path, in which case the
Debian distribution, from which APT will find the information it needs.
<literal>suite</literal> can specify an exact path, in which case the
components must be omitted and <literal>suite</literal> must end with
a slash (<literal>/</literal>). This is useful for the case when only a
particular sub-section of the archive denoted by the URI is of interest.
particular sub-directory of the archive denoted by the URI is of interest.
If <literal>suite</literal> does not specify an exact path, at least
one <literal>component</literal> must be present.</para>

<para><literal>suite</literal> may also contain a variable,
<para><literal>suite</literal> may also contain a variable,
<literal>$(ARCH)</literal>
which expands to the Debian architecture (such as <literal>amd64</literal> or
<literal>armel</literal>) used on the system. This permits architecture-independent
@@ -113,67 +166,80 @@
of interest when specifying an exact path, <literal>APT</literal> will
automatically generate a URI with the current architecture otherwise.</para>

<para>In the traditional style sources.list format since only one
distribution can be specified per line it may be necessary to have
multiple lines for the same URI, if a subset of all available
distributions or components at that location is desired. APT will
sort the URI list after it has generated a complete set internally,
and will collapse multiple references to the same Internet host,
for instance, into a single connection, so that it does not
inefficiently establish an FTP connection, close it, do something
else, and then re-establish a connection to that same host. This
feature is useful for accessing busy FTP sites with limits on the
number of simultaneous anonymous users. APT also parallelizes
connections to different hosts to more effectively deal with sites
with low bandwidth.</para>

<para><literal>options</literal> is always optional and needs to be surrounded by
square brackets. It can consist of multiple settings in the form
<literal><replaceable>setting</replaceable>=<replaceable>value</replaceable></literal>.
Multiple settings are separated by spaces. The following settings are supported by APT
(note however that unsupported settings will be ignored silently):
<itemizedlist>
<listitem><para><literal>arch=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
can be used to specify for which architectures information should
be downloaded. If this option is not set all architectures defined by the
<literal>APT::Architectures</literal> option will be downloaded.</para></listitem>

<listitem><para><literal>arch+=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
and <literal>arch-=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
which can be used to add/remove architectures from the set which will be downloaded.</para></listitem>

<listitem><para><literal>lang=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal>,
<literal>lang+=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> and
<literal>lang-=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> functioning in
the same way as the <literal>arch</literal>-options described before. They can be used to specify for
which languages apt will acquire metadata, like translated package descriptions, for. If not specified, the
default set is defined by the <literal>Acquire::Languages</literal> config option.</para></listitem>

<listitem><para><literal>target=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal>,
<literal>target+=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> and
<literal>target-=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> again functioning in
the same way as the <literal>arch</literal>-options described before. They can be used to specify which
targets apt will try to acquire from this source. If not specified, the default set is defined by
the <literal>APT::Acquire::Targets</literal> configuration scope.</para></listitem>

<listitem><para><literal>trusted=yes</literal> can be set to indicate that packages
from this source are always authenticated even if the <filename>Release</filename> file
is not signed or the signature can't be checked. This disables parts of &apt-secure;
and should therefore only be used in a local and trusted context. <literal>trusted=no</literal>
is the opposite which handles even correctly authenticated sources as not authenticated.</para></listitem>
</itemizedlist></para>
<para>Especially in the one line style format since only one distribution
can be specified per line it may be necessary to have multiple lines for
the same URI, if a subset of all available distributions or components at
that location is desired. APT will sort the URI list after it has
generated a complete set internally, and will collapse multiple
references to the same Internet host, for instance, into a single
connection, so that it does not inefficiently establish a
connection, close it, do something else, and then re-establish a
connection to that same host. APT also parallelizes connections to
different hosts to more effectively deal with sites with low
bandwidth.</para>

<para>It is important to list sources in order of preference, with the most
preferred source listed first. Typically this will result in sorting
by speed from fastest to slowest (CD-ROM followed by hosts on a local
network, followed by distant Internet hosts, for example).</para>

<para>Some examples:</para>
<literallayout>
deb http://ftp.debian.org/debian &stable-codename; main contrib non-free
deb http://security.debian.org/ &stable-codename;/updates main contrib non-free
</literallayout>
<para>As an example, the sources for your distribution could look like this
in one line style format:
<literallayout>&sourceslist-list-format;</literallayout> or like this in
deb822 style format:
<literallayout>&sourceslist-sources-format;</literallayout></para>
</refsect1>

<refsect1><title>The deb and deb-src types: Options</title>
<para>Each source entry can have options specified modifying which and how
the source is accessed and data acquired from it. Format, syntax and names
of the options varies between the two formats one line and deb822 style
as described, but they have both the same options available. For simplicity
we list the deb822 fieldname and provide the one line name in brackets.
Remember that beside setting multivalue options explicitly, there is also
the option to modify them based on the default, but we aren't listing those
names explicitly here. Unsupported options are silently ignored by all
APT versions.

<itemizedlist>
<listitem><para><literal>Architectures</literal>
(<literal>arch</literal>) is a multivalue option defining for
which architectures information should be downloaded. If this
option isn't set the default is all architectures as defined by
the <literal>APT::Architectures</literal> config option.
</para></listitem>

<listitem><para><literal>Languages</literal>
(<literal>lang</literal>) is a multivalue option defining for
which languages information like translated package
descriptions should be downloaded. If this option isn't set
the default is all languages as defined by the
<literal>Acquire::Languages</literal> config option.
</para></listitem>

<listitem><para><literal>Targets</literal>
(<literal>target</literal>) is a multivalue option defining
which download targets apt will try to acquire from this
source. If not specified, the default set is defined by the
<literal>APT::Acquire::Targets</literal> configuration scope.
</para></listitem>

<listitem><para><literal>Trusted</literal> (<literal>trusted</literal>)
is a tri-state value which defaults to APT deciding if a source
is considered trusted or if warnings should be raised before e.g.
packages are installed from this source. This option can be used
to override this decision either with the value <literal>yes</literal>,
which lets APT consider this source always as a trusted source
even if it has no or fails authentication checks by disabling parts
of &apt-secure; and should therefore only be used in a local and trusted
context (if at all) as otherwise security is breached. The opposite
can be achieved with the value no, which causes the source to be handled
as untrusted even if the authentication checks passed successfully.
The default value can't be set explicitly.
</para></listitem>
</itemizedlist>

</para>
</refsect1>

<refsect1><title>URI specification</title>
@@ -247,34 +313,70 @@ deb http://security.debian.org/ &stable-codename;/updates main contrib non-free
</refsect1>
<refsect1><title>Examples</title>
<para>Uses the archive stored locally (or NFS mounted) at /home/jason/debian
<para>Uses the archive stored locally (or NFS mounted) at /home/apt/debian
for stable/main, stable/contrib, and stable/non-free.</para>
<literallayout>deb file:/home/jason/debian stable main contrib non-free</literallayout>
<literallayout>deb file:/home/apt/debian stable main contrib non-free</literallayout>
<literallayout>Types: deb
URIs: file:/home/apt/debian
Suites: stable
Components: main contrib non-free</literallayout>

<para>As above, except this uses the unstable (development) distribution.</para>
<literallayout>deb file:/home/jason/debian unstable main contrib non-free</literallayout>
<literallayout>deb file:/home/apt/debian unstable main contrib non-free</literallayout>
<literallayout>Types: deb
URIs: file:/home/apt/debian
Suites: unstable
Components: main contrib non-free</literallayout>

<para>Source line for the above</para>
<literallayout>deb-src file:/home/jason/debian unstable main contrib non-free</literallayout>
<literallayout>deb-src file:/home/apt/debian unstable main contrib non-free</literallayout>
<literallayout>Types: deb-src
URIs: file:/home/apt/debian
Suites: unstable
Components: main contrib non-free</literallayout>


<para>The first line gets package information for the architectures in <literal>APT::Architectures</literal>
while the second always retrieves <literal>amd64</literal> and <literal>armel</literal>.</para>
<literallayout>deb http://ftp.debian.org/debian &stable-codename; main
deb [ arch=amd64,armel ] http://ftp.debian.org/debian &stable-codename; main</literallayout>
<literallayout>deb http://httpredir.debian.org/debian &stable-codename; main
deb [ arch=amd64,armel ] http://httpredir.debian.org/debian &stable-codename; main</literallayout>
<literallayout>Types: deb
URIs: http://httpredir.debian.org/debian
Suites: &stable-codename;
Components: main

Types: deb
URIs: http://httpredir.debian.org/debian
Suites: &stable-codename;
Components: main
Architectures: amd64 armel
</literallayout>

<para>Uses HTTP to access the archive at archive.debian.org, and uses only
the hamm/main area.</para>
<literallayout>deb http://archive.debian.org/debian-archive hamm main</literallayout>
<literallayout>Types: deb
URIs: http://archive.debian.org/debian-archive
Suites: hamm
Components: main</literallayout>

<para>Uses FTP to access the archive at ftp.debian.org, under the debian
directory, and uses only the &stable-codename;/contrib area.</para>
<literallayout>deb ftp://ftp.debian.org/debian &stable-codename; contrib</literallayout>
<literallayout>Types: deb
URIs: ftp://ftp.debian.org/debian
Suites: &stable-codename;
Components: contrib</literallayout>

<para>Uses FTP to access the archive at ftp.debian.org, under the debian
directory, and uses only the unstable/contrib area. If this line appears as
well as the one in the previous example in <filename>sources.list</filename>
a single FTP session will be used for both resource lines.</para>
<literallayout>deb ftp://ftp.debian.org/debian unstable contrib</literallayout>
<literallayout>Types: deb
URIs: ftp://ftp.debian.org/debian
Suites: unstable
Components: contrib</literallayout>

<para>Uses HTTP to access the archive at ftp.tlh.debian.org, under the
universe directory, and uses only files found under
@@ -284,15 +386,32 @@ deb [ arch=amd64,armel ] http://ftp.debian.org/debian &stable-codename; main</li
illustrates how to use the substitution variable; official debian
archives are not structured like this]
<literallayout>deb http://ftp.tlh.debian.org/universe unstable/binary-$(ARCH)/</literallayout>
<literallayout>Types: deb
URIs: http://ftp.tlh.debian.org/universe
Suites: unstable/binary-$(ARCH)/</literallayout>
</para>

<para>Uses HTTP to get binary packages as well as sources from the stable, testing and unstable
suites and the components main and contrib.</para>
<literallayout>deb http://httpredir.debian.org/debian stable main contrib
deb-src http://httpredir.debian.org/debian stable main contrib
deb http://httpredir.debian.org/debian testing main contrib
deb-src http://httpredir.debian.org/debian testing main contrib
deb http://httpredir.debian.org/debian unstable main contrib
deb-src http://httpredir.debian.org/debian unstable main contrib</literallayout>
<literallayout>Types: deb deb-src
URIs: http://httpredir.debian.org/debian
Suites: stable testing unstable
Components: main contrib
</literallayout>

</refsect1>
<refsect1><title>See Also</title>
<para>&apt-cache; &apt-conf;
<para>&apt-get;, &apt-conf;
</para>
</refsect1>

&manbugs;
</refentry>

</refentry>

+ 56
- 19
test/integration/test-apt-sources-deb822 View File

@@ -7,9 +7,8 @@ TESTDIR=$(readlink -f $(dirname $0))
setupenvironment
configarchitecture 'i386'

echo 'APT::Sources::Use-Deb822 "true";' > rootdir/etc/apt/apt.conf.d/00enabledeb822

SOURCES='rootdir/etc/apt/sources.list'
LISTS='rootdir/etc/apt/sources.list.d/test.list'
SOURCES='rootdir/etc/apt/sources.list.d/test.sources'
BASE='# some comment
# that contains a : as well
#Types: meep
@@ -17,23 +16,48 @@ BASE='# some comment
Types: deb
URIs: http://ftp.debian.org/debian
Suites: stable
Sections: main
Components: main
Description: summay
and the long part'

msgtest 'Test sources.list' 'old style'
echo "deb http://ftp.debian.org/debian stable main" > $SOURCES
msgcleantest() {
rm -f $LISTS $SOURCES
msgtest "$@"
}

msgcleantest 'Test sources.list' 'old style'
echo "deb http://ftp.debian.org/debian stable main" > $LISTS
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgcleantest 'Test sources.list' 'old style with options'
echo "deb [trusted=yes arch+=armel,powerpc] http://ftp.debian.org/debian stable main" > $LISTS
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/binary-powerpc/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-powerpc_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgcleantest 'Test sources.list' 'old style with comments'
echo "deb http://ftp.debian.org/debian stable main # non-free" > $LISTS
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgcleantest 'Test sources.list' 'old style with option comments'
echo "deb [trusted=yes#yeahreally] http://ftp.debian.org/debian stable main # non-free" > $LISTS
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test sources.list' 'simple deb822'
msgcleantest 'Test sources.list' 'simple deb822'
echo "$BASE" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test deb822 with' 'two entries'
msgcleantest 'Test deb822 with' 'two entries'
# Two entries
echo "$BASE" > $SOURCES
echo "" >> $SOURCES
@@ -46,7 +70,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris

# two suite entries
msgtest 'Test deb822 with' 'two Suite entries'
msgcleantest 'Test deb822 with' 'two Suite entries'
echo "$BASE" | sed -e "s/stable/stable unstable/" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
@@ -55,7 +79,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/unstable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_unstable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris

msgtest 'Test deb822' 'architecture option'
msgcleantest 'Test deb822' 'architecture option'
echo "$BASE" > $SOURCES
echo "Architectures: amd64 armel" >> $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
@@ -63,17 +87,30 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris


msgtest 'Test old-style sources.list file which has' 'malformed dist'
echo "deb http://ftp.debian.org" > $SOURCES
testequal --nomsg "E: Malformed line 1 in source list $TMPWORKINGDIRECTORY/rootdir/etc/apt/sources.list (dist)
msgcleantest 'Test old-style' 'suite arch variable'
echo 'deb http://ftp.tlh.debian.org/universe unstable/binary-$(ARCH)/' > $LISTS
testequal --nomsg "'http://ftp.tlh.debian.org/universe/unstable/binary-i386/InRelease' ftp.tlh.debian.org_universe_unstable_binary-i386_InRelease 0
'http://ftp.tlh.debian.org/universe/unstable/binary-i386/Packages.bz2' ftp.tlh.debian.org_universe_unstable_binary-i386_Packages 0
'http://ftp.tlh.debian.org/universe/unstable/binary-i386/en.bz2' ftp.tlh.debian.org_universe_unstable_binary-i386_en 0 " aptget update --print-uris

msgcleantest 'Test deb822' 'suite arch variable'
echo 'Types: deb
URIs: http://ftp.tlh.debian.org/universe
Suites: stable/binary-$(ARCH)/' > $SOURCES
testequal --nomsg "'http://ftp.tlh.debian.org/universe/stable/binary-i386/InRelease' ftp.tlh.debian.org_universe_stable_binary-i386_InRelease 0
'http://ftp.tlh.debian.org/universe/stable/binary-i386/Packages.bz2' ftp.tlh.debian.org_universe_stable_binary-i386_Packages 0
'http://ftp.tlh.debian.org/universe/stable/binary-i386/en.bz2' ftp.tlh.debian.org_universe_stable_binary-i386_en 0 " aptget update --print-uris

msgcleantest 'Test old-style sources.list file which has' 'malformed dist'
echo "deb http://ftp.debian.org" > $LISTS
testequal --nomsg "E: Malformed entry 1 in list file $TMPWORKINGDIRECTORY/$LISTS (Suite)
E: The list of sources could not be read." aptget update --print-uris

msgtest 'Test deb822 sources.list file which has' 'malformed URI'
msgcleantest 'Test deb822 sources.list file which has' 'malformed URI'
echo "Types: deb
Suites: stable
" > $SOURCES
testequal --nomsg "E: Malformed stanza 0 in source list $TMPWORKINGDIRECTORY/rootdir/etc/apt/sources.list (URI parse)
testequal --nomsg "E: Malformed entry 1 in sources file $TMPWORKINGDIRECTORY/$SOURCES (URI)
E: The list of sources could not be read." aptget update --print-uris

# with Enabled: false
@@ -82,7 +119,7 @@ echo "Enabled: no" >> $SOURCES
testempty aptget update --print-uris

# multiple URIs
msgtest 'Test deb822 sources.list file which has' 'Multiple URIs work'
msgcleantest 'Test deb822 sources.list file which has' 'Multiple URIs work'
echo "$BASE" | sed -e 's#http://ftp.debian.org/debian#http://ftp.debian.org/debian http://ftp.de.debian.org/debian#' > $SOURCES
testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp.de.debian.org_debian_dists_stable_InRelease 0
'http://ftp.de.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.de.debian.org_debian_dists_stable_main_binary-i386_Packages 0
@@ -92,7 +129,7 @@ testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

# multiple Type in one field
msgtest 'Test deb822 sources.list file which has' 'Multiple Types work'
msgcleantest 'Test deb822 sources.list file which has' 'Multiple Types work'
echo "$BASE" | sed -e 's#Types: deb#Types: deb deb-src#' > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/source/Sources.bz2' ftp.debian.org_debian_dists_stable_main_source_Sources 0
@@ -100,7 +137,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris

# a Suite
msgtest 'Test deb822 sources.list file which has' 'a exact path and no sections'
msgcleantest 'Test deb822 sources.list file which has' 'an exact path and no sections'
cat > $SOURCES <<EOF
Types: deb
URIs: http://emacs.naquadah.org


+ 9
- 2
test/libapt/file-helpers.cc View File

@@ -56,10 +56,17 @@ void helperCreateLink(std::string const &dir, std::string const &targetname, std
void helperCreateTemporaryFile(std::string const &id, FileFd &fd, std::string * const filename, char const * const content)
{
std::string name("apt-test-");
name.append(id).append(".XXXXXXXX");
name.append(id);
size_t const giventmp = name.find(".XXXXXX.");
if (giventmp == std::string::npos)
name.append(".XXXXXX");
char * tempfile = strdup(name.c_str());
ASSERT_STRNE(NULL, tempfile);
int tempfile_fd = mkstemp(tempfile);
int tempfile_fd;
if (giventmp == std::string::npos)
tempfile_fd = mkstemp(tempfile);
else
tempfile_fd = mkstemps(tempfile, name.length() - (giventmp + 7));
ASSERT_NE(-1, tempfile_fd);
if (filename != NULL)
*filename = tempfile;


+ 5
- 10
test/libapt/sourcelist_test.cc View File

@@ -12,31 +12,26 @@

#include "file-helpers.h"

class SourceList : public pkgSourceList {
public:
using pkgSourceList::ParseFileDeb822;
};

TEST(SourceListTest,ParseFileDeb822)
{
FileFd fd;
std::string tempfile;
createTemporaryFile("parsefiledeb822", fd, &tempfile,
createTemporaryFile("parsefiledeb822.XXXXXX.sources", fd, &tempfile,
"Types: deb\n"
"URIs: http://ftp.debian.org/debian\n"
"Suites: stable\n"
"Sections: main\n"
"Components: main\n"
"Description: short\n"
" long description that can be very long\n"
"\n"
"Types: deb\n"
"URIs: http://ftp.debian.org/debian\n"
"Suites: unstable\n"
"Sections: main non-free\n");
"Components: main non-free\n");
fd.Close();

SourceList sources;
EXPECT_EQ(2, sources.ParseFileDeb822(tempfile));
pkgSourceList sources;
EXPECT_EQ(true, sources.Read(tempfile));
EXPECT_EQ(2, sources.size());

if (tempfile.empty() == false)


+ 7
- 1
vendor/README View File

@@ -44,6 +44,10 @@ apt-key script and the keyring-package in particular as a dependency for apt.

The field current-codename is optional and can be used in sources.list.in.

The fields sourceslist-list-format and sourceslist-sources-format are used as
examples in the sources.list manpage and the first one is additionally
available in the sources.list.in template.
They should in general reflect the default sources of your distro.

== sources.list.in

@@ -55,6 +59,7 @@ You can use some placeholders in this file, namely:
* &debian-oldstable-codename;
* &debian-testing-codename;
* &ubuntu-codename;
* &sourceslist-list-format;
with the value you would expect based on the name.

The placeholder &current-codename; is yours and can be set in apt-vendor.ent
@@ -63,4 +68,5 @@ The placeholder &current-codename; is yours and can be set in apt-vendor.ent
== apt.conf-*

Files in your vendor directory following this naming scheme will be picked up
by the debian/rules file and installed in /etc/apt/apt.conf.d/ directory.
by the debian/rules file and installed in /etc/apt/apt.conf.d/ directory, with
"apt.conf-" removed from the beginning of the filename.

+ 9
- 0
vendor/blankon/apt-vendor.ent View File

@@ -6,3 +6,12 @@
<!ENTITY keyring-master-filename "/usr/share/keyrings/blankon-master-keyring.gpg">
<!ENTITY keyring-uri "http://arsip.blankonlinux.or.id/blankon/project/blankon-archive-keyring.gpg">
<!ENTITY current-codename "tambora">

<!ENTITY sourceslist-list-format "deb http://arsip.blankonlinux.or.id/blankon &current-codename; main restricted
deb http://arsip.blankonlinux.or.id/blankon &current-codename;-security main restricted
deb http://arsip.blankonlinux.or.id/blankon &current-codename;-updates main restricted">

<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://arsip.blankonlinux.or.id/blankon
Suites: &current-codename; &current-codename;-security &current-codename;-updates
Components: main restricted">

+ 12
- 0
vendor/debian/apt-vendor.ent View File

@@ -5,3 +5,15 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/debian-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">

<!ENTITY sourceslist-list-format "deb http://httpredir.debian.org/debian &stable-codename; main contrib non-free
deb http://security.debian.org &stable-codename;/updates main contrib non-free">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://httpredir.debian.org/debian
Suites: &stable-codename;
Components: main contrib non-free

Types: deb
URIs: http://security.debian.org
Suites: &stable-codename;/updates
Components: main contrib non-free">

+ 1
- 2
vendor/debian/sources.list.in View File

@@ -1,7 +1,6 @@
# See sources.list(5) manpage for more information
# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.
deb http://ftp.us.debian.org/debian &debian-stable-codename; main contrib non-free
deb http://security.debian.org &debian-stable-codename;/updates main contrib non-free
&sourceslist-list-format;

# Uncomment if you want the apt-get source function to work
#deb-src http://ftp.us.debian.org/debian &debian-stable-codename; main contrib non-free


+ 6
- 0
vendor/raspbian/apt-vendor.ent View File

@@ -5,3 +5,9 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/raspbian-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">

<!ENTITY sourceslist-list-format "deb http://mirrordirector.raspbian.org/raspbian &stable-codename; main contrib non-free">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://mirrordirector.raspbian.org/raspbian
Suites: &stable-codename;
Components: main contrib non-free">

+ 7
- 0
vendor/steamos/apt-vendor.ent View File

@@ -6,3 +6,10 @@
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
<!ENTITY current-codename "alchemist">

<!ENTITY sourceslist-list-format "deb http://repo.steampowered.com/steamos &current-codename; main contrib non-free
deb-src http://repo.steampowered.com/steamos &current-codename; main contrib non-free">
<!ENTITY sourceslist-sources-format "Types: deb deb-src
URIs: http://repo.steampowered.com/steamos
Suites: &current-codename;
Components: main contrib non-free">

+ 1
- 3
vendor/steamos/sources.list.in View File

@@ -1,5 +1,3 @@
# See sources.list(5) manpage for more information
# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.

deb http://repo.steampowered.com/steamos &current-codename; main contrib non-free
deb-src http://repo.steampowered.com/steamos &current-codename; main contrib non-free
&sourceslist-list-format;

+ 6
- 0
vendor/tanglu/apt-vendor.ent View File

@@ -6,3 +6,9 @@
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
<!ENTITY current-codename "bartholomea">

<!ENTITY sourceslist-list-format "deb http://archive.tanglu.org/tanglu &current-codename; main contrib non-free">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://archive.tanglu.org/tanglu
Suites: &current-codename;
Components: main contrib non-free">

+ 13
- 0
vendor/ubuntu/apt-vendor.ent View File

@@ -5,3 +5,16 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/ubuntu-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "/usr/share/keyrings/ubuntu-master-keyring.gpg">
<!ENTITY keyring-uri "http://archive.ubuntu.com/ubuntu/project/ubuntu-archive-keyring.gpg">

<!ENTITY sourceslist-list-format "deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
deb http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://us.archive.ubuntu.com/ubuntu
Suites: &ubuntu-codename; &ubuntu-codename;-updates
Components: main restricted

Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: &ubuntu-codename;-security
Components: main restricted">

Loading…
Cancel
Save