Move botlike-filename-regexp to analytics.config

The extraction of the analytics from the projects is a very expensive
operation. While the time-based parameters make sense to be in the API
the global options for "tagging" the commits as bot-like or not, is
very unlikely to change for every single invocation.

Move the botlike-filename-regexp into the new analytics.config so
that the results of the analytics extraction can be later on cached
consistently and reused as much as possible.

The actual caching is addressed in a follow-up change.

Change-Id: Ic3ac347fca59d4b8be0c20c32848682a55fdf26c
diff --git a/README.md b/README.md
index e7eb7ab..0f9f244 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@
 
 ## How to configure
 
-Nothing to configure, it just works.
+See the relevant section in the [configuration guide](src/main/resources/Documentation/config.md)
 
 ## How to use
 
@@ -71,7 +71,6 @@
 - --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
-- --botlike-filename-regexps -n comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like
 
 NOTE: Timestamp format is consistent with Gerrit's query syntax, see /Documentation/user-search.html for details.
 
@@ -92,55 +91,3 @@
    {"name":"John Doe","email":"john.doe@mycompany.com","num_commits":1, "num_files":4,"added_lines":9,"deleted_lines":1, "commits":[{"sha1":"6a1f73738071e299f600017d99f7252d41b96b4b","date":"Apr 28, 2011 5:13:14 AM","merge":false,"bot_like": false}],"is_bot_like": false,"issues_codes":["PRJ-001"],"issues_links":["https://jira.company.org/PRJ-001"]}
    {"name":"Matt Smith","email":"matt.smith@mycompany.com","num_commits":1, "num_files":1,"added_lines":90,"deleted_lines":10,"commits":[{"sha1":"54527e7e3086758a23e3b069f183db6415aca304","date":"Sep 8, 2015 3:11:23 AM","merge":true,"bot_like": false,}],"is_bot_like": false,"branches":["branch1"],"issues_codes":["PRJ-002","PRJ-003"],"issues_links":["https://jira.company.org/PRJ-002","https://jira.company.org/PRJ-003"]}
 ```
-
-- BOT-like:
-Flags the commit as bot-like when *all* files in that commit match any of the following regular expressions: 
-
-    * .+\\.xml
-    * .+\\.bzl
-    * BUILD
-    * WORKSPACE
-    * \\.gitignore
-    * plugins/
-    * \\.settings
-
-```
-curl 'http://gerrit.mycompany.com/projects/myproject/analytics~contributors?botlike-filename-regexps=.%2B%5C.xml%2C.%2B%5C.bzl%2CBUILD%2CWORKSPACE%2C%5C.gitignore%2Cplugins%2F%2C%5C.settings'
-
-{
-  "year": 2018,
-  "month": 3,
-  "day": 21,
-  "hour": 19,
-  "name": "Dave Borowitz",
-  "email": "dborowitz@google.com",
-  "num_commits": 1,
-  "num_files": 6,
-  "num_distinct_files": 6,
-  "added_lines": 6,
-  "deleted_lines": 6,
-  "commits": [
-    {
-      "sha1": "a3ab2e1d07e6745f50b1d9907f6580c6521fd035",
-      "date": 1521661246000,
-      "merge": false,
-      "bot_like": true,
-      "files": [
-        "version.bzl",
-        "gerrit-plugin-gwtui/pom.xml",
-        "gerrit-extension-api/pom.xml",
-        "gerrit-war/pom.xml",
-        "gerrit-plugin-api/pom.xml",
-        "gerrit-acceptance-framework/pom.xml"
-      ]
-    }
-  ],
-  "branches": [],
-  "issues_codes": [],
-  "issues_links": [],
-  "last_commit_date": 1521661246000,
-  "is_merge": false,
-  "is_bot_like": true
-}
-```
-
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..89a6806
--- /dev/null
+++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,25 @@
+# Analytics plugin configuration
+
+The configuration is located on `$GERRIT_SITE/etc/analytics.config` and allows
+to customize the default parameters for the analytics extraction.
+
+## Parameters
+
+- `contributors.botlike-filename-regexp`
+
+  List of regexps that identify a bot-like commit, commits that modify only
+  files whose name is a match will be flagged as bot-like.
+
+  Default: empty
+
+  Example:
+  ```ini
+  [contributors]
+    botlike-filename-regexp = .+\\.xml
+    botlike-filename-regexp = .+\\.bzl
+    botlike-filename-regexp = BUILD
+    botlike-filename-regexp = WORKSPACE
+  ```
+
+  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
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala
new file mode 100644
index 0000000..108b271
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/AnalyticsConfig.scala
@@ -0,0 +1,30 @@
+// 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.analytics
+
+import com.google.gerrit.extensions.annotations.PluginName
+import com.google.gerrit.server.config.PluginConfigFactory
+import com.google.inject.Inject
+import org.eclipse.jgit.lib.Config
+
+class AnalyticsConfig @Inject() (val pluginConfigFactory: PluginConfigFactory, @PluginName val pluginName: String) {
+
+  lazy val pluginConfig: Config = pluginConfigFactory.getGlobalPluginConfig(pluginName)
+
+  val Contributors = "contributors"
+  val BotlikeFilenameRegexp = "botlike-filename-regexp"
+
+  lazy val botlikeFilenameRegexps: List[String] = 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 8dbd4d4..1bda651 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
@@ -29,13 +29,14 @@
 @CommandMetaData(name = "contributors", description = "Extracts the list of contributors to a project")
 class ContributorsCommand @Inject()(val executor: ContributorsService,
                                     val projects: ProjectsCollection,
-                                    val gsonFmt: GsonFormatter)
+                                    val gsonFmt: GsonFormatter,
+                                    val config: AnalyticsConfig)
   extends SshCommand with ProjectResourceParser {
 
   private var beginDate: Option[Long] = None
   private var endDate: Option[Long] = None
   private var granularity: Option[AggregationStrategy] = None
-  private var botLikeRegexps: List[String] = List.empty[String]
+  private var botLikeRegexps: List[String] = config.botlikeFilenameRegexps
 
   @ArgOption(name = "--extract-branches", aliases = Array("-r"),
     usage = "Do extra parsing to extract a list of all branches for each line")
@@ -75,12 +76,6 @@
     usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
   private var extractIssues: Boolean = false
 
-  @ArgOption(name = "--botlike-filename-regexps", aliases = Array("-n"),
-    usage = "comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like")
-  def setBotLikeRegexps(value: String): Unit = {
-    botLikeRegexps = value.split(",").toList
-  }
-
   override protected def run =
     gsonFmt.format(executor.get(projectRes, beginDate, endDate,
       granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues, botLikeRegexps), stdout)
@@ -88,13 +83,14 @@
 }
 
 class ContributorsResource @Inject()(val executor: ContributorsService,
-                                     val gson: GsonFormatter)
+                                     val gson: GsonFormatter,
+                                     val config: AnalyticsConfig)
   extends RestReadView[ProjectResource] {
 
   private var beginDate: Option[Long] = None
   private var endDate: Option[Long] = None
   private var granularity: Option[AggregationStrategy] = None
-  private var botLikeRegexps: List[String] = List.empty[String]
+  private var botLikeRegexps: List[String] = config.botlikeFilenameRegexps
 
   @ArgOption(name = "--since", aliases = Array("--after", "-b"), metaVar = "QUERY",
     usage = "(included) begin timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
@@ -134,12 +130,6 @@
     usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
   private var extractIssues: Boolean = false
 
-  @ArgOption(name = "--botlike-filename-regexps", aliases = Array("-n"),
-    usage = "comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like")
-  def setBotLikeRegexps(value: String): Unit = {
-    botLikeRegexps = value.split(",").toList
-  }
-
   override def apply(projectRes: ProjectResource) =
     Response.ok(
       new GsonStreamedResult[UserActivitySummary](gson,