Skip to content

Commit fd36153

Browse files
committed
WIP: export_orig: excludes files set in Files-Excluded
Signed-off-by: Shengjing Zhu <i@zhsj.me>
1 parent 50b9223 commit fd36153

5 files changed

Lines changed: 116 additions & 2 deletions

File tree

gbp/deb/copyright.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# vim: set fileencoding=utf-8 :
2+
#
3+
# (C) 2018 Shengjing Zhu <i@zhsj.me>
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, please see
16+
# <http://www.gnu.org/licenses/>
17+
"""A Debian Copyright file"""
18+
import email
19+
import os
20+
21+
22+
class NoCopyrightError(Exception):
23+
"""No copyright found"""
24+
pass
25+
26+
27+
class ParseCopyrightError(Exception):
28+
"""Problem parsing copyright"""
29+
pass
30+
31+
32+
class Copyright(object):
33+
"""A Debian copyright"""
34+
def __init__(self, contents=None, filename="debian/copyright"):
35+
"""
36+
Parse an existing copyright file.
37+
38+
@param contents: content of a control file
39+
@type contents: C{str}
40+
@param filename: name of the control file
41+
@type filename: C{str}
42+
@return: Copyright object
43+
@rtype: C{gbp.deb.conrol.Copyright} object
44+
"""
45+
if contents:
46+
copyright = email.message_from_string(contents)
47+
else:
48+
if not os.access(filename, os.F_OK):
49+
raise NoCopyrightError("Copyright file %s doesn't exist" % filename)
50+
with open(filename) as f:
51+
copyright = email.message_from_file(f)
52+
53+
if not copyright.items():
54+
raise ParseCopyrightError("Empty or invalid copyright file or contents")
55+
56+
self._copyright = copyright
57+
self.filename = filename
58+
59+
@property
60+
def files_excluded(self):
61+
"""The file list to be excluded"""
62+
return self._copyright['Files-Excluded'].split()

gbp/deb/git.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def create_upstream_tarball_via_pristine_tar(self, source, output_dir, comp, com
331331
return True
332332

333333
def create_upstream_tarball_via_git_archive(self, source, output_dir, treeish,
334-
comp, with_submodules, component=None):
334+
comp, with_submodules, component=None, excludes=None):
335335
"""
336336
Create a compressed orig tarball in output_dir using git archive
337337
@@ -347,6 +347,8 @@ def create_upstream_tarball_via_git_archive(self, source, output_dir, treeish,
347347
@type with_submodules: C{bool}
348348
@param component: component to add to tarball name
349349
@type component: C{str}
350+
@param excludes: files to be excluded from tarball
351+
@type excludes: C{list}
350352
351353
Raises GitRepositoryError in case of an error
352354
"""
@@ -355,11 +357,18 @@ def create_upstream_tarball_via_git_archive(self, source, output_dir, treeish,
355357
source.upstream_tarball_name(comp.type, component=component))
356358
prefix = "%s-%s" % (source.name, source.upstream_version)
357359

360+
old_attributes = self.read_git_dir_attributes()
361+
if excludes:
362+
attributes = '\n'.join([f + ' export-ignore' for f in excludes])
363+
attributes = attributes + '\n' + old_attributes
364+
self.write_git_dir_attributes(attributes)
358365
try:
359366
if self.has_submodules() and with_submodules:
360367
submodules = True
361368
self.update_submodules()
362369
self.archive_comp(treeish, output, prefix, comp, submodules=submodules)
370+
if excludes:
371+
self.write_git_dir_attributes(old_attributes)
363372
except Exception as e:
364373
raise GitRepositoryError("Error creating %s: %s" % (output, e))
365374
return True

gbp/deb/source.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from gbp.deb.format import DebianSourceFormat
2222
from gbp.deb.changelog import ChangeLog
2323
from gbp.deb.control import Control
24+
from gbp.deb.copyright import Copyright
2425

2526

2627
class FileVfs(object):
@@ -57,6 +58,7 @@ def __init__(self, vfs):
5758
"""
5859
self._changelog = None
5960
self._control = None
61+
self._copyright = None
6062

6163
if isinstance(vfs, str):
6264
self._vfs = FileVfs(vfs)
@@ -114,6 +116,19 @@ def control(self):
114116
raise DebianSourceError('Failed to read control file: %s' % err)
115117
return self._control
116118

119+
@property
120+
def copyright(self):
121+
"""
122+
Return the L{gbp.deb.copyright}
123+
"""
124+
if not self._copyright:
125+
try:
126+
with self._vfs.open('debian/copyright', 'rb') as crf:
127+
self._copyright = Copyright(crf.read().decode('utf-8'))
128+
except IOError as err:
129+
raise DebianSourceError('Failed to read copyright file: %s' % err)
130+
return self._copyright
131+
117132
@property
118133
def sourcepkg(self):
119134
"""

gbp/git/repository.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,3 +2096,20 @@ def clone(cls, path, remote, depth=0, recursive=False, mirror=False,
20962096
% (remote, abspath, err[1]))
20972097
return None
20982098
#}
2099+
2100+
#{ Attributes in Git_DIR
2101+
def read_git_dir_attributes(self):
2102+
path = os.path.join(self.git_dir, 'info/attributes')
2103+
if not os.path.isfile(path):
2104+
return ''
2105+
with open(path, 'r') as f:
2106+
content = f.read()
2107+
return content
2108+
2109+
def write_git_dir_attributes(self, content):
2110+
path = os.path.join(self.git_dir, 'info')
2111+
if not os.path.isdir(path):
2112+
raise GitRepositoryError("Path %s is not directory" % path)
2113+
with open(os.path.join(path, 'attributes'), 'w') as f:
2114+
f.write(content)
2115+
#}

gbp/scripts/export_orig.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,15 @@ def git_archive_build_origs(repo, source, output_dir, options):
208208
upstream_tree))
209209
gbp.log.debug("Building upstream tarball with compression %s" % comp)
210210
tree = repo.tree_drop_dirs(upstream_tree, options.components) if options.components else upstream_tree
211-
repo.create_upstream_tarball_via_git_archive(source, output_dir, tree, comp, options.with_submodules)
211+
212+
if options.exclude_with_copyright:
213+
excludes = source.copyright.files_excluded
214+
else:
215+
excludes = []
216+
gbp.log.debug("Excluding files from archive: %s" % excludes)
217+
218+
repo.create_upstream_tarball_via_git_archive(source, output_dir, tree, comp,
219+
options.with_submodules, excludes=excludes)
212220
for component in options.components:
213221
subtree = repo.tree_get_dir(upstream_tree, component)
214222
if not subtree:
@@ -298,6 +306,9 @@ def build_parser(name):
298306
help="Compression level, default is '%(compression-level)s'")
299307
orig_group.add_config_file_option("component", action="append", metavar='COMPONENT',
300308
dest="components")
309+
orig_group.add_config_file_option(option_name="exclude-with-copyright", action="store_true",
310+
dest="exclude_with_copyright", default=False,
311+
help="exclude files in Files-Excluded field set in debian/copyright")
301312
branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch")
302313
branch_group.add_boolean_config_file_option(option_name="submodules", dest="with_submodules")
303314
return parser

0 commit comments

Comments
 (0)