Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add force and prune checkbox #60

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ protected static class MirrorSettings {
boolean tags;
boolean notes;
boolean atomic;
boolean prune;
boolean force;
}

public static final String PLUGIN_SETTINGS_KEY = "com.englishtown.stash.hook.mirror";
Expand All @@ -49,6 +51,8 @@ protected static class MirrorSettings {
static final String SETTING_TAGS = "tags";
static final String SETTING_NOTES = "notes";
static final String SETTING_ATOMIC = "atomic";
static final String SETTING_PRUNE = "prune";
static final String SETTING_FORCE = "force";
static final int MAX_ATTEMPTS = 5;
static final String DEFAULT_REFSPEC = "+refs/heads/*:refs/heads/*";

Expand Down Expand Up @@ -137,18 +141,26 @@ public void run() {
GitScmCommandBuilder builder = (GitScmCommandBuilder) obj;
PasswordHandler passwordHandler = getPasswordHandler(builder, password);

// Call push command with the prune flag and refspecs for heads and tags
// Call push command with the refspecs for heads and tags
// Do not use the mirror flag as pull-request refs are included
builder.command("push")
.argument("--prune") // this deletes locally deleted branches
.argument(authenticatedUrl)
.argument("--force");
builder.command("push");

// this deletes locally deleted branches
if (settings.prune) {
builder.argument("--prune");
}

// Use an atomic transaction to have a consistent state
if (settings.atomic) {
builder.argument("--atomic");
}

builder.argument(authenticatedUrl);

if (settings.force) {
builder.argument("--force");
}

// Add refspec args
String refspecs = Strings.isNullOrEmpty(settings.refspec) ? DEFAULT_REFSPEC : settings.refspec;
for (String refspec : refspecs.split("\\s|\\n")) {
Expand Down Expand Up @@ -224,7 +236,7 @@ public void validate(
boolean ok = true;
logger.debug("MirrorRepositoryHook: validate started.");

List<MirrorSettings> mirrorSettings = getMirrorSettings(settings, false, false, false);
List<MirrorSettings> mirrorSettings = getMirrorSettings(settings, false, false, false, false, false);

for (MirrorSettings ms : mirrorSettings) {
if (!validate(ms, settings, errors)) {
Expand All @@ -248,10 +260,10 @@ public void validate(
}

protected List<MirrorSettings> getMirrorSettings(Settings settings) {
return getMirrorSettings(settings, true, true, true);
return getMirrorSettings(settings, true, true, true, true, true);
}

protected List<MirrorSettings> getMirrorSettings(Settings settings, boolean defTags, boolean defNotes, boolean defAtomic) {
protected List<MirrorSettings> getMirrorSettings(Settings settings, boolean defTags, boolean defNotes, boolean defAtomic, boolean defPrune, boolean defForce) {

List<MirrorSettings> results = new ArrayList<>();
Map<String, Object> allSettings = settings.asMap();
Expand All @@ -269,6 +281,8 @@ protected List<MirrorSettings> getMirrorSettings(Settings settings, boolean defT
ms.tags = (settings.getBoolean(SETTING_TAGS + suffix, defTags));
ms.notes = (settings.getBoolean(SETTING_NOTES + suffix, defNotes));
ms.atomic = (settings.getBoolean(SETTING_ATOMIC + suffix, defAtomic));
ms.prune = (settings.getBoolean(SETTING_PRUNE + suffix, defPrune));
ms.force = (settings.getBoolean(SETTING_FORCE + suffix, defForce));
ms.suffix = String.valueOf(count++);

results.add(ms);
Expand Down Expand Up @@ -344,6 +358,8 @@ protected void updateSettings(List<MirrorSettings> mirrorSettings, Settings sett
values.put(SETTING_TAGS + ms.suffix, ms.tags);
values.put(SETTING_NOTES + ms.suffix, ms.notes);
values.put(SETTING_ATOMIC + ms.suffix, ms.atomic);
values.put(SETTING_PRUNE + ms.suffix, ms.prune);
values.put(SETTING_FORCE + ms.suffix, ms.force);
}

// Unfortunately the settings are stored in an immutable map, so need to cheat with reflection
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/i18n/stash-hook-mirror.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ mirror-repository-hook.refspec.description=The git refspec(s) to mirror (default
mirror-repository-hook.tags.label=Tags (ie. +refs/tags/*:refs/tags/*)
mirror-repository-hook.notes.label=Notes (ie. +refs/notes/*:refs/notes/*)
mirror-repository-hook.atomic.label=Atomic
mirror-repository-hook.prune.label=Prune
mirror-repository-hook.force.label=Force
10 changes: 10 additions & 0 deletions src/main/resources/static/mirror-repository-hook.soy
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@
'id' : 'atomic' + $index,
'labelText': getText('mirror-repository-hook.atomic.label'),
'isChecked' : $config['atomic' + $index] != false
],
[
'id' : 'prune' + $index,
'labelText': getText('mirror-repository-hook.prune.label'),
'isChecked' : $config['prune' + $index] != false
],
[
'id' : 'force' + $index,
'labelText': getText('mirror-repository-hook.force.label'),
'isChecked' : $config['force' + $index] != false
]
] /}
{/call}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.mockito.Mockito.*;

/**
Expand Down Expand Up @@ -269,6 +270,54 @@ public void testValidate() throws Exception {

}

@Test
public void testPruneFlag() throws Exception{
when(passwordEncryptor.decrypt(anyString())).thenReturn(password);

Repository repo = mock(Repository.class);

RepositoryHookContext context = mock(RepositoryHookContext.class);
Settings settings = ownSettings(false, true);
when(context.getSettings()).thenReturn(settings);
when(context.getRepository()).thenReturn(repo);

hook.postReceive(context, new ArrayList<>());

verify(executor).submit(argumentCaptor.capture());
Runnable runnable = argumentCaptor.getValue();
runnable.run();

verify(builder, times(1)).command(eq("push"));
verify(builder, never()).argument(eq("--prune"));
verify(builder, times(1)).argument(eq("--atomic"));
verify(builder, times(1)).argument(eq(repository));
verify(builder, times(1)).argument(eq("--force"));
}

@Test
public void testForceFlag() throws Exception{
when(passwordEncryptor.decrypt(anyString())).thenReturn(password);

Repository repo = mock(Repository.class);

RepositoryHookContext context = mock(RepositoryHookContext.class);
Settings settings = ownSettings(true, false);
when(context.getSettings()).thenReturn(settings);
when(context.getRepository()).thenReturn(repo);

hook.postReceive(context, new ArrayList<>());

verify(executor).submit(argumentCaptor.capture());
Runnable runnable = argumentCaptor.getValue();
runnable.run();

verify(builder, times(1)).command(eq("push"));
verify(builder, times(1)).argument(eq("--prune"));
verify(builder, times(1)).argument(eq("--atomic"));
verify(builder, times(1)).argument(eq(repository));
verify(builder, never()).argument(eq("--force"));
}

private RepositoryHookContext buildContext(Repository repo) {
RepositoryHookContext context = mock(RepositoryHookContext.class);
Settings settings = defaultSettings();
Expand All @@ -290,6 +339,26 @@ private Settings defaultSettings() {
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_TAGS), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_NOTES), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_ATOMIC), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_PRUNE), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_FORCE), eq(true))).thenReturn(true);
return settings;
}

private Settings ownSettings(boolean pruneFlag, boolean forceFlag) {
Map<String, Object> map = new HashMap<String, Object>();
map.put(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL, "");

Settings settings = mock(Settings.class);
when(settings.asMap()).thenReturn(map);
when(settings.getString(eq(MirrorRepositoryHook.SETTING_MIRROR_REPO_URL), eq(""))).thenReturn(mirrorRepoUrlHttp);
when(settings.getString(eq(MirrorRepositoryHook.SETTING_USERNAME), eq(""))).thenReturn(username);
when(settings.getString(eq(MirrorRepositoryHook.SETTING_PASSWORD), eq(""))).thenReturn(password);
when(settings.getString(eq(MirrorRepositoryHook.SETTING_REFSPEC), eq(""))).thenReturn(refspec);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_TAGS), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_NOTES), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_ATOMIC), eq(true))).thenReturn(true);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_PRUNE), eq(pruneFlag))).thenReturn(pruneFlag);
when(settings.getBoolean(eq(MirrorRepositoryHook.SETTING_FORCE), eq(forceFlag))).thenReturn(forceFlag);
return settings;
}
}