def test_git_message_opts(self, repo, make_git_repo, tmp_path): """Verify message-related options are passed through to `git commit`.""" git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0', commit=False) path = str(tmp_path / 'msg') with open(path, 'w') as f: f.write('commit1') with patch('sys.argv', self.args + ['-u', '-F', path]), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 0 commit_msg = git_repo.log(['-1', '--pretty=tformat:%B', 'HEAD']) assert commit_msg == ['commit1'] repo.create_ebuild('cat/pkg-1') git_repo.add_all('cat/pkg-1', commit=False) with os_environ(GIT_EDITOR="sed -i '1s/1/2/'"), \ patch('sys.argv', self.args + ['-u', '-t', path]), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 0 commit_msg = git_repo.log(['-1', '--pretty=tformat:%B', 'HEAD']) assert commit_msg == ['commit2']
def test_failed_scan(self, capsys, repo, make_git_repo): git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0') # verify staged changes via `pkgcheck scan` before creating commit repo.create_ebuild('cat/pkg-1', license='') git_repo.add_all('cat/pkg-1', commit=False) with patch('sys.argv', self.args + ['--scan']), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 1 out, err = capsys.readouterr() assert not err assert out == textwrap.dedent("""\ cat/pkg MissingLicense: version 1: no license defined FAILURES cat/pkg MissingLicense: version 1: no license defined """) # ignore failures to create the commit with patch('sys.argv', self.args + ['--scan', '--ask']), \ patch('sys.stdin', StringIO('y\n')), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 0
def test_failed_push(self, capsys): self.child_repo.create_ebuild('cat/pkg-1', eapi='-1') self.child_git_repo.add_all('cat/pkg-1') # failed scans don't push commits with patch('sys.argv', self.args), \ pytest.raises(SystemExit) as excinfo, \ chdir(self.child_git_repo.path): self.script() assert excinfo.value.code == 1 out, err = capsys.readouterr() assert out == textwrap.dedent("""\ cat/pkg InvalidEapi: version 1: invalid EAPI '-1' FAILURES cat/pkg InvalidEapi: version 1: invalid EAPI '-1' """) # but failures can be ignored to push anyway with patch('sys.argv', self.args + ['--ask']), \ patch('sys.stdin', StringIO('y\n')), \ pytest.raises(SystemExit) as excinfo, \ chdir(self.child_git_repo.path): self.script() assert excinfo.value.code == 0
def test_scan_args(self, repo, make_git_repo, tool): git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0', commit=False) # pkgcheck isn't run in verbose mode by default with chdir(repo.location): options, _ = tool.parse_args(['commit']) assert '-v' not in options.scan_args # verbosity level is passed down to pkgcheck with chdir(repo.location): options, _ = tool.parse_args(['commit', '-v']) assert '-v' in options.scan_args
def run(self): try: import pytest except ImportError: raise DistutilsExecError('pytest is not installed') if self.skip_build: builddir = MODULEDIR else: # build extensions and byte-compile python build_ext = self.reinitialize_command('build_ext') build_py = self.reinitialize_command('build_py') build_ext.ensure_finalized() build_py.ensure_finalized() self.run_command('build_ext') self.run_command('build_py') builddir = os.path.abspath(build_py.build_lib) # force reimport of project from builddir sys.modules.pop(MODULE_NAME, None) with syspath(builddir): from snakeoil.contexts import chdir # Change the current working directory to the builddir during testing # so coverage paths are correct. with chdir(builddir): ret = pytest.main(self.test_args) sys.exit(ret)
def test_chdir(tmpdir): orig_cwd = os.getcwd() with chdir(str(tmpdir)): assert orig_cwd != os.getcwd() assert orig_cwd == os.getcwd()
def test_dir_target(self, repo, capsys, tool): repo.create_ebuild('cat/pkg-0') with chdir(repo.location): options, _ = tool.parse_args( ['manifest', pjoin(repo.location, 'cat')]) matches = [x.cpvstr for x in repo.itermatch(options.restriction)] assert matches == ['cat/pkg-0']
def test_chdir(self): orig_cwd = os.getcwd() with chdir(self.dir): self.assertNotEqual(orig_cwd, os.getcwd()) self.assertEqual(orig_cwd, os.getcwd())
def __call__(self, ebd): self.opts = arghparse.Namespace() self.ebd = ebd ret = 0 # read info from bash side nonfatal = self.read() == 'true' self.cwd = self.read() options = shlex.split(self.read()) args = self.read().strip('\0') args = args.split('\0') if args else [] # parse args and run command with chdir(self.cwd): try: args = self.parse_args(options, args) ret = self.run(args) except IpcCommandError as e: if nonfatal: ret = (e.code, e.msg) else: raise IpcCommandError(msg=e.msg, code=e.code, name=self.name) except KeyboardInterrupt: raise except Exception as e: raise IpcInternalError('internal failure') from e # return completion status to the bash side self.write(self._encode_ret(ret))
def test_non_git_repo_cwd(self, repo, capsys, tool): with pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): tool.parse_args(['commit']) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.strip() == 'pkgdev commit: error: not in git repo'
def test_commit_signing(self, repo, make_git_repo, tool): git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0', commit=False) # signed commits aren't enabled by default with chdir(repo.location): options, _ = tool.parse_args(['commit', '-u']) assert '--signoff' not in options.commit_args assert '--gpg-sign' not in options.commit_args # signed commits enabled by layout.conf setting with open(pjoin(git_repo.path, 'metadata/layout.conf'), 'a+') as f: f.write('sign-commits = true\n') with chdir(repo.location): options, _ = tool.parse_args(['commit', '-u']) assert '--signoff' in options.commit_args assert '--gpg-sign' in options.commit_args
def test_successful_run(self, git_repo): with chdir(git_repo.path): p = git.run('rev-parse', '--abbrev-ref', 'HEAD', stdout=subprocess.PIPE) assert p.stdout.strip() == 'main'
def test_mask_ebuild_path(self): with os_environ(EDITOR="sed -i '1s/$/mask comment/'"), \ patch('sys.argv', self.args + ['cat/pkg/pkg-0.ebuild']), \ pytest.raises(SystemExit), \ chdir(pjoin(self.repo.path)): self.script() assert self.profile.masks == frozenset([atom_cls('=cat/pkg-0')])
def test_selected_targets(self, fakerepo): # selected repo options, _func = self.tool.parse_args(self.args + ['-r', 'stubrepo']) assert options.target_repo.repo_id == 'stubrepo' assert options.restrictions == [(base.repository_scope, packages.AlwaysTrue)] # dir path options, _func = self.tool.parse_args(self.args + [fakerepo]) assert options.target_repo.repo_id == 'fakerepo' assert options.restrictions == [(base.repository_scope, packages.AlwaysTrue)] # file path os.makedirs(pjoin(fakerepo, 'dev-util', 'foo')) ebuild_path = pjoin(fakerepo, 'dev-util', 'foo', 'foo-0.ebuild') touch(ebuild_path) options, _func = self.tool.parse_args(self.args + [ebuild_path]) restrictions = [ restricts.CategoryDep('dev-util'), restricts.PackageDep('foo'), restricts.VersionMatch('=', '0'), ] assert list(options.restrictions) == [ (base.version_scope, packages.AndRestriction(*restrictions)) ] assert options.target_repo.repo_id == 'fakerepo' # cwd path in unconfigured repo with chdir(pjoin(fakerepo, 'dev-util', 'foo')): options, _func = self.tool.parse_args(self.args) assert options.target_repo.repo_id == 'fakerepo' restrictions = [ restricts.CategoryDep('dev-util'), restricts.PackageDep('foo'), ] assert list(options.restrictions) == [ (base.package_scope, packages.AndRestriction(*restrictions)) ] # cwd path in configured repo stubrepo = pjoin(pkgcore_const.DATA_PATH, 'stubrepo') with chdir(stubrepo): options, _func = self.tool.parse_args(self.args) assert options.target_repo.repo_id == 'stubrepo' assert list(options.restrictions) == [(base.repository_scope, packages.AlwaysTrue)]
def test_empty_mask_comment(self, capsys): with os_environ(EDITOR="sed -i 's/#/#/'"), \ patch('sys.argv', self.args + ['cat/pkg']), \ pytest.raises(SystemExit), \ chdir(pjoin(self.repo.path)): self.script() out, err = capsys.readouterr() assert err.strip() == "pkgdev mask: error: empty mask comment"
def test_non_ebuild_git_repo_cwd(self, make_repo, git_repo, capsys, tool): os.mkdir(pjoin(git_repo.path, 'repo')) repo = make_repo(pjoin(git_repo.path, 'repo')) with pytest.raises(SystemExit), \ chdir(repo.location): tool.parse_args(['push']) out, err = capsys.readouterr() assert err.strip() == 'pkgdev push: error: not in ebuild git repo'
def test_bad_repo_cwd(self, make_repo, capsys, tool): repo = make_repo(masters=('nonexistent', )) with pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): tool.parse_args(['commit']) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.strip().startswith('pkgdev commit: error: repo init failed')
def test_invalid_atom_target(self, repo, capsys, tool): with pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): tool.parse_args(['manifest', '=cat/pkg']) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.startswith( "pkgdev manifest: error: invalid atom: '=cat/pkg'")
def test_nonexistent_editor(self, capsys): with os_environ(EDITOR='12345'), \ patch('sys.argv', self.args + ['cat/pkg']), \ pytest.raises(SystemExit), \ chdir(pjoin(self.repo.path)): self.script() out, err = capsys.readouterr() assert err.strip() == "pkgdev mask: error: nonexistent editor: '12345'"
def test_non_repo_dir_target(self, tmp_path, repo, capsys, tool): with pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): tool.parse_args(['manifest', str(tmp_path)]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.startswith( "pkgdev manifest: error: 'fake' repo doesn't contain:")
def test_commit_tags(self, capsys, repo, make_git_repo, tool): git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0', commit=False) with chdir(repo.location): # bug IDs for opt in ('-b', '--bug'): options, _ = tool.parse_args(['commit', opt, '1']) assert options.footer == {('Bug', 'https://bugs.gentoo.org/1')} # bug URLs for opt in ('-b', '--bug'): options, _ = tool.parse_args( ['commit', opt, 'https://bugs.gentoo.org/2']) assert options.footer == {('Bug', 'https://bugs.gentoo.org/2')} # bug IDs for opt in ('-c', '--closes'): options, _ = tool.parse_args(['commit', opt, '1']) assert options.footer == {('Closes', 'https://bugs.gentoo.org/1')} # bug URLs for opt in ('-c', '--closes'): options, _ = tool.parse_args( ['commit', opt, 'https://bugs.gentoo.org/2']) assert options.footer == {('Closes', 'https://bugs.gentoo.org/2')} # bad URL for opt in ('-b', '-c'): with pytest.raises(SystemExit) as excinfo: tool.parse_args(['commit', opt, 'bugs.gentoo.org/1']) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out assert 'invalid URL: bugs.gentoo.org/1' in err # generic tags for opt in ('-T', '--tag'): for value, expected in ( ('tag:value', ('Tag', 'value')), ('tag:multiple values', ('Tag', 'multiple values')), ('tag:multiple:values', ('Tag', 'multiple:values')), ): options, _ = tool.parse_args(['commit', opt, value]) assert options.footer == {expected} # bad tags for opt in ('-T', '--tag'): for value in ('', ':', 'tag:', ':value', 'tag'): with pytest.raises(SystemExit) as excinfo: tool.parse_args(['commit', opt, value]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out assert 'invalid commit tag' in err
def test_git_push_args_passthrough(self, repo, make_git_repo, tool): """Unknown arguments for ``pkgdev push`` are passed to ``git push``.""" git_repo = make_git_repo(repo.location) with chdir(git_repo.path): options, _ = tool.parse_args(['push', 'origin', 'main']) assert options.push_args == ['origin', 'main'] options, _ = tool.parse_args(['push', '-n', '--signed']) assert '--dry-run' in options.push_args assert '--signed' in options.push_args
def test_non_ebuild_git_repo_cwd(self, make_repo, git_repo, capsys, tool): os.mkdir(pjoin(git_repo.path, 'repo')) repo = make_repo(pjoin(git_repo.path, 'repo')) with pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): tool.parse_args(['commit']) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.strip() == 'pkgdev commit: error: not in ebuild git repo'
def test_push(self, capsys): self.child_repo.create_ebuild('cat/pkg-1') self.child_git_repo.add_all('cat/pkg-1') with patch('sys.argv', self.args), \ pytest.raises(SystemExit) as excinfo, \ chdir(self.child_git_repo.path): self.script() assert excinfo.value.code == 0
def test_git_commit_args_passthrough(self, repo, make_git_repo, tool): """Unknown arguments for ``pkgdev commit`` are passed to ``git commit``.""" git_repo = make_git_repo(repo.location) repo.create_ebuild('cat/pkg-0') git_repo.add_all('cat/pkg-0', commit=False) with chdir(repo.location): for opt in ('--author="A U Thor <*****@*****.**>"', '-e'): options, _ = tool.parse_args(['commit', opt]) assert options.commit_args == [opt]
def test_good_manifest(self, capsys, repo): repo.create_ebuild('cat/pkg-0') with patch('sys.argv', self.args), \ pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): self.script() assert excinfo.value.code == 0 out, err = capsys.readouterr() assert out == err == ''
def test_empty_repo(self, capsys, repo, make_git_repo): git_repo = make_git_repo(repo.location) with patch('sys.argv', self.args), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out assert err.strip() == 'pkgdev commit: error: no staged changes exist'
def commit(): with patch('sys.argv', self.args + ['-a', '-m', 'msg']), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 0 out, err = capsys.readouterr() assert err == out == '' message = git_repo.log(['-1', '--pretty=tformat:%B', 'HEAD']) return message[0]
def test_bad_manifest(self, capsys, repo): repo.create_ebuild('cat/pkg-0') repo.create_ebuild('cat/pkg-1', eapi='-1') with patch('sys.argv', self.args), \ pytest.raises(SystemExit) as excinfo, \ chdir(repo.location): self.script() assert excinfo.value.code == 1 out, err = capsys.readouterr() assert not err assert out == " * cat/pkg-1: invalid EAPI '-1'\n"
def commit(): with os_environ(GIT_EDITOR="sed -i '1s/$/summary/'"), \ patch('sys.argv', self.args + ['-a']), \ pytest.raises(SystemExit) as excinfo, \ chdir(git_repo.path): self.script() assert excinfo.value.code == 0 out, err = capsys.readouterr() assert err == out == '' message = git_repo.log(['-1', '--pretty=tformat:%B', 'HEAD']) return message[0]
def run(self, args): dest_dir = args.target.rsplit(os.path.sep, 1)[0] if dest_dir != args.target: self.install_dirs([dest_dir]) target = pjoin(self.op.ED, args.target.lstrip(os.path.sep)) with chdir(self.op.ED): try: try: self._link(args.source, target) except FileExistsError: # overwrite target if it exists os.unlink(target) self._link(args.source, target) except OSError as e: raise IpcCommandError( f'failed creating link: {args.source!r} -> {args.target!r}: {e.strerror}')
def setup(self): """Execute the setup phase, mapping out to pkg_setup in the ebuild. Necessarily dirs are created as required, and build env is initialized at this point. """ if self.distcc: for p in ("", "/lock", "/state"): if not ensure_dirs(pjoin(self.env["DISTCC_DIR"], p), mode=0o2775, gid=portage_gid): raise format.FailedDirectory( pjoin(self.env["DISTCC_DIR"], p), "failed creating needed distcc directory") if self.ccache: # yuck. st = None try: st = os.stat(self.env["CCACHE_DIR"]) except OSError as e: st = None if not ensure_dirs(self.env["CCACHE_DIR"], mode=0o2775, gid=portage_gid): raise format.FailedDirectory( self.env["CCACHE_DIR"], "failed creation of ccache dir") from e # XXX this is more then mildly stupid. st = os.stat(self.env["CCACHE_DIR"]) try: if st.st_gid != portage_gid or (st.st_mode & 0o2775) != 0o2775: try: cwd = os.getcwd() except OSError: cwd = "/" with chdir(cwd): # crap. os.chmod(self.env["CCACHE_DIR"], 0o2775) os.chown(self.env["CCACHE_DIR"], -1, portage_gid) if 0 != spawn( ["chgrp", "-R", str(portage_gid), self.env["CCACHE_DIR"]]): raise format.FailedDirectory( self.env["CCACHE_DIR"], "failed changing ownership for CCACHE_DIR") if 0 != spawn_bash( "find '%s' -type d -print0 | %s --null chmod 02775" % (self.env["CCACHE_DIR"], xargs)): raise format.FailedDirectory( self.env["CCACHE_DIR"], "failed correcting perms for CCACHE_DIR") if 0 != spawn_bash( "find '%s' -type f -print0 | %s --null chmod 0775" % (self.env["CCACHE_DIR"], xargs)): raise format.FailedDirectory( self.env["CCACHE_DIR"], "failed correcting perms for CCACHE_DIR") except OSError as e: raise format.FailedDirectory( self.env["CCACHE_DIR"], "failed ensuring perms/group owner for CCACHE_DIR") from e return setup_mixin.setup(self)