From 086a4711610ae59edb174476a8ba9fbbe114b9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 23 Jun 2020 11:40:08 +0200 Subject: [PATCH 1/8] Fix migration of non-bare git repositories During the migration of git repositories from v1 to v2, we have to create an "scmm" config section with the repository id of the current repository. If this does not happen, further write requests to this repository will fail, because the hooks cannot determine the id. However, the migration failed to write this configuration for non-bare repositories. Therefore this fix checks beforehand, whether a '.git' folder exists in the date directory. If this is the case, we assume that this is a non-bare repository and write the config file inside this folder. --- CHANGELOG.md | 4 + .../repository/update/GitV2UpdateStep.java | 18 +++- .../update/GitV2UpdateStepTest.java | 92 +++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/update/GitV2UpdateStepTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 82abb84b2e..e170cab88e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Fixed +- Migration of non-bare repositories ([#1213](https://github.com/scm-manager/scm-manager/pull/1213)) + ## [2.1.0] - 2020-06-18 ### Added - Option to configure jvm parameter of docker container with env JAVA_OPTS or with arguments ([#1175](https://github.com/scm-manager/scm-manager/pull/1175)) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/update/GitV2UpdateStep.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/update/GitV2UpdateStep.java index 0bbb479ed6..d805fae53c 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/update/GitV2UpdateStep.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/update/GitV2UpdateStep.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.repository.update; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; @@ -38,6 +38,7 @@ import sonia.scm.version.Version; import javax.inject.Inject; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import static sonia.scm.version.Version.parse; @@ -60,7 +61,8 @@ public class GitV2UpdateStep implements UpdateStep { (repositoryId, path) -> { Repository repository = repositoryMetadataAccess.read(path); if (isGitDirectory(repository)) { - try (org.eclipse.jgit.lib.Repository gitRepository = build(path.resolve("data").toFile())) { + final Path effectiveGitPath = determineEffectiveGitFolder(path); + try (org.eclipse.jgit.lib.Repository gitRepository = build(effectiveGitPath.toFile())) { new GitConfigHelper().createScmmConfig(repository, gitRepository); } catch (IOException e) { throw new UpdateException("could not update repository with id " + repositoryId + " in path " + path, e); @@ -70,6 +72,18 @@ public class GitV2UpdateStep implements UpdateStep { ); } + public Path determineEffectiveGitFolder(Path path) { + Path bareGitFolder = path.resolve("data"); + Path nonBareGitFolder = bareGitFolder.resolve(".git"); + final Path effectiveGitPath; + if (Files.exists(nonBareGitFolder)) { + effectiveGitPath = nonBareGitFolder; + } else { + effectiveGitPath = bareGitFolder; + } + return effectiveGitPath; + } + private org.eclipse.jgit.lib.Repository build(File directory) throws IOException { return new FileRepositoryBuilder() .setGitDir(directory) diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/update/GitV2UpdateStepTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/update/GitV2UpdateStepTest.java new file mode 100644 index 0000000000..c207a4bf54 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/update/GitV2UpdateStepTest.java @@ -0,0 +1,92 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.update; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryLocationResolver; +import sonia.scm.update.UpdateStepRepositoryMetadataAccess; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.function.BiConsumer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class GitV2UpdateStepTest { + + @Mock + RepositoryLocationResolver locationResolver; + @Mock + RepositoryLocationResolver.RepositoryLocationResolverInstance locationResolverInstance; + @Mock + UpdateStepRepositoryMetadataAccess repositoryMetadataAccess; + + @InjectMocks + GitV2UpdateStep updateStep; + + @BeforeEach + void createDataDirectory(@TempDir Path temp) throws IOException { + Files.createDirectories(temp.resolve("data")); + } + + @BeforeEach + void initRepositoryFolder(@TempDir Path temp) { + when(locationResolver.forClass(Path.class)).thenReturn(locationResolverInstance); + when(repositoryMetadataAccess.read(temp)).thenReturn(new Repository("123", "git", "space", "X")); + doAnswer(invocation -> { + invocation.getArgument(0, BiConsumer.class).accept("123", temp); + return null; + }).when(locationResolverInstance).forAllLocations(any()); + } + + @Test + void shouldWriteConfigFileForBareRepositories(@TempDir Path temp) { + updateStep.doUpdate(); + + assertThat(temp.resolve("data").resolve("config")).exists(); + } + + @Test + void shouldWriteConfigFileForNonBareRepositories(@TempDir Path temp) throws IOException { + Files.createDirectories(temp.resolve("data").resolve(".git")); + + updateStep.doUpdate(); + + assertThat(temp.resolve("data").resolve("config")).doesNotExist(); + assertThat(temp.resolve("data").resolve(".git").resolve("config")).exists(); + } +} From 137f4e1eaecc9d5bf13f5c5b976b36747602acdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 23 Jun 2020 17:28:58 +0200 Subject: [PATCH 2/8] Adjust changelog for release 2.1.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe68dcdcdd..86aa6412f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## [2.1.1] - 2020-06-23 ### Fixed - Wait until recommended java installation is available for deb packages ([#1209](https://github.com/scm-manager/scm-manager/pull/1209)) - Do not force java home of recommended java dependency for rpm and deb packages ([#1195](https://github.com/scm-manager/scm-manager/issues/1195) and [#1208](https://github.com/scm-manager/scm-manager/pull/1208)) From e5c7b4eda4358b5143d95a522eed7044e81dff42 Mon Sep 17 00:00:00 2001 From: CES Marvin Date: Tue, 23 Jun 2020 15:34:23 +0000 Subject: [PATCH 3/8] release version 2.1.1 --- lerna.json | 2 +- pom.xml | 2 +- scm-annotation-processor/pom.xml | 6 ++--- scm-annotations/pom.xml | 4 ++-- scm-core/pom.xml | 8 +++---- scm-dao-xml/pom.xml | 8 +++---- scm-it/pom.xml | 20 ++++++++--------- scm-packaging/deb/pom.xml | 6 ++--- scm-packaging/docker/pom.xml | 4 ++-- scm-packaging/helm/pom.xml | 4 ++-- scm-packaging/pom.xml | 4 ++-- scm-packaging/release-yaml/pom.xml | 4 ++-- scm-packaging/rpm/pom.xml | 6 ++--- scm-packaging/unix/pom.xml | 4 ++-- scm-packaging/windows/pom.xml | 4 ++-- scm-plugins/pom.xml | 10 ++++----- scm-plugins/scm-git-plugin/package.json | 4 ++-- scm-plugins/scm-git-plugin/pom.xml | 2 +- scm-plugins/scm-hg-plugin/package.json | 4 ++-- scm-plugins/scm-hg-plugin/pom.xml | 2 +- scm-plugins/scm-legacy-plugin/package.json | 4 ++-- scm-plugins/scm-legacy-plugin/pom.xml | 4 ++-- scm-plugins/scm-svn-plugin/package.json | 4 ++-- scm-plugins/scm-svn-plugin/pom.xml | 2 +- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 ++--- scm-ui/pom.xml | 4 ++-- scm-ui/ui-components/package.json | 2 +- scm-ui/ui-plugins/package.json | 4 ++-- scm-ui/ui-webapp/package.json | 4 ++-- scm-webapp/pom.xml | 26 +++++++++++----------- 31 files changed, 86 insertions(+), 86 deletions(-) diff --git a/lerna.json b/lerna.json index 66f41fc5a6..ffa2cdc5ad 100644 --- a/lerna.json +++ b/lerna.json @@ -5,5 +5,5 @@ ], "npmClient": "yarn", "useWorkspaces": true, - "version": "2.1.0" + "version": "2.1.1" } diff --git a/pom.xml b/pom.xml index db981176f6..355f8d0b7f 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ sonia.scm scm pom - 2.2.0-SNAPSHOT + 2.1.1 The easiest way to share your Git, Mercurial and Subversion repositories over http. diff --git a/scm-annotation-processor/pom.xml b/scm-annotation-processor/pom.xml index d2c4b4656e..8b2d3e97b9 100644 --- a/scm-annotation-processor/pom.xml +++ b/scm-annotation-processor/pom.xml @@ -31,12 +31,12 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-annotation-processor - 2.2.0-SNAPSHOT + 2.1.1 scm-annotation-processor @@ -46,7 +46,7 @@ sonia.scm scm-annotations - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-annotations/pom.xml b/scm-annotations/pom.xml index ff9e074223..d25e67bfaf 100644 --- a/scm-annotations/pom.xml +++ b/scm-annotations/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 scm-annotations - 2.2.0-SNAPSHOT + 2.1.1 scm-annotations diff --git a/scm-core/pom.xml b/scm-core/pom.xml index ff62629f03..7e7d0e9bed 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -31,11 +31,11 @@ scm sonia.scm - 2.2.0-SNAPSHOT + 2.1.1 scm-core - 2.2.0-SNAPSHOT + 2.1.1 scm-core @@ -54,7 +54,7 @@ sonia.scm scm-annotations - 2.2.0-SNAPSHOT + 2.1.1 @@ -221,7 +221,7 @@ sonia.scm scm-annotation-processor - 2.2.0-SNAPSHOT + 2.1.1 provided diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 2dddf39386..fd582451aa 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 scm-dao-xml - 2.2.0-SNAPSHOT + 2.1.1 scm-dao-xml @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.2.0-SNAPSHOT + 2.1.1 @@ -58,7 +58,7 @@ sonia.scm scm-test - 2.2.0-SNAPSHOT + 2.1.1 test diff --git a/scm-it/pom.xml b/scm-it/pom.xml index 5206830d97..e9b0c25641 100644 --- a/scm-it/pom.xml +++ b/scm-it/pom.xml @@ -31,40 +31,40 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-it war - 2.2.0-SNAPSHOT + 2.1.1 scm-it sonia.scm scm-core - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-test - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm.plugins scm-git-plugin - 2.2.0-SNAPSHOT + 2.1.1 test sonia.scm.plugins scm-git-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test @@ -72,14 +72,14 @@ sonia.scm.plugins scm-hg-plugin - 2.2.0-SNAPSHOT + 2.1.1 test sonia.scm.plugins scm-hg-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test @@ -87,14 +87,14 @@ sonia.scm.plugins scm-svn-plugin - 2.2.0-SNAPSHOT + 2.1.1 test sonia.scm.plugins scm-svn-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test diff --git a/scm-packaging/deb/pom.xml b/scm-packaging/deb/pom.xml index 7a3d0c9b47..a9655700dd 100644 --- a/scm-packaging/deb/pom.xml +++ b/scm-packaging/deb/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 deb deb - 2.2.0-SNAPSHOT + 2.1.1 Packaging for Debian/Ubuntu deb @@ -46,7 +46,7 @@ sonia.scm scm-server - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-packaging/docker/pom.xml b/scm-packaging/docker/pom.xml index 1b3d10143b..6dd41435c7 100644 --- a/scm-packaging/docker/pom.xml +++ b/scm-packaging/docker/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 docker pom - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-packaging/helm/pom.xml b/scm-packaging/helm/pom.xml index 3b2dff90f4..d2a8a6124f 100644 --- a/scm-packaging/helm/pom.xml +++ b/scm-packaging/helm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 helm helm - 2.2.0-SNAPSHOT + 2.1.1 3.2.1 diff --git a/scm-packaging/pom.xml b/scm-packaging/pom.xml index ff519e91a5..5799edfe50 100644 --- a/scm-packaging/pom.xml +++ b/scm-packaging/pom.xml @@ -31,13 +31,13 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm.packaging scm-packaging pom - 2.2.0-SNAPSHOT + 2.1.1 packages.scm-manager.org diff --git a/scm-packaging/release-yaml/pom.xml b/scm-packaging/release-yaml/pom.xml index 694ca48fff..11fe6097bd 100644 --- a/scm-packaging/release-yaml/pom.xml +++ b/scm-packaging/release-yaml/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 release-yaml pom - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-packaging/rpm/pom.xml b/scm-packaging/rpm/pom.xml index fa5743c9c5..e0c24c77ea 100644 --- a/scm-packaging/rpm/pom.xml +++ b/scm-packaging/rpm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 rpm rpm - 2.2.0-SNAPSHOT + 2.1.1 Packaging for RedHat/Centos/Fedora rpm @@ -46,7 +46,7 @@ sonia.scm scm-server - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-packaging/unix/pom.xml b/scm-packaging/unix/pom.xml index e4f72df8ef..b49dce50dc 100644 --- a/scm-packaging/unix/pom.xml +++ b/scm-packaging/unix/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 unix pom - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-packaging/windows/pom.xml b/scm-packaging/windows/pom.xml index cdc1bcdf4d..2a8d446fbf 100644 --- a/scm-packaging/windows/pom.xml +++ b/scm-packaging/windows/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.2.0-SNAPSHOT + 2.1.1 windows pom - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index d4696c5ce8..1c4f6e3e8a 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -31,13 +31,13 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm.plugins scm-plugins pom - 2.2.0-SNAPSHOT + 2.1.1 scm-plugins @@ -59,7 +59,7 @@ sonia.scm scm-core - 2.2.0-SNAPSHOT + 2.1.1 provided @@ -68,7 +68,7 @@ sonia.scm scm-annotation-processor - 2.2.0-SNAPSHOT + 2.1.1 provided @@ -98,7 +98,7 @@ sonia.scm scm-test - 2.2.0-SNAPSHOT + 2.1.1 test diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json index 540c3fb207..f406d25659 100644 --- a/scm-plugins/scm-git-plugin/package.json +++ b/scm-plugins/scm-git-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-git-plugin", "private": true, - "version": "2.1.0", + "version": "2.1.1", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -20,6 +20,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.1.0" + "@scm-manager/ui-plugins": "^2.1.1" } } diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 6e4db9e3f3..53bf44f810 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.2.0-SNAPSHOT + 2.1.1 scm-git-plugin diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json index 82aa1b2945..8cd1e03641 100644 --- a/scm-plugins/scm-hg-plugin/package.json +++ b/scm-plugins/scm-hg-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-hg-plugin", "private": true, - "version": "2.1.0", + "version": "2.1.1", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.1.0" + "@scm-manager/ui-plugins": "^2.1.1" } } diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index dbf85955d8..8fe52cf4fd 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -31,7 +31,7 @@ sonia.scm.plugins scm-plugins - 2.2.0-SNAPSHOT + 2.1.1 scm-hg-plugin diff --git a/scm-plugins/scm-legacy-plugin/package.json b/scm-plugins/scm-legacy-plugin/package.json index 3f0dcc4e85..1b9335e950 100644 --- a/scm-plugins/scm-legacy-plugin/package.json +++ b/scm-plugins/scm-legacy-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-legacy-plugin", "private": true, - "version": "2.1.0", + "version": "2.1.1", "license": "MIT", "main": "./src/main/js/index.tsx", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.1.0" + "@scm-manager/ui-plugins": "^2.1.1" } } diff --git a/scm-plugins/scm-legacy-plugin/pom.xml b/scm-plugins/scm-legacy-plugin/pom.xml index 8069f82678..ab3aa2b78c 100644 --- a/scm-plugins/scm-legacy-plugin/pom.xml +++ b/scm-plugins/scm-legacy-plugin/pom.xml @@ -29,12 +29,12 @@ sonia.scm.plugins scm-plugins - 2.2.0-SNAPSHOT + 2.1.1 scm-legacy-plugin Support migrated repository urls and v1 passwords - 2.2.0-SNAPSHOT + 2.1.1 smp diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json index ea2cacc2d8..43854a0082 100644 --- a/scm-plugins/scm-svn-plugin/package.json +++ b/scm-plugins/scm-svn-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-svn-plugin", "private": true, - "version": "2.1.0", + "version": "2.1.1", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.1.0" + "@scm-manager/ui-plugins": "^2.1.1" } } diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 154af84d44..4812066cb3 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.2.0-SNAPSHOT + 2.1.1 scm-svn-plugin diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 5b4a881ad8..de92dc7beb 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-server - 2.2.0-SNAPSHOT + 2.1.1 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 78b213f594..60908482f2 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-test - 2.2.0-SNAPSHOT + 2.1.1 scm-test @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.2.0-SNAPSHOT + 2.1.1 diff --git a/scm-ui/pom.xml b/scm-ui/pom.xml index 86da9d94d7..0c81467d5c 100644 --- a/scm-ui/pom.xml +++ b/scm-ui/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-ui war - 2.2.0-SNAPSHOT + 2.1.1 scm-ui diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json index 87871564f7..7bbd35e789 100644 --- a/scm-ui/ui-components/package.json +++ b/scm-ui/ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@scm-manager/ui-components", - "version": "2.1.0", + "version": "2.1.1", "description": "UI Components for SCM-Manager and its plugins", "main": "src/index.ts", "files": [ diff --git a/scm-ui/ui-plugins/package.json b/scm-ui/ui-plugins/package.json index 296e4570ea..6ca49827fd 100644 --- a/scm-ui/ui-plugins/package.json +++ b/scm-ui/ui-plugins/package.json @@ -1,12 +1,12 @@ { "name": "@scm-manager/ui-plugins", - "version": "2.1.0", + "version": "2.1.1", "license": "MIT", "bin": { "ui-plugins": "./bin/ui-plugins.js" }, "dependencies": { - "@scm-manager/ui-components": "^2.1.0", + "@scm-manager/ui-components": "^2.1.1", "@scm-manager/ui-extensions": "^2.1.0", "classnames": "^2.2.6", "query-string": "^5.0.1", diff --git a/scm-ui/ui-webapp/package.json b/scm-ui/ui-webapp/package.json index 1655fa19aa..c9aa79a570 100644 --- a/scm-ui/ui-webapp/package.json +++ b/scm-ui/ui-webapp/package.json @@ -1,9 +1,9 @@ { "name": "@scm-manager/ui-webapp", - "version": "2.1.0", + "version": "2.1.1", "private": true, "dependencies": { - "@scm-manager/ui-components": "^2.1.0", + "@scm-manager/ui-components": "^2.1.1", "@scm-manager/ui-extensions": "^2.1.0", "classnames": "^2.2.5", "history": "^4.10.1", diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 50ff2a3121..4fd7806f92 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-webapp war - 2.2.0-SNAPSHOT + 2.1.1 scm-webapp @@ -48,7 +48,7 @@ sonia.scm scm-annotation-processor - 2.2.0-SNAPSHOT + 2.1.1 provided @@ -73,13 +73,13 @@ sonia.scm scm-core - 2.2.0-SNAPSHOT + 2.1.1 sonia.scm scm-dao-xml - 2.2.0-SNAPSHOT + 2.1.1 @@ -332,7 +332,7 @@ sonia.scm scm-test - 2.2.0-SNAPSHOT + 2.1.1 test @@ -394,7 +394,7 @@ sonia.scm.plugins scm-git-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test @@ -402,14 +402,14 @@ sonia.scm.plugins scm-git-plugin - 2.2.0-SNAPSHOT + 2.1.1 test sonia.scm.plugins scm-hg-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test @@ -417,14 +417,14 @@ sonia.scm.plugins scm-hg-plugin - 2.2.0-SNAPSHOT + 2.1.1 test sonia.scm.plugins scm-svn-plugin - 2.2.0-SNAPSHOT + 2.1.1 tests test @@ -432,7 +432,7 @@ sonia.scm.plugins scm-svn-plugin - 2.2.0-SNAPSHOT + 2.1.1 test @@ -718,7 +718,7 @@ sonia.scm scm-ui - 2.2.0-SNAPSHOT + 2.1.1 war From c5f2502e6f109b257063d9954bd6548a1284c6eb Mon Sep 17 00:00:00 2001 From: CES Marvin Date: Tue, 23 Jun 2020 16:22:47 +0000 Subject: [PATCH 4/8] prepare for next development iteration --- pom.xml | 2 +- scm-annotation-processor/pom.xml | 6 +++--- scm-annotations/pom.xml | 4 ++-- scm-core/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-it/pom.xml | 20 ++++++++++---------- scm-packaging/deb/pom.xml | 6 +++--- scm-packaging/docker/pom.xml | 4 ++-- scm-packaging/helm/pom.xml | 4 ++-- scm-packaging/pom.xml | 4 ++-- scm-packaging/release-yaml/pom.xml | 4 ++-- scm-packaging/rpm/pom.xml | 6 +++--- scm-packaging/unix/pom.xml | 4 ++-- scm-packaging/windows/pom.xml | 4 ++-- scm-plugins/pom.xml | 10 +++++----- scm-plugins/scm-git-plugin/pom.xml | 2 +- scm-plugins/scm-hg-plugin/pom.xml | 2 +- scm-plugins/scm-legacy-plugin/pom.xml | 4 ++-- scm-plugins/scm-svn-plugin/pom.xml | 2 +- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-ui/pom.xml | 4 ++-- scm-webapp/pom.xml | 26 +++++++++++++------------- 23 files changed, 72 insertions(+), 72 deletions(-) diff --git a/pom.xml b/pom.xml index 355f8d0b7f..db981176f6 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ sonia.scm scm pom - 2.1.1 + 2.2.0-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. diff --git a/scm-annotation-processor/pom.xml b/scm-annotation-processor/pom.xml index 8b2d3e97b9..d2c4b4656e 100644 --- a/scm-annotation-processor/pom.xml +++ b/scm-annotation-processor/pom.xml @@ -31,12 +31,12 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-annotation-processor - 2.1.1 + 2.2.0-SNAPSHOT scm-annotation-processor @@ -46,7 +46,7 @@ sonia.scm scm-annotations - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-annotations/pom.xml b/scm-annotations/pom.xml index d25e67bfaf..ff9e074223 100644 --- a/scm-annotations/pom.xml +++ b/scm-annotations/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT scm-annotations - 2.1.1 + 2.2.0-SNAPSHOT scm-annotations diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 7e7d0e9bed..ff62629f03 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -31,11 +31,11 @@ scm sonia.scm - 2.1.1 + 2.2.0-SNAPSHOT scm-core - 2.1.1 + 2.2.0-SNAPSHOT scm-core @@ -54,7 +54,7 @@ sonia.scm scm-annotations - 2.1.1 + 2.2.0-SNAPSHOT @@ -221,7 +221,7 @@ sonia.scm scm-annotation-processor - 2.1.1 + 2.2.0-SNAPSHOT provided diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index fd582451aa..2dddf39386 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT scm-dao-xml - 2.1.1 + 2.2.0-SNAPSHOT scm-dao-xml @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.1.1 + 2.2.0-SNAPSHOT @@ -58,7 +58,7 @@ sonia.scm scm-test - 2.1.1 + 2.2.0-SNAPSHOT test diff --git a/scm-it/pom.xml b/scm-it/pom.xml index e9b0c25641..5206830d97 100644 --- a/scm-it/pom.xml +++ b/scm-it/pom.xml @@ -31,40 +31,40 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-it war - 2.1.1 + 2.2.0-SNAPSHOT scm-it sonia.scm scm-core - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-test - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm.plugins scm-git-plugin - 2.1.1 + 2.2.0-SNAPSHOT test sonia.scm.plugins scm-git-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test @@ -72,14 +72,14 @@ sonia.scm.plugins scm-hg-plugin - 2.1.1 + 2.2.0-SNAPSHOT test sonia.scm.plugins scm-hg-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test @@ -87,14 +87,14 @@ sonia.scm.plugins scm-svn-plugin - 2.1.1 + 2.2.0-SNAPSHOT test sonia.scm.plugins scm-svn-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test diff --git a/scm-packaging/deb/pom.xml b/scm-packaging/deb/pom.xml index a9655700dd..7a3d0c9b47 100644 --- a/scm-packaging/deb/pom.xml +++ b/scm-packaging/deb/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT deb deb - 2.1.1 + 2.2.0-SNAPSHOT Packaging for Debian/Ubuntu deb @@ -46,7 +46,7 @@ sonia.scm scm-server - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-packaging/docker/pom.xml b/scm-packaging/docker/pom.xml index 6dd41435c7..1b3d10143b 100644 --- a/scm-packaging/docker/pom.xml +++ b/scm-packaging/docker/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT docker pom - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-packaging/helm/pom.xml b/scm-packaging/helm/pom.xml index d2a8a6124f..3b2dff90f4 100644 --- a/scm-packaging/helm/pom.xml +++ b/scm-packaging/helm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT helm helm - 2.1.1 + 2.2.0-SNAPSHOT 3.2.1 diff --git a/scm-packaging/pom.xml b/scm-packaging/pom.xml index 5799edfe50..ff519e91a5 100644 --- a/scm-packaging/pom.xml +++ b/scm-packaging/pom.xml @@ -31,13 +31,13 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm.packaging scm-packaging pom - 2.1.1 + 2.2.0-SNAPSHOT packages.scm-manager.org diff --git a/scm-packaging/release-yaml/pom.xml b/scm-packaging/release-yaml/pom.xml index 11fe6097bd..694ca48fff 100644 --- a/scm-packaging/release-yaml/pom.xml +++ b/scm-packaging/release-yaml/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT release-yaml pom - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-packaging/rpm/pom.xml b/scm-packaging/rpm/pom.xml index e0c24c77ea..fa5743c9c5 100644 --- a/scm-packaging/rpm/pom.xml +++ b/scm-packaging/rpm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT rpm rpm - 2.1.1 + 2.2.0-SNAPSHOT Packaging for RedHat/Centos/Fedora rpm @@ -46,7 +46,7 @@ sonia.scm scm-server - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-packaging/unix/pom.xml b/scm-packaging/unix/pom.xml index b49dce50dc..e4f72df8ef 100644 --- a/scm-packaging/unix/pom.xml +++ b/scm-packaging/unix/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT unix pom - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-packaging/windows/pom.xml b/scm-packaging/windows/pom.xml index 2a8d446fbf..cdc1bcdf4d 100644 --- a/scm-packaging/windows/pom.xml +++ b/scm-packaging/windows/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.1.1 + 2.2.0-SNAPSHOT windows pom - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 1c4f6e3e8a..d4696c5ce8 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -31,13 +31,13 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm.plugins scm-plugins pom - 2.1.1 + 2.2.0-SNAPSHOT scm-plugins @@ -59,7 +59,7 @@ sonia.scm scm-core - 2.1.1 + 2.2.0-SNAPSHOT provided @@ -68,7 +68,7 @@ sonia.scm scm-annotation-processor - 2.1.1 + 2.2.0-SNAPSHOT provided @@ -98,7 +98,7 @@ sonia.scm scm-test - 2.1.1 + 2.2.0-SNAPSHOT test diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 53bf44f810..6e4db9e3f3 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.1.1 + 2.2.0-SNAPSHOT scm-git-plugin diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 8fe52cf4fd..dbf85955d8 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -31,7 +31,7 @@ sonia.scm.plugins scm-plugins - 2.1.1 + 2.2.0-SNAPSHOT scm-hg-plugin diff --git a/scm-plugins/scm-legacy-plugin/pom.xml b/scm-plugins/scm-legacy-plugin/pom.xml index ab3aa2b78c..8069f82678 100644 --- a/scm-plugins/scm-legacy-plugin/pom.xml +++ b/scm-plugins/scm-legacy-plugin/pom.xml @@ -29,12 +29,12 @@ sonia.scm.plugins scm-plugins - 2.1.1 + 2.2.0-SNAPSHOT scm-legacy-plugin Support migrated repository urls and v1 passwords - 2.1.1 + 2.2.0-SNAPSHOT smp diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 4812066cb3..154af84d44 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.1.1 + 2.2.0-SNAPSHOT scm-svn-plugin diff --git a/scm-server/pom.xml b/scm-server/pom.xml index de92dc7beb..5b4a881ad8 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-server - 2.1.1 + 2.2.0-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 60908482f2..78b213f594 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-test - 2.1.1 + 2.2.0-SNAPSHOT scm-test @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.1.1 + 2.2.0-SNAPSHOT diff --git a/scm-ui/pom.xml b/scm-ui/pom.xml index 0c81467d5c..86da9d94d7 100644 --- a/scm-ui/pom.xml +++ b/scm-ui/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-ui war - 2.1.1 + 2.2.0-SNAPSHOT scm-ui diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 4fd7806f92..50ff2a3121 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-webapp war - 2.1.1 + 2.2.0-SNAPSHOT scm-webapp @@ -48,7 +48,7 @@ sonia.scm scm-annotation-processor - 2.1.1 + 2.2.0-SNAPSHOT provided @@ -73,13 +73,13 @@ sonia.scm scm-core - 2.1.1 + 2.2.0-SNAPSHOT sonia.scm scm-dao-xml - 2.1.1 + 2.2.0-SNAPSHOT @@ -332,7 +332,7 @@ sonia.scm scm-test - 2.1.1 + 2.2.0-SNAPSHOT test @@ -394,7 +394,7 @@ sonia.scm.plugins scm-git-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test @@ -402,14 +402,14 @@ sonia.scm.plugins scm-git-plugin - 2.1.1 + 2.2.0-SNAPSHOT test sonia.scm.plugins scm-hg-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test @@ -417,14 +417,14 @@ sonia.scm.plugins scm-hg-plugin - 2.1.1 + 2.2.0-SNAPSHOT test sonia.scm.plugins scm-svn-plugin - 2.1.1 + 2.2.0-SNAPSHOT tests test @@ -432,7 +432,7 @@ sonia.scm.plugins scm-svn-plugin - 2.1.1 + 2.2.0-SNAPSHOT test @@ -718,7 +718,7 @@ sonia.scm scm-ui - 2.1.1 + 2.2.0-SNAPSHOT war From a64fad96226b73473c3772bb029ea4ddec61a4dc Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 24 Jun 2020 07:07:20 +0200 Subject: [PATCH 5/8] update winsw to v2.9.0 --- scm-packaging/windows/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-packaging/windows/pom.xml b/scm-packaging/windows/pom.xml index cdc1bcdf4d..3041009d2e 100644 --- a/scm-packaging/windows/pom.xml +++ b/scm-packaging/windows/pom.xml @@ -71,11 +71,11 @@ wget - https://github.com/winsw/winsw/releases/download/v2.8.0/WinSW.NETCore31.x64.exe + https://github.com/winsw/winsw/releases/download/v2.9.0/WinSW.NETCore31.x64.exe false scm-server.exe ${project.build.directory}/windows - ebb2bb0ab0746ff5a20f65c76855a71c53aa806eb55ebd08fd18ded51ea23b58 + 59d29a41652cfc9a564c9c05d77976391833a6fb686bce941ad89f8f8dff120b From 0eeddd5103a52ec714a263ab6341165ad1aa2343 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Fri, 19 Jun 2020 11:50:58 +0200 Subject: [PATCH 6/8] enrich commit mentions by internal links e. g. "repoNamespace/repoName@commitId" --- CHANGELOG.md | 4 + .../src/MarkdownLinkRenderer.test.tsx | 20 +++- .../src/MarkdownLinkRenderer.tsx | 19 ++-- .../src/MarkdownView.stories.tsx | 4 +- scm-ui/ui-components/src/MarkdownView.tsx | 12 ++- .../__resources__/markdown-commit-link.md.ts | 39 +++++++ .../src/remarkCommitLinksParser.test.ts | 59 ++++++++++ .../src/remarkCommitLinksParser.ts | 101 ++++++++++++++++++ scm-ui/ui-components/src/validation.ts | 2 +- scm-ui/ui-webapp/public/locales/de/repos.json | 3 + scm-ui/ui-webapp/public/locales/en/repos.json | 3 + 11 files changed, 252 insertions(+), 14 deletions(-) create mode 100644 scm-ui/ui-components/src/__resources__/markdown-commit-link.md.ts create mode 100644 scm-ui/ui-components/src/remarkCommitLinksParser.test.ts create mode 100644 scm-ui/ui-components/src/remarkCommitLinksParser.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 82abb84b2e..52ea215aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- enrich commit mentions in markdown viewer by internal links ([#1210](https://github.com/scm-manager/scm-manager/pull/1210)) + ## [2.1.0] - 2020-06-18 ### Added - Option to configure jvm parameter of docker container with env JAVA_OPTS or with arguments ([#1175](https://github.com/scm-manager/scm-manager/pull/1175)) diff --git a/scm-ui/ui-components/src/MarkdownLinkRenderer.test.tsx b/scm-ui/ui-components/src/MarkdownLinkRenderer.test.tsx index 7a5b8e68dc..037bf0f73f 100644 --- a/scm-ui/ui-components/src/MarkdownLinkRenderer.test.tsx +++ b/scm-ui/ui-components/src/MarkdownLinkRenderer.test.tsx @@ -21,7 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import { isAnchorLink, isExternalLink, isLinkWithProtocol, createLocalLink } from "./MarkdownLinkRenderer"; +import { + isAnchorLink, + isExternalLink, + isLinkWithProtocol, + createLocalLink, + isInternalScmRepoLink +} from "./MarkdownLinkRenderer"; describe("test isAnchorLink", () => { it("should return true", () => { @@ -67,6 +73,18 @@ describe("test isLinkWithProtocol", () => { }); }); +describe("test isInternalScmRepoLink", () => { + it("should return true", () => { + expect(isInternalScmRepoLink("/repo/scmadmin/git/code/changeset/1234567")).toBe(true); + expect(isInternalScmRepoLink("/repo/scmadmin/git")).toBe(true); + }); + it("should return false", () => { + expect(isInternalScmRepoLink("repo/path/link")).toBe(false); + expect(isInternalScmRepoLink("/some/path/link")).toBe(false); + expect(isInternalScmRepoLink("#some-anchor")).toBe(false); + }); +}); + describe("test createLocalLink", () => { it("should handle relative links", () => { expectLocalLink("/src", "/src/README.md", "docs/Home.md", "/src/docs/Home.md"); diff --git a/scm-ui/ui-components/src/MarkdownLinkRenderer.tsx b/scm-ui/ui-components/src/MarkdownLinkRenderer.tsx index 8ae1bc6135..fc38bd388b 100644 --- a/scm-ui/ui-components/src/MarkdownLinkRenderer.tsx +++ b/scm-ui/ui-components/src/MarkdownLinkRenderer.tsx @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import React, {FC} from "react"; -import {Link, useLocation} from "react-router-dom"; +import React, { FC } from "react"; +import { Link, useLocation } from "react-router-dom"; import ExternalLink from "./navigation/ExternalLink"; -import {withContextPath} from "./urls"; +import { withContextPath } from "./urls"; const externalLinkRegex = new RegExp("^http(s)?://"); export const isExternalLink = (link: string) => { @@ -35,6 +35,10 @@ export const isAnchorLink = (link: string) => { return link.startsWith("#"); }; +export const isInternalScmRepoLink = (link: string) => { + return link.startsWith("/repo/"); +}; + const linkWithProtcolRegex = new RegExp("^[a-z]+:"); export const isLinkWithProtocol = (link: string) => { return linkWithProtcolRegex.test(link); @@ -56,10 +60,10 @@ const normalizePath = (path: string) => { if (part === "..") { stack.pop(); } else if (part !== ".") { - stack.push(part) + stack.push(part); } } - const normalizedPath = stack.join("/") + const normalizedPath = stack.join("/"); if (normalizedPath.startsWith("/")) { return normalizedPath; } @@ -75,6 +79,9 @@ const isSubDirectoryOf = (basePath: string, currentPath: string) => { }; export const createLocalLink = (basePath: string, currentPath: string, link: string) => { + if (isInternalScmRepoLink(link)) { + return link; + } if (isAbsolute(link)) { return join(basePath, link); } @@ -102,7 +109,7 @@ type Props = LinkProps & { base: string; }; -const MarkdownLinkRenderer: FC = ({href, base, children}) => { +const MarkdownLinkRenderer: FC = ({ href, base, children }) => { const location = useLocation(); if (isExternalLink(href)) { return {children}; diff --git a/scm-ui/ui-components/src/MarkdownView.stories.tsx b/scm-ui/ui-components/src/MarkdownView.stories.tsx index 2c2e1cc9f4..54c87cc6f2 100644 --- a/scm-ui/ui-components/src/MarkdownView.stories.tsx +++ b/scm-ui/ui-components/src/MarkdownView.stories.tsx @@ -31,6 +31,7 @@ import MarkdownWithoutLang from "./__resources__/markdown-without-lang.md"; import MarkdownXmlCodeBlock from "./__resources__/markdown-xml-codeblock.md"; import MarkdownInlineXml from "./__resources__/markdown-inline-xml.md"; import MarkdownLinks from "./__resources__/markdown-links.md"; +import MarkdownCommitLinks from "./__resources__/markdown-commit-link.md"; import Title from "./layout/Title"; import { Subtitle } from "./layout"; import { MemoryRouter } from "react-router-dom"; @@ -52,4 +53,5 @@ storiesOf("MarkdownView", module) )) - .add("Links", () => ); + .add("Links", () => ) + .add("Commit Links", () => ); diff --git a/scm-ui/ui-components/src/MarkdownView.tsx b/scm-ui/ui-components/src/MarkdownView.tsx index 546d1610a6..e46c95370a 100644 --- a/scm-ui/ui-components/src/MarkdownView.tsx +++ b/scm-ui/ui-components/src/MarkdownView.tsx @@ -22,7 +22,7 @@ * SOFTWARE. */ import React, { FC } from "react"; -import { withRouter, RouteComponentProps } from "react-router-dom"; +import { RouteComponentProps, withRouter } from "react-router-dom"; // @ts-ignore import Markdown from "react-markdown/with-html"; import { binder } from "@scm-manager/ui-extensions"; @@ -30,10 +30,11 @@ import ErrorBoundary from "./ErrorBoundary"; import SyntaxHighlighter from "./SyntaxHighlighter"; import MarkdownHeadingRenderer from "./MarkdownHeadingRenderer"; import { create } from "./MarkdownLinkRenderer"; -import { useTranslation } from "react-i18next"; +import {useTranslation, WithTranslation, withTranslation} from "react-i18next"; import Notification from "./Notification"; +import { createTransformer } from "./remarkCommitLinksParser"; -type Props = RouteComponentProps & { +type Props = RouteComponentProps & WithTranslation & { content: string; renderContext?: object; renderers?: any; @@ -100,7 +101,7 @@ class MarkdownView extends React.Component { } render() { - const { content, renderers, renderContext, enableAnchorHeadings, skipHtml, basePath } = this.props; + const { content, renderers, renderContext, enableAnchorHeadings, skipHtml, basePath, t } = this.props; const rendererFactory = binder.getExtension("markdown-renderer-factory"); let rendererList = renderers; @@ -134,6 +135,7 @@ class MarkdownView extends React.Component { escapeHtml={skipHtml} source={content} renderers={rendererList} + astPlugins={[createTransformer(t)]} /> @@ -141,4 +143,4 @@ class MarkdownView extends React.Component { } } -export default withRouter(MarkdownView); +export default withRouter(withTranslation("repos")(MarkdownView)); diff --git a/scm-ui/ui-components/src/__resources__/markdown-commit-link.md.ts b/scm-ui/ui-components/src/__resources__/markdown-commit-link.md.ts new file mode 100644 index 0000000000..462179a73d --- /dev/null +++ b/scm-ui/ui-components/src/__resources__/markdown-commit-link.md.ts @@ -0,0 +1,39 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +export default `# Commit Links in Markdown +namespace/name@1a5s4w8a + +Please check for this commit: namespace/name@1a5s4w8a + +hitchhiker/heart-of-gold@c7237cb60689046990dc9dc2a388a517adb3e2b2 + +hitchhiker/heart-of-gold@c7237cb + +hitchhiker/heart-of-gold@42 + +[hitchhiker/heart-of-gold@42](https://scm-manager.org/) + +Prefix hitchhiker/heart-of-gold@42 some text hitchhiker/heart-of-gold@21 suffix + +`; diff --git a/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts b/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts new file mode 100644 index 0000000000..11ca3b7444 --- /dev/null +++ b/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { regExpPattern } from "./remarkCommitLinksParser"; + +describe("Remark Commit Links RegEx Tests", () => { + it("should match simple names", () => { + expect("namespace/name@1a5s4w8a".match(regExpPattern)).toBeTruthy(); + }); + it("should match complex names", () => { + expect("hitchhiker/heart-of-gold@c7237cb60689046990dc9dc2a388a517adb3e2b2".match(regExpPattern)).toBeTruthy(); + }); + it("should replace match", () => { + expect("Prefix namespace/name@42 suffix".replace(regExpPattern, "replaced")).toBe("Prefix replaced suffix"); + }); + it("should match groups", () => { + const match = regExpPattern.exec("namespace/name@42"); + expect(match).toBeTruthy(); + if (match) { + expect(match[1]).toBe("namespace"); + expect(match[2]).toBe("name"); + expect(match[3]).toBe("42"); + } + }); + it("should match multiple links in text", () => { + const text = "Prefix hitchhiker/heart-of-gold@42 some text hitchhiker/heart-of-gold@21 suffix"; + const matches = []; + + let match = regExpPattern.exec(text); + while (match !== null) { + matches.push(match[0]); + match = regExpPattern.exec(text); + } + + expect(matches[0]).toBe("hitchhiker/heart-of-gold@42"); + expect(matches[1]).toBe("hitchhiker/heart-of-gold@21"); + }); +}); diff --git a/scm-ui/ui-components/src/remarkCommitLinksParser.ts b/scm-ui/ui-components/src/remarkCommitLinksParser.ts new file mode 100644 index 0000000000..50b8cc8d3b --- /dev/null +++ b/scm-ui/ui-components/src/remarkCommitLinksParser.ts @@ -0,0 +1,101 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { MarkdownAbstractSyntaxTree, MdastPlugin } from "react-markdown"; +import { nameRegex } from "./validation"; +// @ts-ignore No types available +import visit from "unist-util-visit"; +import { TFunction } from "i18next"; + +const namePartRegex = nameRegex.source.substring(1, nameRegex.source.length - 1); + +// Visible for testing +export const regExpPattern = new RegExp(`(${namePartRegex})\\/(${namePartRegex})@([\\w\\d]+)`, "g"); + +function match(value: string): RegExpMatchArray[] { + const matches = []; + let m = regExpPattern.exec(value); + while (m) { + matches.push(m); + m = regExpPattern.exec(value); + } + return matches; +} + +export const createTransformer = (t: TFunction): MdastPlugin => { + return (tree: MarkdownAbstractSyntaxTree) => { + visit(tree, "text", (node: MarkdownAbstractSyntaxTree, index: number, parent: MarkdownAbstractSyntaxTree) => { + if (parent.type === "link" || !node.value) { + return; + } + + let nodeText = node.value; + const matches = match(nodeText); + + if (matches.length > 0) { + const children = []; + for (const m of matches) { + const i = nodeText.indexOf(m[0]); + if (i > 0) { + children.push({ + type: "text", + value: nodeText.substring(0, i) + }); + } + + children.push({ + type: "link", + url: `/repo/${m[1]}/${m[2]}/code/changeset/${m[3]}`, + title: t("changeset.shortlink.title", { + namespace: m[1], + name: m[2], + id: m[3] + }), + children: [ + { + type: "text", + value: m[0] + } + ] + }); + + nodeText = nodeText.substring(i + m[0].length); + } + + if (nodeText.length > 0) { + children.push({ + type: "text", + value: nodeText + }); + } + + parent.children![index] = { + type: "text", + children + }; + } + }); + return tree; + }; +}; diff --git a/scm-ui/ui-components/src/validation.ts b/scm-ui/ui-components/src/validation.ts index e6502a7ed9..fcdb1a6dfd 100644 --- a/scm-ui/ui-components/src/validation.ts +++ b/scm-ui/ui-components/src/validation.ts @@ -22,7 +22,7 @@ * SOFTWARE. */ -const nameRegex = /^[A-Za-z0-9\.\-_][A-Za-z0-9\.\-_@]*$/; +export const nameRegex = /^[A-Za-z0-9\.\-_][A-Za-z0-9\.\-_@]*$/; export const isNameValid = (name: string) => { return nameRegex.test(name); diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index 882f63a7e6..808bf431e9 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -88,6 +88,9 @@ "shortSummary": "Committet <0/> <1/>", "tags": "Tags", "diffNotSupported": "Diff des Changesets wird von diesem Repositorytyp nicht unterstützt", + "shortlink": { + "title": "Changeset {{id}} aus {{namespace}}/{{name}}" + }, "parents": { "label" : "Parent", "label_plural": "Parents" diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 7102cff33a..e98052aba3 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -87,6 +87,9 @@ "summary": "Changeset <0/> was committed <1/>", "shortSummary": "Committed <0/> <1/>", "tags": "Tags", + "shortlink": { + "title": "Changeset {{id}} of {{namespace}}/{{name}}" + }, "diffNotSupported": "Diff of changesets is not supported by the type of repository", "buttons": { "details": "Details", From 149b6cbc2a13dbb142174430dd5d2d2f91111c60 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Wed, 24 Jun 2020 16:15:27 +0200 Subject: [PATCH 7/8] update storyshots --- .../src/__snapshots__/storyshots.test.ts.snap | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index a1db5dadc0..71cc6c0ecd 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -39183,6 +39183,87 @@ exports[`Storyshots MarkdownView Code without Lang 1`] = ` `; +exports[`Storyshots MarkdownView Commit Links 1`] = ` + +`; + exports[`Storyshots MarkdownView Default 1`] = `
Date: Thu, 25 Jun 2020 13:24:48 +0200 Subject: [PATCH 8/8] fix unit test --- .../src/remarkCommitLinksParser.test.ts | 19 +++++++++++++------ .../src/remarkCommitLinksParser.ts | 8 +++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts b/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts index 11ca3b7444..9d54e3539a 100644 --- a/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts +++ b/scm-ui/ui-components/src/remarkCommitLinksParser.test.ts @@ -26,16 +26,20 @@ import { regExpPattern } from "./remarkCommitLinksParser"; describe("Remark Commit Links RegEx Tests", () => { it("should match simple names", () => { - expect("namespace/name@1a5s4w8a".match(regExpPattern)).toBeTruthy(); + const regExp = new RegExp(regExpPattern, "g"); + expect("namespace/name@1a5s4w8a".match(regExp)).toBeTruthy(); }); it("should match complex names", () => { - expect("hitchhiker/heart-of-gold@c7237cb60689046990dc9dc2a388a517adb3e2b2".match(regExpPattern)).toBeTruthy(); + const regExp = new RegExp(regExpPattern, "g"); + expect("hitchhiker/heart-of-gold@c7237cb60689046990dc9dc2a388a517adb3e2b2".match(regExp)).toBeTruthy(); }); it("should replace match", () => { - expect("Prefix namespace/name@42 suffix".replace(regExpPattern, "replaced")).toBe("Prefix replaced suffix"); + const regExp = new RegExp(regExpPattern, "g"); + expect("Prefix namespace/name@42 suffix".replace(regExp, "replaced")).toBe("Prefix replaced suffix"); }); it("should match groups", () => { - const match = regExpPattern.exec("namespace/name@42"); + const regExp = new RegExp(regExpPattern, "g"); + const match = regExp.exec("namespace/name@42"); expect(match).toBeTruthy(); if (match) { expect(match[1]).toBe("namespace"); @@ -44,15 +48,18 @@ describe("Remark Commit Links RegEx Tests", () => { } }); it("should match multiple links in text", () => { + const regExp = new RegExp(regExpPattern, "g"); const text = "Prefix hitchhiker/heart-of-gold@42 some text hitchhiker/heart-of-gold@21 suffix"; const matches = []; - let match = regExpPattern.exec(text); + let match = regExp.exec(text); while (match !== null) { matches.push(match[0]); - match = regExpPattern.exec(text); + match = regExp.exec(text); } + console.log(matches) + expect(matches[0]).toBe("hitchhiker/heart-of-gold@42"); expect(matches[1]).toBe("hitchhiker/heart-of-gold@21"); }); diff --git a/scm-ui/ui-components/src/remarkCommitLinksParser.ts b/scm-ui/ui-components/src/remarkCommitLinksParser.ts index 50b8cc8d3b..fa26c793db 100644 --- a/scm-ui/ui-components/src/remarkCommitLinksParser.ts +++ b/scm-ui/ui-components/src/remarkCommitLinksParser.ts @@ -31,19 +31,21 @@ import { TFunction } from "i18next"; const namePartRegex = nameRegex.source.substring(1, nameRegex.source.length - 1); // Visible for testing -export const regExpPattern = new RegExp(`(${namePartRegex})\\/(${namePartRegex})@([\\w\\d]+)`, "g"); +export const regExpPattern = `(${namePartRegex})\\/(${namePartRegex})@([\\w\\d]+)`; function match(value: string): RegExpMatchArray[] { + const regExp = new RegExp(regExpPattern, "g"); const matches = []; - let m = regExpPattern.exec(value); + let m = regExp.exec(value); while (m) { matches.push(m); - m = regExpPattern.exec(value); + m = regExp.exec(value); } return matches; } export const createTransformer = (t: TFunction): MdastPlugin => { + return (tree: MarkdownAbstractSyntaxTree) => { visit(tree, "text", (node: MarkdownAbstractSyntaxTree, index: number, parent: MarkdownAbstractSyntaxTree) => { if (parent.type === "link" || !node.value) {