[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#262204: apt-ftparchive: patch to add Release files to generate



Here is a patch to add generation of the top-level Release file to the
generate function of apt-ftparchive.  I fear that my C++ is *very* rusty
and my understanding of the STL leaves a lot to be desired.  I hope it's
not too hideous.  If this is a workable approach, I'd be happy to
fine-tune it to correct any problems.

I left the default to be off so as to not change the default behavior; I
don't know if that's best or not.

This patch also corrects another issue that I noticed while I was working
on this.  Previously, apt-ftparchive release included the top-level
Release file (which is generally what it was in the process of
generating).  Looking at ftp.us.debian.org, that appears to not be
correct, so I added code to special-case and exclude the top-level Release
file.

Note that most of the complexity of the patch is to allow the Release
configuration variables to also be set in the TreeDefault and Tree
sections of the generate configuration.

Here is the patch:

--- apt-0.5.27/ftparchive/writer.h.orig	2003-12-26 14:55:13.000000000 -0800
+++ apt-0.5.27/ftparchive/writer.h	2004-07-31 01:58:47.000000000 -0700
@@ -17,6 +17,7 @@
 #pragma interface "writer.h"
 #endif 
 
+#include <apt-pkg/configuration.h>
 #include <string>
 #include <stdio.h>
 #include <iostream>
@@ -155,6 +156,10 @@
 {
 public:
    ReleaseWriter(string DB);
+   void LoadConfig(Configuration *Config, const char *Prefix);
+   inline void SetField(string Key, string Value)
+      {if (Fields.find(Key) != Fields.end()) Fields[Key] = Value;}
+   void Start();
    virtual bool DoPackage(string FileName);
    void Finish();
 
@@ -162,6 +167,7 @@
    // General options
    string PathPrefix;
    string DirStrip;
+   map<string,string> Fields;
 
 protected:
    struct CheckSum
--- apt-0.5.27/ftparchive/writer.cc.orig	2004-03-23 17:40:43.000000000 -0800
+++ apt-0.5.27/ftparchive/writer.cc	2004-07-31 02:18:03.000000000 -0700
@@ -821,7 +821,6 @@
       datestr[0] = '\0';
    }
 
-   map<string,string> Fields;
    Fields["Origin"] = "";
    Fields["Label"] = "";
    Fields["Suite"] = "";
@@ -832,16 +831,37 @@
    Fields["Components"] = "";
    Fields["Description"] = "";
 
+   LoadConfig(_config, "APT::FTPArchive::Release::");
+}
+									/*}}}*/
+// ReleaseWriter::LoadConfig - Load fields from configuration		/*{{{*/
+// ---------------------------------------------------------------------
+void ReleaseWriter::LoadConfig(Configuration *Config, const char *Prefix)
+{
    for(map<string,string>::const_iterator I = Fields.begin();
        I != Fields.end();
        ++I)
    {
-      string Config = string("APT::FTPArchive::Release::") + (*I).first;
-      string Value = _config->Find(Config, (*I).second.c_str());
+      string Value = Config->Find(string(Prefix) + (*I).first);
       if (Value == "")
          continue;
-
-      fprintf(Output, "%s: %s\n", (*I).first.c_str(), Value.c_str());
+      Fields[(*I).first] = Value;
+   }
+}
+									/*}}}*/
+// ReleaseWriter::Start - Output the header of a Release file		/*{{{*/
+// ---------------------------------------------------------------------
+void ReleaseWriter::Start()
+{
+   for(map<string,string>::const_iterator I = Fields.begin();
+       I != Fields.end();
+       ++I)
+   {
+      string Field = (*I).first;
+      string Value = Fields[Field];
+      if (Value == "")
+         continue;
+      fprintf(Output, "%s: %s\n", Field.c_str(), Value.c_str());
    }
 }
 									/*}}}*/
@@ -866,6 +886,10 @@
    if (PathPrefix.empty() == false)
       NewFileName = flCombine(PathPrefix,NewFileName);
 
+   // Special-case the top-level Release file, which should not be included.
+   if (NewFileName == "Release")
+      return true;
+
    FileFd fd(FileName, FileFd::ReadOnly);
 
    if (!fd.IsOpen())
--- apt-0.5.27/ftparchive/apt-ftparchive.cc.orig	2004-01-02 13:48:13.000000000 -0800
+++ apt-0.5.27/ftparchive/apt-ftparchive.cc	2004-07-31 02:43:53.000000000 -0700
@@ -584,6 +584,7 @@
       "  -d=?  Select the optional caching database\n"
       "  --no-delink Enable delinking debug mode\n"
       "  --contents  Control contents file generation\n"
+      "  --release   Control release file generation\n"
       "  -c=?  Read this configuration file\n"
       "  -o=?  Set an arbitary configuration option") << endl;
    
@@ -684,6 +685,7 @@
    string Dir = CmdL.FileList[1];
 
    ReleaseWriter Release("");
+   Release.Start();
    Release.DirStrip = Dir;
 
    if (_error->PendingError() == true)
