Skip to content

Commit 1e9af1e

Browse files
committed
WIP: Add pristine-lfs support
Add pristine-lfs support similar to the existing pristine-tar support. Since pristine-lfs has a Python interface, use that instead of the command-line interface, but use it in a fail-safe way. Unlike pristine-tar, pristine-lfs supports looking up tarballs by a version, so use that instead of picking tarballs manually. If both pristine-lfs and pristine-tar are enabled, only import tarballs with pristine-lfs; when checking out, prefer pristine-lfs, but also do pristine-tar. Signed-off-by: Andrej Shadura <[email protected]>
1 parent 6a3030d commit 1e9af1e

File tree

8 files changed

+176
-5
lines changed

8 files changed

+176
-5
lines changed

gbp/config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ class GbpOptionParser(OptionParser):
166166
'pq-from': 'DEBIAN',
167167
'prebuild': '',
168168
'preexport': '',
169+
'pristine-lfs': 'False',
170+
'pristine-lfs-commit': 'False',
169171
'pristine-tar': 'False',
170172
'pristine-tar-commit': 'False',
171173
'purge': 'True',
@@ -224,6 +226,12 @@ class GbpOptionParser(OptionParser):
224226
'commit-msg':
225227
"Format string for commit message used to commit, "
226228
"the changelog, default is '%(commit-msg)s'",
229+
'pristine-lfs':
230+
"Use pristine-lfs to create orig tarball, "
231+
"default is '%(pristine-lfs)s'",
232+
'pristine-lfs-commit':
233+
"When generating a tarball, commit it to the pristine-lfs branch '%(pristine-lfs-commit)s' "
234+
"default is '%(pristine-lfs-commit)s'",
227235
'pristine-tar':
228236
"Use pristine-tar to create orig tarball, "
229237
"default is '%(pristine-tar)s'",

gbp/deb/git.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from gbp.command_wrappers import CommandExecFailed
2323
from gbp.git import GitRepositoryError
2424
from gbp.deb.pristinetar import DebianPristineTar
25+
from gbp.deb.pristinelfs import PristineLfs
2526
from gbp.paths import to_bin
2627
from gbp.pkg.git import PkgGitRepository
2728
from gbp.pkg.pkgpolicy import PkgPolicy
@@ -339,6 +340,44 @@ def create_upstream_tarball_via_pristine_tar(self, source, output_dir, comp, ups
339340
e))
340341
return True
341342

