From ba7623944bada45accb551ffe66901dfa756a0bc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 16:07:08 +0300 Subject: [PATCH] rpm: support guessing spec file from git treeish Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 76 +++++++++++++++++++++++++++--------------- gbp/scripts/import_orig_rpm.py | 2 +- tests/test_rpm.py | 41 ++++++++++++++++++++++- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 8bbab70..7aa7ba4 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -768,44 +768,66 @@ def parse_srpm(srpmfile): return srcrpm -def guess_spec(topdir, recursive=True, preferred_name=None): - """Guess a spec file""" +def guess_spec_fn(file_list, preferred_name=None): + """Guess spec file from a list of filenames""" specs = [] - abstop = os.path.abspath(topdir) - for (root, dirs, files) in os.walk(abstop): - for f in files: - # Stop at the first file matching the preferred name - if f == preferred_name: - gbp.log.debug("Found a preferred spec file: %s in %s" % (f, root)) - specs = [os.path.join(root,f)] - recursive = False - break - if f.endswith(".spec"): - gbp.log.debug("Found spec file: %s in %s" % (f, root)) - specs.append(os.path.join(root,f)) + for filepath in file_list: + filename = os.path.basename(filepath) + # Stop at the first file matching the preferred name + if filename == preferred_name: + gbp.log.debug("Found a preferred spec file %s" % filepath) + specs = [filepath] + break + if filename.endswith(".spec"): + gbp.log.debug("Found spec file %s" % filepath) + specs.append(filepath) + if len(specs) == 0: + raise NoSpecError("No spec file found.") + elif len(specs) > 1: + raise NoSpecError("Multiple spec files found (%s), don't know which " + "to use." % ', '.join(specs)) + return specs[0] + +def guess_spec(topdir, recursive=True, preferred_name=None): + """Guess a spec file""" + file_list = [] + if not topdir: + topdir = '.' + for root, dirs, files in os.walk(topdir): + file_list.extend([os.path.join(root, fname) for fname in files]) if not recursive: del dirs[:] # Skip .git dir in any case if '.git' in dirs: dirs.remove('.git') - - if len(specs) == 0: - raise NoSpecError("No spec file found.") - elif len(specs) > 1: - filenames = [os.path.relpath(spec, abstop) for spec in specs] - raise NoSpecError("Multiple spec files found (%s), don't know which " - "to use." % ', '.join(filenames)) - return SpecFile(specs[0]) + return SpecFile(os.path.abspath(guess_spec_fn(file_list, preferred_name))) -def guess_spec_repo(repo, branch, packaging_dir): +def guess_spec_repo(repo, treeish, topdir='', recursive=True, preferred_name=None): """ - @todo: implement this - Try to find/parse the spec file from given branch in the git - repository. + Try to find/parse the spec file from a given git treeish. """ - raise NoSpecError, "Searching spec from other branch not implemented yet" + topdir = topdir.rstrip('/') + ('/') if topdir else '' + try: + file_list = [nam for (mod, typ, sha, nam) in + repo.list_tree(treeish, recursive, topdir) if typ == 'blob'] + except GitRepositoryError as err: + raise NoSpecError("Cannot find spec file from treeish %s, Git error: %s" + % (treeish, err)) + spec_path = guess_spec_fn(file_list, preferred_name) + return spec_from_repo(repo, treeish, spec_path) + + +def spec_from_repo(repo, treeish, spec_path): + """Get and parse a spec file from a give Git treeish""" + try: + spec = SpecFile(filedata=repo.show('%s:%s' % (treeish, spec_path))) + spec.specdir = os.path.dirname(spec_path) + spec.specfile = os.path.basename(spec_path) + return spec + except GitRepositoryError as err: + raise NoSpecError("Git error: %s" % err) def string_to_int(val_str): diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index b208ad1..8eacfb2 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -58,7 +58,7 @@ def detect_name_and_version(repo, source, options): # we're not on the packaging-branch (but upstream, for # example). spec = guess_spec_repo(repo, options.packaging_branch, - options.packaging_dir) + options.packaging_dir, True, preferred_fn) sourcepackage = spec.name except NoSpecError: if options.interactive: diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 47aaf7f..69ab85b 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -23,7 +23,9 @@ import tempfile from nose.tools import assert_raises from gbp.errors import GbpError -from gbp.rpm import SrcRpmFile, SpecFile, parse_srpm, guess_spec, NoSpecError +from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, + guess_spec_repo, spec_from_repo) +from gbp.git.repository import GitRepository DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') @@ -321,6 +323,11 @@ class TestSpecFile(object): class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) def test_parse_srpm(self): """Test parse_srpm() function""" @@ -346,4 +353,36 @@ class TestUtilityFunctions(object): assert spec.specfile == 'gbp-test2.spec' assert spec.specdir == SPEC_DIR + def test_guess_spec_repo(self): + """Test guess_spec_repo() and spec_from_repo() functions""" + # Create dummy repository with some commits + repo = GitRepository.create(self.tmpdir) + with open(os.path.join(repo.path, 'foo.txt'), 'w') as fobj: + fobj.write('bar\n') + repo.add_files('foo.txt') + repo.commit_all('Add dummy file') + os.mkdir(os.path.join(repo.path, 'packaging')) + shutil.copy(os.path.join(SPEC_DIR, 'gbp-test.spec'), + os.path.join(repo.path, 'packaging')) + repo.add_files('packaging/gbp-test.spec') + repo.commit_all('Add spec file') + + # Spec not found + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD~1', recursive=True) + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD', recursive=False) + # Spec found + spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) + spec = guess_spec_repo(repo, 'HEAD', recursive=True) + assert spec.specfile == 'gbp-test.spec' + assert spec.specdir == 'packaging' + assert spec.specpath == 'packaging/gbp-test.spec' + + # Test spec_from_repo() + with assert_raises(NoSpecError): + spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') + assert spec.specfile == 'gbp-test.spec' + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- 2.7.4