Add the ability to access different SCM repositories
For now, this is limited to GitLab, the intention is to extend this
to other Git SCMs too.
GitLab stores repositories under a different path from Gerrit, some
logic is required to calculate the new path.
When using GitLab backend, the project should be set to the GitLab Id
of that project, rather than the name. The metric will be exposed with
the project Id too. Further details on GitLab project ids at [1].
[1]https://docs.gitlab.com/ee/user/project/working_with_projects.html#access-a-project-by-using-the-project-id
Change-Id: I68928a261e3a93feb7a489d44758d2e71bc729cc
diff --git a/BUILD b/BUILD
index 7370013..319fe9f 100644
--- a/BUILD
+++ b/BUILD
@@ -21,7 +21,8 @@
],
resources = glob(
["src/main/resources/**/*"],
- )
+ ),
+ deps = ["@commons-codec//jar"],
)
java_library(
diff --git a/README.md b/README.md
index da92331..987d373 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
# Plugin to collect Git repository metrics
-This plugin allows a systematic collection of repository metrics.
+This plugin allows a systematic collection of repository metrics. It's primary use-case is
+with Gerrit, however it's possible for it to work with multiple Git SCM systems, including bare
+Git repositories.
+
Metrics are updated upon a `ref-update` receive.
## How to build
@@ -23,11 +26,26 @@
bazel-genfiles/plugins/git-repo-metrics/git-repo-metrics.jar
```
-## How to install
+## How to install with Gerrit
Copy the git-repo-metrics.jar into the Gerrit's /plugins directory and wait for the plugin to be automatically
loaded.
+## How to install with a different SCM
+
+This plugin can also work with Git repositories hosted by other Git based SCM tools,
+however the metrics are still expose via Gerrit, so a dedicated Gerrit instance running alongside
+the current SCM tool is still required.
+So to make this plugin work with other Git SCM tools, a Gerrit installation needs to be set-up and
+the `basePath` needs to be set to the git data directory of the tool of choice.
+You will also need to set `gracePeriod` and `forceCollection`, as when using a different SCM tool
+than Gerrit the usual hooks aren't triggered.
+Finally, a configuration option will need to be specified to indicate which Backend is being used.
+Currently supported backend, other than GERRIT are:
+- GITLAB
+
+Find more in the configuration section below.
+
## Configuration
More information about the plugin configuration can be found in the [config.md](src/resources/Documentation/config.md)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitBackend.java b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitBackend.java
new file mode 100644
index 0000000..9c98e41
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitBackend.java
@@ -0,0 +1,40 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.gitrepometrics;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+public enum GitBackend {
+ GERRIT {
+ @Override
+ public String repoPath(String projectName) {
+ return projectName;
+ }
+ },
+
+ GITLAB {
+ @Override
+ public String repoPath(String projectName) {
+ String sha256OfProjectName = DigestUtils.sha256Hex(projectName);
+ return String.format("%s/%s/%s.git",
+ sha256OfProjectName.substring(0, 2),
+ sha256OfProjectName.substring(2, 4),
+ sha256OfProjectName);
+ }
+ };
+
+ abstract String repoPath(String projectName);
+
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsConfig.java b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsConfig.java
index 83719a3..bd80489 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsConfig.java
@@ -51,4 +51,8 @@
public int getPoolSize() {
return config.getInt("git-repo-metrics", null, "poolSize", 1);
}
+
+ public GitBackend getGitBackend() {
+ return config.getEnum("git-repo-metrics", null, "gitBackend", GitBackend.GERRIT);
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTask.java b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTask.java
index 838429e..14ab53e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTask.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTask.java
@@ -39,20 +39,23 @@
private final String projectName;
private GitRepoMetricsCache gitRepoMetricsCache;
private GitRepositoryManager repoManager;
+ private GitBackend gitBackend;
@Inject
UpdateGitMetricsTask(
GitRepoMetricsCache gitRepoMetricsCache,
GitRepositoryManager repoManager,
+ GitRepoMetricsConfig config,
@Assisted String projectName) {
this.projectName = projectName;
this.gitRepoMetricsCache = gitRepoMetricsCache;
this.repoManager = repoManager;
+ this.gitBackend = config.getGitBackend();
}
@Override
public void run() {
- Project.NameKey projectNameKey = Project.nameKey(projectName);
+ Project.NameKey projectNameKey = Project.nameKey(gitBackend.repoPath(projectName));
try (Repository repository = repoManager.openRepository(projectNameKey)) {
logger.atInfo().log(
"Running task to collect stats: repo %s, project %s",
diff --git a/src/resources/Documentation/config.md b/src/resources/Documentation/config.md
index 2c0f39c..28e2aa7 100644
--- a/src/resources/Documentation/config.md
+++ b/src/resources/Documentation/config.md
@@ -38,6 +38,7 @@
project = test-project
project = another-repo
gracePeriod = 5m
+ backend = GERRIT
```
_git-repo-metrics.forcedCollection_: Force the repositories' metric collection update every
_gracePeriod_ interval. By default, disabled.
@@ -48,4 +49,11 @@
_git-repo-metrics.gracePeriod_: Grace period between samples collection. Used to avoid aggressive
metrics collection. By default, 0.
-_git-repo-metrics.poolSize_: Number of threads available to collect metrics. By default, 1.
\ No newline at end of file
+_git-repo-metrics.poolSize_: Number of threads available to collect metrics. By default, 1.
+_git-repo-metrics.gitBackend_: Name of the Git SCM tool managing the Git data, for which this tools will expose
+metrics.
+
+Currently supported values:
+- GERRIT (default)
+- GITLAB
+
diff --git a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheIT.java b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheIT.java
index 4eee736..087899a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheIT.java
@@ -27,8 +27,11 @@
import com.googlesource.gerrit.plugins.gitrepometrics.collectors.FSMetricsCollector;
import com.googlesource.gerrit.plugins.gitrepometrics.collectors.GitRefsMetricsCollector;
import com.googlesource.gerrit.plugins.gitrepometrics.collectors.GitStatsMetricsCollector;
+
+import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import org.junit.Test;
@@ -66,10 +69,11 @@
pluginName = "git-repo-metrics",
name = "git-repo-metrics.project",
values = {"testProject1", "testProject2"})
- public void shouldRegisterAllMetrics() {
+ public void shouldRegisterAllMetrics() throws IOException {
+ ConfigSetupUtils configSetupUtils = new ConfigSetupUtils(Arrays.asList("testProject1", "testProject2"));
List<Project.NameKey> availableProjects = Arrays.asList(testProject1, testProject2);
- new UpdateGitMetricsTask(gitRepoMetricsCache, repoManager, testProject1.get()).run();
- new UpdateGitMetricsTask(gitRepoMetricsCache, repoManager, testProject2.get()).run();
+ new UpdateGitMetricsTask(gitRepoMetricsCache, repoManager, configSetupUtils.getGitRepoMetricsConfig(), testProject1.get()).run();
+ new UpdateGitMetricsTask(gitRepoMetricsCache, repoManager, configSetupUtils.getGitRepoMetricsConfig(), testProject2.get()).run();
int expectedMetricsCount =
fsMetricsCollector.availableMetrics().size()