343+
@property
344+
def pristine_lfs_branch(self):
345+
"""
346+
The name of the pristine-lfs branch, whether it already exists or
347+
not.
348+
"""
349+
return PristineLfs.branch
350+
351+
def has_pristine_lfs_branch(self):
352+
"""
353+
Whether the repo has a I{pristine-lfs} branch.
354+
355+
@return: C{True} if the repo has pristine-lfs commits already, C{False}
356+
otherwise
357+
@rtype: C{Bool}
358+
"""
359+
return True if self.has_branch(self.pristine_lfs_branch) else False
360+
361+
def create_pristine_lfs_commits(self, sources):
362+
"""
363+
Create pristine-lfs commits for a package with main tarball
364+
and (optional) component tarballs based on upstream_tree
365+
366+
@param soures: C{list} of tarball as I{UpstreamSource}. First one being the main
367+
tarball the other ones additional tarballs.
368+
"""
369+
components = [t.component for t in sources[1:]]
370+
all_files = [
371+
source.path for source in sources
372+
] + [
373+
source.signaturefile for source in sources if source.signaturefile
374+
]
375+
376+
try:
377+
self.pristine_lfs.commit(all_files)
378+
except CommandExecFailed as e:
379+
raise GitRepositoryError(str(e))
380+
342381
def create_upstream_tarball_via_git_archive(self, source, output_dir, treeish,
343382
comp, with_submodules, component=None):
344383
"""

gbp/deb/pristinelfs.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# vim: set fileencoding=utf-8 :
2+
#
3+
# (C) 2021 Andrej Shadura <[email protected]>
4+
# (C) 2021 Collabora Ltd
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation; either version 2 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program; if not, please see
17+
# <http://www.gnu.org/licenses/>
18+
"""Check in and check out archives from the pristine-lfs branch"""
19+
20+
from __future__ import annotations
21+
22+
import logging
23+
24+
from gbp.command_wrappers import CommandExecFailed
25+
from gbp.deb import DebianPkgPolicy
26+
from gbp.git import GitRepository, GitRepositoryError
27+
28+
try:
29+
from pristine_lfs.main import do_list, do_verify, do_commit_files, do_checkout
30+
from pristine_lfs.errors import CommandFailed, DifferentFilesExist, GitError
31+
except ImportError:
32+
def pristine_lfs_not_found(*args, **kwargs):
33+
raise CommandExecFailed("pristine-lfs not installed")
34+
35+
do_list = do_verify = do_checkout = do_commit_files = pristine_lfs_not_found
36+
37+
class DifferentFilesExist(Exception):
38+
pass
39+
40+
GitError = DifferentFilesExist
41+
42+
logger = logging.getLogger('pristine-lfs')
43+
44+
class PristineLfs:
45+
branch = 'pristine-lfs'
46+
47+
def __init__(self, repo: GitRepository):
48+
self.repo = repo
49+
50+
def commit(self, files: list[str], quiet: bool = False):
51+
"""
52+
Commit files I{files} to the pristine-lfs branch
53+
54+
@param files: list of files to commit
55+
@type files: C{list}
56+
"""
57+
logger.setLevel(logging.WARNING if quiet else logging.INFO)
58+
59+
try:
60+
ios = [open(f, 'rb') for f in files]
61+
do_commit_files(tarballs=ios, branch=self.branch)
62+
except (OSError, CommandFailed) as e:
63+
raise CommandExecFailed(str(e))
64+
except (DifferentFilesExist, GitError) as e:
65+
raise GitRepositoryError(str(e))
66+
67+
def checkout(self, package: str, version: str, output_dir: str, quiet: bool = False):
68+
"""
69+
Check out all orig tarballs for package I{package} of I{version} to
70+
I{output_dir}
71+
72+
@param package: the package to check out the orig tarballs for
73+
@type package: C{str}
74+
@param version: the version to check out the orig tarballs for
75+
@type version: C{str}
76+
@param output_dir: the directory to put the tarballs into
77+
@type output_dir: C{str}
78+
"""
79+
logger.setLevel(logging.WARNING if quiet else logging.INFO)
80+
81+
try:
82+
do_checkout(package=package, version=version, branch=self.branch, outdir=output_dir)
83+
except (OSError, CommandFailed) as e:
84+
raise CommandExecFailed(str(e))
85+
except GitError as e:
86+
raise GitRepositoryError(str(e))

gbp/pkg/git.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from gbp.command_wrappers import (CatenateTarArchive, CatenateZipArchive)
2525
from gbp.git import GitRepository, GitRepositoryError
2626
from gbp.deb.pristinetar import DebianPristineTar
27+
from gbp.deb.pristinelfs import PristineLfs
2728

2829

2930
import gbp.log
@@ -35,6 +36,7 @@ class PkgGitRepository(GitRepository):
3536
def __init__(self, *args, **kwargs):
3637
super(PkgGitRepository, self).__init__(*args, **kwargs)
3738
self.pristine_tar = DebianPristineTar(self)
39+
self.pristine_lfs = PristineLfs(self)
3840

3941
@staticmethod
4042
def sanitize_prefix(prefix):

gbp/scripts/buildpackage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ def build_parser(name, prefix=None):
385385
tag_group.add_config_file_option(option_name="debian-tag-msg", dest="debian_tag_msg")
386386
tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag")
387387
orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree")
388+
orig_group.add_boolean_config_file_option(option_name="pristine-lfs", dest="pristine_lfs")
388389
orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar")
389390
orig_group.add_boolean_config_file_option(option_name="pristine-tar-commit",
390391
dest="pristine_tar_commit")

gbp/scripts/clone.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ def main(argv):
199199
branches = [options.debian_branch, options.upstream_branch]
200200
if options.pristine_tar:
201201
branches += [repo.pristine_tar_branch]
202+
if options.pristine_lfs:
203+
branches += [repo.pristine_lfs_branch]
202204
gbp.log.debug('Will track branches: %s' % branches)
203205
for branch in branches:
204206
remote = 'origin/%s' % branch

gbp/scripts/export_orig.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def prepare_upstream_tarballs(repo, source, options, tarball_dir, output_dir):
3636
"""
3737
Make sure we have the needed upstream tarballs. The default order is:
3838
- look in tarball_dir and if found symlink to it
39+
- create tarball using pristine-lfs
3940
- create tarball using pristine-tar
4041
- create tarball using git-archive
4142
@@ -68,7 +69,8 @@ def prepare_upstream_tarballs(repo, source, options, tarball_dir, output_dir):
6869