@@ -698,6 +700,67 @@
 }
 
 									/*}}}*/
+// GenerateRelease - Generate Release with config overrides.		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void GenerateRelease(Configuration &Setup)
+{
+   string ArchiveDir = Setup.FindDir("Dir::ArchiveDir");
+
+   const Configuration::Item *Top = Setup.Tree("tree");
+   for (Top = (Top == 0?0:Top->Child); Top != 0;)
+   {
+      string Dir = flCombine(ArchiveDir,Top->Tag);
+      Configuration Block(Top);
+
+      ReleaseWriter Release("");
+      Release.LoadConfig(&Setup,"TreeDefault::Release::");
+      Release.LoadConfig(&Block,"Release::");
+
+      string Components = Block.Find("Sections");
+      if (Components != "")
+         Release.SetField(string("Components"),Components);
+
+      // The architectures list needs some massaging to remove all and source.
+      string Architectures = Block.Find("Architectures");
+      if (Architectures != "")
+      {
+	 string Arch, Arches;
+	 const char *Original = Architectures.c_str();
+	 while (ParseQuoteWord(Original,Arch) == true)
+            if (Arch != "source" && Arch != "all")
+            {
+               if (Arches != "")
+                  Arches += " ";
+               Arches += Arch;
+            }
+         Release.SetField(string("Architectures"),Arches);
+      }
+
+      string File = flCombine(Dir,"Release");
+      FILE *F = fopen(File.c_str(),"w");
+      if (F == 0)
+      {
+         _error->Errno("fopen",_("Unable to open %s"),File.c_str());
+         return;
+      }
+      Release.Output = F;
+
+      Release.Start();
+      Release.DirStrip = Dir;
+
+      if (_error->PendingError() == true)
+         return;
+
+      if (Release.RecursiveScan(Dir) == false)
+         return;
+
+      Release.Finish();
+
+      Top = Top->Next;
+   }
+}
+									/*}}}*/
 // Generate - Full generate, using a config file			/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -786,6 +849,9 @@
       
       delete [] List;
    }
+
+   if (_config->FindB("APT::FTPArchive::GenerateRelease",false) == true)
+      GenerateRelease(Setup);
    
    if (_config->FindB("APT::FTPArchive::Contents",true) == false)
       return true;
@@ -907,6 +973,7 @@
       {0,"delink","APT::FTPArchive::DeLinkAct",0},
       {0,"readonly","APT::FTPArchive::ReadOnlyDB",0},
       {0,"contents","APT::FTPArchive::Contents",0},
+      {0,"release","APT::FTPArchive::GenerateRelease",0},
       {'c',"config-file",0,CommandLine::ConfigFile},
       {'o',"option",0,CommandLine::ArbItem},
       {0,0,0,0}};
--- apt-0.5.27/doc/apt-ftparchive.1.xml.orig	2004-03-11 10:17:08.000000000 -0800
+++ apt-0.5.27/doc/apt-ftparchive.1.xml	2004-07-31 02:52:05.000000000 -0700
@@ -38,6 +38,7 @@
       <arg><option>--delink</option></arg>
       <arg><option>--readonly</option></arg>
       <arg><option>--contents</option></arg>
+      <arg><option>--release</option></arg>
       <arg><option>-o=<replaceable>config string</replaceable></option></arg>
       <arg><option>-c=<replaceable>file</replaceable></option></arg>      
       <group choice="req">
@@ -329,7 +330,16 @@
       file. Relative files names are prefixed with the archive directory. 
       This is used when processing source indexs.</para></listitem>
       </varlistentry>
-     </variablelist>     
+     </variablelist>
+     <para>
+     In addition, values for the additional metadata fields in the Release
+     file can be set with variables under <literal>Release</literal>,
+     e.g. <literal>Release::Origin</literal>.  The supported fields are:
+     <literal>Origin</literal>, <literal>Label</literal>,
+     <literal>Suite</literal>, <literal>Version</literal>,
+     <literal>Codename</literal>, <literal>Date</literal>,
+     <literal>Description</literal>.  Values set here will override the
+     default values from <literal>Apt::FTPArchive::Release</literal>.</para>
    </refsect2>
    
    <refsect2><title>Tree Section</title>
@@ -531,6 +541,15 @@
      Configuration Item: <literal>APT::FTPArchive::Contents</literal>.</para></listitem>
      </varlistentry>
 
+     <varlistentry><term><option>--release</option></term>
+     <listitem><para>
+     Perform release file generation. When this option is set and
+     <literal>generate</literal> is run, Release files will also be
+     generated for every Tree specified in the <literal>generate</literal>
+     configuration. the default is off.
+     Configuration Item: <literal>APT::FTPArchive::GenerateRelease</literal>.</para></listitem>
+     </varlistentry>
+
      <varlistentry><term><option>-s</option></term><term><option>--source-override</option></term>
      <listitem><para>
      Select the source override file to use with the <literal>sources</literal> command.


-- 
Russ Allbery (rra@stanford.edu)             <http://www.eyrie.org/~eagle/>



Reply to: