c37cea80f3ce29d843fbf9cceae6f1f8fbf70b5a
[tools/git-buildpackage.git] / gbp / scripts / import_dscs.py
1 # vim: set fileencoding=utf-8 :
2 #
3 # (C) 2008, 2009, 2010 Guido Guenther <agx@sigxcpu.org>
4 #    This program is free software; you can redistribute it and/or modify
5 #    it under the terms of the GNU General Public License as published by
6 #    the Free Software Foundation; either version 2 of the License, or
7 #    (at your option) any later version.
8 #
9 #    This program is distributed in the hope that it will be useful,
10 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #    GNU General Public License for more details.
13 #
14 #    You should have received a copy of the GNU General Public License
15 #    along with this program; if not, write to the Free Software
16 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 """Import multiple dsc files into GIT in one go"""
18
19 import glob
20 import os
21 import sys
22 import tempfile
23 import gbp.command_wrappers as gbpc
24 from gbp.deb import DpkgCompareVersions
25 from gbp.deb.dscfile import DscFile
26 from gbp.errors import GbpError
27 from gbp.git import GitRepository, GitRepositoryError
28 from gbp.scripts import import_dsc
29 from gbp.config import GbpOptionParser
30 import gbp.log
31
32 class DscCompareVersions(DpkgCompareVersions):
33     def __init__(self):
34         DpkgCompareVersions.__init__(self)
35
36     def __call__(self, dsc1, dsc2):
37         return DpkgCompareVersions.__call__(self, dsc1.version, dsc2.version)
38
39
40 class GitImportDsc(object):
41     def __init__(self, args):
42         self.args = args
43
44     def importdsc(self, dsc):
45         return import_dsc.main(['import-dsc'] + self.args + [dsc.dscfile])
46
47
48 def fetch_snapshots(pkg, downloaddir):
49     "Fetch snapshots using debsnap von snapshots.debian.org"
50     dscs = None
51
52     gbp.log.info("Downloading snapshots of '%s' to '%s'..." %
53                  (pkg, downloaddir))
54     debsnap = gbpc.Command("debsnap", [ '--force', '--destdir=%s' %
55                                         (downloaddir), pkg])
56     try:
57         debsnap()
58     except gbpc.CommandExecFailed:
59         if debsnap.retcode == 2:
60             gbp.log.warn("Some packages failed to download. Continuing.")
61             pass
62         else:
63             raise
64
65     dscs = glob.glob(os.path.join(downloaddir, '*.dsc'))
66     if not dscs:
67         raise GbpError('No package downloaded')
68
69     return [os.path.join(downloaddir, dsc) for dsc in dscs]
70
71 def set_gbp_conf_files():
72     """
73     Filter out all gbp.conf files that are local to the git repository and set
74     GBP_CONF_FILES accordingly so gbp import-dsc will only use these.
75     """
76     global_config = GbpOptionParser.get_config_files(no_local=True)
77     gbp_conf_files = ':'.join(global_config)
78     os.environ['GBP_CONF_FILES'] = gbp_conf_files
79     gbp.log.debug("Setting GBP_CONF_FILES to '%s'" % gbp_conf_files)
80
81 def print_help():
82     print("""Usage: gbp import-dscs [options] [gbp-import-dsc options] /path/to/dsc1 [/path/to/dsc2] ...
83        gbp import-dscs --debsnap [options] [gbp-import-dsc options] package
84
85 Options:
86
87     --ignore-repo-config: ignore gbp.conf in git repo
88 """)
89
90
91 def main(argv):
92     dirs = dict(top=os.path.abspath(os.curdir))
93     dscs = []
94     ret = 0
95     verbose = False
96     dsc_cmp = DscCompareVersions()
97     use_debsnap = False
98
99     try:
100         import_args = argv[1:]
101
102         if '--verbose' in import_args:
103             verbose = True
104         gbp.log.setup(False, verbose)
105
106         if '--ignore-repo-config' in import_args:
107             set_gbp_conf_files()
108             import_args.remove('--ignore-repo-config')
109         # Not using Configparser since we want to pass all unknown options
110         # unaltered to gbp import-dsc
111         if '--debsnap' in import_args:
112             use_debsnap = True
113             import_args.remove('--debsnap')
114             if import_args == []:
115                 print_help()
116                 raise GbpError
117             pkg = import_args[-1]
118             import_args = import_args[:-1]
119         else:
120             for arg in argv[::-1]:
121                 if arg.endswith('.dsc'):
122                     dscs.append(DscFile.parse(arg))
123                     import_args.remove(arg)
124
125         if not use_debsnap and not dscs:
126             print_help()
127             raise GbpError
128
129         if use_debsnap:
130             dirs['tmp'] = os.path.abspath(tempfile.mkdtemp())
131             dscs = [ DscFile.parse(f) for f in fetch_snapshots(pkg, dirs['tmp']) ]
132
133         dscs.sort(cmp=dsc_cmp)
134         importer = GitImportDsc(import_args)
135
136         try:
137             repo = GitRepository('.')
138             (clean, out) = repo.is_clean()
139             if not clean:
140                 gbp.log.err("Repository has uncommitted changes, "
141                             "commit these first: ")
142                 raise GbpError(out)
143             else:
144                 dirs['pkg'] = dirs['top']
145         except GitRepositoryError:
146             # no git repository there yet
147             dirs['pkg'] = os.path.join(dirs['top'], dscs[0].pkg)
148
149         if importer.importdsc(dscs[0]):
150             raise GbpError("Failed to import '%s'" % dscs[0].dscfile)
151         os.chdir(dirs['pkg'])
152
153         for dsc in dscs[1:]:
154             if importer.importdsc(dsc):
155                 raise GbpError("Failed to import '%s'" % dscs[0].dscfile)
156
157     except (GbpError, gbpc.CommandExecFailed, GitRepositoryError) as err:
158         if len(err.__str__()):
159             gbp.log.err(err)
160         ret = 1
161     finally:
162         if 'tmp' in dirs:
163             gbpc.RemoveTree(dirs['tmp'])()
164         os.chdir(dirs['top'])
165
166     if not ret:
167         gbp.log.info('Everything imported under %s' % dirs['pkg'])
168     return ret
169
170 if __name__ == '__main__':
171     sys.exit(main(sys.argv))
172
173 # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: