Skip to content

Commit

Permalink
Cleanup branch protections to take into account user branch names
Browse files Browse the repository at this point in the history
(feature/95_branch_names)
  • Loading branch information
Nicholas Wiles committed Mar 24, 2018
1 parent a934360 commit a4e6468
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 43 deletions.
20 changes: 20 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,23 @@ def test_config_create(mocker, tmp_dir):
result = runner.invoke(zazu.cli.cli, ['config', '--list'])
assert result.exit_code == 0
assert os.path.isfile(path)


def test_branch_names(git_repo):
with zazu.util.cd(git_repo.working_tree_dir):
uut = zazu.config.Config('')
assert uut.develop_branch_name() == 'develop'
assert uut.master_branch_name() == 'master'


def test_alt_branch_names(git_repo):
with zazu.util.cd(git_repo.working_tree_dir):
with open('zazu.yaml', 'w') as file:
config = {
'branches': {'develop': 'alt_develop',
'master': 'alt_master'}
}
yaml.dump(config, file)
uut = zazu.config.Config('')
assert uut.develop_branch_name() == 'alt_develop'
assert uut.master_branch_name() == 'alt_master'
25 changes: 15 additions & 10 deletions tests/test_git_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,18 @@ def test_touched_files(git_repo):
assert len(zazu.git_helper.get_touched_files(git_repo)) == 2


def test_get_merged_branches(git_repo):
merged = zazu.git_helper.get_merged_branches(git_repo, 'master')
assert merged == ['master']
zazu.git_helper.get_merged_branches(git_repo, 'master', True)
assert merged == ['master']


def test_git_filter_undeletable():
some_branches = ['-', 'master', 'develop', '*current', 'HEAD', 'origin/HEAD', 'feature/foo']
assert zazu.git_helper.filter_undeletable(some_branches) == ['feature/foo']
def test_merged_branches(git_repo):
with zazu.util.cd(git_repo.working_tree_dir):
git_repo.create_head('foo').checkout()
with open('test', 'w') as f:
pass
git_repo.index.add(['test'])
git_repo.index.commit('commit')
git_repo.git.checkout('master')
merged = zazu.git_helper.merged_branches(git_repo, 'master')
assert not merged
git_repo.git.merge('foo')
merged = zazu.git_helper.merged_branches(git_repo, 'master')
assert merged == {'foo'}
zazu.git_helper.merged_branches(git_repo, 'master', True)
assert merged == {'foo'}
8 changes: 4 additions & 4 deletions tests/test_repo_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ def test_cleanup(git_repo):
git_repo.git.commit('-am', 'touch readme')
git_repo.git.checkout('master')
git_repo.git.merge('feature/F00-1')
assert 'feature/F00-1' in zazu.git_helper.get_merged_branches(git_repo, 'master')
assert 'feature/F00-1' in zazu.git_helper.merged_branches(git_repo, 'master')
runner = click.testing.CliRunner()
result = runner.invoke(zazu.cli.cli, ['repo', 'cleanup', '-b', 'master', '-y'])
assert result.exit_code == 0
assert not result.exception
assert 'feature/F00-1' not in zazu.git_helper.get_merged_branches(git_repo, 'master')
assert 'feature/F00-1' not in zazu.git_helper.merged_branches(git_repo, 'master')


def test_cleanup_remote(git_repo_with_local_origin, mocker):
Expand All @@ -77,12 +77,12 @@ def test_cleanup_remote(git_repo_with_local_origin, mocker):
git_repo.git.checkout('master')
git_repo.git.merge('feature/F00-1')
git_repo.git.push('--all', 'origin')
assert 'feature/F00-1' in zazu.git_helper.get_merged_branches(git_repo, 'origin/master')
assert 'feature/F00-1' in zazu.git_helper.merged_branches(git_repo, 'origin/master')
runner = click.testing.CliRunner()
result = runner.invoke(zazu.cli.cli, ['repo', 'cleanup', '-y', '-r'])
assert result.exit_code == 0
assert not result.exception
assert 'feature/F00-1' not in zazu.git_helper.get_merged_branches(git_repo, 'origin/master')
assert 'feature/F00-1' not in zazu.git_helper.merged_branches(git_repo, 'origin/master')


def test_descriptors_from_branches():
Expand Down
11 changes: 9 additions & 2 deletions zazu/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,18 +290,25 @@ def stylers(self):

def develop_branch_name(self):
try:
return self.project_config().get('branches', {})['develop']
return self.project_config()['branches']['develop']
except (click.ClickException, KeyError):
pass
return 'develop'

