Merge changes from topic "ref-config-section"

* changes:
  AccessSection: stop inheritting from RefConfigSection
  AccessSection: update visibility modifiers
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index cebac23..f64d693 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -4769,7 +4769,7 @@
 
 +
 The time zone cannot be specified but is always the system default
-time zone.
+time zone. Hours must be zero-padded, i.e. `06:00` rather than `6:00`.
 
 The section (and optionally the subsection) in which the `interval` and
 `startTime` keys must be set depends on the background job for which a
diff --git a/java/com/google/gerrit/pgm/util/SiteProgram.java b/java/com/google/gerrit/pgm/util/SiteProgram.java
index de8238d..7c384e7 100644
--- a/java/com/google/gerrit/pgm/util/SiteProgram.java
+++ b/java/com/google/gerrit/pgm/util/SiteProgram.java
@@ -47,7 +47,7 @@
       aliases = {"-d"},
       usage = "Local directory containing site data")
   private void setSitePath(String path) {
-    sitePath = Paths.get(path);
+    sitePath = Paths.get(path).normalize();
   }
 
   private Path sitePath = Paths.get(".");
@@ -55,7 +55,7 @@
   protected SiteProgram() {}
 
   protected SiteProgram(Path sitePath) {
-    this.sitePath = sitePath;
+    this.sitePath = sitePath.normalize();
   }
 
   /** @return the site path specified on the command line. */
diff --git a/java/com/google/gerrit/server/config/ScheduleConfig.java b/java/com/google/gerrit/server/config/ScheduleConfig.java
index c5f53b3..963107a2 100644
--- a/java/com/google/gerrit/server/config/ScheduleConfig.java
+++ b/java/com/google/gerrit/server/config/ScheduleConfig.java
@@ -91,7 +91,7 @@
  *       executions are {@code Wed 10:30}, {@code Fri 10:30}. etc.
  *   <li>
  *       <pre>
- * foo.startTime = 6:00
+ * foo.startTime = 06:00
  * foo.interval = 1 day
  * </pre>
  *       Assuming that the server is started on {@code Mon 7:00} then this yields the first run on
@@ -174,7 +174,18 @@
       return true;
     }
 
-    if (interval <= 0 || initialDelay < 0) {
+    if (interval != INVALID_CONFIG && interval <= 0) {
+      logger.atSevere().log("Invalid interval value \"%d\" for \"%s\": must be > 0", interval, key);
+      interval = INVALID_CONFIG;
+    }
+
+    if (initialDelay != INVALID_CONFIG && initialDelay < 0) {
+      logger.atSevere().log(
+          "Invalid initial delay value \"%d\" for \"%s\": must be >= 0", initialDelay, key);
+      initialDelay = INVALID_CONFIG;
+    }
+
+    if (interval == INVALID_CONFIG || initialDelay == INVALID_CONFIG) {
       logger.atSevere().log("Invalid schedule configuration for \"%s\" is ignored. ", key);
       return true;
     }
@@ -216,6 +227,9 @@
       return ConfigUtil.getTimeUnit(
           rc, section, subsection, keyInterval, MISSING_CONFIG, TimeUnit.MILLISECONDS);
     } catch (IllegalArgumentException e) {
+      // We only need to log the exception message; it already includes the
+      // section.subsection.key and bad value.
+      logger.atSevere().log("%s", e.getMessage());
       return INVALID_CONFIG;
     }
   }
@@ -258,6 +272,7 @@
       }
       return delay;
     } catch (DateTimeParseException e) {
+      logger.atSevere().log("Invalid start time: %s", e.getMessage());
       return INVALID_CONFIG;
     }
   }
diff --git a/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java b/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
index f0e9153..6926052 100644
--- a/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
+++ b/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
@@ -41,15 +41,18 @@
   @Test
   public void initialDelay() throws Exception {
     assertThat(initialDelay("11:00", "1h")).isEqualTo(ms(1, HOURS));
+    assertThat(initialDelay("11:00", "1 hour")).isEqualTo(ms(1, HOURS));
     assertThat(initialDelay("05:30", "1h")).isEqualTo(ms(30, MINUTES));
     assertThat(initialDelay("09:30", "1h")).isEqualTo(ms(30, MINUTES));
     assertThat(initialDelay("13:30", "1h")).isEqualTo(ms(30, MINUTES));
     assertThat(initialDelay("13:59", "1h")).isEqualTo(ms(59, MINUTES));
 
     assertThat(initialDelay("11:00", "1d")).isEqualTo(ms(1, HOURS));
+    assertThat(initialDelay("11:00", "1 day")).isEqualTo(ms(1, HOURS));
     assertThat(initialDelay("05:30", "1d")).isEqualTo(ms(19, HOURS) + ms(30, MINUTES));
 
     assertThat(initialDelay("11:00", "1w")).isEqualTo(ms(1, HOURS));
+    assertThat(initialDelay("11:00", "1 week")).isEqualTo(ms(1, HOURS));
     assertThat(initialDelay("05:30", "1w")).isEqualTo(ms(7, DAYS) - ms(4, HOURS) - ms(30, MINUTES));
 
     assertThat(initialDelay("Mon 11:00", "1w")).isEqualTo(ms(3, DAYS) + ms(1, HOURS));
@@ -200,6 +203,9 @@
 
     rc.setString("a", null, ScheduleConfig.KEY_STARTTIME, "0100");
     assertThat(ScheduleConfig.builder(rc, "a").buildSchedule()).isEmpty();
+
+    rc.setString("a", null, ScheduleConfig.KEY_STARTTIME, "1:00");
+    assertThat(ScheduleConfig.builder(rc, "a").buildSchedule()).isEmpty();
   }
 
   @Test
diff --git a/resources/com/google/gerrit/server/mime/mime-types.properties b/resources/com/google/gerrit/server/mime/mime-types.properties
index e4d478e..71b57bb 100644
--- a/resources/com/google/gerrit/server/mime/mime-types.properties
+++ b/resources/com/google/gerrit/server/mime/mime-types.properties
@@ -209,6 +209,7 @@
 sql = text/x-sql
 ss = text/x-scheme
 st = text/x-stsrc
+starlark = text/x-python
 stex = text/x-stex
 sv = text/x-systemverilog
 svh = text/x-systemverilog