)]}'
{
  "commit": "f59d2635c5815903405131969e61ccfc86349fd6",
  "tree": "236789700199aa1712a79e5e2c13f6fbc5314668",
  "parents": [
    "5b890d1a4c13cc7144fbfdd2a0b525c1627db4ec"
  ],
  "author": {
    "name": "Michael Bolin",
    "email": "mbolin@fb.com",
    "time": "Tue Nov 12 12:43:57 2013 -0800"
  },
  "committer": {
    "name": "Michael Bolin",
    "email": "mbolin@fb.com",
    "time": "Sat Nov 16 19:35:34 2013 -0800"
  },
  "message": "Convert DexProducedFromJavaLibraryThatContainsClassFiles into an AbstractCachingBuildRule that is an AbiRule.\n\nSummary:\nThere are three possible scenarios when building `DexProducedFromJavaLibraryThatContainsClassFiles`:\n\n(1) The are are no `.class` files to dex.\n(2) There are `.class` files that need to be dexed to update/create the `.dex.jar` file in `buck-out`.\n(3) The existing `.dex.jar` file in `buck-out` already represents the `.class` files to dex.\n\nIn order to be able to look at what is in `buck-out` before building (case 3), we either\nneed to get a rule key match (which works by default in Buck), or leverage the `AbiRule`\nlogic we already have in place for Java rules. (If we wait until we start building\n`DexProducedFromJavaLibraryThatContainsClassFiles`, the `buck-out` directory containing\nthe old `.dex.jar` may already be deleted.)\n\nRecall that an `AbiRule` can avoid rebuilding if the following conditions hold:\n(1) The hash of the current rule definition and its input files matches the\nhash on disk (written in `.metadata/METADATA_KEY_FOR_RULE_KEY_WITHOUT_DEPS`).\n(2) All relevant deps that have an ABI have the same ABI as the last time the\nrule was built (written in `.metadata/ABI_KEY_FOR_DEPS_ON_DISK_METADATA`).\n\nTherefore, for an `AccumulateClassNames`, we assign it an ABI based on the\ncontents of the `classes.txt` file that it writes.\nBecause a `DexProducedFromJavaLibraryThatContainsClassFiles` has a\n`AccumulateClassNames` as its only dependency, the ABI of `AccumulateClassNames`\nis the ABI-key-for-deps of the `DexProducedFromJavaLibraryThatContainsClassFiles`.\n\nUltimately, this ensures that if a `java_library` rule is recompiled such that its\ngenerated `.class` files are the same (this happens when a `java_library` rule is\nrecompiled in response to one of its deps changing in a way that does not affect\nthat `java_library` that depends on it, such as adding a new public method),\nthen the output of the `classes.txt` file for the `java_library` should be the same.\nIn turn, because the ABI of the `AccumulateClassNames` that generated the\n`classes.txt` is unchanged, the `DexProducedFromJavaLibraryThatContainsClassFiles`\nshould rightfully avoid a rebuild. This optimization can have a significant impact on\nincremental build times.\n\nTest Plan: Sandcastle builds.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "401dc5cdffa33349ee07cc2a598b32dca3552113",
      "old_mode": 33188,
      "old_path": "src/com/facebook/buck/android/AndroidBinaryRule.java",
      "new_id": "d99c4ddeee6f3233c73077a9782b53e6b96b2afb",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/android/AndroidBinaryRule.java"
    },
    {
      "type": "modify",
      "old_id": "9fb3aca488d1d48483d92dfb0fc6cef7e1a2208c",
      "old_mode": 33188,
      "old_path": "src/com/facebook/buck/android/BUCK",
      "new_id": "7270ae2596bb1792555bbd87aad2444deb8c0e55",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/android/BUCK"
    },
    {
      "type": "modify",
      "old_id": "d917476bef84a2c802d893c69613b41e10e85578",
      "old_mode": 33188,
      "old_path": "src/com/facebook/buck/android/DexProducedFromJavaLibraryThatContainsClassFiles.java",
      "new_id": "172870430fc16c4a6db3a3c29d32dc01d27a4a63",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/android/DexProducedFromJavaLibraryThatContainsClassFiles.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8d5b301fa38592a22ff173a9e0bf4c2b345e4ef8",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/android/IntermediateDexRule.java"
    },
    {
      "type": "modify",
      "old_id": "142bfad4c0080818c6ccc1c43520e587a2d0d2fa",
      "old_mode": 33188,
      "old_path": "src/com/facebook/buck/java/AccumulateClassNames.java",
      "new_id": "a0069cc3623f4e43a6da2cfb75ed9f9261218702",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/java/AccumulateClassNames.java"
    },
    {
      "type": "modify",
      "old_id": "e2e0cb5893cc5fffee0b4913b631dfdb7d5a161a",
      "old_mode": 33188,
      "old_path": "src/com/facebook/buck/java/AccumulateClassNamesStep.java",
      "new_id": "8add939ad68560f810890b09f076885b39725d85",
      "new_mode": 33188,
      "new_path": "src/com/facebook/buck/java/AccumulateClassNamesStep.java"
    },
    {
      "type": "modify",
      "old_id": "4d5fd00f4a3abcb941921ec0806abd446a818be9",
      "old_mode": 33188,
      "old_path": "test/com/facebook/buck/android/BUCK",
      "new_id": "4677812a9c7b00e102c0a566c2489f3db9b353f9",
      "new_mode": 33188,
      "new_path": "test/com/facebook/buck/android/BUCK"
    },
    {
      "type": "modify",
      "old_id": "c18b4a5c331206c404922294cb41bc1e86272eb9",
      "old_mode": 33188,
      "old_path": "test/com/facebook/buck/android/DexProducedFromJavaLibraryThatContainsClassFilesTest.java",
      "new_id": "4d2f5bf0c1d5fdafd5e3ff5e3bf9f19c403310a4",
      "new_mode": 33188,
      "new_path": "test/com/facebook/buck/android/DexProducedFromJavaLibraryThatContainsClassFilesTest.java"
    },
    {
      "type": "modify",
      "old_id": "d9987a684aa33931641c403c72d5e5f082a00450",
      "old_mode": 33188,
      "old_path": "test/com/facebook/buck/java/AccumulateClassNamesTest.java",
      "new_id": "9c1dbcfc29f0f99ba918cb1266b637cd8ca2198a",
      "new_mode": 33188,
      "new_path": "test/com/facebook/buck/java/AccumulateClassNamesTest.java"
    }
  ]
}
