Merge pull request #473 from marcosbarbero/master

* pull473:
  Add force-pull flag for dirty repositories
This commit is contained in:
Spencer Gibb
2016-08-10 13:23:24 -06:00
2 changed files with 148 additions and 16 deletions

View File

@@ -20,15 +20,18 @@ import static org.springframework.util.StringUtils.hasText;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.TransportCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
@@ -51,6 +54,7 @@ import com.jcraft.jsch.Session;
*
* @author Dave Syer
* @author Roy Clarkson
* @author Marcos Barbero
*/
public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
implements EnvironmentRepository, SearchPathLocator, InitializingBean {
@@ -76,6 +80,12 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
private String defaultLabel = DEFAULT_LABEL;
/**
* Flag to indicate that the repository should force pull. If true discard any local
* changes and take from remote repository.
*/
private boolean forcePull;
public JGitEnvironmentRepository(ConfigurableEnvironment environment) {
super(environment);
}
@@ -112,6 +122,14 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
this.defaultLabel = defaultLabel;
}
public boolean isForcePull() {
return forcePull;
}
public void setForcePull(boolean forcePull) {
this.forcePull = forcePull;
}
@Override
public synchronized Locations getLocations(String application, String profile,
String label) {
@@ -204,9 +222,35 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
return checkout.call();
}
private boolean shouldPull(Git git, Ref ref) throws GitAPIException {
return git.status().call().isClean() && ref != null && git.getRepository()
.getConfig().getString("remote", "origin", "url") != null;
/* for testing */ boolean shouldPull(Git git, Ref ref) throws GitAPIException {
boolean shouldPull;
Status gitStatus = git.status().call();
if (this.isForcePull() && !gitStatus.isClean()) {
shouldPull = true;
logDirty(gitStatus);
}
else {
shouldPull = gitStatus.isClean() && ref != null && git.getRepository()
.getConfig().getString("remote", "origin", "url") != null;
}
return shouldPull;
}
@SuppressWarnings("unchecked")
private void logDirty(Status status) {
Set<String> dirties = dirties(status.getAdded(), status.getChanged(),
status.getRemoved(), status.getMissing(), status.getModified(),
status.getConflicting(), status.getUntracked());
this.logger.warn(String.format("Dirty files found: %s", dirties));
}
@SuppressWarnings("unchecked")
private Set<String> dirties(Set<String>... changes) {
Set<String> dirties = new HashSet<>();
for (Set<String> files : changes) {
dirties.addAll(files);
}
return dirties;
}
private boolean shouldTrack(Git git, String label) throws GitAPIException {

View File

@@ -16,9 +16,28 @@
package org.springframework.cloud.config.server.environment;
import java.io.File;
import java.io.IOException;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.StatusCommand;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.core.env.StandardEnvironment;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
@@ -27,18 +46,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.core.env.StandardEnvironment;
/**
* @author Dave Syer
*
@@ -227,6 +234,87 @@ public class JGitEnvironmentRepositoryTests {
verify(mockGit, times(0)).fetch();
}
@Test
public void shouldPullForcepullNotClean() throws Exception {
Git git = mock(Git.class);
StatusCommand statusCommand = mock(StatusCommand.class);
Status status = mock(Status.class);
when(git.status()).thenReturn(statusCommand);
when(statusCommand.call()).thenReturn(status);
when(status.isClean()).thenReturn(false);
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(
this.environment);
repo.setForcePull(true);
boolean shouldPull = repo.shouldPull(git, null);
assertThat("shouldPull was false", shouldPull, is(true));
}
@Test
public void shouldPullForcepullClean() throws Exception {
Git git = mock(Git.class);
StatusCommand statusCommand = mock(StatusCommand.class);
Status status = mock(Status.class);
when(git.status()).thenReturn(statusCommand);
when(statusCommand.call()).thenReturn(status);
when(status.isClean()).thenReturn(true);
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(
this.environment);
repo.setForcePull(true);
boolean shouldPull = repo.shouldPull(git, null);
assertThat("shouldPull was true", shouldPull, is(false));
}
@Test
public void shouldPullNotClean() throws Exception {
Git git = mock(Git.class);
StatusCommand statusCommand = mock(StatusCommand.class);
Status status = mock(Status.class);
Ref ref = mock(Ref.class);
when(git.status()).thenReturn(statusCommand);
when(statusCommand.call()).thenReturn(status);
when(status.isClean()).thenReturn(false);
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(
this.environment);
boolean shouldPull = repo.shouldPull(git, ref);
assertThat("shouldPull was true", shouldPull, is(false));
}
@Test
public void shouldPullClean() throws Exception {
Git git = mock(Git.class);
StatusCommand statusCommand = mock(StatusCommand.class);
Status status = mock(Status.class);
Ref ref = mock(Ref.class);
Repository repository = mock(Repository.class);
StoredConfig storedConfig = mock(StoredConfig.class);
when(git.status()).thenReturn(statusCommand);
when(git.getRepository()).thenReturn(repository);
when(repository.getConfig()).thenReturn(storedConfig);
when(storedConfig.getString("remote", "origin", "url")).thenReturn("http://example/git");
when(statusCommand.call()).thenReturn(status);
when(status.isClean()).thenReturn(true);
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(
this.environment);
boolean shouldPull = repo.shouldPull(git, ref);
assertThat("shouldPull was false", shouldPull, is(true));
}
class MockGitFactory extends JGitEnvironmentRepository.JGitFactory {
private Git mockGit;