Build using Maven and cache succesful builds

This pull request introduces `SparkBuildManager`, a component that maintains a cache of binary Spark distributions, indexed by their SHAs. This makes it much faster to test against multiple Spark versions because we don’t have to completely re-build Spark for each test run.

I removed the `SPARK_SKIP_PREP` configuration option, since it’s not very useful anymore: if we’re running multiple tests against the same Spark version, we’ll just use the cached build.

This PR helps to lay the groundwork for automated testing against multiple Spark versions; I'll finish adding support for this in a later PR.