From 0ae5c9c1abf85dde13b8188fd264956b879b8baa Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Nov 10 2016 03:35:35 +0000 Subject: [PATCH 1/3] Better clog Fix #135 Signed-off-by: Chenxiong Qi --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 2204f7a..87246e9 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -1322,8 +1322,7 @@ class Commands(object): # First lets see if we got a message or we're on a real tty: if not sys.stdin.isatty(): if not message and not file: - raise rpkgError('Must have a commit message or be on a real ' - 'tty.') + raise rpkgError('Must have a commit message or be on a real tty.') # construct the git command # We do this via subprocess because the git module is terrible. @@ -1337,8 +1336,7 @@ class Commands(object): elif file: # If we get a relative file name, prepend our path to it. if self.path and not file.startswith('/'): - cmd.extend(['-F', os.path.abspath(os.path.join(self.path, - file))]) + cmd.extend(['-F', os.path.abspath(os.path.join(self.path, file))]) else: cmd.extend(['-F', os.path.abspath(file)]) if not files: @@ -1923,44 +1921,33 @@ class Commands(object): def clog(self, raw=False): """Write the latest spec changelog entry to a clog file""" - # This is a little ugly. We want to find where %changelog starts, - # then only deal with the content up to the first empty newline. - # Then remove any lines that start with $ or %, and then replace - # %% with % - - cloglines = [] - first = True - spec = open(os.path.join(self.path, self.spec), 'r').readlines() - for line in spec: - if line.lower().startswith('%changelog'): - # Grab all the lines below changelog - for line2 in spec[spec.index(line):]: - if line2.startswith('\n'): - break - if line2.startswith('$'): - continue - if line2.startswith('%'): - continue - if line2.startswith('*'): - if first: - # skip the email n/v/r line. Redundant - continue - # Otherwise what follows is the next entry - break - if first: - if not raw: - cloglines.append(line2.lstrip('- ').replace('%%', - '%')) - cloglines.append("\n") - else: - cloglines.append(line2.replace('%%', '%')) - first = False - else: - cloglines.append(line2.replace('%%', '%')) + spec_file = os.path.join(self.path, self.spec) + cmd = ['rpm', '--qf', '%{CHANGELOGTEXT}\n', '--specfile', spec_file] + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = proc.communicate() + if proc.returncode > 0: + raise rpkgError(stderr.strip()) + + clog_lines = [] + buf = six.StringIO(stdout) + for line in buf: + if line == '\n' or line.startswith('$'): + continue + if line == '(none)\n': + # (none) may appear as the last line in changelog got from SPEC + # file. In some cases, e.g. there is only one changelog entry + # in SPEC, no (none) line presents. Thus, when for loop ends, all + # lines of changelog are handled. + break + if raw: + clog_lines.append(line) + else: + clog_lines.append(line.replace('- ', '', 1)) + buf.close() # Now open the clog file and write out the lines - clogfile = open(os.path.join(self.path, 'clog'), 'w') - clogfile.writelines(cloglines) + with open(os.path.join(self.path, 'clog'), 'w') as clog: + clog.writelines(clog_lines) def compile(self, arch=None, short=False, builddir=None, nocheck=False): """Run rpmbuild -bc on a module diff --git a/pyrpkg/cli.py b/pyrpkg/cli.py old mode 100755 new mode 100644 index 4c1a454..fa89303 --- a/pyrpkg/cli.py +++ b/pyrpkg/cli.py @@ -430,6 +430,15 @@ defined, packages will be built sequentially.""" % {'name': self.name}) ' changelog message unless one is given to the ' 'command. A push can be done at the same time.') commit_parser.add_argument( + '-m', '--message', default=None, + help='Use the given as the commit message summary') + commit_parser.add_argument( + '--with-changelog', + action='store_true', + default=None, + help='Get the last changelog from SPEC as commit message content. ' + 'This option must be used with -m together.') + commit_parser.add_argument( '-c', '--clog', default=False, action='store_true', help='Generate the commit message from the Changelog section') commit_parser.add_argument( @@ -439,9 +448,6 @@ defined, packages will be built sequentially.""" % {'name': self.name}) '-t', '--tag', default=False, action='store_true', help='Create a tag for this commit') commit_parser.add_argument( - '-m', '--message', default=None, - help='Use the given as the commit message') - commit_parser.add_argument( '-F', '--file', default=None, help='Take the commit message from the given file') # allow one to commit /and/ push at the same time. @@ -1054,17 +1060,37 @@ see API KEY section of copr-cli(1) man page. target=self.args.clone_target) def commit(self): - if self.args.clog: + if self.args.with_changelog and not self.args.message: + raise rpkgError('--with-changelog must be used with -m together.') + + if self.args.message and self.args.with_changelog: + # Combose commit message with a summary and content into a file. + self.cmd.clog(True) + clog_file = os.path.abspath(os.path.join(self.args.path, 'clog')) + commit_msg_file = os.path.abspath(os.path.join(self.args.path, 'commit-message')) + with open(commit_msg_file, 'w') as commit_msg: + commit_msg.write(self.args.message) + commit_msg.write('\n\n') + with open(clog_file, 'r') as clog: + commit_msg.write(clog.read()) + self.args.file = commit_msg_file + os.remove(clog_file) + # This assignment is a magic because commit message is in the file + # commit-message already. + self.args.message = None + elif self.args.clog: self.cmd.clog(self.args.raw) - self.args.file = os.path.abspath(os.path.join(self.args.path, - 'clog')) + self.args.file = os.path.abspath(os.path.join(self.args.path, 'clog')) + + # It is okay without specifying either -m or --clog. Changes will be + # committed with command ``git commit``, then git will invoke default + # configured editor for you and let you enter the commit message. + try: - self.cmd.commit(self.args.message, self.args.file, - self.args.files, self.args.signoff) + self.cmd.commit(self.args.message, self.args.file, self.args.files, self.args.signoff) if self.args.tag: tagname = self.cmd.nvr - self.cmd.add_tag(tagname, True, self.args.message, - self.args.file) + self.cmd.add_tag(tagname, True, self.args.message, self.args.file) except Exception: if self.args.tag: self.log.error('Could not commit, will not tag!') @@ -1072,7 +1098,7 @@ see API KEY section of copr-cli(1) man page. self.log.error('Could not commit, will not push!') raise finally: - if self.args.clog and os.path.isfile(self.args.file): + if self.args.clog or self.args.with_changelog and os.path.isfile(self.args.file): os.remove(self.args.file) del self.args.file diff --git a/setup.py b/setup.py index 15d0ba7..bfac7c6 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( data_files=[('/etc/bash_completion.d', ['etc/bash_completion.d/rpkg.bash']), ('/etc/rpkg', ['etc/rpkg/rpkg.conf'])], install_requires=['six', 'pycurl'], # + koji, but it's not in PyPI - tests_require=['nose', 'mock'], + tests_require=['nose', 'mock', 'GitPython'], test_suite='nose.collector', classifiers=( 'Development Status :: 5 - Production/Stable', diff --git a/tests/fixtures/rpkg.conf b/tests/fixtures/rpkg.conf new file mode 100644 index 0000000..40b6f15 --- /dev/null +++ b/tests/fixtures/rpkg.conf @@ -0,0 +1,11 @@ +[rpkg] +lookaside = http://localhost/repo/pkgs +lookasidehash = md5 +lookaside_cgi = https://localhost/repo/pkgs/upload.cgi +gitbaseurl = ssh://%(user)s@localhost/%(module)s +anongiturl = git://localhost/%(module)s +branchre = f\d$|f\d\d$|el\d$|olpc\d$|master$ +kojiconfig = /etc/koji.conf +build_client = koji +clone_config = + bz.default-component %(module)s diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..d5f6c6a --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- + +import os + +from six.moves import configparser + +import git +import pyrpkg.cli + +from mock import patch +from utils import CommandTestCase +from utils import run +from pyrpkg import rpkgError + + +# rpkg.conf for running tests below +config_file = os.path.join(os.path.dirname(__file__), 'fixtures', 'rpkg.conf') + +fake_spec_content = ''' +Summary: package demo +Name: pkgtool +Version: 0.1 +Release: 1%{?dist} +License: GPL +%description +package demo for testing +%changelog +* Mon Nov 07 2016 cqi@redhat.com +- first release 0.1 +- add new spec +''' + + +class CliTestCase(CommandTestCase): + + def new_cli(self): + config = configparser.SafeConfigParser() + config.read(config_file) + + client = pyrpkg.cli.cliClient(config, name='rpkg') + client.do_imports() + client.parse_cmdline() + + return client + + def make_changes(self): + cmds = (['touch', 'new-file.txt'], + ['git', 'add', 'new-file.txt']) + map(lambda cmd: run(cmd, cwd=self.cloned_repo_path), cmds) + + +class TestClog(CliTestCase): + + def setUp(self): + super(TestClog, self).setUp() + + self.make_changes() + + def cli_clog(self): + """Run clog command""" + cli = self.new_cli() + cli.clog() + + def test_clog(self): + with patch('sys.argv', ['rpkg', '--path', self.cloned_repo_path, 'clog']): + self.cli_clog() + + clog_file = os.path.join(self.cloned_repo_path, 'clog') + self.assertTrue(os.path.exists(clog_file)) + with open(clog_file, 'r') as f: + clog = f.read().strip() + self.assertEqual('Initial version', clog) + + def test_raw_clog(self): + with patch('sys.argv', ['rpkg', '--path', self.cloned_repo_path, 'clog', '--raw']): + self.cli_clog() + + clog_file = os.path.join(self.cloned_repo_path, 'clog') + self.assertTrue(os.path.exists(clog_file)) + with open(clog_file, 'r') as f: + clog = f.read().strip() + self.assertEqual('- Initial version', clog) + + +class TestCommit(CliTestCase): + + def setUp(self): + super(TestCommit, self).setUp() + self.make_changes() + + def get_last_commit_message(self): + repo = git.Repo(self.cloned_repo_path) + return repo.iter_commits().next().message.strip() + + def cli_commit(self): + """Run commit command""" + cli = self.new_cli() + cli.commit() + + def test_with_only_summary(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + 'commit', '-m', 'new release']): + self.cli_commit() + + commit_msg = self.get_last_commit_message() + self.assertEqual('new release', commit_msg) + + def test_with_summary_and_changelog(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + 'commit', '-m', 'new release', '--with-changelog']): + self.cli_commit() + + commit_msg = self.get_last_commit_message() + expected_commit_msg = '''new release + +- Initial version''' + self.assertEqual(expected_commit_msg, commit_msg) + self.assertFalse(os.path.exists(os.path.join(self.cloned_repo_path, 'clog'))) + self.assertFalse(os.path.exists(os.path.join(self.cloned_repo_path, 'commit-message'))) + + def test_with_clog(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, 'commit', '--clog']): + self.cli_commit() + + commit_msg = self.get_last_commit_message() + expected_commit_msg = 'Initial version' + self.assertEqual(expected_commit_msg, commit_msg) + self.assertFalse(os.path.exists(os.path.join(self.cloned_repo_path, 'clog'))) + + def test_with_raw_clog(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + 'commit', '--clog', '--raw']): + self.cli_commit() + + commit_msg = self.get_last_commit_message() + expected_commit_msg = '- Initial version' + self.assertEqual(expected_commit_msg, commit_msg) + self.assertFalse(os.path.exists(os.path.join(self.cloned_repo_path, 'clog'))) + + def test_cannot_use_with_changelog_without_a_summary(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + 'commit', '--with-changelog']): + self.assertRaises(rpkgError, self.cli_commit) + + def test_push_after_commit(self): + repo = git.Repo(self.cloned_repo_path) + self.checkout_branch(repo, 'eng-rhel-6') + + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + 'commit', '-m', 'new release', '--with-changelog', '--push']): + self.cli_commit() + + diff_commits = repo.git.rev_list('origin/master...master') + self.assertEqual('', diff_commits) diff --git a/tests/test_commands.py b/tests/test_commands.py index 7267c89..01ffc3d 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2,147 +2,13 @@ import os import shutil -import tempfile -import unittest -import subprocess import git from mock import patch -from pyrpkg import Commands from pyrpkg import rpkgError -# Following global variables are used to construct Commands for tests in this -# module. Only for testing purpose, and they are not going to be used for -# hitting real services. -lookaside = 'http://dist-git-qa.server/repo/pkgs' -lookaside_cgi = 'http://dist-git-qa.server/lookaside/upload.cgi' -gitbaseurl = 'ssh://%(user)s@dist-git-qa.server/rpms/%(module)s' -anongiturl = 'git://dist-git-qa.server/rpms/%(module)s' -lookasidehash = 'md5' -branchre = 'rhel' -kojiconfig = '/etc/koji.conf.d/brewstage.conf' -build_client = 'brew-stage' - -spec_file = ''' -Summary: Dummy summary -Name: docpkg -Version: 1.2 -Release: 2 -License: GPL -Group: Applications/Productivity -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -%description -This is a dummy description. -%prep -%build -%clean -rm -rf $$RPM_BUILD_ROOT -%install -rm -rf $RPM_BUILD_ROOT -mkdir $RPM_BUILD_ROOT -%files -%changelog -* Thu Apr 21 2006 Chenxiong Qi - 1.2-2 -- Initial version -''' - - -def run(cmd, **kwargs): - returncode = subprocess.call(cmd, **kwargs) - if returncode != 0: - raise RuntimeError('Command fails. Command: %s. Return code %d' % ( - ' '.join(cmd), returncode)) - - -class CommandTestCase(unittest.TestCase): - - def setUp(self): - # create a base repo - self.repo_path = tempfile.mkdtemp(prefix='rpkg-commands-tests-') - - # Add spec file to this repo and commit - spec_file_path = os.path.join(self.repo_path, 'package.spec') - with open(spec_file_path, 'w') as f: - f.write(spec_file) - - git_cmds = [ - ['git', 'init'], - ['git', 'add', spec_file_path], - ['git', 'config', 'user.email', 'cqi@redhat.com'], - ['git', 'config', 'user.name', 'Chenxiong Qi'], - ['git', 'commit', '-m', '"initial commit"'], - ['git', 'branch', 'eng-rhel-6'], - ['git', 'branch', 'eng-rhel-6.5'], - ['git', 'branch', 'eng-rhel-7'], - ] - for cmd in git_cmds: - run(cmd, cwd=self.repo_path) - - # Clone the repo - self.cloned_repo_path = tempfile.mkdtemp(prefix='rpkg-commands-tests-cloned-') - git_cmds = [ - ['git', 'clone', self.repo_path, self.cloned_repo_path], - ['git', 'branch', '--track', 'eng-rhel-6', 'origin/eng-rhel-6'], - ['git', 'branch', '--track', 'eng-rhel-6.5', 'origin/eng-rhel-6.5'], - ['git', 'branch', '--track', 'eng-rhel-7', 'origin/eng-rhel-7'], - ] - for cmd in git_cmds: - run(cmd, cwd=self.cloned_repo_path) - - def tearDown(self): - shutil.rmtree(self.repo_path) - shutil.rmtree(self.cloned_repo_path) - - def make_commands(self, path=None, user=None, dist=None, target=None, quiet=None): - """Helper method for creating Commands object for test cases - - This is where you should extend to add more features to support - additional requirements from other Commands specific test cases. - - Some tests need customize one of user, dist, target, and quiet options - when creating an instance of Commands. Keyword arguments user, dist, - target, and quiet here is for this purpose. - - :param str path: path to repository where this Commands will work on - top of - :param str user: user passed to --user option - :param str dist: dist passed to --dist option - :param str target: target passed to --target option - :param str quiet: quiet passed to --quiet option - """ - _repo_path = path if path else self.cloned_repo_path - return Commands(_repo_path, - lookaside, lookasidehash, lookaside_cgi, - gitbaseurl, anongiturl, - branchre, - kojiconfig, build_client, - user=user, dist=dist, target=target, quiet=quiet) - - def checkout_branch(self, repo, branch_name): - """Checkout to a local branch - - :param git.Repo repo: `git.Repo` instance represents a git repository - that current code works on top of. - :param str branch_name: name of local branch to checkout - """ - heads = [head for head in repo.heads if head.name == branch_name] - assert len(heads) > 0, \ - 'Repo must have a local branch named {} that ' \ - 'is for running tests. But now, it does not exist. Please check ' \ - 'if the repo is correct.'.format(branch_name) - - heads[0].checkout() - - def create_branch(self, repo, branch_name): - repo.git.branch(branch_name) - - def make_a_dummy_commit(self, repo): - filename = os.path.join(repo.working_dir, 'document.txt') - with open(filename, 'a+') as f: - f.write('Hello rpkg') - repo.index.add([filename]) - repo.index.commit('update document') +from utils import CommandTestCase def mock_load_rpmdefines(self): @@ -430,3 +296,50 @@ class CheckRepoWithOrWithoutDistOptionCase(CommandTestCase): 'should not happen. Something must be going wrong.') self.fail('Should not fail. Something must be going wrong.') + + +class ClogTest(CommandTestCase): + + def setUp(self): + super(ClogTest, self).setUp() + + with open(os.path.join(self.repo_path, self.spec_file), 'w') as specfile: + specfile.write(''' +Summary: package demo +Name: pkgtool +Version: 0.1 +Release: 1%{?dist} +License: GPL +%description +package demo for testing +%changelog +* Mon Nov 07 2016 cqi@redhat.com +- add %%changelog section +- add new spec +$what_is_this + +* Mon Nov 06 2016 cqi@redhat.com +- initial +''') + + self.cmd = self.make_commands(self.repo_path) + + def test_clog(self): + self.cmd.clog() + + with open(os.path.join(self.repo_path, 'clog'), 'r') as clog: + clog_lines = clog.readlines() + + expected_lines = ['add %changelog section\n', + 'add new spec\n'] + self.assertEqual(expected_lines, clog_lines) + + def test_raw_clog(self): + self.cmd.clog(raw=True) + + with open(os.path.join(self.repo_path, 'clog'), 'r') as clog: + clog_lines = clog.readlines() + + expected_lines = ['- add %changelog section\n', + '- add new spec\n'] + self.assertEqual(expected_lines, clog_lines) diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..1ccf485 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- + +import os +import subprocess +import tempfile +import unittest +import shutil + +from pyrpkg import Commands + +# Following global variables are used to construct Commands for tests in this +# module. Only for testing purpose, and they are not going to be used for +# hitting real services. +lookaside = 'http://dist-git-qa.server/repo/pkgs' +lookaside_cgi = 'http://dist-git-qa.server/lookaside/upload.cgi' +gitbaseurl = 'ssh://%(user)s@dist-git-qa.server/rpms/%(module)s' +anongiturl = 'git://dist-git-qa.server/rpms/%(module)s' +lookasidehash = 'md5' +branchre = 'rhel' +kojiconfig = '/etc/koji.conf.d/brewstage.conf' +build_client = 'brew-stage' + +spec_file = ''' +Summary: Dummy summary +Name: docpkg +Version: 1.2 +Release: 2 +License: GPL +Group: Applications/Productivity +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +%description +This is a dummy description. +%prep +%build +%clean +rm -rf $$RPM_BUILD_ROOT +%install +rm -rf $RPM_BUILD_ROOT +mkdir $RPM_BUILD_ROOT +%files +%changelog +* Thu Apr 21 2006 Chenxiong Qi - 1.2-2 +- Initial version +''' + + +def run(cmd, **kwargs): + returncode = subprocess.call(cmd, **kwargs) + if returncode != 0: + raise RuntimeError('Command fails. Command: %s. Return code %d' % ( + ' '.join(cmd), returncode)) + + +class CommandTestCase(unittest.TestCase): + + def setUp(self): + # create a base repo + self.repo_path = tempfile.mkdtemp(prefix='rpkg-commands-tests-') + + self.spec_file = 'package.spec' + + # Add spec file to this repo and commit + spec_file_path = os.path.join(self.repo_path, self.spec_file) + with open(spec_file_path, 'w') as f: + f.write(spec_file) + + git_cmds = [ + ['git', 'init'], + ['git', 'add', spec_file_path], + ['git', 'config', 'user.email', 'cqi@redhat.com'], + ['git', 'config', 'user.name', 'Chenxiong Qi'], + ['git', 'commit', '-m', '"initial commit"'], + ['git', 'branch', 'eng-rhel-6'], + ['git', 'branch', 'eng-rhel-6.5'], + ['git', 'branch', 'eng-rhel-7'], + ] + for cmd in git_cmds: + run(cmd, cwd=self.repo_path) + + # Clone the repo + self.cloned_repo_path = tempfile.mkdtemp(prefix='rpkg-commands-tests-cloned-') + run(['git', 'clone', self.repo_path, self.cloned_repo_path]) + git_cmds = [ + ['git', 'config', 'user.email', 'cqi@redhat.com'], + ['git', 'config', 'user.name', 'Chenxiong Qi'], + ['git', 'config', 'push.default', 'simple'], + ['git', 'branch', '--track', 'eng-rhel-6', 'origin/eng-rhel-6'], + ['git', 'branch', '--track', 'eng-rhel-6.5', 'origin/eng-rhel-6.5'], + ['git', 'branch', '--track', 'eng-rhel-7', 'origin/eng-rhel-7'], + ] + for cmd in git_cmds: + run(cmd, cwd=self.cloned_repo_path) + + def tearDown(self): + shutil.rmtree(self.repo_path) + shutil.rmtree(self.cloned_repo_path) + + def make_commands(self, path=None, user=None, dist=None, target=None, quiet=None): + """Helper method for creating Commands object for test cases + + This is where you should extend to add more features to support + additional requirements from other Commands specific test cases. + + Some tests need customize one of user, dist, target, and quiet options + when creating an instance of Commands. Keyword arguments user, dist, + target, and quiet here is for this purpose. + + :param str path: path to repository where this Commands will work on + top of + :param str user: user passed to --user option + :param str dist: dist passed to --dist option + :param str target: target passed to --target option + :param str quiet: quiet passed to --quiet option + """ + _repo_path = path if path else self.cloned_repo_path + return Commands(_repo_path, + lookaside, lookasidehash, lookaside_cgi, + gitbaseurl, anongiturl, + branchre, + kojiconfig, build_client, + user=user, dist=dist, target=target, quiet=quiet) + + def checkout_branch(self, repo, branch_name): + """Checkout to a local branch + + :param git.Repo repo: `git.Repo` instance represents a git repository + that current code works on top of. + :param str branch_name: name of local branch to checkout + """ + heads = [head for head in repo.heads if head.name == branch_name] + assert len(heads) > 0, \ + 'Repo must have a local branch named {} that ' \ + 'is for running tests. But now, it does not exist. Please check ' \ + 'if the repo is correct.'.format(branch_name) + + heads[0].checkout() + + def create_branch(self, repo, branch_name): + repo.git.branch(branch_name) + + def make_a_dummy_commit(self, repo): + filename = os.path.join(repo.working_dir, 'document.txt') + with open(filename, 'a+') as f: + f.write('Hello rpkg') + repo.index.add([filename]) + repo.index.commit('update document') From e1045964036ec6dc5525bc2abc8a0c40cfcf6311 Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Nov 10 2016 07:37:19 +0000 Subject: [PATCH 2/3] More test cases for cli commands Signed-off-by: Chenxiong Qi --- diff --git a/tests/test_cli.py b/tests/test_cli.py index d5f6c6a..e29e7fe 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -152,3 +152,86 @@ class TestCommit(CliTestCase): diff_commits = repo.git.rev_list('origin/master...master') self.assertEqual('', diff_commits) + + +class TestSrpm(CliTestCase): + + def test_srpm(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'srpm']): + cli = self.new_cli() + cli.srpm() + + self.assertTrue(os.path.exists(os.path.join(self.cloned_repo_path, + 'docpkg-1.2-2.el6.src.rpm'))) + + +class TestCompile(CliTestCase): + + def test_compile(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'compile']): + cli = self.new_cli() + cli.compile() + + +class TestPrep(CliTestCase): + + def test_compile(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'prep']): + cli = self.new_cli() + cli.prep() + + +class TestInstall(CliTestCase): + + def test_compile(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'install']): + cli = self.new_cli() + cli.install() + + +class TestLocal(CliTestCase): + + def test_local(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'local']): + cli = self.new_cli() + cli.local() + + self.assertFilesExists(( + 'docpkg-1.2-2.el6.src.rpm', + 'x86_64/docpkg-1.2-2.el6.x86_64.rpm', + )) + + def test_local_with_arch(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'local', '--arch', 'i686']): + cli = self.new_cli() + cli.local() + + self.assertFilesExists(( + 'docpkg-1.2-2.el6.src.rpm', + 'i686/docpkg-1.2-2.el6.i686.rpm', + )) + + def test_local_with_builddir(self): + custom_builddir = os.path.join(self.cloned_repo_path, 'this-builddir') + + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'local', '--builddir', custom_builddir]): + cli = self.new_cli() + cli.local() + + self.assertFilesExists(('this-builddir/README.rst',)) + + +class TestVerifyFiles(CliTestCase): + + def test_verify_files(self): + with patch('sys.argv', new=['rpkg', '--path', self.cloned_repo_path, + '--release', 'rhel-6', 'verify-files']): + cli = self.new_cli() + cli.verify_files() diff --git a/tests/test_commands.py b/tests/test_commands.py index 01ffc3d..2e672d5 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -72,7 +72,7 @@ class LoadNameVerRelTest(CommandTestCase): self.assertEqual('docpkg', self.cmd._module_name_spec) self.assertEqual('0', self.cmd._epoch) self.assertEqual('1.2', self.cmd._ver) - self.assertEqual('2', self.cmd._rel) + self.assertEqual('2.el6', self.cmd._rel) def test_load_spec_where_path_contains_space(self): """Ensure load_nameverrel works with a repo whose path contains space @@ -104,7 +104,7 @@ class LoadNameVerRelTest(CommandTestCase): self.assertEqual('docpkg', cmd._module_name_spec) self.assertEqual('0', cmd._epoch) self.assertEqual('1.2', cmd._ver) - self.assertEqual('2', cmd._rel) + self.assertEqual('2.el6', cmd._rel) @patch('pyrpkg.Commands.load_rpmdefines', new=mock_load_rpmdefines) @patch('pyrpkg.Commands.load_spec', diff --git a/tests/utils.py b/tests/utils.py index 1ccf485..c386510 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -24,20 +24,21 @@ spec_file = ''' Summary: Dummy summary Name: docpkg Version: 1.2 -Release: 2 +Release: 2%{dist} License: GPL Group: Applications/Productivity BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %description This is a dummy description. %prep +%check %build +touch README.rst %clean rm -rf $$RPM_BUILD_ROOT %install -rm -rf $RPM_BUILD_ROOT -mkdir $RPM_BUILD_ROOT %files +%doc README.rst %changelog * Thu Apr 21 2006 Chenxiong Qi - 1.2-2 - Initial version @@ -51,7 +52,19 @@ def run(cmd, **kwargs): ' '.join(cmd), returncode)) -class CommandTestCase(unittest.TestCase): +class Assertions(object): + + def assertFilesExists(self, filenames): + """Assert existence of files within package repository + + :param filenames: a sequence of file names within package repository to be checked. + :type filenames: list or tuple + """ + for filename in filenames: + self.assertTrue(os.path.exists(os.path.join(self.cloned_repo_path, filename))) + + +class CommandTestCase(Assertions, unittest.TestCase): def setUp(self): # create a base repo From c5138c177d2371c2c34e510a1b0a81656cb36420 Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Nov 10 2016 07:54:52 +0000 Subject: [PATCH 3/3] Recommend --release instead of --dist Since --release is replacing --dist, to recommend --release is the right way. Signed-off-by: Chenxiong Qi --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 87246e9..2ee6a02 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -358,7 +358,7 @@ class Commands(object): try: merge = self.repo.git.config('--get', 'branch.%s.merge' % localbranch) except git.GitCommandError as e: - raise rpkgError('Unable to find remote branch. Use --dist') + raise rpkgError('Unable to find remote branch. Use --release') # Trim off the refs/heads so that we're just working with # the branch name merge = merge.replace('refs/heads/', '') @@ -694,7 +694,7 @@ class Commands(object): osver = re.search(r'rhel-\d.*$', self.branch_merge).group() except AttributeError: raise rpkgError('Could not find the base OS ver from branch name' - ' %s. Consider using --dist option' % + ' %s. Consider using --release option' % self.branch_merge) self._distvar, self._distval = osver.split('-') self._distval = self._distval.replace('.', '_')