def master_branch_name(self):
try:
return self.project_config().get('branches', {})['master']
return self.project_config()['branches']['master']
except (click.ClickException, KeyError):
pass
return 'master'

def protected_branches(self):
"""Return set of protected branches that can't be deleted."""
develop = self.develop_branch_name()
master = self.master_branch_name()
return {develop, 'origin/{}'.format(develop),
master, 'origin/{}'.format(master)}

def zazu_version_required(self):
"""Return the version of zazu requested by the config file."""
return self.project_config().get('zazu', '')
Expand Down
22 changes: 3 additions & 19 deletions zazu/git_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,12 @@ def install_git_hook(hooks_folder, hook_name, hook_resource_path):
shutil.copy(hook_resource_path, hook_path)


def parse_branch_return_list(branches):
"""Parse return from git branch into list of branch names."""
ret = branches
for i, branch in enumerate(ret):
if branch.startswith('* '):
ret[i] = branch[2:]
break
return ret


def get_merged_branches(repo, target_branch, remote=False):
"""Return list of branches that have been merged with the target_branch."""
def merged_branches(repo, target_branch, remote=False):
"""Return set of branches that have been merged with the target_branch."""
args = ['--merged', target_branch]
if remote:
args.insert(0, '-r')
return parse_branch_return_list([b.strip() for b in repo.git.branch(args).strip().split('\n') if b])


def filter_undeletable(branches):
"""Filter out branches that we don't want to delete."""
undeletable = set(['master', 'develop', 'origin/develop', 'origin/master', '-', 'HEAD'])
return [b for b in branches if (b not in undeletable) and (not b.startswith('*')) and (not b.startswith('origin/HEAD'))]
return {b.strip() for b in repo.git.branch(args).strip().split('\n') if b and not b.startswith('*')}


def read_staged(path):
Expand Down
17 changes: 9 additions & 8 deletions zazu/repo/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,27 +93,28 @@ def cleanup(ctx, remote, target_branch, yes):
issue_tracker = ctx.obj.issue_tracker()
except click.ClickException:
issue_tracker = None
closed_branches = set([])
closed_branches = set()
protected_branches = ctx.obj.protected_branches()
if remote:
repo_obj.git.fetch('--prune')
remote_branches = zazu.git_helper.filter_undeletable([b.name for b in repo_obj.remotes.origin.refs])
remote_branches = {b.name for b in repo_obj.remotes.origin.refs} - protected_branches
if issue_tracker is not None:
closed_branches = set(get_closed_branches(issue_tracker, remote_branches))
merged_remote_branches = zazu.git_helper.filter_undeletable(zazu.git_helper.get_merged_branches(repo_obj, target_branch, remote=True))
merged_remote_branches = [b.replace('origin/', '') for b in merged_remote_branches]
branches_to_delete = set(merged_remote_branches) | closed_branches
merged_remote_branches = zazu.git_helper.merged_branches(repo_obj, target_branch, remote=True) - protected_branches
merged_remote_branches = {b.replace('origin/', '') for b in merged_remote_branches}
branches_to_delete = merged_remote_branches | closed_branches
if branches_to_delete:
confirmation = 'These remote branches will be deleted: {} Proceed?'.format(zazu.util.pprint_list(branches_to_delete))
if yes or click.confirm(confirmation):
for b in branches_to_delete:
click.echo('Deleting {}'.format(b))
repo_obj.git.push('-df', 'origin', *branches_to_delete)
merged_branches = zazu.git_helper.filter_undeletable(zazu.git_helper.get_merged_branches(repo_obj, target_branch))
local_branches = set(zazu.git_helper.filter_undeletable([b.name for b in repo_obj.heads]))
merged_branches = zazu.git_helper.merged_branches(repo_obj, target_branch) - protected_branches
local_branches = {b.name for b in repo_obj.heads} - protected_branches
if issue_tracker is not None:
branches_to_check = local_branches - closed_branches
closed_branches |= set(get_closed_branches(issue_tracker, branches_to_check))
branches_to_delete = (closed_branches & local_branches) | set(merged_branches)
branches_to_delete = (closed_branches & local_branches) | merged_branches
if branches_to_delete:
confirmation = 'These local branches will be deleted: {}\n Proceed?'.format(zazu.util.pprint_list(branches_to_delete))
if yes or click.confirm(confirmation):
Expand Down

0 comments on commit a4e6468

Please sign in to comment.