summaryrefslogtreecommitdiff
path: root/patchtracker/SourceArchive.py
blob: 4ad4152384e57a39996af0a54f46bace8e48232b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import os
import errno
from fnmatch import fnmatch
from gzip import GzipFile
from debian_bundle import deb822

import patchtracker.Conf as Conf

class Archive:
  root = None
  distsdir = None

  def __init__(self, dir):
    self.root = dir
    self.distsdir = os.sep.join([dir, "dists"])

  def suites(self):
    for s in os.listdir(self.distsdir):
      yield s

  def components(self, suite):
    f = file(self.distsdir + os.sep + os.sep.join([suite, "Release"]))
    rel = deb822.Release(f)
    for comp in rel['Components'].split(' '):
      yield comp

  def sourcepackages(self, suite, component):
    sfile=os.sep.join([self.distsdir,suite,component,"/source/Sources.gz"])
    for ent in deb822.Sources.iter_paragraphs(GzipFile(sfile)):
      if fnmatch(ent['Package'], 'av*'):
        yield SourcePackage(ent)

  def __str__(self):
    return "Archive rooted at "+self.root

class SourcePackage:
  name = None
  format = None
  diffgz = None
  loc = None
  type = "Native"
  version = None
  seriespatches = {}
  directpatches = []
  # todo
  vcs = {}

  def __init__(self, info):
    self.name = info['Package']  
    self.format = info['Format']  
    self.loc = info['Directory']  
    self.version = info['Version']  

    for f in info['Files']:
      if fnmatch(f['name'], '*.diff.gz'):
        self.diffgz=f
        self.type = "Debian-diff"

    if self.diffgz != None:
      self.debianonlydiff = "_".join([self.name, self.version, "debianonly.diff"])
      self.nondebiandiff = "_".join([self.name, self.version, "nondebian.diff"])

  def idx(self):
    name = str(self)
    if len(name) < 4 or name[0:3] != "lib":
      return name[0]
    else:
      return name[0:4]

  ## XXX okay, all of this could be made quite a bit cleaner
  def diff_series(self, outdir):
    if self.diffgz:
      debdiff = os.sep.join([outdir, self.debianonlydiff])
      seriesdir = os.sep.join([outdir, "series"])
      try:
        os.mkdir(os.sep.join([outdir,"series"]))
      except OSError, e:
        if e.errno != errno.EEXIST:
          raise e
        # XXX better way to be idempotent
        else:
          return
      os.system("filterdiff -p 1 -i 'debian/patches/*' "+debdiff+"| ( cd "+
                seriesdir+"; patch -s )")
      for (blah,blahblah,files) in os.walk(seriesdir):
        try:
          files.remove('series')
          files.remove('00list')
        except:
          pass
        for f in files:
          p = os.sep.join([seriesdir, f])
          # get the info for summary generation
          fd = os.popen("diffstat "+p)
          self.seriespatches[f] = fd.read()
          fd.close()
          os.system("source-highlight -s diff -f xhtml -i "+p+" -o "+p+".html")
          
  def diff_debiandir(self, outdir):
    try:
      src = os.sep.join([Conf.archive_root, self.loc, self.diffgz['name']])
      dst = os.sep.join([outdir, self.debianonlydiff])
      try:
        os.stat(dst)
        return
      # XXX better way to be idempotent
      except OSError, e:
        pass
      os.system("filterdiff -z -p 1 -i 'debian/*' "+src+" > "+dst)
      os.system("source-highlight -s diff -f xhtml -i "+dst+" -o "+dst+".html")
    # in the case of native packages there is no diffgz
    except TypeError:
      pass

  def diff_nondebiandir(self, outdir):
    try:
      src = os.sep.join([Conf.archive_root, self.loc, self.diffgz['name']])
      dst = os.sep.join([outdir, self.nondebiandiff])
      try:
        os.stat(dst)
        return
      # XXX better way to be idempotent
      except OSError, e:
        pass
      os.system("filterdiff -z -p 1 -x 'debian/*' "+src+" > "+dst)
      os.system("source-highlight -s diff -f xhtml -i "+dst+" -o "+dst+".html")
    # in the case of native packages there is no diffgz
    except TypeError:
      pass

  def __str__(self):
    return self.name

class SourcePackageIndex:
  pkgs = {}

  def ins(self, srcpkg, rel):
    idx = srcpkg.idx()
    if not self.pkgs.has_key(idx):
      self.pkgs[idx] = {}
    if not self.pkgs[idx].has_key(srcpkg.name):
      self.pkgs[idx][srcpkg.name] = {}
    if not self.pkgs[idx][srcpkg.name].has_key(rel):
      self.pkgs[idx][srcpkg.name][rel] = srcpkg

  def indices(self):
    for k,v in self.pkgs.iteritems():
      yield (k,v)