Add string.capitalize()

--
MOS_MIGRATED_REVID=101575207
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index e7cbf90..93a01e9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -385,6 +385,26 @@
     return result;
   }
 
+  @SkylarkSignature(
+    name = "capitalize",
+    objectType = StringModule.class,
+    returnType = String.class,
+    doc =
+        "Returns a copy of the string with its first character capitalized and the rest"
+            + "lowercased. This method does not support non-ascii characters.",
+    mandatoryPositionals = {@Param(name = "self", type = String.class, doc = "This string.")}
+  )
+  private static BuiltinFunction capitalize =
+      new BuiltinFunction("capitalize") {
+        @SuppressWarnings("unused")
+        public String invoke(String self) throws EvalException {
+          if (self.isEmpty()) {
+            return self;
+          }
+          return Character.toUpperCase(self.charAt(0)) + self.substring(1).toLowerCase();
+        }
+      };
+
   @SkylarkSignature(name = "title", objectType = StringModule.class,
       returnType = String.class,
       doc =
@@ -1379,9 +1399,28 @@
       + "</pre>")
   public static final class DictModule {}
 
-  public static final List<BaseFunction> stringFunctions = ImmutableList.<BaseFunction>of(
-      count, endswith, find, index, format, join, lower, partition, replace, rfind,
-      rindex, rpartition, rsplit, slice, split, startswith, strip, title, upper);
+  public static final List<BaseFunction> stringFunctions =
+      ImmutableList.<BaseFunction>of(
+          capitalize,
+          count,
+          endswith,
+          find,
+          index,
+          format,
+          join,
+          lower,
+          partition,
+          replace,
+          rfind,
+          rindex,
+          rpartition,
+          rsplit,
+          slice,
+          split,
+          startswith,
+          strip,
+          title,
+          upper);
 
   public static final List<BaseFunction> listPureFunctions = ImmutableList.<BaseFunction>of(
       slice);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
index 29a9459..36db735 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
@@ -346,6 +346,15 @@
   }
 
   @Test
+  public void testCapitalize() throws Exception {
+    new BothModesTest()
+        .testStatement("'hello world'.capitalize()", "Hello world")
+        .testStatement("'HELLO WORLD'.capitalize()", "Hello world")
+        .testStatement("''.capitalize()", "")
+        .testStatement("'12 lower UPPER 34'.capitalize()", "12 lower upper 34");
+  }
+
+  @Test
   public void testPyStringRfind() throws Exception {
     new BothModesTest()
         .testStatement("'banana'.rfind('na')", 4)