def test_branch_tags(local): """Test with branches and tags. :param local: conftest fixture. """ sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip() remotes = list_remote(str(local)) expected = [ [sha, 'feature', 'heads'], [sha, 'master', 'heads'], [sha, 'annotated_tag', 'tags'], [sha, 'light_tag', 'tags'], ] assert remotes == expected # New commit to master locally. local.join('README').write('changed') pytest.run(local, ['git', 'commit', '-am', 'Changed']) remotes = list_remote(str(local)) assert remotes == expected # Push. pytest.run(local, ['git', 'push', 'origin', 'master']) sha2 = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip() remotes = list_remote(str(local)) expected = [ [sha, 'feature', 'heads'], [sha2, 'master', 'heads'], [sha, 'annotated_tag', 'tags'], [sha, 'light_tag', 'tags'], ] assert remotes == expected
def test_empty_remote(local_commit, remote): """Test with valid but empty remote. :param local_commit: conftest fixture. :param remote: conftest fixture. """ pytest.run(local_commit, ['git', 'remote', 'add', 'origin', remote]) remotes = list_remote(str(local_commit)) assert not remotes # Push. pytest.run(local_commit, ['git', 'push', 'origin', 'master']) remotes = list_remote(str(local_commit)) assert [i[1:] for i in remotes] == [['master', 'heads']]
def test_new_branch_tags(tmpdir, local_light, fail): """Test with new branches and tags unknown to local repo. :param tmpdir: pytest fixture. :param local_light: conftest fixture. :param bool fail: Fail by not fetching. """ remotes = [r for r in list_remote(str(local_light)) if r[1] == 'ob_at'] # Fail. sha = remotes[0][0] target = tmpdir.ensure_dir('exported', sha) if fail: with pytest.raises(CalledProcessError): export(str(local_light), sha, str(target)) return # Fetch. fetch_commits(str(local_light), remotes) # Export. export(str(local_light), sha, str(target)) files = [f.relto(target) for f in target.listdir()] assert files == ['README'] assert target.join('README').read() == 'new'
def gather_git_info(root, conf_rel_paths, whitelist_branches, whitelist_tags): """Gather info about the remote git repository. Get list of refs. :raise HandledError: If function fails with a handled error. Will be logged before raising. :param str root: Root directory of repository. :param iter conf_rel_paths: List of possible relative paths (to git root) of Sphinx conf.py (e.g. docs/conf.py). :param iter whitelist_branches: Optional list of patterns to filter branches by. :param iter whitelist_tags: Optional list of patterns to filter tags by. :return: Commits with docs. A list of tuples: (sha, name, kind, date, conf_rel_path). :rtype: list """ log = logging.getLogger(__name__) # List remote. log.info('Getting list of all remote branches/tags...') try: remotes = list_remote(root) except GitError as exc: log.error(exc.message) log.error(exc.output) raise HandledError log.info('Found: %s', ' '.join(i[1] for i in remotes)) # Filter and date. try: try: dates_paths = filter_and_date(root, conf_rel_paths, (i[0] for i in remotes)) except GitError: log.info('Need to fetch from remote...') fetch_commits(root, remotes) try: dates_paths = filter_and_date(root, conf_rel_paths, (i[0] for i in remotes)) except GitError as exc: log.error(exc.message) log.error(exc.output) raise HandledError except subprocess.CalledProcessError as exc: log.debug(json.dumps(dict(command=exc.cmd, cwd=root, code=exc.returncode, output=exc.output))) log.error('Failed to get dates for all remote commits.') raise HandledError filtered_remotes = [[i[0], i[1], i[2], ] + dates_paths[i[0]] for i in remotes if i[0] in dates_paths] log.info('With docs: %s', ' '.join(i[1] for i in filtered_remotes)) if not whitelist_branches and not whitelist_tags: return filtered_remotes # Apply whitelist. whitelisted_remotes = list() for remote in filtered_remotes: if remote[2] == 'heads' and whitelist_branches: if not any(re.search(p, remote[1]) for p in whitelist_branches): continue if remote[2] == 'tags' and whitelist_tags: if not any(re.search(p, remote[1]) for p in whitelist_tags): continue whitelisted_remotes.append(remote) log.info('Passed whitelisting: %s', ' '.join(i[1] for i in whitelisted_remotes)) return whitelisted_remotes
def test_outdated_local(tmpdir, local, remote): """Test with remote changes not pulled. :param tmpdir: pytest fixture. :param local: conftest fixture. :param remote: conftest fixture. """ # Commit to separate local repo and push to common remote. local_ahead = tmpdir.ensure_dir('local_ahead') pytest.run(local_ahead, ['git', 'clone', remote, '.']) local_ahead.join('README').write('changed') pytest.run(local_ahead, ['git', 'commit', '-am', 'Changed master']) pytest.run(local_ahead, ['git', 'checkout', 'feature']) local_ahead.join('README').write('changed') pytest.run(local_ahead, ['git', 'commit', '-am', 'Changed feature']) pytest.run(local_ahead, ['git', 'push', 'origin', 'master', 'feature']) # Commits not fetched. remotes = list_remote(str(local)) shas = [r[0] for r in remotes] with pytest.raises(GitError): filter_and_date(str(local), ['README'], shas) # Pull and retry. pytest.run(local, ['git', 'pull', 'origin', 'master']) pytest.run(local, ['git', 'checkout', 'feature']) pytest.run(local, ['git', 'pull', 'origin', 'feature']) dates = filter_and_date(str(local), ['README'], shas) assert len( dates ) == 3 # Original SHA is the same for everything. Plus above two commits.
def test_new_branch_tags(local, local_light, clone_branch): """Test with new branches and tags unknown to local repo. :param local: conftest fixture. :param local_light: conftest fixture. :param bool clone_branch: Test with local repo cloned with --branch. """ if clone_branch: local = local_light # Get SHAs and verify not fetched. remotes = list_remote(str(local)) assert len( remotes ) == 7 # master feature light_tag annotated_tag nb_tag orphaned_branch ob_at shas = {r[0] for r in remotes} assert len(shas) == 3 with pytest.raises(GitError): filter_and_date(str(local), ['README'], shas) # Fetch and verify. fetch_commits(str(local), remotes) dates = filter_and_date(str(local), ['README'], shas) assert len(dates) == 3 pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])
def test_fetch_existing(local): """Fetch commit that is already locally available. :param local: conftest fixture. """ remotes = list_remote(str(local)) fetch_commits(str(local), remotes) pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--']) # Exit 0 if nothing changed.
def test_fetch_existing(local): """Fetch commit that is already locally available. :param local: conftest fixture. """ remotes = list_remote(str(local)) fetch_commits(str(local), remotes) pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--' ]) # Exit 0 if nothing changed.
def test_outdated_local(tmpdir, local, remote): """Test with remote changes not pulled. :param tmpdir: pytest fixture. :param local: conftest fixture. :param remote: conftest fixture. """ # Setup separate local repo now before pushing changes to it from the primary local repo. local_outdated = tmpdir.ensure_dir('local_outdated') pytest.run(local_outdated, ['git', 'clone', '--branch', 'master', remote, '.']) sha = pytest.run(local_outdated, ['git', 'rev-parse', 'HEAD']).strip() remotes = list_remote(str(local_outdated)) expected = [ [sha, 'feature', 'heads'], [sha, 'master', 'heads'], [sha, 'annotated_tag', 'tags'], [sha, 'light_tag', 'tags'], ] assert remotes == expected # Make changes from primary local and push to common remote. local.join('README').write('changed') pytest.run(local, ['git', 'commit', '-am', 'Changed']) pytest.run(local, ['git', 'push', 'origin', 'master']) sha2 = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip() remotes = list_remote(str(local)) expected = [ [sha, 'feature', 'heads'], [sha2, 'master', 'heads'], [sha, 'annotated_tag', 'tags'], [sha, 'light_tag', 'tags'], ] assert remotes == expected # Run list_remote() on outdated repo and verify it still gets latest refs. remotes = list_remote(str(local_outdated)) assert remotes == expected
def test_new_branch_tags(local, local_light, clone_branch): """Test with new branches and tags unknown to local repo. :param local: conftest fixture. :param local_light: conftest fixture. :param bool clone_branch: Test with local repo cloned with --branch. """ if clone_branch: local = local_light # Get SHAs and verify not fetched. remotes = list_remote(str(local)) assert len(remotes) == 7 # master feature light_tag annotated_tag nb_tag orphaned_branch ob_at shas = {r[0] for r in remotes} assert len(shas) == 3 with pytest.raises(GitError): filter_and_date(str(local), ['README'], shas) # Fetch and verify. fetch_commits(str(local), remotes) dates = filter_and_date(str(local), ['README'], shas) assert len(dates) == 3 pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])
def test_bad_remote(tmpdir, local_empty): """Test with no/invalid remote. :param tmpdir: pytest fixture. :param local_empty: conftest fixture. """ # Test no remotes. with pytest.raises(GitError) as exc: list_remote(str(local_empty)) assert 'No remote configured to list refs from.' in exc.value.output # Test wrong name. pytest.run(local_empty, ['git', 'remote', 'add', 'something', tmpdir.ensure_dir('empty')]) with pytest.raises(GitError) as exc: list_remote(str(local_empty)) assert 'No remote configured to list refs from.' in exc.value.output # Invalid remote. pytest.run(local_empty, ['git', 'remote', 'rename', 'something', 'origin']) with pytest.raises(GitError) as exc: list_remote(str(local_empty)) assert 'does not appear to be a git repository' in exc.value.output