mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-24 01:09:48 +01:00
Add a modifications provider for hooks
This new modifications provider consistently computes the modifications caused by a push to a branch. In contrast to the changeset provider that often has been used before to check what has changed, this also works for forced updates, rebased branches and fast-forwards. Because these types of changes are normally only used with git, this provider (for now) has only been implemented for git. Pushed-by: Rene Pfeuffer<rene.pfeuffer@cloudogu.com> Pushed-by: Alexander Dammeier<alexander.dammeier@cloudogu.com> Co-authored-by: René Pfeuffer<rene.pfeuffer@cloudogu.com> Committed-by: René Pfeuffer<rene.pfeuffer@cloudogu.com>
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -40,7 +40,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GitHookBranchProvider}.
|
||||
*
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -48,9 +48,9 @@ public class GitHookBranchProviderTest {
|
||||
|
||||
@Mock
|
||||
private ReceiveCommand command;
|
||||
|
||||
|
||||
private List<ReceiveCommand> commands;
|
||||
|
||||
|
||||
/**
|
||||
* Prepare mocks for upcoming test.
|
||||
*/
|
||||
@@ -58,37 +58,37 @@ public class GitHookBranchProviderTest {
|
||||
public void setUpMocks(){
|
||||
commands = Lists.newArrayList(command);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link GitHookBranchProvider#getCreatedOrModified()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetCreatedOrModified(){
|
||||
List<ReceiveCommand.Type> types = Arrays.asList(
|
||||
ReceiveCommand.Type.CREATE, ReceiveCommand.Type.UPDATE, ReceiveCommand.Type.UPDATE_NONFASTFORWARD
|
||||
List<ReceiveCommand.Type> types = Arrays.asList(
|
||||
ReceiveCommand.Type.CREATE, ReceiveCommand.Type.UPDATE, ReceiveCommand.Type.UPDATE_NONFASTFORWARD
|
||||
);
|
||||
for ( ReceiveCommand.Type type : types ){
|
||||
checkCreatedOrModified(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkCreatedOrModified(ReceiveCommand.Type type){
|
||||
GitHookBranchProvider provider = createGitHookBranchProvider(type, "refs/heads/hello");
|
||||
assertThat(provider.getCreatedOrModified(), Matchers.contains("hello"));
|
||||
assertThat(provider.getDeletedOrClosed(), empty());
|
||||
assertThat(provider.getDeletedOrClosed(), empty());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link GitHookBranchProvider#getDeletedOrClosed()}.
|
||||
*/
|
||||
*/
|
||||
@Test
|
||||
public void testGetDeletedOrClosed(){
|
||||
GitHookBranchProvider provider = createGitHookBranchProvider(ReceiveCommand.Type.DELETE, "refs/heads/hello");
|
||||
assertThat(provider.getDeletedOrClosed(), Matchers.contains("hello"));
|
||||
assertThat(provider.getCreatedOrModified(), empty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link GitHookBranchProvider} with a tag instead of a branch.
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ public class GitHookBranchProviderTest {
|
||||
assertThat(provider.getCreatedOrModified(), empty());
|
||||
assertThat(provider.getDeletedOrClosed(), empty());
|
||||
}
|
||||
|
||||
|
||||
private GitHookBranchProvider createGitHookBranchProvider(ReceiveCommand.Type type, String refName){
|
||||
when(command.getType()).thenReturn(type);
|
||||
when(command.getRefName()).thenReturn(refName);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.transport.ReceiveCommand;
|
||||
import org.junit.Test;
|
||||
import sonia.scm.repository.spi.AbstractGitCommandTestBase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class GitHookModificationsProviderTest extends AbstractGitCommandTestBase {
|
||||
|
||||
@Test
|
||||
public void shouldReturnModificationsForNormalUpdate() throws IOException {
|
||||
GitHookModificationsProvider provider = mockProviderWithChange(ReceiveCommand.Type.UPDATE);
|
||||
|
||||
assertThat(provider.getModifications("rename"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnModificationsForFastForward() throws IOException {
|
||||
GitHookModificationsProvider provider = mockProviderWithChange(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
|
||||
|
||||
assertThat(provider.getModifications("rename"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnEmptyModificationsForBranchWithRevertedCommit() throws IOException {
|
||||
GitHookModificationsProvider provider = mockProviderWithChange(ReceiveCommand.Type.UPDATE, "03ca33468c2094249973d0ca11b80243a20de368", "592d797cd36432e591416e8b2b98154f4f163411");
|
||||
|
||||
assertThat(provider.getModifications("rename"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnEmptyModificationsForDeletedBranch() throws IOException {
|
||||
GitHookModificationsProvider provider = mockProviderWithChange(
|
||||
ReceiveCommand.Type.DELETE,
|
||||
"0000000000000000000000000000000000000000",
|
||||
"fcd0ef1831e4002ac43ea539f4094334c79ea9ec");
|
||||
|
||||
assertThat(provider.getModifications("rename"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(5)
|
||||
.extracting("path")
|
||||
.contains("a.txt", "b.txt", "c/d.txt", "c/e.txt", "f.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnEmptyModificationsForCreatedBranch() throws IOException {
|
||||
GitHookModificationsProvider provider = mockProviderWithChange(
|
||||
ReceiveCommand.Type.CREATE,
|
||||
"fcd0ef1831e4002ac43ea539f4094334c79ea9ec",
|
||||
"0000000000000000000000000000000000000000");
|
||||
|
||||
assertThat(provider.getModifications("rename"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(5)
|
||||
.extracting("path")
|
||||
.contains("a.txt", "b.txt", "c/d.txt", "c/e.txt", "f.txt");
|
||||
}
|
||||
|
||||
private GitHookModificationsProvider mockProviderWithChange(ReceiveCommand.Type update) throws IOException {
|
||||
return mockProviderWithChange(
|
||||
update,
|
||||
"383b954b27e052db6880d57f1c860dc208795247",
|
||||
"fcd0ef1831e4002ac43ea539f4094334c79ea9ec");
|
||||
}
|
||||
|
||||
private GitHookModificationsProvider mockProviderWithChange(ReceiveCommand.Type update, String newObjectId, String oldObjectId) throws IOException {
|
||||
ReceiveCommand receiveCommand = mock(ReceiveCommand.class);
|
||||
when(receiveCommand.getRefName()).thenReturn("refs/heads/rename");
|
||||
when(receiveCommand.getType()).thenReturn(update);
|
||||
when(receiveCommand.getNewId()).thenReturn(ObjectId.fromString(newObjectId));
|
||||
when(receiveCommand.getOldId()).thenReturn(ObjectId.fromString(oldObjectId));
|
||||
return new GitHookModificationsProvider(List.of(receiveCommand), createContext().open());
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import sonia.scm.repository.PreReceiveRepositoryHookEvent;
|
||||
import sonia.scm.repository.api.BranchRequest;
|
||||
import sonia.scm.repository.api.HookChangesetBuilder;
|
||||
import sonia.scm.repository.api.HookContextFactory;
|
||||
import sonia.scm.repository.api.HookModificationsProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -164,6 +165,11 @@ public class GitBranchCommandTest extends AbstractGitCommandTestBase {
|
||||
PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0);
|
||||
assertThat(event.getContext().getBranchProvider().getCreatedOrModified()).containsExactly("new_branch");
|
||||
assertThat(event.getContext().getBranchProvider().getDeletedOrClosed()).isEmpty();
|
||||
HookModificationsProvider modificationsProvider = event.getContext().getModificationsProvider();
|
||||
assertThat(modificationsProvider.getModifications("new_branch"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -190,5 +196,10 @@ public class GitBranchCommandTest extends AbstractGitCommandTestBase {
|
||||
"f360a8738e4a29333786c5817f97a2c912814536",
|
||||
"d1dfecbfd5b4a2f77fe40e1bde29e640f7f944be"
|
||||
);
|
||||
HookModificationsProvider modificationsProvider = event.getContext().getModificationsProvider();
|
||||
assertThat(modificationsProvider.getModifications("squash"))
|
||||
.extracting("modifications")
|
||||
.asList()
|
||||
.hasSize(8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class GitModificationsCommandTest extends AbstractRemoteCommandTestBase {
|
||||
|
||||
command.getModifications(revision);
|
||||
|
||||
Mockito.verify(command.context, times(3)).open();
|
||||
Mockito.verify(command.context, times(2)).open();
|
||||
Mockito.verify(repository, never()).close();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user