mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-08 05:10:20 +01:00
merge 2.0.0-m3
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -757,7 +757,7 @@
|
||||
<guice.version>4.0</guice.version>
|
||||
|
||||
<!-- event bus -->
|
||||
<legman.version>1.3.0</legman.version>
|
||||
<legman.version>1.4.0</legman.version>
|
||||
|
||||
<!-- webserver -->
|
||||
<jetty.version>9.2.10.v20150310</jetty.version>
|
||||
|
||||
265
scm-it/src/test/java/sonia/scm/it/DiffITCase.java
Normal file
265
scm-it/src/test/java/sonia/scm/it/DiffITCase.java
Normal file
@@ -0,0 +1,265 @@
|
||||
package sonia.scm.it;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import sonia.scm.it.utils.RepositoryUtil;
|
||||
import sonia.scm.it.utils.ScmRequests;
|
||||
import sonia.scm.it.utils.TestData;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.client.api.RepositoryClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static sonia.scm.it.utils.RestUtil.ADMIN_PASSWORD;
|
||||
import static sonia.scm.it.utils.RestUtil.ADMIN_USERNAME;
|
||||
|
||||
public class DiffITCase {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tempFolder = new TemporaryFolder();
|
||||
private RepositoryClient svnRepositoryClient;
|
||||
private RepositoryClient gitRepositoryClient;
|
||||
private RepositoryClient hgRepositoryClient;
|
||||
private ScmRequests.RepositoryResponse<ScmRequests.IndexResponse> svnRepositoryResponse;
|
||||
private ScmRequests.RepositoryResponse<ScmRequests.IndexResponse> hgRepositoryResponse;
|
||||
private ScmRequests.RepositoryResponse<ScmRequests.IndexResponse> gitRepositoryResponse;
|
||||
private File svnFolder;
|
||||
private File gitFolder;
|
||||
private File hgFolder;
|
||||
|
||||
@Before
|
||||
public void init() throws IOException {
|
||||
TestData.createDefault();
|
||||
String namespace = ADMIN_USERNAME;
|
||||
String repo = TestData.getDefaultRepoName("svn");
|
||||
svnRepositoryResponse =
|
||||
ScmRequests.start()
|
||||
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
.requestRepository(namespace, repo)
|
||||
.assertStatusCode(HttpStatus.SC_OK);
|
||||
svnFolder = tempFolder.newFolder("svn");
|
||||
svnRepositoryClient = RepositoryUtil.createRepositoryClient("svn", svnFolder);
|
||||
|
||||
repo = TestData.getDefaultRepoName("git");
|
||||
gitRepositoryResponse =
|
||||
ScmRequests.start()
|
||||
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
.requestRepository(namespace, repo)
|
||||
.assertStatusCode(HttpStatus.SC_OK);
|
||||
gitFolder = tempFolder.newFolder("git");
|
||||
gitRepositoryClient = RepositoryUtil.createRepositoryClient("git", gitFolder);
|
||||
|
||||
repo = TestData.getDefaultRepoName("hg");
|
||||
hgRepositoryResponse =
|
||||
ScmRequests.start()
|
||||
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
.requestRepository(namespace, repo)
|
||||
.assertStatusCode(HttpStatus.SC_OK);
|
||||
hgFolder = tempFolder.newFolder("hg");
|
||||
hgRepositoryClient = RepositoryUtil.createRepositoryClient("hg", hgFolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindDiffsInGitFormat() throws IOException {
|
||||
String svnDiff = getDiff(RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a"), gitRepositoryResponse);
|
||||
String hgDiff = getDiff(RepositoryUtil.createAndCommitFile(hgRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a"), hgRepositoryResponse);
|
||||
|
||||
assertThat(Lists.newArrayList(svnDiff, gitDiff, hgDiff))
|
||||
.allSatisfy(diff -> assertThat(diff)
|
||||
.contains("diff --git "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnAddFileDiffShouldBeConvertedToGitDiff() throws IOException {
|
||||
String svnDiff = getDiff(RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a"), gitRepositoryResponse);
|
||||
|
||||
String expected = getGitDiffWithoutIndexLine(gitDiff);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnDeleteFileDiffShouldBeConvertedToGitDiff() throws IOException {
|
||||
RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a");
|
||||
RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a");
|
||||
|
||||
String svnDiff = getDiff(RepositoryUtil.removeAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(RepositoryUtil.removeAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt"), gitRepositoryResponse);
|
||||
|
||||
String expected = getGitDiffWithoutIndexLine(gitDiff);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnUpdateFileDiffShouldBeConvertedToGitDiff() throws IOException {
|
||||
RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a");
|
||||
RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt", "content of a");
|
||||
|
||||
String svnDiff = getDiff(RepositoryUtil.updateAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, "a.txt", "the updated content of a"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(RepositoryUtil.updateAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, "a.txt", "the updated content of a"), gitRepositoryResponse);
|
||||
|
||||
String expected = getGitDiffWithoutIndexLine(gitDiff);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnMultipleChangesDiffShouldBeConvertedToGitDiff() throws IOException {
|
||||
String svnDiff = getDiff(applyMultipleChanges(svnRepositoryClient, "fileToBeDeleted.txt", "fileToBeUpdated.txt", "addedFile.txt"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(applyMultipleChanges(gitRepositoryClient, "fileToBeDeleted.txt", "fileToBeUpdated.txt", "addedFile.txt"), gitRepositoryResponse);
|
||||
|
||||
String endOfDiffPart = "\\ No newline at end of file\n";
|
||||
String[] gitDiffs = gitDiff.split(endOfDiffPart);
|
||||
List<String> expected = Arrays.stream(gitDiffs)
|
||||
.map(this::getGitDiffWithoutIndexLine)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(svnDiff.split(endOfDiffPart))
|
||||
.containsExactlyInAnyOrderElementsOf(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnMultipleSubFolderChangesDiffShouldBeConvertedToGitDiff() throws IOException {
|
||||
String svnDiff = getDiff(applyMultipleChanges(svnRepositoryClient, "a/b/fileToBeDeleted.txt", "a/c/fileToBeUpdated.txt", "a/d/addedFile.txt"), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(applyMultipleChanges(gitRepositoryClient, "a/b/fileToBeDeleted.txt", "a/c/fileToBeUpdated.txt", "a/d/addedFile.txt"), gitRepositoryResponse);
|
||||
|
||||
String endOfDiffPart = "\\ No newline at end of file\n";
|
||||
String[] gitDiffs = gitDiff.split(endOfDiffPart);
|
||||
List<String> expected = Arrays.stream(gitDiffs)
|
||||
.map(this::getGitDiffWithoutIndexLine)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(svnDiff.split(endOfDiffPart))
|
||||
.containsExactlyInAnyOrderElementsOf(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnLargeChangesDiffShouldBeConvertedToGitDiff() throws IOException, URISyntaxException {
|
||||
String fileName = "SvnDiffGenerator_forTest";
|
||||
RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, fileName, "");
|
||||
RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, fileName, "");
|
||||
|
||||
String fileContent = getFileContent("/diff/largefile/original/SvnDiffGenerator_forTest");
|
||||
String svnDiff = getDiff(RepositoryUtil.updateAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, fileName, fileContent), svnRepositoryResponse);
|
||||
String gitDiff = getDiff(RepositoryUtil.updateAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, fileName, fileContent), gitRepositoryResponse);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(getGitDiffWithoutIndexLine(gitDiff));
|
||||
|
||||
fileContent = getFileContent("/diff/largefile/modified/v1/SvnDiffGenerator_forTest");
|
||||
svnDiff = getDiff(RepositoryUtil.updateAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, fileName, fileContent), svnRepositoryResponse);
|
||||
gitDiff = getDiff(RepositoryUtil.updateAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, fileName, fileContent), gitRepositoryResponse);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(getGitDiffWithoutIndexLine(gitDiff));
|
||||
|
||||
fileContent = getFileContent("/diff/largefile/modified/v2/SvnDiffGenerator_forTest");
|
||||
svnDiff = getDiff(RepositoryUtil.updateAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, fileName, fileContent), svnRepositoryResponse);
|
||||
gitDiff = getDiff(RepositoryUtil.updateAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, fileName, fileContent), gitRepositoryResponse);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(getGitDiffWithoutIndexLine(gitDiff));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: the binary Git Diff output is not GIT conform
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
@SuppressWarnings("squid:S1607")
|
||||
public void svnBinaryChangesDiffShouldBeConvertedToGitDiff() throws IOException, URISyntaxException {
|
||||
String fileName = "binary";
|
||||
File file = new File(svnRepositoryClient.getWorkingCopy(), fileName);
|
||||
Files.copy(Paths.get(getClass().getResource("/diff/binaryfile/echo").toURI()), Paths.get(file.toURI()));
|
||||
Changeset commit = RepositoryUtil.addFileAndCommit(svnRepositoryClient, fileName, ADMIN_USERNAME, "");
|
||||
|
||||
file = new File(gitRepositoryClient.getWorkingCopy(), fileName);
|
||||
Files.copy(Paths.get(getClass().getResource("/diff/binaryfile/echo").toURI()), Paths.get(file.toURI()));
|
||||
|
||||
Changeset commit1 = RepositoryUtil.addFileAndCommit(gitRepositoryClient, fileName, ADMIN_USERNAME, "");
|
||||
String svnDiff = getDiff(commit, svnRepositoryResponse);
|
||||
String gitDiff = getDiff(commit1, gitRepositoryResponse);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(getGitDiffWithoutIndexLine(gitDiff));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void svnRenameChangesDiffShouldBeConvertedToGitDiff() throws IOException, URISyntaxException {
|
||||
String fileName = "a.txt";
|
||||
RepositoryUtil.createAndCommitFile(svnRepositoryClient, ADMIN_USERNAME, fileName, "content of a");
|
||||
RepositoryUtil.createAndCommitFile(gitRepositoryClient, ADMIN_USERNAME, fileName, "content of a");
|
||||
|
||||
String newFileName = "renamed_a.txt";
|
||||
File file = new File(svnRepositoryClient.getWorkingCopy(), fileName);
|
||||
file.renameTo(new File(svnRepositoryClient.getWorkingCopy(), newFileName));
|
||||
|
||||
String svnDiff = getDiff(RepositoryUtil.addFileAndCommit(svnRepositoryClient, newFileName, ADMIN_USERNAME, "renamed file"), svnRepositoryResponse);
|
||||
|
||||
file = new File(gitRepositoryClient.getWorkingCopy(), fileName);
|
||||
file.renameTo(new File(gitRepositoryClient.getWorkingCopy(), newFileName));
|
||||
String gitDiff = getDiff(RepositoryUtil.addFileAndCommit(gitRepositoryClient, newFileName, ADMIN_USERNAME, "renamed file"), gitRepositoryResponse);
|
||||
|
||||
String expected = getGitDiffWithoutIndexLine(gitDiff);
|
||||
assertThat(svnDiff)
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
public String getFileContent(String name) throws URISyntaxException, IOException {
|
||||
Path path;
|
||||
path = Paths.get(getClass().getResource(name).toURI());
|
||||
Stream<String> lines = Files.lines(path);
|
||||
String data = lines.collect(Collectors.joining("\n"));
|
||||
lines.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The index line is not provided from the svn git formatter and it is not needed in the ui diff view
|
||||
* for more details about the git diff format: https://git-scm.com/docs/git-diff
|
||||
*
|
||||
* @param gitDiff
|
||||
* @return diff without the index line
|
||||
*/
|
||||
private String getGitDiffWithoutIndexLine(String gitDiff) {
|
||||
return gitDiff.replaceAll(".*(index.*\n)", "");
|
||||
}
|
||||
|
||||
private String getDiff(Changeset svnChangeset, ScmRequests.RepositoryResponse<ScmRequests.IndexResponse> svnRepositoryResponse) {
|
||||
return svnRepositoryResponse.requestChangesets()
|
||||
.requestDiffInGitFormat(svnChangeset.getId())
|
||||
.getResponse()
|
||||
.body()
|
||||
.asString();
|
||||
}
|
||||
|
||||
private Changeset applyMultipleChanges(RepositoryClient repositoryClient, String fileToBeDeleted, final String fileToBeUpdated, final String addedFile) throws IOException {
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileToBeDeleted, "file to be deleted");
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileToBeUpdated, "file to be updated");
|
||||
Map<String, String> addedFiles = new HashMap<String, String>() {{
|
||||
put(addedFile, "content");
|
||||
}};
|
||||
Map<String, String> modifiedFiles = new HashMap<String, String>() {{
|
||||
put(fileToBeUpdated, "the updated content");
|
||||
}};
|
||||
ArrayList<String> removedFiles = Lists.newArrayList(fileToBeDeleted);
|
||||
return RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package sonia.scm.it;
|
||||
|
||||
import groovy.util.logging.Slf4j;
|
||||
import io.restassured.response.ExtractableResponse;
|
||||
import io.restassured.response.Response;
|
||||
import org.apache.http.HttpStatus;
|
||||
@@ -37,6 +38,7 @@ import static sonia.scm.it.utils.RestUtil.given;
|
||||
import static sonia.scm.it.utils.ScmTypes.availableScmTypes;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
@Slf4j
|
||||
public class RepositoryAccessITCase {
|
||||
|
||||
@Rule
|
||||
@@ -63,9 +65,9 @@ public class RepositoryAccessITCase {
|
||||
String repo = TestData.getDefaultRepoName(repositoryType);
|
||||
repositoryResponse =
|
||||
ScmRequests.start()
|
||||
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
.requestRepository(namespace, repo)
|
||||
.assertStatusCode(HttpStatus.SC_OK);
|
||||
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
.requestRepository(namespace, repo)
|
||||
.assertStatusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,6 +177,7 @@ public class RepositoryAccessITCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("squid:S2925")
|
||||
public void shouldReadContent() throws IOException, InterruptedException {
|
||||
RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder);
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, "scmadmin", "a.txt", "a");
|
||||
@@ -262,40 +265,6 @@ public class RepositoryAccessITCase {
|
||||
assertThat(changesets).size().isBetween(2, 3); // svn has an implicit root revision '0' that is extra to the two commits
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindDiffs() throws IOException {
|
||||
RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder);
|
||||
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, "scmadmin", "a.txt", "a");
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, "scmadmin", "b.txt", "b");
|
||||
|
||||
String changesetsUrl = given()
|
||||
.when()
|
||||
.get(TestData.getDefaultRepositoryUrl(repositoryType))
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.path("_links.changesets.href");
|
||||
|
||||
String diffUrl = given()
|
||||
.when()
|
||||
.get(changesetsUrl)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.path("_embedded.changesets[0]._links.diff.href");
|
||||
|
||||
given()
|
||||
.when()
|
||||
.get(diffUrl)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.body()
|
||||
.asString()
|
||||
.contains("diff");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -393,12 +362,10 @@ public class RepositoryAccessITCase {
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "b.txt", "b");
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "c.txt", "c");
|
||||
RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "d.txt", "d");
|
||||
Map<String, String> addedFiles = new HashMap<String, String>()
|
||||
{{
|
||||
Map<String, String> addedFiles = new HashMap<String, String>() {{
|
||||
put("a.txt", "bla bla");
|
||||
}};
|
||||
Map<String, String> modifiedFiles = new HashMap<String, String>()
|
||||
{{
|
||||
Map<String, String> modifiedFiles = new HashMap<String, String>() {{
|
||||
put("b.txt", "new content");
|
||||
}};
|
||||
ArrayList<String> removedFiles = Lists.newArrayList("c.txt", "d.txt");
|
||||
@@ -414,7 +381,7 @@ public class RepositoryAccessITCase {
|
||||
.assertAdded(a -> assertThat(a)
|
||||
.hasSize(1)
|
||||
.containsExactly("a.txt"))
|
||||
.assertModified(m-> assertThat(m)
|
||||
.assertModified(m -> assertThat(m)
|
||||
.hasSize(1)
|
||||
.containsExactly("b.txt"))
|
||||
.assertRemoved(r -> assertThat(r)
|
||||
|
||||
@@ -80,6 +80,11 @@ public class RepositoryUtil {
|
||||
return file;
|
||||
}
|
||||
|
||||
public static Changeset updateAndCommitFile(RepositoryClient repositoryClient, String username, String fileName, String content) throws IOException {
|
||||
writeAndAddFile(repositoryClient, fileName, content);
|
||||
return commit(repositoryClient, username, "updated " + fileName);
|
||||
}
|
||||
|
||||
public static Changeset removeAndCommitFile(RepositoryClient repositoryClient, String username, String fileName) throws IOException {
|
||||
deleteFileAndApplyRemoveCommand(repositoryClient, fileName);
|
||||
return commit(repositoryClient, username, "removed " + fileName);
|
||||
@@ -102,11 +107,21 @@ public class RepositoryUtil {
|
||||
} else {
|
||||
path = thisName;
|
||||
}
|
||||
repositoryClient.getAddCommand().add(path);
|
||||
addFile(repositoryClient, path);
|
||||
return path;
|
||||
}
|
||||
|
||||
static Changeset commit(RepositoryClient repositoryClient, String username, String message) throws IOException {
|
||||
public static Changeset addFileAndCommit(RepositoryClient repositoryClient, String path, String username, String message) throws IOException {
|
||||
repositoryClient.getAddCommand().add(path);
|
||||
return commit(repositoryClient, username, message);
|
||||
}
|
||||
|
||||
|
||||
public static void addFile(RepositoryClient repositoryClient, String path) throws IOException {
|
||||
repositoryClient.getAddCommand().add(path);
|
||||
}
|
||||
|
||||
public static Changeset commit(RepositoryClient repositoryClient, String username, String message) throws IOException {
|
||||
LOG.info("user: {} try to commit with message: {}", username, message);
|
||||
Changeset changeset = repositoryClient.getCommitCommand().commit(new Person(username, username + "@scm-manager.org"), message);
|
||||
if (repositoryClient.isCommandSupported(ClientCommand.PUSH)) {
|
||||
|
||||
@@ -234,8 +234,8 @@ public class ScmRequests {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DiffResponse<ChangesetsResponse> requestDiff(String revision) {
|
||||
return new DiffResponse<>(applyGETRequestFromLink(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href"), this);
|
||||
public DiffResponse<ChangesetsResponse> requestDiffInGitFormat(String revision) {
|
||||
return new DiffResponse<>(applyGETRequestFromLinkWithParams(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href", "?format=GIT"), this);
|
||||
}
|
||||
|
||||
public ModificationsResponse<ChangesetsResponse> requestModifications(String revision) {
|
||||
@@ -362,6 +362,10 @@ public class ScmRequests {
|
||||
this.previousResponse = previousResponse;
|
||||
}
|
||||
|
||||
public Response getResponse(){
|
||||
return response;
|
||||
}
|
||||
|
||||
public PREV returnToPrevious() {
|
||||
return previousResponse;
|
||||
}
|
||||
|
||||
BIN
scm-it/src/test/resources/diff/binaryfile/echo
Executable file
BIN
scm-it/src/test/resources/diff/binaryfile/echo
Executable file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -113,92 +113,35 @@
|
||||
<plugin>
|
||||
<groupId>sonia.scm.maven</groupId>
|
||||
<artifactId>smp-maven-plugin</artifactId>
|
||||
<version>1.0.0-alpha-2</version>
|
||||
<version>1.0.0-alpha-3</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<disableCompression>true</disableCompression>
|
||||
<links>
|
||||
<link>@scm-manager/ui-types</link>
|
||||
<link>@scm-manager/ui-components</link>
|
||||
</links>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>fix-descriptor</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>fix-descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>append-dependencies</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>append-dependencies</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.sdorra</groupId>
|
||||
<artifactId>buildfrontend-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<node>
|
||||
<version>${nodejs.version}</version>
|
||||
</node>
|
||||
<pkgManager>
|
||||
<type>YARN</type>
|
||||
<version>${yarn.version}</version>
|
||||
</pkgManager>
|
||||
<failOnMissingPackageJson>false</failOnMissingPackageJson>
|
||||
<script>build</script>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>build</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.sdorra</groupId>
|
||||
<artifactId>buildfrontend-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<node>
|
||||
<version>${nodejs.version}</version>
|
||||
</node>
|
||||
<pkgManager>
|
||||
<type>YARN</type>
|
||||
<version>${yarn.version}</version>
|
||||
</pkgManager>
|
||||
<failOnMissingPackageJson>false</failOnMissingPackageJson>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>sonia.maven</groupId>
|
||||
<artifactId>web-compressor</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compress-directory</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<replace>true</replace>
|
||||
<baseDirectory>${project.build.directory}/classes</baseDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>doc</id>
|
||||
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
./node_modules/@scm-manager/ui-components/flow-typed
|
||||
|
||||
[options]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// flow-typed signature: cf86673cc32d185bdab1d2ea90578d37
|
||||
// flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x
|
||||
|
||||
type $npm$classnames$Classes =
|
||||
| string
|
||||
| { [className: string]: * }
|
||||
| false
|
||||
| void
|
||||
| null;
|
||||
|
||||
declare module "classnames" {
|
||||
declare module.exports: (
|
||||
...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]>
|
||||
) => string;
|
||||
}
|
||||
|
||||
declare module "classnames/bind" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
|
||||
declare module "classnames/dedupe" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,331 +0,0 @@
|
||||
// flow-typed signature: 23b805356f90ad9384dd88489654e380
|
||||
// flow-typed version: e9374c5fe9/moment_v2.3.x/flow_>=v0.25.x
|
||||
|
||||
type moment$MomentOptions = {
|
||||
y?: number | string,
|
||||
year?: number | string,
|
||||
years?: number | string,
|
||||
M?: number | string,
|
||||
month?: number | string,
|
||||
months?: number | string,
|
||||
d?: number | string,
|
||||
day?: number | string,
|
||||
days?: number | string,
|
||||
date?: number | string,
|
||||
h?: number | string,
|
||||
hour?: number | string,
|
||||
hours?: number | string,
|
||||
m?: number | string,
|
||||
minute?: number | string,
|
||||
minutes?: number | string,
|
||||
s?: number | string,
|
||||
second?: number | string,
|
||||
seconds?: number | string,
|
||||
ms?: number | string,
|
||||
millisecond?: number | string,
|
||||
milliseconds?: number | string
|
||||
};
|
||||
|
||||
type moment$MomentObject = {
|
||||
years: number,
|
||||
months: number,
|
||||
date: number,
|
||||
hours: number,
|
||||
minutes: number,
|
||||
seconds: number,
|
||||
milliseconds: number
|
||||
};
|
||||
|
||||
type moment$MomentCreationData = {
|
||||
input: string,
|
||||
format: string,
|
||||
locale: Object,
|
||||
isUTC: boolean,
|
||||
strict: boolean
|
||||
};
|
||||
|
||||
type moment$CalendarFormat = string | ((moment: moment$Moment) => string);
|
||||
|
||||
type moment$CalendarFormats = {
|
||||
sameDay?: moment$CalendarFormat,
|
||||
nextDay?: moment$CalendarFormat,
|
||||
nextWeek?: moment$CalendarFormat,
|
||||
lastDay?: moment$CalendarFormat,
|
||||
lastWeek?: moment$CalendarFormat,
|
||||
sameElse?: moment$CalendarFormat
|
||||
};
|
||||
|
||||
declare class moment$LocaleData {
|
||||
months(moment: moment$Moment): string,
|
||||
monthsShort(moment: moment$Moment): string,
|
||||
monthsParse(month: string): number,
|
||||
weekdays(moment: moment$Moment): string,
|
||||
weekdaysShort(moment: moment$Moment): string,
|
||||
weekdaysMin(moment: moment$Moment): string,
|
||||
weekdaysParse(weekDay: string): number,
|
||||
longDateFormat(dateFormat: string): string,
|
||||
isPM(date: string): boolean,
|
||||
meridiem(hours: number, minutes: number, isLower: boolean): string,
|
||||
calendar(
|
||||
key:
|
||||
| "sameDay"
|
||||
| "nextDay"
|
||||
| "lastDay"
|
||||
| "nextWeek"
|
||||
| "prevWeek"
|
||||
| "sameElse",
|
||||
moment: moment$Moment
|
||||
): string,
|
||||
relativeTime(
|
||||
number: number,
|
||||
withoutSuffix: boolean,
|
||||
key: "s" | "m" | "mm" | "h" | "hh" | "d" | "dd" | "M" | "MM" | "y" | "yy",
|
||||
isFuture: boolean
|
||||
): string,
|
||||
pastFuture(diff: any, relTime: string): string,
|
||||
ordinal(number: number): string,
|
||||
preparse(str: string): any,
|
||||
postformat(str: string): any,
|
||||
week(moment: moment$Moment): string,
|
||||
invalidDate(): string,
|
||||
firstDayOfWeek(): number,
|
||||
firstDayOfYear(): number
|
||||
}
|
||||
declare class moment$MomentDuration {
|
||||
humanize(suffix?: boolean): string,
|
||||
milliseconds(): number,
|
||||
asMilliseconds(): number,
|
||||
seconds(): number,
|
||||
asSeconds(): number,
|
||||
minutes(): number,
|
||||
asMinutes(): number,
|
||||
hours(): number,
|
||||
asHours(): number,
|
||||
days(): number,
|
||||
asDays(): number,
|
||||
months(): number,
|
||||
asWeeks(): number,
|
||||
weeks(): number,
|
||||
asMonths(): number,
|
||||
years(): number,
|
||||
asYears(): number,
|
||||
add(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
subtract(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
as(unit: string): number,
|
||||
get(unit: string): number,
|
||||
toJSON(): string,
|
||||
toISOString(): string,
|
||||
isValid(): boolean
|
||||
}
|
||||
declare class moment$Moment {
|
||||
static ISO_8601: string,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
locale?: string,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
initDate: ?Object | number | Date | Array<number> | moment$Moment | string
|
||||
): moment$Moment,
|
||||
static unix(seconds: number): moment$Moment,
|
||||
static utc(): moment$Moment,
|
||||
static utc(number: number | Array<number>): moment$Moment,
|
||||
static utc(
|
||||
str: string,
|
||||
str2?: string | Array<string>,
|
||||
str3?: string
|
||||
): moment$Moment,
|
||||
static utc(moment: moment$Moment): moment$Moment,
|
||||
static utc(date: Date): moment$Moment,
|
||||
static parseZone(): moment$Moment,
|
||||
static parseZone(rawDate: string): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string | Array<string>
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
locale: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
isValid(): boolean,
|
||||
invalidAt(): 0 | 1 | 2 | 3 | 4 | 5 | 6,
|
||||
creationData(): moment$MomentCreationData,
|
||||
millisecond(number: number): this,
|
||||
milliseconds(number: number): this,
|
||||
millisecond(): number,
|
||||
milliseconds(): number,
|
||||
second(number: number): this,
|
||||
seconds(number: number): this,
|
||||
second(): number,
|
||||
seconds(): number,
|
||||
minute(number: number): this,
|
||||
minutes(number: number): this,
|
||||
minute(): number,
|
||||
minutes(): number,
|
||||
hour(number: number): this,
|
||||
hours(number: number): this,
|
||||
hour(): number,
|
||||
hours(): number,
|
||||
date(number: number): this,
|
||||
dates(number: number): this,
|
||||
date(): number,
|
||||
dates(): number,
|
||||
day(day: number | string): this,
|
||||
days(day: number | string): this,
|
||||
day(): number,
|
||||
days(): number,
|
||||
weekday(number: number): this,
|
||||
weekday(): number,
|
||||
isoWeekday(number: number): this,
|
||||
isoWeekday(): number,
|
||||
dayOfYear(number: number): this,
|
||||
dayOfYear(): number,
|
||||
week(number: number): this,
|
||||
weeks(number: number): this,
|
||||
week(): number,
|
||||
weeks(): number,
|
||||
isoWeek(number: number): this,
|
||||
isoWeeks(number: number): this,
|
||||
isoWeek(): number,
|
||||
isoWeeks(): number,
|
||||
month(number: number): this,
|
||||
months(number: number): this,
|
||||
month(): number,
|
||||
months(): number,
|
||||
quarter(number: number): this,
|
||||
quarter(): number,
|
||||
year(number: number): this,
|
||||
years(number: number): this,
|
||||
year(): number,
|
||||
years(): number,
|
||||
weekYear(number: number): this,
|
||||
weekYear(): number,
|
||||
isoWeekYear(number: number): this,
|
||||
isoWeekYear(): number,
|
||||
weeksInYear(): number,
|
||||
isoWeeksInYear(): number,
|
||||
get(string: string): number,
|
||||
set(unit: string, value: number): this,
|
||||
set(options: { [unit: string]: number }): this,
|
||||
static max(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static max(dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(dates: Array<moment$Moment>): moment$Moment,
|
||||
add(
|
||||
value: number | moment$MomentDuration | moment$Moment | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
subtract(
|
||||
value: number | moment$MomentDuration | moment$Moment | string | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
startOf(unit: string): this,
|
||||
endOf(unit: string): this,
|
||||
local(): this,
|
||||
utc(): this,
|
||||
utcOffset(
|
||||
offset: number | string,
|
||||
keepLocalTime?: boolean,
|
||||
keepMinutes?: boolean
|
||||
): this,
|
||||
utcOffset(): number,
|
||||
format(format?: string): string,
|
||||
fromNow(removeSuffix?: boolean): string,
|
||||
from(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
toNow(removePrefix?: boolean): string,
|
||||
to(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
calendar(refTime?: any, formats?: moment$CalendarFormats): string,
|
||||
diff(
|
||||
date: moment$Moment | string | number | Date | Array<number>,
|
||||
format?: string,
|
||||
floating?: boolean
|
||||
): number,
|
||||
valueOf(): number,
|
||||
unix(): number,
|
||||
daysInMonth(): number,
|
||||
toDate(): Date,
|
||||
toArray(): Array<number>,
|
||||
toJSON(): string,
|
||||
toISOString(
|
||||
keepOffset?: boolean
|
||||
): string,
|
||||
toObject(): moment$MomentObject,
|
||||
isBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSame(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isBetween(
|
||||
fromDate: moment$Moment | string | number | Date | Array<number>,
|
||||
toDate?: ?moment$Moment | string | number | Date | Array<number>,
|
||||
granularity?: ?string,
|
||||
inclusion?: ?string
|
||||
): boolean,
|
||||
isDST(): boolean,
|
||||
isDSTShifted(): boolean,
|
||||
isLeapYear(): boolean,
|
||||
clone(): moment$Moment,
|
||||
static isMoment(obj: any): boolean,
|
||||
static isDate(obj: any): boolean,
|
||||
static locale(locale: string, localeData?: Object): string,
|
||||
static updateLocale(locale: string, localeData?: ?Object): void,
|
||||
static locale(locales: Array<string>): string,
|
||||
locale(locale: string, customization?: Object | null): moment$Moment,
|
||||
locale(): string,
|
||||
static months(): Array<string>,
|
||||
static monthsShort(): Array<string>,
|
||||
static weekdays(): Array<string>,
|
||||
static weekdaysShort(): Array<string>,
|
||||
static weekdaysMin(): Array<string>,
|
||||
static months(): string,
|
||||
static monthsShort(): string,
|
||||
static weekdays(): string,
|
||||
static weekdaysShort(): string,
|
||||
static weekdaysMin(): string,
|
||||
static localeData(key?: string): moment$LocaleData,
|
||||
static duration(
|
||||
value: number | Object | string,
|
||||
unit?: string
|
||||
): moment$MomentDuration,
|
||||
static isDuration(obj: any): boolean,
|
||||
static normalizeUnits(unit: string): string,
|
||||
static invalid(object: any): moment$Moment
|
||||
}
|
||||
|
||||
declare module "moment" {
|
||||
declare module.exports: Class<moment$Moment>;
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// flow-typed signature: ba35d02d668b0d0a3e04a63a6847974e
|
||||
// flow-typed version: <<STUB>>/react-jss_v8.6.1/flow_v0.79.1
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'react-jss'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'react-jss/dist/react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/dist/react-jss.min' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/contextTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/createHoc' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/getDisplayName' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/ns' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/propTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'react-jss/dist/react-jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss'>;
|
||||
}
|
||||
declare module 'react-jss/dist/react-jss.min.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss.min'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/contextTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/contextTypes'>;
|
||||
}
|
||||
declare module 'react-jss/lib/createHoc.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/createHoc'>;
|
||||
}
|
||||
declare module 'react-jss/lib/getDisplayName.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/getDisplayName'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/jss'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/ns.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/ns'>;
|
||||
}
|
||||
declare module 'react-jss/lib/propTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/propTypes'>;
|
||||
}
|
||||
@@ -3,12 +3,15 @@
|
||||
"license" : "BSD-3-Clause",
|
||||
"main": "src/main/js/index.js",
|
||||
"scripts": {
|
||||
"build": "ui-bundler plugin"
|
||||
"build": "ui-bundler plugin",
|
||||
"watch": "ui-bundler plugin -w",
|
||||
"lint": "ui-bundler lint",
|
||||
"flow": "flow check"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scm-manager/ui-extensions": "^0.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17"
|
||||
"@scm-manager/ui-bundler": "^0.0.19"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,20 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>sonia.scm.maven</groupId>
|
||||
<artifactId>smp-maven-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<corePlugin>true</corePlugin>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
@@ -61,33 +70,6 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.sdorra</groupId>
|
||||
<artifactId>buildfrontend-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>link-ui-types</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-types</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>link-ui-components</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-components</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -707,9 +707,9 @@
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||
|
||||
"@scm-manager/ui-bundler@^0.0.17":
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.17.tgz#949b90ca57e4268be28fcf4975bd9622f60278bb"
|
||||
"@scm-manager/ui-bundler@^0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.19.tgz#646ab1fa1e5389fad614542215c60678fb9816ae"
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
./node_modules/@scm-manager/ui-components/flow-typed
|
||||
|
||||
[options]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// flow-typed signature: cf86673cc32d185bdab1d2ea90578d37
|
||||
// flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x
|
||||
|
||||
type $npm$classnames$Classes =
|
||||
| string
|
||||
| { [className: string]: * }
|
||||
| false
|
||||
| void
|
||||
| null;
|
||||
|
||||
declare module "classnames" {
|
||||
declare module.exports: (
|
||||
...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]>
|
||||
) => string;
|
||||
}
|
||||
|
||||
declare module "classnames/bind" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
|
||||
declare module "classnames/dedupe" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
1108
scm-plugins/scm-hg-plugin/flow-typed/npm/jest_v23.x.x.js
vendored
1108
scm-plugins/scm-hg-plugin/flow-typed/npm/jest_v23.x.x.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,331 +0,0 @@
|
||||
// flow-typed signature: 23b805356f90ad9384dd88489654e380
|
||||
// flow-typed version: e9374c5fe9/moment_v2.3.x/flow_>=v0.25.x
|
||||
|
||||
type moment$MomentOptions = {
|
||||
y?: number | string,
|
||||
year?: number | string,
|
||||
years?: number | string,
|
||||
M?: number | string,
|
||||
month?: number | string,
|
||||
months?: number | string,
|
||||
d?: number | string,
|
||||
day?: number | string,
|
||||
days?: number | string,
|
||||
date?: number | string,
|
||||
h?: number | string,
|
||||
hour?: number | string,
|
||||
hours?: number | string,
|
||||
m?: number | string,
|
||||
minute?: number | string,
|
||||
minutes?: number | string,
|
||||
s?: number | string,
|
||||
second?: number | string,
|
||||
seconds?: number | string,
|
||||
ms?: number | string,
|
||||
millisecond?: number | string,
|
||||
milliseconds?: number | string
|
||||
};
|
||||
|
||||
type moment$MomentObject = {
|
||||
years: number,
|
||||
months: number,
|
||||
date: number,
|
||||
hours: number,
|
||||
minutes: number,
|
||||
seconds: number,
|
||||
milliseconds: number
|
||||
};
|
||||
|
||||
type moment$MomentCreationData = {
|
||||
input: string,
|
||||
format: string,
|
||||
locale: Object,
|
||||
isUTC: boolean,
|
||||
strict: boolean
|
||||
};
|
||||
|
||||
type moment$CalendarFormat = string | ((moment: moment$Moment) => string);
|
||||
|
||||
type moment$CalendarFormats = {
|
||||
sameDay?: moment$CalendarFormat,
|
||||
nextDay?: moment$CalendarFormat,
|
||||
nextWeek?: moment$CalendarFormat,
|
||||
lastDay?: moment$CalendarFormat,
|
||||
lastWeek?: moment$CalendarFormat,
|
||||
sameElse?: moment$CalendarFormat
|
||||
};
|
||||
|
||||
declare class moment$LocaleData {
|
||||
months(moment: moment$Moment): string,
|
||||
monthsShort(moment: moment$Moment): string,
|
||||
monthsParse(month: string): number,
|
||||
weekdays(moment: moment$Moment): string,
|
||||
weekdaysShort(moment: moment$Moment): string,
|
||||
weekdaysMin(moment: moment$Moment): string,
|
||||
weekdaysParse(weekDay: string): number,
|
||||
longDateFormat(dateFormat: string): string,
|
||||
isPM(date: string): boolean,
|
||||
meridiem(hours: number, minutes: number, isLower: boolean): string,
|
||||
calendar(
|
||||
key:
|
||||
| "sameDay"
|
||||
| "nextDay"
|
||||
| "lastDay"
|
||||
| "nextWeek"
|
||||
| "prevWeek"
|
||||
| "sameElse",
|
||||
moment: moment$Moment
|
||||
): string,
|
||||
relativeTime(
|
||||
number: number,
|
||||
withoutSuffix: boolean,
|
||||
key: "s" | "m" | "mm" | "h" | "hh" | "d" | "dd" | "M" | "MM" | "y" | "yy",
|
||||
isFuture: boolean
|
||||
): string,
|
||||
pastFuture(diff: any, relTime: string): string,
|
||||
ordinal(number: number): string,
|
||||
preparse(str: string): any,
|
||||
postformat(str: string): any,
|
||||
week(moment: moment$Moment): string,
|
||||
invalidDate(): string,
|
||||
firstDayOfWeek(): number,
|
||||
firstDayOfYear(): number
|
||||
}
|
||||
declare class moment$MomentDuration {
|
||||
humanize(suffix?: boolean): string,
|
||||
milliseconds(): number,
|
||||
asMilliseconds(): number,
|
||||
seconds(): number,
|
||||
asSeconds(): number,
|
||||
minutes(): number,
|
||||
asMinutes(): number,
|
||||
hours(): number,
|
||||
asHours(): number,
|
||||
days(): number,
|
||||
asDays(): number,
|
||||
months(): number,
|
||||
asWeeks(): number,
|
||||
weeks(): number,
|
||||
asMonths(): number,
|
||||
years(): number,
|
||||
asYears(): number,
|
||||
add(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
subtract(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
as(unit: string): number,
|
||||
get(unit: string): number,
|
||||
toJSON(): string,
|
||||
toISOString(): string,
|
||||
isValid(): boolean
|
||||
}
|
||||
declare class moment$Moment {
|
||||
static ISO_8601: string,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
locale?: string,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
initDate: ?Object | number | Date | Array<number> | moment$Moment | string
|
||||
): moment$Moment,
|
||||
static unix(seconds: number): moment$Moment,
|
||||
static utc(): moment$Moment,
|
||||
static utc(number: number | Array<number>): moment$Moment,
|
||||
static utc(
|
||||
str: string,
|
||||
str2?: string | Array<string>,
|
||||
str3?: string
|
||||
): moment$Moment,
|
||||
static utc(moment: moment$Moment): moment$Moment,
|
||||
static utc(date: Date): moment$Moment,
|
||||
static parseZone(): moment$Moment,
|
||||
static parseZone(rawDate: string): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string | Array<string>
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
locale: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
isValid(): boolean,
|
||||
invalidAt(): 0 | 1 | 2 | 3 | 4 | 5 | 6,
|
||||
creationData(): moment$MomentCreationData,
|
||||
millisecond(number: number): this,
|
||||
milliseconds(number: number): this,
|
||||
millisecond(): number,
|
||||
milliseconds(): number,
|
||||
second(number: number): this,
|
||||
seconds(number: number): this,
|
||||
second(): number,
|
||||
seconds(): number,
|
||||
minute(number: number): this,
|
||||
minutes(number: number): this,
|
||||
minute(): number,
|
||||
minutes(): number,
|
||||
hour(number: number): this,
|
||||
hours(number: number): this,
|
||||
hour(): number,
|
||||
hours(): number,
|
||||
date(number: number): this,
|
||||
dates(number: number): this,
|
||||
date(): number,
|
||||
dates(): number,
|
||||
day(day: number | string): this,
|
||||
days(day: number | string): this,
|
||||
day(): number,
|
||||
days(): number,
|
||||
weekday(number: number): this,
|
||||
weekday(): number,
|
||||
isoWeekday(number: number): this,
|
||||
isoWeekday(): number,
|
||||
dayOfYear(number: number): this,
|
||||
dayOfYear(): number,
|
||||
week(number: number): this,
|
||||
weeks(number: number): this,
|
||||
week(): number,
|
||||
weeks(): number,
|
||||
isoWeek(number: number): this,
|
||||
isoWeeks(number: number): this,
|
||||
isoWeek(): number,
|
||||
isoWeeks(): number,
|
||||
month(number: number): this,
|
||||
months(number: number): this,
|
||||
month(): number,
|
||||
months(): number,
|
||||
quarter(number: number): this,
|
||||
quarter(): number,
|
||||
year(number: number): this,
|
||||
years(number: number): this,
|
||||
year(): number,
|
||||
years(): number,
|
||||
weekYear(number: number): this,
|
||||
weekYear(): number,
|
||||
isoWeekYear(number: number): this,
|
||||
isoWeekYear(): number,
|
||||
weeksInYear(): number,
|
||||
isoWeeksInYear(): number,
|
||||
get(string: string): number,
|
||||
set(unit: string, value: number): this,
|
||||
set(options: { [unit: string]: number }): this,
|
||||
static max(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static max(dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(dates: Array<moment$Moment>): moment$Moment,
|
||||
add(
|
||||
value: number | moment$MomentDuration | moment$Moment | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
subtract(
|
||||
value: number | moment$MomentDuration | moment$Moment | string | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
startOf(unit: string): this,
|
||||
endOf(unit: string): this,
|
||||
local(): this,
|
||||
utc(): this,
|
||||
utcOffset(
|
||||
offset: number | string,
|
||||
keepLocalTime?: boolean,
|
||||
keepMinutes?: boolean
|
||||
): this,
|
||||
utcOffset(): number,
|
||||
format(format?: string): string,
|
||||
fromNow(removeSuffix?: boolean): string,
|
||||
from(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
toNow(removePrefix?: boolean): string,
|
||||
to(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
calendar(refTime?: any, formats?: moment$CalendarFormats): string,
|
||||
diff(
|
||||
date: moment$Moment | string | number | Date | Array<number>,
|
||||
format?: string,
|
||||
floating?: boolean
|
||||
): number,
|
||||
valueOf(): number,
|
||||
unix(): number,
|
||||
daysInMonth(): number,
|
||||
toDate(): Date,
|
||||
toArray(): Array<number>,
|
||||
toJSON(): string,
|
||||
toISOString(
|
||||
keepOffset?: boolean
|
||||
): string,
|
||||
toObject(): moment$MomentObject,
|
||||
isBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSame(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isBetween(
|
||||
fromDate: moment$Moment | string | number | Date | Array<number>,
|
||||
toDate?: ?moment$Moment | string | number | Date | Array<number>,
|
||||
granularity?: ?string,
|
||||
inclusion?: ?string
|
||||
): boolean,
|
||||
isDST(): boolean,
|
||||
isDSTShifted(): boolean,
|
||||
isLeapYear(): boolean,
|
||||
clone(): moment$Moment,
|
||||
static isMoment(obj: any): boolean,
|
||||
static isDate(obj: any): boolean,
|
||||
static locale(locale: string, localeData?: Object): string,
|
||||
static updateLocale(locale: string, localeData?: ?Object): void,
|
||||
static locale(locales: Array<string>): string,
|
||||
locale(locale: string, customization?: Object | null): moment$Moment,
|
||||
locale(): string,
|
||||
static months(): Array<string>,
|
||||
static monthsShort(): Array<string>,
|
||||
static weekdays(): Array<string>,
|
||||
static weekdaysShort(): Array<string>,
|
||||
static weekdaysMin(): Array<string>,
|
||||
static months(): string,
|
||||
static monthsShort(): string,
|
||||
static weekdays(): string,
|
||||
static weekdaysShort(): string,
|
||||
static weekdaysMin(): string,
|
||||
static localeData(key?: string): moment$LocaleData,
|
||||
static duration(
|
||||
value: number | Object | string,
|
||||
unit?: string
|
||||
): moment$MomentDuration,
|
||||
static isDuration(obj: any): boolean,
|
||||
static normalizeUnits(unit: string): string,
|
||||
static invalid(object: any): moment$Moment
|
||||
}
|
||||
|
||||
declare module "moment" {
|
||||
declare module.exports: Class<moment$Moment>;
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// flow-typed signature: ba35d02d668b0d0a3e04a63a6847974e
|
||||
// flow-typed version: <<STUB>>/react-jss_v8.6.1/flow_v0.79.1
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'react-jss'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'react-jss/dist/react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/dist/react-jss.min' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/contextTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/createHoc' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/getDisplayName' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/ns' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/propTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'react-jss/dist/react-jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss'>;
|
||||
}
|
||||
declare module 'react-jss/dist/react-jss.min.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss.min'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/contextTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/contextTypes'>;
|
||||
}
|
||||
declare module 'react-jss/lib/createHoc.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/createHoc'>;
|
||||
}
|
||||
declare module 'react-jss/lib/getDisplayName.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/getDisplayName'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/jss'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/ns.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/ns'>;
|
||||
}
|
||||
declare module 'react-jss/lib/propTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/propTypes'>;
|
||||
}
|
||||
@@ -9,6 +9,6 @@
|
||||
"@scm-manager/ui-extensions": "^0.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17"
|
||||
"@scm-manager/ui-bundler": "^0.0.19"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -54,7 +52,18 @@
|
||||
<strictCheck>true</strictCheck>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>sonia.scm.maven</groupId>
|
||||
<artifactId>smp-maven-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<corePlugin>true</corePlugin>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
@@ -68,33 +77,6 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.sdorra</groupId>
|
||||
<artifactId>buildfrontend-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>link-ui-types</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-types</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>link-ui-components</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-components</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -641,9 +641,9 @@
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||
|
||||
"@scm-manager/ui-bundler@^0.0.17":
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.17.tgz#949b90ca57e4268be28fcf4975bd9622f60278bb"
|
||||
"@scm-manager/ui-bundler@^0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.19.tgz#646ab1fa1e5389fad614542215c60678fb9816ae"
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
@@ -660,6 +660,7 @@
|
||||
browserify-css "^0.14.0"
|
||||
colors "^1.3.1"
|
||||
commander "^2.17.1"
|
||||
connect-history-api-fallback "^1.5.0"
|
||||
eslint "^5.4.0"
|
||||
eslint-config-react-app "^2.1.0"
|
||||
eslint-plugin-flowtype "^2.50.0"
|
||||
|
||||
@@ -23,4 +23,19 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>sonia.scm.maven</groupId>
|
||||
<artifactId>smp-maven-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<corePlugin>true</corePlugin>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
./node_modules/@scm-manager/ui-components/flow-typed
|
||||
|
||||
[options]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// flow-typed signature: cf86673cc32d185bdab1d2ea90578d37
|
||||
// flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x
|
||||
|
||||
type $npm$classnames$Classes =
|
||||
| string
|
||||
| { [className: string]: * }
|
||||
| false
|
||||
| void
|
||||
| null;
|
||||
|
||||
declare module "classnames" {
|
||||
declare module.exports: (
|
||||
...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]>
|
||||
) => string;
|
||||
}
|
||||
|
||||
declare module "classnames/bind" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
|
||||
declare module "classnames/dedupe" {
|
||||
declare module.exports: $Exports<"classnames">;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,331 +0,0 @@
|
||||
// flow-typed signature: 23b805356f90ad9384dd88489654e380
|
||||
// flow-typed version: e9374c5fe9/moment_v2.3.x/flow_>=v0.25.x
|
||||
|
||||
type moment$MomentOptions = {
|
||||
y?: number | string,
|
||||
year?: number | string,
|
||||
years?: number | string,
|
||||
M?: number | string,
|
||||
month?: number | string,
|
||||
months?: number | string,
|
||||
d?: number | string,
|
||||
day?: number | string,
|
||||
days?: number | string,
|
||||
date?: number | string,
|
||||
h?: number | string,
|
||||
hour?: number | string,
|
||||
hours?: number | string,
|
||||
m?: number | string,
|
||||
minute?: number | string,
|
||||
minutes?: number | string,
|
||||
s?: number | string,
|
||||
second?: number | string,
|
||||
seconds?: number | string,
|
||||
ms?: number | string,
|
||||
millisecond?: number | string,
|
||||
milliseconds?: number | string
|
||||
};
|
||||
|
||||
type moment$MomentObject = {
|
||||
years: number,
|
||||
months: number,
|
||||
date: number,
|
||||
hours: number,
|
||||
minutes: number,
|
||||
seconds: number,
|
||||
milliseconds: number
|
||||
};
|
||||
|
||||
type moment$MomentCreationData = {
|
||||
input: string,
|
||||
format: string,
|
||||
locale: Object,
|
||||
isUTC: boolean,
|
||||
strict: boolean
|
||||
};
|
||||
|
||||
type moment$CalendarFormat = string | ((moment: moment$Moment) => string);
|
||||
|
||||
type moment$CalendarFormats = {
|
||||
sameDay?: moment$CalendarFormat,
|
||||
nextDay?: moment$CalendarFormat,
|
||||
nextWeek?: moment$CalendarFormat,
|
||||
lastDay?: moment$CalendarFormat,
|
||||
lastWeek?: moment$CalendarFormat,
|
||||
sameElse?: moment$CalendarFormat
|
||||
};
|
||||
|
||||
declare class moment$LocaleData {
|
||||
months(moment: moment$Moment): string,
|
||||
monthsShort(moment: moment$Moment): string,
|
||||
monthsParse(month: string): number,
|
||||
weekdays(moment: moment$Moment): string,
|
||||
weekdaysShort(moment: moment$Moment): string,
|
||||
weekdaysMin(moment: moment$Moment): string,
|
||||
weekdaysParse(weekDay: string): number,
|
||||
longDateFormat(dateFormat: string): string,
|
||||
isPM(date: string): boolean,
|
||||
meridiem(hours: number, minutes: number, isLower: boolean): string,
|
||||
calendar(
|
||||
key:
|
||||
| "sameDay"
|
||||
| "nextDay"
|
||||
| "lastDay"
|
||||
| "nextWeek"
|
||||
| "prevWeek"
|
||||
| "sameElse",
|
||||
moment: moment$Moment
|
||||
): string,
|
||||
relativeTime(
|
||||
number: number,
|
||||
withoutSuffix: boolean,
|
||||
key: "s" | "m" | "mm" | "h" | "hh" | "d" | "dd" | "M" | "MM" | "y" | "yy",
|
||||
isFuture: boolean
|
||||
): string,
|
||||
pastFuture(diff: any, relTime: string): string,
|
||||
ordinal(number: number): string,
|
||||
preparse(str: string): any,
|
||||
postformat(str: string): any,
|
||||
week(moment: moment$Moment): string,
|
||||
invalidDate(): string,
|
||||
firstDayOfWeek(): number,
|
||||
firstDayOfYear(): number
|
||||
}
|
||||
declare class moment$MomentDuration {
|
||||
humanize(suffix?: boolean): string,
|
||||
milliseconds(): number,
|
||||
asMilliseconds(): number,
|
||||
seconds(): number,
|
||||
asSeconds(): number,
|
||||
minutes(): number,
|
||||
asMinutes(): number,
|
||||
hours(): number,
|
||||
asHours(): number,
|
||||
days(): number,
|
||||
asDays(): number,
|
||||
months(): number,
|
||||
asWeeks(): number,
|
||||
weeks(): number,
|
||||
asMonths(): number,
|
||||
years(): number,
|
||||
asYears(): number,
|
||||
add(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
subtract(value: number | moment$MomentDuration | Object, unit?: string): this,
|
||||
as(unit: string): number,
|
||||
get(unit: string): number,
|
||||
toJSON(): string,
|
||||
toISOString(): string,
|
||||
isValid(): boolean
|
||||
}
|
||||
declare class moment$Moment {
|
||||
static ISO_8601: string,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
string?: string,
|
||||
format?: string | Array<string>,
|
||||
locale?: string,
|
||||
strict?: boolean
|
||||
): moment$Moment,
|
||||
static (
|
||||
initDate: ?Object | number | Date | Array<number> | moment$Moment | string
|
||||
): moment$Moment,
|
||||
static unix(seconds: number): moment$Moment,
|
||||
static utc(): moment$Moment,
|
||||
static utc(number: number | Array<number>): moment$Moment,
|
||||
static utc(
|
||||
str: string,
|
||||
str2?: string | Array<string>,
|
||||
str3?: string
|
||||
): moment$Moment,
|
||||
static utc(moment: moment$Moment): moment$Moment,
|
||||
static utc(date: Date): moment$Moment,
|
||||
static parseZone(): moment$Moment,
|
||||
static parseZone(rawDate: string): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string | Array<string>
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
static parseZone(
|
||||
rawDate: string,
|
||||
format: string,
|
||||
locale: string,
|
||||
strict: boolean
|
||||
): moment$Moment,
|
||||
isValid(): boolean,
|
||||
invalidAt(): 0 | 1 | 2 | 3 | 4 | 5 | 6,
|
||||
creationData(): moment$MomentCreationData,
|
||||
millisecond(number: number): this,
|
||||
milliseconds(number: number): this,
|
||||
millisecond(): number,
|
||||
milliseconds(): number,
|
||||
second(number: number): this,
|
||||
seconds(number: number): this,
|
||||
second(): number,
|
||||
seconds(): number,
|
||||
minute(number: number): this,
|
||||
minutes(number: number): this,
|
||||
minute(): number,
|
||||
minutes(): number,
|
||||
hour(number: number): this,
|
||||
hours(number: number): this,
|
||||
hour(): number,
|
||||
hours(): number,
|
||||
date(number: number): this,
|
||||
dates(number: number): this,
|
||||
date(): number,
|
||||
dates(): number,
|
||||
day(day: number | string): this,
|
||||
days(day: number | string): this,
|
||||
day(): number,
|
||||
days(): number,
|
||||
weekday(number: number): this,
|
||||
weekday(): number,
|
||||
isoWeekday(number: number): this,
|
||||
isoWeekday(): number,
|
||||
dayOfYear(number: number): this,
|
||||
dayOfYear(): number,
|
||||
week(number: number): this,
|
||||
weeks(number: number): this,
|
||||
week(): number,
|
||||
weeks(): number,
|
||||
isoWeek(number: number): this,
|
||||
isoWeeks(number: number): this,
|
||||
isoWeek(): number,
|
||||
isoWeeks(): number,
|
||||
month(number: number): this,
|
||||
months(number: number): this,
|
||||
month(): number,
|
||||
months(): number,
|
||||
quarter(number: number): this,
|
||||
quarter(): number,
|
||||
year(number: number): this,
|
||||
years(number: number): this,
|
||||
year(): number,
|
||||
years(): number,
|
||||
weekYear(number: number): this,
|
||||
weekYear(): number,
|
||||
isoWeekYear(number: number): this,
|
||||
isoWeekYear(): number,
|
||||
weeksInYear(): number,
|
||||
isoWeeksInYear(): number,
|
||||
get(string: string): number,
|
||||
set(unit: string, value: number): this,
|
||||
set(options: { [unit: string]: number }): this,
|
||||
static max(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static max(dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(...dates: Array<moment$Moment>): moment$Moment,
|
||||
static min(dates: Array<moment$Moment>): moment$Moment,
|
||||
add(
|
||||
value: number | moment$MomentDuration | moment$Moment | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
subtract(
|
||||
value: number | moment$MomentDuration | moment$Moment | string | Object,
|
||||
unit?: string
|
||||
): this,
|
||||
startOf(unit: string): this,
|
||||
endOf(unit: string): this,
|
||||
local(): this,
|
||||
utc(): this,
|
||||
utcOffset(
|
||||
offset: number | string,
|
||||
keepLocalTime?: boolean,
|
||||
keepMinutes?: boolean
|
||||
): this,
|
||||
utcOffset(): number,
|
||||
format(format?: string): string,
|
||||
fromNow(removeSuffix?: boolean): string,
|
||||
from(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
toNow(removePrefix?: boolean): string,
|
||||
to(
|
||||
value: moment$Moment | string | number | Date | Array<number>,
|
||||
removePrefix?: boolean
|
||||
): string,
|
||||
calendar(refTime?: any, formats?: moment$CalendarFormats): string,
|
||||
diff(
|
||||
date: moment$Moment | string | number | Date | Array<number>,
|
||||
format?: string,
|
||||
floating?: boolean
|
||||
): number,
|
||||
valueOf(): number,
|
||||
unix(): number,
|
||||
daysInMonth(): number,
|
||||
toDate(): Date,
|
||||
toArray(): Array<number>,
|
||||
toJSON(): string,
|
||||
toISOString(
|
||||
keepOffset?: boolean
|
||||
): string,
|
||||
toObject(): moment$MomentObject,
|
||||
isBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSame(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrBefore(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isSameOrAfter(
|
||||
date?: moment$Moment | string | number | Date | Array<number>,
|
||||
units?: ?string
|
||||
): boolean,
|
||||
isBetween(
|
||||
fromDate: moment$Moment | string | number | Date | Array<number>,
|
||||
toDate?: ?moment$Moment | string | number | Date | Array<number>,
|
||||
granularity?: ?string,
|
||||
inclusion?: ?string
|
||||
): boolean,
|
||||
isDST(): boolean,
|
||||
isDSTShifted(): boolean,
|
||||
isLeapYear(): boolean,
|
||||
clone(): moment$Moment,
|
||||
static isMoment(obj: any): boolean,
|
||||
static isDate(obj: any): boolean,
|
||||
static locale(locale: string, localeData?: Object): string,
|
||||
static updateLocale(locale: string, localeData?: ?Object): void,
|
||||
static locale(locales: Array<string>): string,
|
||||
locale(locale: string, customization?: Object | null): moment$Moment,
|
||||
locale(): string,
|
||||
static months(): Array<string>,
|
||||
static monthsShort(): Array<string>,
|
||||
static weekdays(): Array<string>,
|
||||
static weekdaysShort(): Array<string>,
|
||||
static weekdaysMin(): Array<string>,
|
||||
static months(): string,
|
||||
static monthsShort(): string,
|
||||
static weekdays(): string,
|
||||
static weekdaysShort(): string,
|
||||
static weekdaysMin(): string,
|
||||
static localeData(key?: string): moment$LocaleData,
|
||||
static duration(
|
||||
value: number | Object | string,
|
||||
unit?: string
|
||||
): moment$MomentDuration,
|
||||
static isDuration(obj: any): boolean,
|
||||
static normalizeUnits(unit: string): string,
|
||||
static invalid(object: any): moment$Moment
|
||||
}
|
||||
|
||||
declare module "moment" {
|
||||
declare module.exports: Class<moment$Moment>;
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// flow-typed signature: ba35d02d668b0d0a3e04a63a6847974e
|
||||
// flow-typed version: <<STUB>>/react-jss_v8.6.1/flow_v0.79.1
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'react-jss'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'react-jss/dist/react-jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/dist/react-jss.min' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/compose.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/contextTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/createHoc' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/getDisplayName' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/index.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/injectSheet.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/jss' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/JssProvider.test' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/ns' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-jss/lib/propTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'react-jss/dist/react-jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss'>;
|
||||
}
|
||||
declare module 'react-jss/dist/react-jss.min.js' {
|
||||
declare module.exports: $Exports<'react-jss/dist/react-jss.min'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose'>;
|
||||
}
|
||||
declare module 'react-jss/lib/compose.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/compose.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/contextTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/contextTypes'>;
|
||||
}
|
||||
declare module 'react-jss/lib/createHoc.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/createHoc'>;
|
||||
}
|
||||
declare module 'react-jss/lib/getDisplayName.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/getDisplayName'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index'>;
|
||||
}
|
||||
declare module 'react-jss/lib/index.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/index.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet'>;
|
||||
}
|
||||
declare module 'react-jss/lib/injectSheet.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/injectSheet.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/jss.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/jss'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider'>;
|
||||
}
|
||||
declare module 'react-jss/lib/JssProvider.test.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/JssProvider.test'>;
|
||||
}
|
||||
declare module 'react-jss/lib/ns.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/ns'>;
|
||||
}
|
||||
declare module 'react-jss/lib/propTypes.js' {
|
||||
declare module.exports: $Exports<'react-jss/lib/propTypes'>;
|
||||
}
|
||||
@@ -9,6 +9,6 @@
|
||||
"@scm-manager/ui-extensions": "^0.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17"
|
||||
"@scm-manager/ui-bundler": "^0.0.19"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,19 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>sonia.scm.maven</groupId>
|
||||
<artifactId>smp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<corePlugin>true</corePlugin>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- create test jar -->
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
@@ -55,34 +63,6 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.sdorra</groupId>
|
||||
<artifactId>buildfrontend-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>link-ui-types</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-types</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>link-ui-components</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>install-link</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pkg>@scm-manager/ui-components</pkg>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* <p>
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* <p>
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -24,13 +24,11 @@
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* <p>
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -41,14 +39,12 @@ import org.slf4j.LoggerFactory;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.DefaultSVNDiffGenerator;
|
||||
import org.tmatesoft.svn.core.wc.ISVNDiffGenerator;
|
||||
import org.tmatesoft.svn.core.internal.wc2.ng.SvnNewDiffGenerator;
|
||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||
import org.tmatesoft.svn.core.wc.SVNDiffClient;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.SvnUtil;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.util.Util;
|
||||
@@ -61,8 +57,7 @@ import java.io.OutputStream;
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand
|
||||
{
|
||||
public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand {
|
||||
|
||||
/**
|
||||
* the logger for SvnDiffCommand
|
||||
@@ -70,46 +65,26 @@ public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(SvnDiffCommand.class);
|
||||
|
||||
public SvnDiffCommand(SvnContext context, Repository repository)
|
||||
{
|
||||
public SvnDiffCommand(SvnContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDiffResult(DiffCommandRequest request, OutputStream output) throws RevisionNotFoundException {
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("create diff for {}", request);
|
||||
}
|
||||
|
||||
public void getDiffResult(DiffCommandRequest request, OutputStream output) {
|
||||
logger.debug("create diff for {}", request);
|
||||
Preconditions.checkNotNull(request, "request is required");
|
||||
Preconditions.checkNotNull(output, "outputstream is required");
|
||||
|
||||
String path = request.getPath();
|
||||
SVNClientManager clientManager = null;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
SVNURL svnurl = context.createUrl();
|
||||
|
||||
if (Util.isNotEmpty(path))
|
||||
{
|
||||
if (Util.isNotEmpty(path)) {
|
||||
svnurl = svnurl.appendPath(path, true);
|
||||
}
|
||||
|
||||
clientManager = SVNClientManager.newInstance();
|
||||
|
||||
SVNDiffClient diffClient = clientManager.getDiffClient();
|
||||
ISVNDiffGenerator diffGenerator = diffClient.getDiffGenerator();
|
||||
|
||||
if (diffGenerator == null)
|
||||
{
|
||||
diffGenerator = new DefaultSVNDiffGenerator();
|
||||
}
|
||||
|
||||
diffGenerator.setDiffAdded(true);
|
||||
diffGenerator.setDiffDeleted(true);
|
||||
diffClient.setDiffGenerator(diffGenerator);
|
||||
diffClient.setDiffGenerator(new SvnNewDiffGenerator(new SCMSvnDiffGenerator()));
|
||||
|
||||
long currentRev = SvnUtil.getRevisionNumber(request.getRevision());
|
||||
|
||||
@@ -118,13 +93,9 @@ public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand
|
||||
diffClient.doDiff(svnurl, SVNRevision.HEAD,
|
||||
SVNRevision.create(currentRev - 1), SVNRevision.create(currentRev),
|
||||
SVNDepth.INFINITY, false, output);
|
||||
}
|
||||
catch (SVNException ex)
|
||||
{
|
||||
} catch (SVNException ex) {
|
||||
throw new InternalRepositoryException("could not create diff", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
SvnUtil.dispose(clientManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,9 +641,9 @@
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||
|
||||
"@scm-manager/ui-bundler@^0.0.17":
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.17.tgz#949b90ca57e4268be28fcf4975bd9622f60278bb"
|
||||
"@scm-manager/ui-bundler@^0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.19.tgz#646ab1fa1e5389fad614542215c60678fb9816ae"
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
|
||||
95
scm-ui-components/packages/ui-components/flow-typed/npm/react-i18next_v7.x.x.js
vendored
Normal file
95
scm-ui-components/packages/ui-components/flow-typed/npm/react-i18next_v7.x.x.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// flow-typed signature: 65d42f62f8de603dcc631ea5a6b00580
|
||||
// flow-typed version: f3f13164e0/react-i18next_v7.x.x/flow_>=v0.64.x
|
||||
|
||||
declare module "react-i18next" {
|
||||
declare type TFunction = (key?: ?string, data?: ?Object) => string;
|
||||
|
||||
declare type TranslatorProps = {|
|
||||
t: TFunction,
|
||||
i18nLoadedAt: Date,
|
||||
i18n: Object
|
||||
|};
|
||||
|
||||
declare type TranslatorPropsVoid = {
|
||||
t: TFunction | void,
|
||||
i18nLoadedAt: Date | void,
|
||||
i18n: Object | void
|
||||
};
|
||||
|
||||
declare type Translator<P: {}, Component: React$ComponentType<P>> = (
|
||||
WrappedComponent: Component
|
||||
) => React$ComponentType<
|
||||
$Diff<React$ElementConfig<Component>, TranslatorPropsVoid>
|
||||
>;
|
||||
|
||||
declare type TranslateOptions = $Shape<{
|
||||
wait: boolean,
|
||||
nsMode: "default" | "fallback",
|
||||
bindi18n: false | string,
|
||||
bindStore: false | string,
|
||||
withRef: boolean,
|
||||
translateFuncName: string,
|
||||
i18n: Object,
|
||||
usePureComponent: boolean
|
||||
}>;
|
||||
|
||||
declare function translate<P: {}, Component: React$ComponentType<P>>(
|
||||
namespaces?: | string
|
||||
| Array<string>
|
||||
| (($Diff<P, TranslatorPropsVoid>) => string | Array<string>),
|
||||
options?: TranslateOptions
|
||||
): Translator<P, Component>;
|
||||
|
||||
declare type I18nProps = {
|
||||
i18n?: Object,
|
||||
ns?: string | Array<string>,
|
||||
children: (t: TFunction, { i18n: Object, t: TFunction }) => React$Node,
|
||||
initialI18nStore?: Object,
|
||||
initialLanguage?: string
|
||||
};
|
||||
declare var I18n: React$ComponentType<I18nProps>;
|
||||
|
||||
declare type InterpolateProps = {
|
||||
className?: string,
|
||||
dangerouslySetInnerHTMLPartElement?: string,
|
||||
i18n?: Object,
|
||||
i18nKey?: string,
|
||||
options?: Object,
|
||||
parent?: string,
|
||||
style?: Object,
|
||||
t?: TFunction,
|
||||
useDangerouslySetInnerHTML?: boolean
|
||||
};
|
||||
declare var Interpolate: React$ComponentType<InterpolateProps>;
|
||||
|
||||
declare type TransProps = {
|
||||
count?: number,
|
||||
parent?: string,
|
||||
i18n?: Object,
|
||||
i18nKey?: string,
|
||||
t?: TFunction
|
||||
};
|
||||
declare var Trans: React$ComponentType<TransProps>;
|
||||
|
||||
declare type ProviderProps = { i18n: Object, children: React$Element<*> };
|
||||
declare var I18nextProvider: React$ComponentType<ProviderProps>;
|
||||
|
||||
declare type NamespacesProps = {
|
||||
components: Array<React$ComponentType<*>>,
|
||||
i18n: { loadNamespaces: Function }
|
||||
};
|
||||
declare function loadNamespaces(props: NamespacesProps): Promise<void>;
|
||||
|
||||
declare var reactI18nextModule: {
|
||||
type: "3rdParty",
|
||||
init: (instance: Object) => void
|
||||
};
|
||||
|
||||
declare function setDefaults(options: TranslateOptions): void;
|
||||
|
||||
declare function getDefaults(): TranslateOptions;
|
||||
|
||||
declare function getI18n(): Object;
|
||||
|
||||
declare function setI18n(instance: Object): void;
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
"eslint-fix": "eslint src --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17",
|
||||
"@scm-manager/ui-bundler": "^0.0.19",
|
||||
"create-index": "^2.3.0",
|
||||
"enzyme": "^3.5.0",
|
||||
"enzyme-adapter-react-16": "^1.3.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { withContextPath } from "./urls";
|
||||
import {withContextPath} from "./urls";
|
||||
|
||||
type Props = {
|
||||
src: string,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@flow
|
||||
import * as React from "react";
|
||||
import { Route, Link } from "react-router-dom";
|
||||
import {Link, Route} from "react-router-dom";
|
||||
|
||||
// TODO mostly copy of PrimaryNavigationLink
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @flow
|
||||
import { concat, getPageFromMatch, withEndingSlash } from "./urls";
|
||||
import {concat, getPageFromMatch, withEndingSlash} from "./urls";
|
||||
|
||||
describe("tests for withEndingSlash", () => {
|
||||
|
||||
|
||||
@@ -641,9 +641,9 @@
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||
|
||||
"@scm-manager/ui-bundler@^0.0.17":
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.17.tgz#949b90ca57e4268be28fcf4975bd9622f60278bb"
|
||||
"@scm-manager/ui-bundler@^0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.19.tgz#646ab1fa1e5389fad614542215c60678fb9816ae"
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"check": "flow check"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17"
|
||||
"@scm-manager/ui-bundler": "^0.0.19"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//@flow
|
||||
import type { Links } from "./hal";
|
||||
import type {Links} from "./hal";
|
||||
|
||||
export type Permission = PermissionCreateEntry & {
|
||||
_links: Links
|
||||
|
||||
@@ -707,9 +707,9 @@
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||
|
||||
"@scm-manager/ui-bundler@^0.0.17":
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.17.tgz#949b90ca57e4268be28fcf4975bd9622f60278bb"
|
||||
"@scm-manager/ui-bundler@^0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.19.tgz#646ab1fa1e5389fad614542215c60678fb9816ae"
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
|
||||
@@ -10,14 +10,18 @@
|
||||
"bulma": "^0.7.1",
|
||||
"bulma-tooltip": "^2.0.2",
|
||||
"classnames": "^2.2.5",
|
||||
"diff2html": "^2.4.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"history": "^4.7.2",
|
||||
"i18next": "^11.4.0",
|
||||
"i18next-browser-languagedetector": "^2.2.2",
|
||||
"i18next-fetch-backend": "^0.1.0",
|
||||
"moment": "^2.22.2",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"node-sass": "^4.9.3",
|
||||
"postcss-easy-import": "^3.0.0",
|
||||
"react": "^16.4.2",
|
||||
"react-diff-view": "^1.7.0",
|
||||
"react-dom": "^16.4.2",
|
||||
"react-i18next": "^7.9.0",
|
||||
"react-jss": "^8.6.0",
|
||||
"react-redux": "^5.0.7",
|
||||
@@ -44,7 +48,7 @@
|
||||
"pre-commit": "jest && flow && eslint src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scm-manager/ui-bundler": "^0.0.17",
|
||||
"@scm-manager/ui-bundler": "^0.0.19",
|
||||
"copyfiles": "^2.0.0",
|
||||
"enzyme": "^3.3.0",
|
||||
"enzyme-adapter-react-16": "^1.1.1",
|
||||
@@ -54,6 +58,7 @@
|
||||
"node-sass": "^4.9.3",
|
||||
"node-sass-chokidar": "^1.3.0",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"postcss-easy-import": "^3.0.0",
|
||||
"prettier": "^1.13.7",
|
||||
"react-router-enzyme-context": "^1.2.0",
|
||||
"react-test-renderer": "^16.4.1",
|
||||
|
||||
@@ -36,5 +36,9 @@
|
||||
</script>
|
||||
<script src="{{ contextPath }}/vendor.bundle.js"></script>
|
||||
<script src="{{ contextPath }}/scm-ui.bundle.js"></script>
|
||||
|
||||
{{#liveReloadURL}}
|
||||
<script src="{{liveReloadURL}}"></script>
|
||||
{{/liveReloadURL}}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { binder } from "@scm-manager/ui-extensions";
|
||||
import type { Changeset } from "@scm-manager/ui-types";
|
||||
import { Image } from "@scm-manager/ui-components";
|
||||
import {binder} from "@scm-manager/ui-extensions";
|
||||
import type {Changeset} from "@scm-manager/ui-types";
|
||||
import {Image} from "@scm-manager/ui-components";
|
||||
|
||||
type Props = {
|
||||
changeset: Changeset
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@flow
|
||||
import * as React from "react";
|
||||
import { binder } from "@scm-manager/ui-extensions";
|
||||
import {binder} from "@scm-manager/ui-extensions";
|
||||
|
||||
type Props = {
|
||||
children: React.Node
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import type {
|
||||
Changeset,
|
||||
Repository
|
||||
} from "../../../../../scm-ui-components/packages/ui-types/src/index";
|
||||
import type { Changeset, Repository } from "@scm-manager/ui-types";
|
||||
import { Interpolate, translate } from "react-i18next";
|
||||
import injectSheet from "react-jss";
|
||||
import ChangesetTag from "./ChangesetTag";
|
||||
import ChangesetAuthor from "./ChangesetAuthor";
|
||||
import { parseDescription } from "./changesets";
|
||||
import { DateFromNow } from "../../../../../scm-ui-components/packages/ui-components/src/index";
|
||||
import { DateFromNow } from "@scm-manager/ui-components";
|
||||
import AvatarWrapper from "./AvatarWrapper";
|
||||
import AvatarImage from "./AvatarImage";
|
||||
import classNames from "classnames";
|
||||
import ChangesetId from "./ChangesetId";
|
||||
import type { Tag } from "@scm-manager/ui-types";
|
||||
import ScmDiff from "../../containers/ScmDiff";
|
||||
|
||||
const styles = {
|
||||
spacing: {
|
||||
@@ -41,38 +39,43 @@ class ChangesetDetails extends React.Component<Props> {
|
||||
const date = <DateFromNow date={changeset.date} />;
|
||||
|
||||
return (
|
||||
<div className="content">
|
||||
<h4>{description.title}</h4>
|
||||
<article className="media">
|
||||
<AvatarWrapper>
|
||||
<p className={classNames("image", "is-64x64", classes.spacing)}>
|
||||
<AvatarImage changeset={changeset} />
|
||||
</p>
|
||||
</AvatarWrapper>
|
||||
<div className="media-content">
|
||||
<p>
|
||||
<ChangesetAuthor changeset={changeset} />
|
||||
</p>
|
||||
<p>
|
||||
<Interpolate
|
||||
i18nKey="changesets.changeset.summary"
|
||||
id={id}
|
||||
time={date}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div className="media-right">{this.renderTags()}</div>
|
||||
</article>
|
||||
<p>
|
||||
{description.message.split("\n").map((item, key) => {
|
||||
return (
|
||||
<span key={key}>
|
||||
{item}
|
||||
<br />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</p>
|
||||
<div>
|
||||
<div className="content">
|
||||
<h4>{description.title}</h4>
|
||||
<article className="media">
|
||||
<AvatarWrapper>
|
||||
<p className={classNames("image", "is-64x64", classes.spacing)}>
|
||||
<AvatarImage changeset={changeset} />
|
||||
</p>
|
||||
</AvatarWrapper>
|
||||
<div className="media-content">
|
||||
<p>
|
||||
<ChangesetAuthor changeset={changeset} />
|
||||
</p>
|
||||
<p>
|
||||
<Interpolate
|
||||
i18nKey="changesets.changeset.summary"
|
||||
id={id}
|
||||
time={date}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div className="media-right">{this.renderTags()}</div>
|
||||
</article>
|
||||
<p>
|
||||
{description.message.split("\n").map((item, key) => {
|
||||
return (
|
||||
<span key={key}>
|
||||
{item}
|
||||
<br />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<ScmDiff changeset={changeset} sideBySide={false} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//@flow
|
||||
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import React from "react";
|
||||
import type { Repository, Changeset } from "@scm-manager/ui-types";
|
||||
import type {Changeset, Repository} from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
repository: Repository,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import type { Changeset, Repository, Tag } from "@scm-manager/ui-types";
|
||||
import type {Changeset, Repository, Tag} from "@scm-manager/ui-types";
|
||||
import classNames from "classnames";
|
||||
import { translate, Interpolate } from "react-i18next";
|
||||
import {Interpolate, translate} from "react-i18next";
|
||||
import ChangesetId from "./ChangesetId";
|
||||
import injectSheet from "react-jss";
|
||||
import { DateFromNow } from "@scm-manager/ui-components";
|
||||
import {DateFromNow} from "@scm-manager/ui-components";
|
||||
import ChangesetAuthor from "./ChangesetAuthor";
|
||||
import ChangesetTag from "./ChangesetTag";
|
||||
import { compose } from "redux";
|
||||
import { parseDescription } from "./changesets";
|
||||
import {compose} from "redux";
|
||||
import {parseDescription} from "./changesets";
|
||||
import AvatarWrapper from "./AvatarWrapper";
|
||||
import AvatarImage from "./AvatarImage";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import { parseDescription } from "./changesets";
|
||||
import {parseDescription} from "./changesets";
|
||||
|
||||
describe("parseDescription tests", () => {
|
||||
it("should return a description with title and message", () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "../modules/changesets";
|
||||
import ChangesetDetails from "../components/changesets/ChangesetDetails";
|
||||
import { translate } from "react-i18next";
|
||||
import { Loading, ErrorPage } from "@scm-manager/ui-components";
|
||||
import { ErrorPage, Loading } from "@scm-manager/ui-components";
|
||||
|
||||
type Props = {
|
||||
id: string,
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
// @flow
|
||||
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import type {
|
||||
Branch,
|
||||
Changeset,
|
||||
PagedCollection,
|
||||
Repository
|
||||
} from "@scm-manager/ui-types";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import type {Branch, Changeset, PagedCollection, Repository} from "@scm-manager/ui-types";
|
||||
import {
|
||||
fetchChangesets,
|
||||
getChangesets,
|
||||
@@ -16,15 +11,10 @@ import {
|
||||
selectListAsCollection
|
||||
} from "../modules/changesets";
|
||||
|
||||
import { connect } from "react-redux";
|
||||
import {connect} from "react-redux";
|
||||
import ChangesetList from "../components/changesets/ChangesetList";
|
||||
import {
|
||||
ErrorNotification,
|
||||
LinkPaginator,
|
||||
Loading,
|
||||
getPageFromMatch
|
||||
} from "@scm-manager/ui-components";
|
||||
import { compose } from "redux";
|
||||
import {ErrorNotification, getPageFromMatch, LinkPaginator, Loading} from "@scm-manager/ui-components";
|
||||
import {compose} from "redux";
|
||||
|
||||
type Props = {
|
||||
repository: Repository,
|
||||
|
||||
@@ -80,11 +80,6 @@ class RepositoryRoot extends React.Component<Props> {
|
||||
this.props.deleteRepo(repository, this.deleted);
|
||||
};
|
||||
|
||||
matchChangeset = (route: any) => {
|
||||
const url = this.matchedUrl();
|
||||
return route.location.pathname.match(`${url}/changeset/`);
|
||||
};
|
||||
|
||||
matches = (route: any) => {
|
||||
const url = this.matchedUrl();
|
||||
const regex = new RegExp(`${url}(/branches)?/?[^/]*/changesets?.*`);
|
||||
@@ -125,7 +120,7 @@ class RepositoryRoot extends React.Component<Props> {
|
||||
/>
|
||||
<Route
|
||||
path={`${url}/permissions`}
|
||||
render={props => (
|
||||
render={() => (
|
||||
<Permissions
|
||||
namespace={this.props.repository.namespace}
|
||||
repoName={this.props.repository.name}
|
||||
|
||||
51
scm-ui/src/repos/containers/ScmDiff.js
Normal file
51
scm-ui/src/repos/containers/ScmDiff.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// @flow
|
||||
|
||||
import React from "react";
|
||||
import { apiClient } from "@scm-manager/ui-components";
|
||||
import type { Changeset } from "@scm-manager/ui-types";
|
||||
import { Diff2Html } from "diff2html";
|
||||
|
||||
type Props = {
|
||||
changeset: Changeset,
|
||||
sideBySide: boolean
|
||||
};
|
||||
|
||||
type State = {
|
||||
diff: string,
|
||||
error?: Error
|
||||
};
|
||||
|
||||
class ScmDiff extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = { diff: "" };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { changeset } = this.props;
|
||||
const url = changeset._links.diff.href+"?format=GIT";
|
||||
apiClient
|
||||
.get(url)
|
||||
.then(response => response.text())
|
||||
.then(text => this.setState({ ...this.state, diff: text }))
|
||||
.catch(error => this.setState({ ...this.state, error }));
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
inputFormat: "diff",
|
||||
outputFormat: this.props.sideBySide ? "side-by-side" : "line-by-line",
|
||||
showFiles: false,
|
||||
matching: "lines"
|
||||
};
|
||||
|
||||
const outputHtml = Diff2Html.getPrettyHtml(this.state.diff, options);
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line react/no-danger
|
||||
<div dangerouslySetInnerHTML={{ __html: outputHtml }} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ScmDiff;
|
||||
@@ -1,19 +1,10 @@
|
||||
// @flow
|
||||
|
||||
import {
|
||||
FAILURE_SUFFIX,
|
||||
PENDING_SUFFIX,
|
||||
SUCCESS_SUFFIX
|
||||
} from "../../modules/types";
|
||||
import { apiClient, urls } from "@scm-manager/ui-components";
|
||||
import { isPending } from "../../modules/pending";
|
||||
import { getFailure } from "../../modules/failure";
|
||||
import type {
|
||||
Action,
|
||||
Branch,
|
||||
PagedCollection,
|
||||
Repository
|
||||
} from "@scm-manager/ui-types";
|
||||
import {FAILURE_SUFFIX, PENDING_SUFFIX, SUCCESS_SUFFIX} from "../../modules/types";
|
||||
import {apiClient, urls} from "@scm-manager/ui-components";
|
||||
import {isPending} from "../../modules/pending";
|
||||
import {getFailure} from "../../modules/failure";
|
||||
import type {Action, Branch, PagedCollection, Repository} from "@scm-manager/ui-types";
|
||||
|
||||
export const FETCH_CHANGESETS = "scm/repos/FETCH_CHANGESETS";
|
||||
export const FETCH_CHANGESETS_PENDING = `${FETCH_CHANGESETS}_${PENDING_SUFFIX}`;
|
||||
|
||||
@@ -4,27 +4,27 @@ import configureMockStore from "redux-mock-store";
|
||||
import thunk from "redux-thunk";
|
||||
import fetchMock from "fetch-mock";
|
||||
import reducer, {
|
||||
FETCH_CHANGESETS,
|
||||
FETCH_CHANGESETS_FAILURE,
|
||||
FETCH_CHANGESETS_PENDING,
|
||||
FETCH_CHANGESETS_SUCCESS,
|
||||
FETCH_CHANGESET,
|
||||
FETCH_CHANGESET_FAILURE,
|
||||
FETCH_CHANGESET_PENDING,
|
||||
FETCH_CHANGESET_SUCCESS,
|
||||
FETCH_CHANGESETS,
|
||||
FETCH_CHANGESETS_FAILURE,
|
||||
FETCH_CHANGESETS_PENDING,
|
||||
FETCH_CHANGESETS_SUCCESS,
|
||||
fetchChangeset,
|
||||
fetchChangesetIfNeeded,
|
||||
fetchChangesets,
|
||||
fetchChangesetsSuccess,
|
||||
getChangesets,
|
||||
getFetchChangesetsFailure,
|
||||
isFetchChangesetsPending,
|
||||
fetchChangeset,
|
||||
getChangeset,
|
||||
fetchChangesetIfNeeded,
|
||||
shouldFetchChangeset,
|
||||
isFetchChangesetPending,
|
||||
getFetchChangesetFailure,
|
||||
fetchChangesetSuccess,
|
||||
selectListAsCollection
|
||||
getChangeset,
|
||||
getChangesets,
|
||||
getFetchChangesetFailure,
|
||||
getFetchChangesetsFailure,
|
||||
isFetchChangesetPending,
|
||||
isFetchChangesetsPending,
|
||||
selectListAsCollection,
|
||||
shouldFetchChangeset
|
||||
} from "./changesets";
|
||||
|
||||
const branch = {
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// @flow
|
||||
import React from "react";
|
||||
import { translate } from "react-i18next";
|
||||
import { Checkbox, InputField, SubmitButton } from "@scm-manager/ui-components";
|
||||
import {translate} from "react-i18next";
|
||||
import {Checkbox, InputField, SubmitButton} from "@scm-manager/ui-components";
|
||||
import TypeSelector from "./TypeSelector";
|
||||
import type {
|
||||
PermissionCollection,
|
||||
PermissionCreateEntry
|
||||
} from "@scm-manager/ui-types";
|
||||
import type {PermissionCollection, PermissionCreateEntry} from "@scm-manager/ui-types";
|
||||
import * as validator from "./permissionValidation";
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
import { validation } from "@scm-manager/ui-components";
|
||||
import type { PermissionCollection } from "@scm-manager/ui-types";
|
||||
import {validation} from "@scm-manager/ui-components";
|
||||
import type {PermissionCollection} from "@scm-manager/ui-types";
|
||||
|
||||
const isNameValid = validation.isNameValid;
|
||||
|
||||
export { isNameValid };
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
// @flow
|
||||
|
||||
import { apiClient } from "@scm-manager/ui-components";
|
||||
import type {Action} from "@scm-manager/ui-components";
|
||||
import {apiClient} from "@scm-manager/ui-components";
|
||||
import * as types from "../../../modules/types";
|
||||
import type { Action } from "@scm-manager/ui-components";
|
||||
import type {
|
||||
PermissionCollection,
|
||||
Permission,
|
||||
PermissionCreateEntry
|
||||
} from "@scm-manager/ui-types";
|
||||
import { isPending } from "../../../modules/pending";
|
||||
import { getFailure } from "../../../modules/failure";
|
||||
import { Dispatch } from "redux";
|
||||
import type {Permission, PermissionCollection, PermissionCreateEntry} from "@scm-manager/ui-types";
|
||||
import {isPending} from "../../../modules/pending";
|
||||
import {getFailure} from "../../../modules/failure";
|
||||
import {Dispatch} from "redux";
|
||||
|
||||
export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
|
||||
export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
|
||||
|
||||
@@ -3,44 +3,44 @@ import configureMockStore from "redux-mock-store";
|
||||
import thunk from "redux-thunk";
|
||||
import fetchMock from "fetch-mock";
|
||||
import reducer, {
|
||||
fetchPermissions,
|
||||
fetchPermissionsSuccess,
|
||||
getPermissionsOfRepo,
|
||||
isFetchPermissionsPending,
|
||||
getFetchPermissionsFailure,
|
||||
modifyPermission,
|
||||
modifyPermissionSuccess,
|
||||
getModifyPermissionFailure,
|
||||
isModifyPermissionPending,
|
||||
createPermission,
|
||||
hasCreatePermission,
|
||||
deletePermission,
|
||||
deletePermissionSuccess,
|
||||
getDeletePermissionFailure,
|
||||
isDeletePermissionPending,
|
||||
getModifyPermissionsFailure,
|
||||
MODIFY_PERMISSION_FAILURE,
|
||||
MODIFY_PERMISSION_PENDING,
|
||||
FETCH_PERMISSIONS,
|
||||
FETCH_PERMISSIONS_PENDING,
|
||||
FETCH_PERMISSIONS_SUCCESS,
|
||||
FETCH_PERMISSIONS_FAILURE,
|
||||
MODIFY_PERMISSION_SUCCESS,
|
||||
MODIFY_PERMISSION,
|
||||
CREATE_PERMISSION,
|
||||
CREATE_PERMISSION_FAILURE,
|
||||
CREATE_PERMISSION_PENDING,
|
||||
CREATE_PERMISSION_SUCCESS,
|
||||
CREATE_PERMISSION_FAILURE,
|
||||
createPermission,
|
||||
createPermissionSuccess,
|
||||
DELETE_PERMISSION,
|
||||
DELETE_PERMISSION_FAILURE,
|
||||
DELETE_PERMISSION_PENDING,
|
||||
DELETE_PERMISSION_SUCCESS,
|
||||
DELETE_PERMISSION_FAILURE,
|
||||
CREATE_PERMISSION,
|
||||
createPermissionSuccess,
|
||||
deletePermission,
|
||||
deletePermissionSuccess,
|
||||
FETCH_PERMISSIONS,
|
||||
FETCH_PERMISSIONS_FAILURE,
|
||||
FETCH_PERMISSIONS_PENDING,
|
||||
FETCH_PERMISSIONS_SUCCESS,
|
||||
fetchPermissions,
|
||||
fetchPermissionsSuccess,
|
||||
getCreatePermissionFailure,
|
||||
getDeletePermissionFailure,
|
||||
getDeletePermissionsFailure,
|
||||
getFetchPermissionsFailure,
|
||||
getModifyPermissionFailure,
|
||||
getModifyPermissionsFailure,
|
||||
getPermissionsOfRepo,
|
||||
hasCreatePermission,
|
||||
isCreatePermissionPending,
|
||||
getDeletePermissionsFailure
|
||||
isDeletePermissionPending,
|
||||
isFetchPermissionsPending,
|
||||
isModifyPermissionPending,
|
||||
MODIFY_PERMISSION,
|
||||
MODIFY_PERMISSION_FAILURE,
|
||||
MODIFY_PERMISSION_PENDING,
|
||||
MODIFY_PERMISSION_SUCCESS,
|
||||
modifyPermission,
|
||||
modifyPermissionSuccess
|
||||
} from "./permissions";
|
||||
import type { Permission, PermissionCollection } from "@scm-manager/ui-types";
|
||||
import type {Permission, PermissionCollection} from "@scm-manager/ui-types";
|
||||
|
||||
const hitchhiker_puzzle42Permission_user_eins: Permission = {
|
||||
name: "user_eins",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "bulma/sass/utilities/initial-variables";
|
||||
@import "bulma/sass/utilities/functions";
|
||||
|
||||
|
||||
$blue: #33B2E8;
|
||||
|
||||
// $footer-background-color
|
||||
@@ -52,3 +53,5 @@ $blue: #33B2E8;
|
||||
@import "@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
||||
$fa-font-path: "webfonts";
|
||||
@import "@fortawesome/fontawesome-free/scss/solid.scss";
|
||||
|
||||
@import "diff2html/dist/diff2html";
|
||||
|
||||
1454
scm-ui/yarn.lock
1454
scm-ui/yarn.lock
File diff suppressed because it is too large
Load Diff
20
scm-webapp/src/main/java/sonia/scm/ResteasyModule.java
Normal file
20
scm-webapp/src/main/java/sonia/scm/ResteasyModule.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package sonia.scm;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
|
||||
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
|
||||
public class ResteasyModule extends ServletModule {
|
||||
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
bind(HttpServletDispatcher.class).in(Singleton.class);
|
||||
|
||||
Map<String, String> initParams = ImmutableMap.of(ResteasyContextParameters.RESTEASY_SERVLET_MAPPING_PREFIX, "/api");
|
||||
serve("/api/*").with(HttpServletDispatcher.class, initParams);
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,7 @@ public class ScmContextListener extends GuiceResteasyBootstrapServletContextList
|
||||
ClassOverrides overrides = ClassOverrides.findOverrides(pluginLoader.getUberClassLoader());
|
||||
List<Module> moduleList = Lists.newArrayList();
|
||||
|
||||
moduleList.add(new ResteasyModule());
|
||||
moduleList.add(new ScmInitializerModule());
|
||||
moduleList.add(new ScmEventBusModule());
|
||||
moduleList.add(new EagerSingletonModule());
|
||||
|
||||
@@ -57,5 +57,9 @@ public class TemplatingPushStateDispatcher implements PushStateDispatcher {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
public String getLiveReloadURL() {
|
||||
return System.getProperty("livereload.url");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.LogCommandBuilder;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
@@ -26,6 +25,7 @@ import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@@ -89,7 +89,7 @@ public class ChangesetRootResource {
|
||||
@Produces(VndMediaType.CHANGESET)
|
||||
@TypeHint(ChangesetDto.class)
|
||||
@Path("{id}")
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws IOException, RevisionNotFoundException, RepositoryNotFoundException {
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws IOException {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
Repository repository = repositoryService.getRepository();
|
||||
RepositoryPermissions.read(repository).check();
|
||||
@@ -97,8 +97,12 @@ public class ChangesetRootResource {
|
||||
.setStartChangeset(id)
|
||||
.setEndChangeset(id)
|
||||
.getChangesets();
|
||||
if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) {
|
||||
return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build();
|
||||
if (changesets != null && changesets.getChangesets() != null && !changesets.getChangesets().isEmpty()) {
|
||||
Optional<Changeset> changeset = changesets.getChangesets().stream().filter(ch -> ch.getId().equals(id)).findFirst();
|
||||
if (!changeset.isPresent()) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
return Response.ok(changesetToChangesetDtoMapper.map(changeset.get(), repository)).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
@@ -5,16 +5,20 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
@@ -22,6 +26,9 @@ import javax.ws.rs.core.StreamingOutput;
|
||||
public class DiffRootResource {
|
||||
|
||||
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||
|
||||
private static final String DIFF_FORMAT_VALUES_REGEX = "NATIVE|GIT|UNIFIED";
|
||||
|
||||
private final RepositoryServiceFactory serviceFactory;
|
||||
|
||||
@Inject
|
||||
@@ -50,13 +57,15 @@ public class DiffRootResource {
|
||||
@ResponseCode(code = 404, condition = "not found, no revision with the specified param for the repository available or repository not found"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision){
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision , @Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") @QueryParam("format") String format ){
|
||||
HttpUtil.checkForCRLFInjection(revision);
|
||||
DiffFormat diffFormat = DiffFormat.valueOf(format);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
StreamingOutput responseEntry = output -> {
|
||||
try {
|
||||
repositoryService.getDiffCommand()
|
||||
.setRevision(revision)
|
||||
.setFormat(diffFormat)
|
||||
.retriveContent(output);
|
||||
} catch (RevisionNotFoundException e) {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
|
||||
@@ -34,22 +34,19 @@ package sonia.scm.boot;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.github.legman.Subscribe;
|
||||
|
||||
import com.google.inject.servlet.GuiceFilter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -65,6 +62,8 @@ public class BootstrapContextFilter extends GuiceFilter
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
private final BootstrapContextListener listener = new BootstrapContextListener();
|
||||
|
||||
/**
|
||||
* Restart the whole webapp context.
|
||||
*
|
||||
@@ -85,29 +84,20 @@ public class BootstrapContextFilter extends GuiceFilter
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
logger.warn(
|
||||
"destroy filter pipeline, because of a received restart event");
|
||||
logger.warn("destroy filter pipeline, because of a received restart event");
|
||||
destroy();
|
||||
logger.warn(
|
||||
"reinitialize filter pipeline, because of a received restart event");
|
||||
super.init(filterConfig);
|
||||
|
||||
logger.warn("reinitialize filter pipeline, because of a received restart event");
|
||||
initGuice();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param filterConfig
|
||||
*
|
||||
* @throws ServletException
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
this.filterConfig = filterConfig;
|
||||
super.init(filterConfig);
|
||||
|
||||
initGuice();
|
||||
|
||||
if (SCMContext.getContext().getStage() == Stage.DEVELOPMENT)
|
||||
{
|
||||
@@ -116,6 +106,19 @@ public class BootstrapContextFilter extends GuiceFilter
|
||||
}
|
||||
}
|
||||
|
||||
public void initGuice() throws ServletException {
|
||||
super.init(filterConfig);
|
||||
|
||||
listener.contextInitialized(new ServletContextEvent(filterConfig.getServletContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
listener.contextDestroyed(new ServletContextEvent(filterConfig.getServletContext()));
|
||||
ServletContextCleaner.cleanup(filterConfig.getServletContext());
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
|
||||
@@ -148,13 +148,15 @@ public class BootstrapContextListener implements ServletContextListener
|
||||
{
|
||||
context = sce.getServletContext();
|
||||
|
||||
PluginIndex index = readCorePluginIndex(context);
|
||||
|
||||
File pluginDirectory = getPluginDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
extractCorePlugins(context, pluginDirectory, index);
|
||||
if (!isCorePluginExtractionDisabled()) {
|
||||
extractCorePlugins(context, pluginDirectory);
|
||||
} else {
|
||||
logger.info("core plugin extraction is disabled");
|
||||
}
|
||||
|
||||
ClassLoader cl =
|
||||
ClassLoaders.getContextClassLoader(BootstrapContextListener.class);
|
||||
@@ -181,31 +183,8 @@ public class BootstrapContextListener implements ServletContextListener
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart the whole webapp context.
|
||||
*
|
||||
*
|
||||
* @param event restart event
|
||||
*/
|
||||
@Subscribe
|
||||
public void handleRestartEvent(RestartEvent event)
|
||||
{
|
||||
logger.warn("received restart event from {} with reason: {}",
|
||||
event.getCause(), event.getReason());
|
||||
|
||||
if (context == null)
|
||||
{
|
||||
logger.error("context is null, scm-manager is not initialized");
|
||||
}
|
||||
else
|
||||
{
|
||||
ServletContextEvent sce = new ServletContextEvent(context);
|
||||
|
||||
logger.warn("destroy context, because of a received restart event");
|
||||
contextDestroyed(sce);
|
||||
logger.warn("reinitialize context, because of a received restart event");
|
||||
contextInitialized(sce);
|
||||
}
|
||||
private boolean isCorePluginExtractionDisabled() {
|
||||
return Boolean.getBoolean("sonia.scm.boot.disable-core-plugin-extraction");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +193,6 @@ public class BootstrapContextListener implements ServletContextListener
|
||||
*
|
||||
* @param context
|
||||
* @param pluginDirectory
|
||||
* @param name
|
||||
* @param entry
|
||||
*
|
||||
* @throws IOException
|
||||
@@ -269,17 +247,15 @@ public class BootstrapContextListener implements ServletContextListener
|
||||
*
|
||||
* @param context
|
||||
* @param pluginDirectory
|
||||
* @param lines
|
||||
* @param index
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void extractCorePlugins(ServletContext context, File pluginDirectory,
|
||||
PluginIndex index)
|
||||
throws IOException
|
||||
private void extractCorePlugins(ServletContext context, File pluginDirectory) throws IOException
|
||||
{
|
||||
IOUtil.mkdirs(pluginDirectory);
|
||||
|
||||
PluginIndex index = readCorePluginIndex(context);
|
||||
|
||||
for (PluginIndexEntry entry : index)
|
||||
{
|
||||
extractCorePlugin(context, pluginDirectory, entry);
|
||||
|
||||
97
scm-webapp/src/main/java/sonia/scm/boot/RestartServlet.java
Normal file
97
scm-webapp/src/main/java/sonia/scm/boot/RestartServlet.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package sonia.scm.boot;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.Priority;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.filter.WebElement;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* This servlet sends a {@link RestartEvent} to the {@link ScmEventBus} which causes scm-manager to restart the context.
|
||||
* The {@link RestartServlet} can be used for reloading java code or for installing plugins without a complete restart.
|
||||
* At the moment the Servlet accepts only request, if scm-manager was started in the {@link Stage#DEVELOPMENT} stage.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Priority(0)
|
||||
@WebElement("/restart")
|
||||
public class RestartServlet extends HttpServlet {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RestartServlet.class);
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final AtomicBoolean restarting = new AtomicBoolean();
|
||||
|
||||
private final ScmEventBus eventBus;
|
||||
private final Stage stage;
|
||||
|
||||
@Inject
|
||||
public RestartServlet() {
|
||||
this(ScmEventBus.getInstance(), SCMContext.getContext().getStage());
|
||||
}
|
||||
|
||||
RestartServlet(ScmEventBus eventBus, Stage stage) {
|
||||
this.eventBus = eventBus;
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOG.info("received sendRestartEvent request");
|
||||
|
||||
if (isRestartAllowed()) {
|
||||
|
||||
try (InputStream requestInput = req.getInputStream()) {
|
||||
Reason reason = objectMapper.readValue(requestInput, Reason.class);
|
||||
sendRestartEvent(resp, reason);
|
||||
} catch (IOException ex) {
|
||||
LOG.warn("failed to trigger sendRestartEvent event", ex);
|
||||
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
} else {
|
||||
LOG.debug("received restart event in non development stage");
|
||||
resp.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRestartAllowed() {
|
||||
return stage == Stage.DEVELOPMENT;
|
||||
}
|
||||
|
||||
private void sendRestartEvent(HttpServletResponse response, Reason reason) {
|
||||
if ( restarting.compareAndSet(false, true) ) {
|
||||
LOG.info("trigger sendRestartEvent, because of {}", reason.getMessage());
|
||||
eventBus.post(new RestartEvent(RestartServlet.class, reason.getMessage()));
|
||||
|
||||
response.setStatus(HttpServletResponse.SC_ACCEPTED);
|
||||
} else {
|
||||
LOG.warn("scm-manager restarts already");
|
||||
response.setStatus(HttpServletResponse.SC_CONFLICT);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reason {
|
||||
|
||||
private String message;
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package sonia.scm.boot;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Remove cached resources from {@link ServletContext} to allow a clean restart of scm-manager without stale or
|
||||
* duplicated data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
final class ServletContextCleaner {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServletContextCleaner.class);
|
||||
|
||||
private static final Set<String> REMOVE_PREFIX = ImmutableSet.of(
|
||||
"org.jboss.resteasy",
|
||||
"resteasy",
|
||||
"org.apache.shiro",
|
||||
"sonia.scm"
|
||||
);
|
||||
|
||||
private ServletContextCleaner() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cached attributes from {@link ServletContext}.
|
||||
*
|
||||
* @param servletContext servlet context
|
||||
*/
|
||||
static void cleanup(ServletContext servletContext) {
|
||||
LOG.info("remove cached attributes from context");
|
||||
|
||||
Enumeration<String> attributeNames = servletContext.getAttributeNames();
|
||||
while( attributeNames.hasMoreElements()) {
|
||||
String name = attributeNames.nextElement();
|
||||
if (shouldRemove(name)) {
|
||||
LOG.info("remove attribute {} from servlet context", name);
|
||||
servletContext.removeAttribute(name);
|
||||
} else {
|
||||
LOG.info("keep attribute {} in servlet context", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRemove(String name) {
|
||||
for (String prefix : REMOVE_PREFIX) {
|
||||
if (name.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.Stage;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.net.MalformedURLException;
|
||||
@@ -69,19 +71,21 @@ public class DefaultUberWebResourceLoader implements UberWebResourceLoader
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param servletContext
|
||||
* @param plugins
|
||||
*/
|
||||
public DefaultUberWebResourceLoader(ServletContext servletContext,
|
||||
Iterable<PluginWrapper> plugins)
|
||||
{
|
||||
public DefaultUberWebResourceLoader(ServletContext servletContext, Iterable<PluginWrapper> plugins) {
|
||||
this(servletContext, plugins, SCMContext.getContext().getStage());
|
||||
}
|
||||
|
||||
public DefaultUberWebResourceLoader(ServletContext servletContext, Iterable<PluginWrapper> plugins, Stage stage) {
|
||||
this.servletContext = servletContext;
|
||||
this.plugins = plugins;
|
||||
this.cache = CacheBuilder.newBuilder().build();
|
||||
this.cache = createCache(stage);
|
||||
}
|
||||
|
||||
private Cache<String, URL> createCache(Stage stage) {
|
||||
if (stage == Stage.DEVELOPMENT) {
|
||||
return CacheBuilder.newBuilder().maximumSize(0).build(); // Disable caching
|
||||
}
|
||||
return CacheBuilder.newBuilder().build();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
@@ -97,7 +101,7 @@ public class DefaultUberWebResourceLoader implements UberWebResourceLoader
|
||||
@Override
|
||||
public URL getResource(String path)
|
||||
{
|
||||
URL resource = cache.getIfPresent(path);
|
||||
URL resource = getFromCache(path);
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
@@ -105,7 +109,7 @@ public class DefaultUberWebResourceLoader implements UberWebResourceLoader
|
||||
|
||||
if (resource != null)
|
||||
{
|
||||
cache.put(path, resource);
|
||||
addToCache(path, resource);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -116,6 +120,14 @@ public class DefaultUberWebResourceLoader implements UberWebResourceLoader
|
||||
return resource;
|
||||
}
|
||||
|
||||
private URL getFromCache(String path) {
|
||||
return cache.getIfPresent(path);
|
||||
}
|
||||
|
||||
private void addToCache(String path, URL url) {
|
||||
cache.put(path, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -65,9 +65,6 @@
|
||||
<logger name="sonia.scm.event.LegmanScmEventBus" level="DEBUG" />
|
||||
<logger name="sonia.scm.plugin.ext.DefaultAnnotationScanner" level="INFO" />
|
||||
<logger name="sonia.scm.security.ConfigurableLoginAttemptHandler" level="DEBUG" />
|
||||
|
||||
<!-- event bus -->
|
||||
<logger name="sonia.scm.event.LegmanScmEventBus" level="INFO" />
|
||||
|
||||
<!-- cgi -->
|
||||
<logger name="sonia.scm.web.cgi.DefaultCGIExecutor" level="DEBUG" />
|
||||
@@ -93,7 +90,9 @@
|
||||
<logger name="net.sf.ehcache" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<logger name="org.jboss.resteasy" level="DEBUG" />
|
||||
<logger name="org.jboss.resteasy" level="INFO" />
|
||||
|
||||
<logger name="sonia.scm.boot.RestartServlet" level="TRACE" />
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
|
||||
@@ -41,10 +41,6 @@
|
||||
|
||||
<!-- bootstraping -->
|
||||
|
||||
<listener>
|
||||
<listener-class>sonia.scm.boot.BootstrapContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>BootstrapFilter</filter-name>
|
||||
<filter-class>sonia.scm.boot.BootstrapContextFilter</filter-class>
|
||||
@@ -55,25 +51,6 @@
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<!-- rest -->
|
||||
|
||||
<context-param>
|
||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||
<param-value>/api</param-value>
|
||||
</context-param>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Resteasy</servlet-name>
|
||||
<servlet-class>
|
||||
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
|
||||
</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>Resteasy</servlet-name>
|
||||
<url-pattern>/api/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- capture sessions -->
|
||||
<!--
|
||||
TODO remove, we need no longer a session
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -45,6 +46,23 @@ public class TemplatingPushStateDispatcherTest {
|
||||
|
||||
@Test
|
||||
public void testDispatch() throws IOException {
|
||||
TemplatingPushStateDispatcher.IndexHtmlModel model = dispatch();
|
||||
assertEquals("/scm", model.getContextPath());
|
||||
assertNull(model.getLiveReloadURL());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchWithLiveReloadURL() throws IOException {
|
||||
System.setProperty("livereload.url", "/livereload.js");
|
||||
try {
|
||||
TemplatingPushStateDispatcher.IndexHtmlModel model = dispatch();
|
||||
assertEquals("/livereload.js", model.getLiveReloadURL());
|
||||
} finally {
|
||||
System.clearProperty("livereload.url");
|
||||
}
|
||||
}
|
||||
|
||||
private TemplatingPushStateDispatcher.IndexHtmlModel dispatch() throws IOException {
|
||||
when(request.getContextPath()).thenReturn("/scm");
|
||||
when(templateEngine.getTemplate(TemplatingPushStateDispatcher.TEMPLATE)).thenReturn(template);
|
||||
|
||||
@@ -59,8 +77,7 @@ public class TemplatingPushStateDispatcherTest {
|
||||
|
||||
verify(template).execute(any(Writer.class), captor.capture());
|
||||
|
||||
TemplatingPushStateDispatcher.IndexHtmlModel model = (TemplatingPushStateDispatcher.IndexHtmlModel) captor.getValue();
|
||||
assertEquals("/scm", model.getContextPath());
|
||||
return (TemplatingPushStateDispatcher.IndexHtmlModel) captor.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
|
||||
when(logCommandBuilder.setStartChangeset(anyString())).thenReturn(logCommandBuilder);
|
||||
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get(CHANGESET_URL + "id")
|
||||
.get(CHANGESET_URL + id)
|
||||
.accept(VndMediaType.CHANGESET);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -18,19 +18,23 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.api.rest.AuthorizationExceptionMapper;
|
||||
import sonia.scm.api.rest.IllegalArgumentExceptionMapper;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -72,6 +76,7 @@ public class DiffResourceTest extends RepositoryTestBase {
|
||||
dispatcher.getProviderFactory().registerProvider(NotFoundExceptionMapper.class);
|
||||
dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class);
|
||||
dispatcher.getProviderFactory().registerProvider(CRLFInjectionExceptionMapper.class);
|
||||
dispatcher.getProviderFactory().registerProvider(IllegalArgumentExceptionMapper.class);
|
||||
when(service.getDiffCommand()).thenReturn(diffCommandBuilder);
|
||||
subjectThreadState.bind();
|
||||
ThreadContext.bind(subject);
|
||||
@@ -86,19 +91,17 @@ public class DiffResourceTest extends RepositoryTestBase {
|
||||
@Test
|
||||
public void shouldGetDiffs() throws Exception {
|
||||
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.retriveContent(any())).thenReturn(diffCommandBuilder);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get(DIFF_URL + "revision")
|
||||
.accept(VndMediaType.DIFF);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
assertEquals(200, response.getStatus());
|
||||
log.info("Response :{}", response.getContentAsString());
|
||||
|
||||
assertThat(response.getStatus())
|
||||
.isEqualTo(200);
|
||||
assertThat(response.getContentAsString())
|
||||
.isNotNull();
|
||||
String expectedHeader = "Content-Disposition";
|
||||
String expectedValue = "attachment; filename=\"repo-revision.diff\"; filename*=utf-8''repo-revision.diff";
|
||||
assertThat(response.getOutputHeaders().containsKey(expectedHeader)).isTrue();
|
||||
@@ -120,6 +123,7 @@ public class DiffResourceTest extends RepositoryTestBase {
|
||||
@Test
|
||||
public void shouldGet404OnMissingRevision() throws Exception {
|
||||
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.retriveContent(any())).thenThrow(RevisionNotFoundException.class);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
@@ -133,6 +137,7 @@ public class DiffResourceTest extends RepositoryTestBase {
|
||||
@Test
|
||||
public void shouldGet400OnCrlfInjection() throws Exception {
|
||||
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.retriveContent(any())).thenThrow(RevisionNotFoundException.class);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
@@ -143,6 +148,47 @@ public class DiffResourceTest extends RepositoryTestBase {
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGet400OnUnknownFormat() throws Exception {
|
||||
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.retriveContent(any())).thenThrow(RevisionNotFoundException.class);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get(DIFF_URL + "revision?format=Unknown")
|
||||
.accept(VndMediaType.DIFF);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
dispatcher.invoke(request, response);
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptDiffFormats() throws Exception {
|
||||
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.setFormat(any())).thenReturn(diffCommandBuilder);
|
||||
when(diffCommandBuilder.retriveContent(any())).thenReturn(diffCommandBuilder);
|
||||
|
||||
Arrays.stream(DiffFormat.values()).map(DiffFormat::name).forEach(
|
||||
this::assertRequestOk
|
||||
);
|
||||
}
|
||||
|
||||
private void assertRequestOk(String format) {
|
||||
MockHttpRequest request = null;
|
||||
try {
|
||||
request = MockHttpRequest
|
||||
.get(DIFF_URL + "revision?format=" + format)
|
||||
.accept(VndMediaType.DIFF);
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
fail("got exception: " + e);
|
||||
}
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus())
|
||||
.withFailMessage("diff format from DiffFormat enum must be accepted: " + format)
|
||||
.isEqualTo(200);
|
||||
}
|
||||
}
|
||||
|
||||
133
scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java
Normal file
133
scm-webapp/src/test/java/sonia/scm/boot/RestartServletTest.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package sonia.scm.boot;
|
||||
|
||||
import com.github.legman.Subscribe;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.event.ScmTestEventBus;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RestartServletTest {
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Mock
|
||||
private HttpServletResponse response;
|
||||
|
||||
private RestartServlet restartServlet;
|
||||
|
||||
private EventListener listener;
|
||||
|
||||
private void setUpObjectUnderTest(Stage stage) {
|
||||
listener = new EventListener();
|
||||
ScmEventBus eventBus = ScmTestEventBus.getInstance();
|
||||
eventBus.register(listener);
|
||||
|
||||
restartServlet = new RestartServlet(eventBus, stage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestart() throws IOException {
|
||||
setUpObjectUnderTest(Stage.DEVELOPMENT);
|
||||
setRequestInputReason("something changed");
|
||||
|
||||
restartServlet.doPost(request, response);
|
||||
|
||||
verify(response).setStatus(HttpServletResponse.SC_ACCEPTED);
|
||||
|
||||
RestartEvent restartEvent = listener.restartEvent;
|
||||
assertThat(restartEvent).isNotNull();
|
||||
assertThat(restartEvent.getCause()).isEqualTo(RestartServlet.class);
|
||||
assertThat(restartEvent.getReason()).isEqualTo("something changed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartCalledTwice() throws IOException {
|
||||
setUpObjectUnderTest(Stage.DEVELOPMENT);
|
||||
|
||||
setRequestInputReason("initial change");
|
||||
restartServlet.doPost(request, response);
|
||||
verify(response).setStatus(HttpServletResponse.SC_ACCEPTED);
|
||||
|
||||
setRequestInputReason("changed again");
|
||||
restartServlet.doPost(request, response);
|
||||
verify(response).setStatus(HttpServletResponse.SC_CONFLICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartWithInvalidContent() throws IOException {
|
||||
setUpObjectUnderTest(Stage.DEVELOPMENT);
|
||||
|
||||
setRequestInputContent("invalid json");
|
||||
|
||||
restartServlet.doPost(request, response);
|
||||
|
||||
verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartInProductionStage() throws IOException {
|
||||
setUpObjectUnderTest(Stage.PRODUCTION);
|
||||
|
||||
setRequestInputReason("initial change");
|
||||
|
||||
restartServlet.doPost(request, response);
|
||||
|
||||
verify(response).setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
private void setRequestInputReason(String message) throws IOException {
|
||||
String content = createReason(message);
|
||||
setRequestInputContent(content);
|
||||
}
|
||||
|
||||
private void setRequestInputContent(String content) throws IOException {
|
||||
InputStream input = createReasonAsInputStream(content);
|
||||
when(request.getInputStream()).thenReturn(createServletInputStream(input));
|
||||
}
|
||||
|
||||
private ServletInputStream createServletInputStream(final InputStream inputStream) {
|
||||
return new ServletInputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return inputStream.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private InputStream createReasonAsInputStream(String content) {
|
||||
return new ByteArrayInputStream(content.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
private String createReason(String message) {
|
||||
return String.format("{\"message\": \"%s\"}", message);
|
||||
}
|
||||
|
||||
public static class EventListener {
|
||||
|
||||
private RestartEvent restartEvent;
|
||||
|
||||
@Subscribe(async = false)
|
||||
public void store(RestartEvent restartEvent) {
|
||||
this.restartEvent = restartEvent;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package sonia.scm.boot;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ServletContextCleanerTest {
|
||||
|
||||
@Mock
|
||||
private ServletContext servletContext;
|
||||
|
||||
@Test
|
||||
public void testCleanup() {
|
||||
Set<String> names = ImmutableSet.of(
|
||||
"org.jboss.resteasy.Dispatcher",
|
||||
"resteasy.Deployment",
|
||||
"sonia.scm.Context",
|
||||
"org.eclipse.jetty.HttpServer",
|
||||
"javax.servlet.Context",
|
||||
"org.apache.shiro.SecurityManager"
|
||||
);
|
||||
|
||||
when(servletContext.getAttributeNames()).thenReturn(toEnumeration(names));
|
||||
|
||||
ServletContextCleaner.cleanup(servletContext);
|
||||
|
||||
verify(servletContext).removeAttribute("org.jboss.resteasy.Dispatcher");
|
||||
verify(servletContext).removeAttribute("resteasy.Deployment");
|
||||
verify(servletContext).removeAttribute("sonia.scm.Context");
|
||||
verify(servletContext, never()).removeAttribute("org.eclipse.jetty.HttpServer");
|
||||
verify(servletContext, never()).removeAttribute("javax.servlet.Context");
|
||||
verify(servletContext).removeAttribute("org.apache.shiro.SecurityManager");
|
||||
}
|
||||
|
||||
private <T> Enumeration<T> toEnumeration(Collection<T> collection) {
|
||||
return new Vector<>(collection).elements();
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.Stage;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.File;
|
||||
@@ -96,14 +97,12 @@ public class DefaultUberWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
@Test
|
||||
public void testGetResourceFromCache() throws MalformedURLException
|
||||
{
|
||||
public void testGetResourceFromCache() {
|
||||
DefaultUberWebResourceLoader resourceLoader =
|
||||
new DefaultUberWebResourceLoader(servletContext,
|
||||
new ArrayList<PluginWrapper>());
|
||||
new ArrayList<PluginWrapper>(), Stage.PRODUCTION);
|
||||
|
||||
resourceLoader.getCache().put("/myresource", GITHUB);
|
||||
|
||||
@@ -112,6 +111,15 @@ public class DefaultUberWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
assertSame(GITHUB, resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceCacheIsDisableInStageDevelopment() throws MalformedURLException {
|
||||
DefaultUberWebResourceLoader resourceLoader = new DefaultUberWebResourceLoader(servletContext, new ArrayList<>(), Stage.DEVELOPMENT);
|
||||
when(servletContext.getResource("/scm")).thenAnswer(invocation -> new URL("https://scm-manager.org"));
|
||||
URL url = resourceLoader.getResource("/scm");
|
||||
URL secondUrl = resourceLoader.getResource("/scm");
|
||||
assertNotSame(url, secondUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user