Added pluginsInfo capability.
Adding 3 elements in the produced zip file, specifying plugins content,
lib content and the versions for each plugin.
Change-Id: Ib1c8bc4830114f74791145241a3af64979a013cd
diff --git a/src/main/resources/Documentation/rest-api.md b/src/main/resources/Documentation/rest-api.md
index 2f7d684..1595492 100644
--- a/src/main/resources/Documentation/rest-api.md
+++ b/src/main/resources/Documentation/rest-api.md
@@ -31,7 +31,42 @@
}
```
- configInfo - This will add in the zip all the *.config files in the $GERRIT/etc folder
+- pluginsInfo - This will add 3 elements in the zip containing the plugins_dir,
+ lib_dir and the versions for each plugin. Here a possible output:
+```
+lib_dir:
+[
+ {
+ "name": "github-oauth.jar",
+ "perms": "rw-rw-r--",
+ "owner": "gerrit",
+ "group": "gerrit",
+ "date": "2017-06-04T08:35:02Z",
+ "size": 128567
+ }
+]
+plugins_dir:
+[
+ {
+ "name": "gerrit-support.jar",
+ "perms": "rw-rw-r--",
+ "owner": "gerrit",
+ "group": "gerrit",
+ "date": "2017-06-04T08:35:02Z",
+ "size": 9639813
+ }
+]
+
+plugins_versions:
+{
+ "gerrit-support": {
+ "id" : "gerrit-support",
+ "version" : "1.0",
+ "indexUrl" : "/plugins/myplugin",
+ "disabled" : false }
+}
+```
NOTE: API must be authenticated with the credentials of a user with the
'Collect Server Data' capability.
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritFacade.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritFacade.scala
index 2736b9f..1bb9b0c 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritFacade.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritFacade.scala
@@ -16,7 +16,11 @@
package com.googlesource.gerrit.plugins.support
+import com.google.gerrit.extensions.restapi.TopLevelResource
import com.google.gerrit.server.account.CapabilityControl
+import com.google.gerrit.server.plugins.{ListPlugins, PluginsCollection}
+import com.google.gson.JsonElement
+import com.google.inject.{ImplementedBy, Inject}
import com.googlesource.gerrit.plugins.support.latest.LatestCapabilityControl
import com.googlesource.gerrit.plugins.support.legacy.LegacyCapabilityControl
@@ -45,3 +49,22 @@
}
}
}
+
+// Structure of the JSON fields returned by the pluginsInfo method
+case class PluginInfo(id: String, version: String, indexUrl: String, disabled: Boolean)
+
+@ImplementedBy(classOf[GerritPluginsInfoProvider])
+trait PluginsInfoProvider {
+
+ def getPluginsInfo: JsonElement
+}
+
+class GerritPluginsInfoProvider @Inject() (val pluginsCollection: PluginsCollection) extends PluginsInfoProvider {
+
+ override def getPluginsInfo: JsonElement = {
+ pluginsCollection
+ .list
+ .asInstanceOf[ListPlugins]
+ .apply(TopLevelResource.INSTANCE).asInstanceOf[JsonElement]
+ }
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/commands/FileAttribute.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/FileAttribute.scala
new file mode 100644
index 0000000..e5a5b27
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/FileAttribute.scala
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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.support.commands
+
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.attribute.{BasicFileAttributes, PosixFileAttributeView, PosixFileAttributes, PosixFilePermissions}
+
+case class FileAttribute(name: String, perms: String,
+ owner: String, group: String,
+ date: String, size: Long)
+
+object FileAttribute {
+ def from(f: File) = {
+ val p = f.toPath
+
+ FileAttribute(
+ name = f.getName,
+ perms = PosixFilePermissions.toString(
+ Files.getFileAttributeView(p, classOf[PosixFileAttributeView])
+ .readAttributes.permissions),
+ owner = Files.getOwner(p).getName,
+ group = Files.readAttributes(p, classOf[PosixFileAttributes])
+ .group.getName,
+ date =
+ Files.readAttributes(p, classOf[BasicFileAttributes])
+ .creationTime().toString,
+ size = f.length
+ )
+ }
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/commands/PluginsInfoCommand.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/PluginsInfoCommand.scala
new file mode 100644
index 0000000..b2837d3
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/PluginsInfoCommand.scala
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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.support.commands
+
+import java.io.StringWriter
+
+import com.google.gson.JsonArray
+import com.google.inject.Inject
+import com.googlesource.gerrit.plugins.support.GerritSupportCommand.{CommandResult, JsonResult}
+import com.googlesource.gerrit.plugins.support.{GerritSupportCommand, PluginsInfoProvider, SitePathsWrapper}
+
+class PluginsInfoCommand @Inject()(val sitePathsWrapper: SitePathsWrapper,
+ val pluginsInfoProvider: PluginsInfoProvider)
+ extends GerritSupportCommand {
+
+ override def getResults = {
+ try {
+ Seq(
+ listDir("plugins_dir"),
+ listDir("lib_dir"),
+ listPluginsVersions
+ )
+ } catch {
+ case e: Exception => {
+ val error = s"Error while processing pluginsInfo ${e
+ .getMessage}"
+ log.error(error,e)
+ Seq(CommandResult(name, error))
+ }
+ }
+ }
+
+ private def listDir(dir: String): CommandResult = {
+ val jsonArray = new JsonArray()
+ sitePathsWrapper
+ .getAsPath(dir)
+ .toFile
+ .listFiles
+ .map(FileAttribute.from)
+ .map(gson.toJsonTree)
+ .foreach(jsonArray.add)
+
+ CommandResult(dir, JsonResult(jsonArray))
+ }
+
+ private def listPluginsVersions = {
+ val outString = new StringWriter
+
+ CommandResult("plugins_versions",
+ JsonResult(gson.toJsonTree(pluginsInfoProvider.getPluginsInfo))
+ )
+ }
+}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
index 9384c37..833946d 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
@@ -18,6 +18,7 @@
import java.nio.file.Paths
+import com.google.gson.{Gson, JsonElement}
import com.googlesource.gerrit.plugins.support.GerritSupportCommand._
import com.googlesource.gerrit.plugins.support.commands._
import org.mockito.Matchers.any
@@ -72,5 +73,39 @@
content should not be empty
}
+ "plugins-info command" should "return some data" in {
+ val gson = new Gson
+
+ // returns a valid tmp path for any path requested
+ val mockedWrapper = {
+ val mock = Mockito.mock(classOf[SitePathsWrapper])
+ Mockito.when(mock.getAsPath(any[String])).thenReturn(tmpPath.toPath)
+ mock
+ }
+
+ val pluginsInfo = gson.toJsonTree(
+ Map("myplugin" -> PluginInfo("pluginId", "1.0", "/plugins/myplugin", false)))
+ val mockedPluginsCollection = new PluginsInfoProvider { def getPluginsInfo = pluginsInfo }
+
+ // assert we returns three entries for plugins_dir, lib_dir and
+ // plugins_version
+ val Seq(plugins_dir, lib_dir, plugins_versions) =
+ new PluginsInfoCommand(
+ mockedWrapper,
+ mockedPluginsCollection).execute
+
+ plugins_dir.entryName.value should be("plugins_dir")
+ val JsonResult(plugins_dir_result) = plugins_dir.content
+ plugins_dir_result.getAsJsonArray.size should not be 0
+
+ lib_dir.entryName.value should be("lib_dir")
+ val JsonResult(lib_dir_result) = lib_dir.content
+ lib_dir_result.getAsJsonArray.size should not be 0
+
+ plugins_versions.entryName.value should be("plugins_versions")
+ val JsonResult(pluginsInfoJson) = plugins_versions.content
+
+ pluginsInfoJson should be (pluginsInfo)
+ }
}