Move extract-issues to analytics.config

Fix an issue whereby the extract-issue argument was
ignored when passed as parameter of the contributors endpoint.

The extraction of arguments that are unlikely to change often across
invocation is moved to the analytics.config instead, similarly to what
has been done for bot-like-commits.

Honors the extract-issue value, by reading it from the config.

Bug: Issue 10951
Change-Id: I065c5592c9a9982d9d623f744a141ca12338aae6
diff --git a/README.md b/README.md
index 0f9f244..8338bcd 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,6 @@
 - --until -e Ending timestamp (excluded) to consider
 - --aggregate -granularity -g one of email, email_year, email_month, email_day, email_hour defaulting to aggregation by email
 - --extract-branches -r enables splitting of aggregation by branch name and expose branch name in the payload
-- --extract-issues -i enables the extraction of issues from commentLink
 
 NOTE: Timestamp format is consistent with Gerrit's query syntax, see /Documentation/user-search.html for details.
 
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 89a6806..6c08a06 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -22,4 +22,16 @@
   ```
 
   Keep in mind that plugin configurations are written in [git-config style syntax](https://git-scm.com/docs/git-config#_syntax),
-  so you should be escaping regular expressions accordingly.
\ No newline at end of file
+  so you should be escaping regular expressions accordingly.
+
+- `contributors.extract-issues`
+
+  when set to true, enables the extraction of issues from commentLink
+
+  Default: false
+
+  example:
+  ```ini
+  [contributors]
+    extract-issues = true
+  ```
\ No newline at end of file
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala
index 8035a43..fd31626 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala
@@ -16,17 +16,22 @@
 
 import com.google.gerrit.extensions.annotations.PluginName
 import com.google.gerrit.server.config.PluginConfigFactory
-import com.google.inject.Inject
+import com.google.inject.{ImplementedBy, Inject}
 import org.eclipse.jgit.lib.Config
 
-class AnalyticsConfig @Inject() (val pluginConfigFactory: PluginConfigFactory, @PluginName val pluginName: String) {
+@ImplementedBy(classOf[AnalyticsConfigImpl])
+trait AnalyticsConfig {
+  def botlikeFilenameRegexps: List[String]
+  def isExtractIssues: Boolean
+}
 
-  lazy val pluginConfig: Config = pluginConfigFactory.getGlobalPluginConfig(pluginName)
-
-  val Contributors = "contributors"
-  val BotlikeFilenameRegexp = "botlike-filename-regexp"
-
+class AnalyticsConfigImpl @Inject() (val pluginConfigFactory: PluginConfigFactory, @PluginName val pluginName: String) extends AnalyticsConfig{
   lazy val botlikeFilenameRegexps: List[String] = pluginConfigBotLikeFilenameRegexp
+  lazy val isExtractIssues: Boolean = pluginConfig.getBoolean(Contributors, null, ExtractIssues, false)
 
+  private lazy val pluginConfig: Config = pluginConfigFactory.getGlobalPluginConfig(pluginName)
+  private val Contributors = "contributors"
+  private val BotlikeFilenameRegexp = "botlike-filename-regexp"
+  private val ExtractIssues = "extract-issues"
   private lazy val pluginConfigBotLikeFilenameRegexp = pluginConfig.getStringList(Contributors, null, BotlikeFilenameRegexp).toList
 }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
index 8e048e2..e57cd1d 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
@@ -14,19 +14,14 @@
 
 package com.googlesource.gerrit.plugins.analytics
 
-import com.google.common.cache.{Cache, LoadingCache}
-import com.google.gerrit.extensions.api.projects.CommentLinkInfo
 import com.google.gerrit.extensions.restapi.{BadRequestException, Response, RestReadView}
 import com.google.gerrit.server.git.GitRepositoryManager
 import com.google.gerrit.server.project.{ProjectCache, ProjectResource}
 import com.google.gerrit.server.restapi.project.ProjectsCollection
 import com.google.gerrit.sshd.{CommandMetaData, SshCommand}
 import com.google.inject.Inject
-import com.google.inject.name.Named
 import com.googlesource.gerrit.plugins.analytics.common.DateConversions._
 import com.googlesource.gerrit.plugins.analytics.common._
-import com.googlesource.gerrit.plugins.analytics.common.CommitsStatisticsCache.COMMITS_STATISTICS_CACHE
-import org.eclipse.jgit.lib.ObjectId
 import org.kohsuke.args4j.{Option => ArgOption}
 
 
@@ -76,13 +71,9 @@
     }
   }
 
-  @ArgOption(name = "--extract-issues", aliases = Array("-i"),
-    usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
-  private var extractIssues: Boolean = false
-
   override protected def run =
     gsonFmt.format(executor.get(projectRes, beginDate, endDate,
-      granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues), stdout)
+      granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches), stdout)
 
 }
 
@@ -130,15 +121,11 @@
     usage = "Do extra parsing to extract a list of all branches for each line")
   private var extractBranches: Boolean = false
 
-  @ArgOption(name = "--extract-issues", aliases = Array("-i"),
-    usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
-  private var extractIssues: Boolean = false
-
   override def apply(projectRes: ProjectResource) =
     Response.ok(
       new GsonStreamedResult[UserActivitySummary](gson,
         executor.get(projectRes, beginDate, endDate,
-          granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues)))
+          granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches)))
 }
 
 class ContributorsService @Inject()(repoManager: GitRepositoryManager,
@@ -148,15 +135,9 @@
                                     commitsStatisticsCache: CommitsStatisticsCache) {
   import RichBoolean._
 
-  import scala.collection.JavaConverters._
-
   def get(projectRes: ProjectResource, startDate: Option[Long], stopDate: Option[Long],
-          aggregationStrategy: AggregationStrategy, extractBranches: Boolean, extractIssues: Boolean)
+          aggregationStrategy: AggregationStrategy, extractBranches: Boolean)
   : TraversableOnce[UserActivitySummary] = {
-    val nameKey = projectRes.getNameKey
-    val commentLinks: List[CommentLinkInfo] = extractIssues.option {
-      projectCache.get(nameKey).getCommentLinks.asScala
-    }.toList.flatten
 
     ManagedResource.use(repoManager.openRepository(projectRes.getNameKey)) { repo =>
       val stats  = new Statistics(projectRes.getNameKey, commitsStatisticsCache)
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
index 36a175b..1144901 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
@@ -20,7 +20,7 @@
 import com.google.gerrit.server.git.GitRepositoryManager
 import com.google.gerrit.server.project.ProjectCache
 import com.google.inject.Inject
-import com.googlesource.gerrit.plugins.analytics.{CommitInfo, IssueInfo}
+import com.googlesource.gerrit.plugins.analytics.{AnalyticsConfig, CommitInfo, IssueInfo}
 import com.googlesource.gerrit.plugins.analytics.common.ManagedResource.use
 import org.eclipse.jgit.diff.{DiffFormatter, RawTextComparator}
 import org.eclipse.jgit.revwalk.RevWalk
@@ -30,14 +30,20 @@
 import scala.collection.JavaConverters._
 import scala.util.matching.Regex
 
-class CommitsStatisticsLoader @Inject() (gitRepositoryManager: GitRepositoryManager, projectCache: ProjectCache, botLikeExtractor: BotLikeExtractor) extends CacheLoader[CommitsStatisticsCacheKey, CommitsStatistics] {
+class CommitsStatisticsLoader @Inject() (
+  gitRepositoryManager: GitRepositoryManager,
+  projectCache: ProjectCache,
+  botLikeExtractor: BotLikeExtractor,
+  config: AnalyticsConfig
+) extends CacheLoader[CommitsStatisticsCacheKey, CommitsStatistics] {
 
   override def load(cacheKey: CommitsStatisticsCacheKey): CommitsStatistics = {
     import RevisionBrowsingSupport._
 
     val objectId = cacheKey.commitId
     val nameKey = new Project.NameKey(cacheKey.projectName)
-    val commentInfoList: Seq[CommentLinkInfo] = projectCache.get(nameKey).getCommentLinks.asScala
+    val commentInfoList: Seq[CommentLinkInfo] =
+      if(config.isExtractIssues) projectCache.get(nameKey).getCommentLinks.asScala else Seq.empty
     val replacers = commentInfoList.map(info =>
       Replacer(
         info.`match`.r,
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
index e9f9c7a..5bb73c5 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
@@ -46,7 +46,8 @@
     extractor.isBotLike(Set("some/path/anyFile")).shouldBe(false)
   }
 
-  private def newBotLikeExtractorImpl(botLikeRegexps: List[String]) = new BotLikeExtractorImpl(new AnalyticsConfig(null, null) {
+  private def newBotLikeExtractorImpl(botLikeRegexps: List[String]) = new BotLikeExtractorImpl(new AnalyticsConfig {
     override lazy val botlikeFilenameRegexps = botLikeRegexps
+    override lazy val isExtractIssues: Boolean = false
   })
 }
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
index f10c772..59a6d90 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
@@ -21,6 +21,7 @@
 import com.google.gerrit.extensions.annotations.PluginName
 import com.google.gerrit.reviewdb.client.Project
 import com.google.inject.{AbstractModule, Module}
+import com.googlesource.gerrit.plugins.analytics.AnalyticsConfig
 import org.eclipse.jgit.api.MergeCommand.FastForwardMode
 import org.eclipse.jgit.api.{Git, MergeResult}
 import org.eclipse.jgit.internal.storage.file.FileRepository
@@ -152,6 +153,10 @@
 
   override def createModule(): Module = new AbstractModule {
     override def configure(): Unit = {
+      bind(classOf[AnalyticsConfig]).toInstance(new AnalyticsConfig {
+        override def botlikeFilenameRegexps: List[String] = List.empty
+        override def isExtractIssues: Boolean = true
+      })
       bind(classOf[String]).annotatedWith(classOf[PluginName]).toInstance("analytics")
     }
   }