Convert DexProducedFromJavaLibraryThatContainsClassFiles into an AbstractCachingBuildRule that is an AbiRule.

Summary:
There are three possible scenarios when building `DexProducedFromJavaLibraryThatContainsClassFiles`:

(1) The are are no `.class` files to dex.
(2) There are `.class` files that need to be dexed to update/create the `.dex.jar` file in `buck-out`.
(3) The existing `.dex.jar` file in `buck-out` already represents the `.class` files to dex.

In order to be able to look at what is in `buck-out` before building (case 3), we either
need to get a rule key match (which works by default in Buck), or leverage the `AbiRule`
logic we already have in place for Java rules. (If we wait until we start building
`DexProducedFromJavaLibraryThatContainsClassFiles`, the `buck-out` directory containing
the old `.dex.jar` may already be deleted.)

Recall that an `AbiRule` can avoid rebuilding if the following conditions hold:
(1) The hash of the current rule definition and its input files matches the
hash on disk (written in `.metadata/METADATA_KEY_FOR_RULE_KEY_WITHOUT_DEPS`).
(2) All relevant deps that have an ABI have the same ABI as the last time the
rule was built (written in `.metadata/ABI_KEY_FOR_DEPS_ON_DISK_METADATA`).

Therefore, for an `AccumulateClassNames`, we assign it an ABI based on the
contents of the `classes.txt` file that it writes.
Because a `DexProducedFromJavaLibraryThatContainsClassFiles` has a
`AccumulateClassNames` as its only dependency, the ABI of `AccumulateClassNames`
is the ABI-key-for-deps of the `DexProducedFromJavaLibraryThatContainsClassFiles`.

Ultimately, this ensures that if a `java_library` rule is recompiled such that its
generated `.class` files are the same (this happens when a `java_library` rule is
recompiled in response to one of its deps changing in a way that does not affect
that `java_library` that depends on it, such as adding a new public method),
then the output of the `classes.txt` file for the `java_library` should be the same.
In turn, because the ABI of the `AccumulateClassNames` that generated the
`classes.txt` is unchanged, the `DexProducedFromJavaLibraryThatContainsClassFiles`
should rightfully avoid a rebuild. This optimization can have a significant impact on
incremental build times.

Test Plan: Sandcastle builds.
9 files changed
tree: 236789700199aa1712a79e5e2c13f6fbc5314668
  1. .idea/
  2. bin/
  3. config/
  4. docs/
  5. lib/
  6. plugin/
  7. pmd/
  8. scripts/
  9. src/
  10. test/
  11. testdata/
  12. third-party/
  13. .buckconfig
  14. .classpath
  15. .gitignore
  16. .project
  17. .travis.yml
  18. buck.iml
  19. build.xml
  20. DEFS
  21. LICENSE
  22. README.md
README.md

Buck

Buck is an Android build tool. To see what Buck can do for you, check out the documentation at http://facebook.github.io/buck/.

Build Status

Installation

To build Buck, run the following:

git clone git@github.com:facebook/buck.git
cd buck
ant
./bin/buck --help

License

Apache License 2.0