6970
# Create tarball if missing or forced
7071
if not du.DebianPkgPolicy.has_origs(orig_files, output_dir) or options.force_create:
71-
if not pristine_tar_build_origs(repo, source, output_dir, options):
72+
if (not pristine_lfs_checkout_origs(repo, source, output_dir, options) and
73+
not pristine_tar_build_origs(repo, source, output_dir, options)):
7274
git_archive_build_origs(repo, source, output_dir, options)
7375
maybe_pristine_tar_commit(repo, source, options, output_dir, orig_files)
7476
pristine_tar_verify_origs(repo, source, options, output_dir, orig_files)
@@ -92,6 +94,26 @@ def pristine_tar_prepare_orig_tree(repo, source, options):
9294
"orig tarball via pristine-tar" % tree_name)
9395

9496

97+
def pristine_lfs_checkout_origs(repo, source, output_dir, options):
98+
"""
99+
Check out orig tarballs using pristine-lfs
100+
101+
@returns: C{True} if tarball was built, C{False} otherwise
102+
"""
103+
gbp.log.info(options)
104+
if not options.pristine_lfs:
105+
return False
106+
107+
if not repo.has_branch(repo.pristine_lfs_branch):
108+
gbp.log.warn('Pristine-lfs branch "%s" not found' %
109+
repo.pristine_lfs_branch)
110+
111+
try:
112+
repo.pristine_lfs.checkout(source.name, source.version, output_dir, quiet=not options.verbose)
113+
return True
114+
except CommandExecFailed:
115+
return False
116+
95117
def pristine_tar_build_origs(repo, source, output_dir, options):
96118
"""
97119
Build orig tarball using pristine-tar
@@ -297,6 +319,7 @@ def build_parser(name):
297319
tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag")
298320
orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree")
299321
orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar")
322+
orig_group.add_boolean_config_file_option(option_name="pristine-lfs", dest="pristine_lfs")
300323
orig_group.add_config_file_option(option_name="force-create", dest="force_create",
301324
help="force creation of orig tarball", action="store_true")
302325
orig_group.add_config_file_option(option_name="tarball-dir", dest="tarball_dir", type="path",

gbp/scripts/import_orig.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,10 @@ def set_bare_repo_options(options):
323323
if options.pristine_tar or options.merge:
324324
gbp.log.info("Bare repository: setting %s%s options"
325325
% (["", " '--no-pristine-tar'"][options.pristine_tar],
326+
["", " '--no-pristine-lfs'"][options.pristine_lfs],
326327
["", " '--no-merge'"][options.merge]))
327328
options.pristine_tar = False
329+
options.pristine_lfs = False
328330
options.merge = False
329331

330332

@@ -378,6 +380,8 @@ def build_parser(name):
378380
dest="upstream_tag")
379381
import_group.add_config_file_option(option_name="filter",
380382
dest="filters", action="append")
383+
import_group.add_boolean_config_file_option(option_name="pristine-lfs",
384+
dest="pristine_lfs")
381385
import_group.add_boolean_config_file_option(option_name="pristine-tar",
382386
dest="pristine_tar")
383387
import_group.add_boolean_config_file_option(option_name="filter-pristine-tar",
@@ -514,9 +518,12 @@ def main(argv):
514518
create_missing_branch=is_empty,
515519
)
516520

517-
if options.pristine_tar:
521+
if options.pristine_tar or options.pristine_lfs:
518522
if pristine_orig:
519-
repo.rrr_branch(repo.pristine_tar_branch)
523+
if options.pristine_lfs:
524+
repo.rrr_branch(repo.pristine_lfs_branch)
525+
elif options.pristine_tar:
526+
repo.rrr_branch(repo.pristine_tar_branch)
520527
for source in sources:
521528
# Enforce signature file exists with --upstream-signatures=on
522529
if options.upstream_signatures.is_on() and not source.signaturefile:
@@ -526,9 +533,12 @@ def main(argv):
526533
# For all practical purposes we're interested in pristine_orig's path
527534
if pristine_orig != sources[0].path:
528535
sources[0]._path = pristine_orig
529-
repo.create_pristine_tar_commits(import_branch, sources)
536+
if options.pristine_lfs:
537+
repo.create_pristine_lfs_commits(sources)
538+
elif options.pristine_tar:
539+
repo.create_pristine_tar_commits(import_branch, sources)
530540
else:
531-
gbp.log.warn("'%s' not an archive, skipping pristine-tar" % sources[0].path)
541+
gbp.log.warn("'%s' not an archive, skipping pristine-tar/pristine-lfs" % sources[0].path)
532542

533543
repo.create_tag(name=tag,
534544
msg="Upstream version %s" % version,

0 commit comments

Comments
 (0)