warp.build changelog

Zero Config Builds, SemanticCache, Hinting and more! 🚀

changelog cover

This is our biggest release yet and we're super excited to share it with you 🤩

⚡️ Zero Configuration Builds

When you ask Warp to build something, Warp needs to understand how to build it. But writing Build files (in whatever format) is a drag: Makefiles get messy, BUILD.bazel files go out of date. In this release of Warp we introduce fully zero-config builds through a new concept we're calling Warp Signatures (yes, we like Star Trek 🖖, sue us). 

A Warp Signature is a unique recipe for building a piece of source code at a point in time, that can be derived statically from analyzing the repository, and is updated automatically as the file changes.

Make a code change? No problem.

Warp understands how to update the build graph based on the semantics of your change. New import? New dependency. Removed call to library? Removed dependency.

To bootstrap a repository, we've built a new command: warp lift. This takes care of flattening all dependencies, and analyzing all the code you're relying on, to make signature generation possible and fast.

🏁 Semantic Test Caching

Picture a test suite. When it starts out, it usually has just a handful of tests, maybe a few of them are big but its no big deal to rerun them all. If it was cached by file changes, then you will have to rerun this entire test suite any time a single test in it changes.

As your test suite grows, you could split it up into several files, but as with any other code this isn't free.

Starting with support for the Erlang ecosystem, Warp can now cache results going as deeply as to AST-diff test cases within single test suites/files. This allows existing large test suites to be cached with excellent granularity, and takes the burden away from refactors that only are required with coarser-granularity caching.

🏃 Runtime Dependencies

Usually building A requires B and C (its dependencies) to exist and be built beforehand. However, some other times we can build A without having built B and C, as long as we have B and C at runtime. Dynamically linked libraries, and all language supporting late-binding (such as Erlang and Elixir), support this.

This feature dramatically speeds up compilation in large projects since we can parallelize a lot more work, while still being able guarantee that the build is correct.

🔧 Warp Analyzer Protocol

to make interfacing with new ecosystems easier in the long run, we're introducing an alpha version of a protocol that will allow us to plug in different LSPs directly into Warp for analysis of build targets. This is currently implemented as a gRPC/Protobuf service interface, and it powers Warp's dependency resolution and signature generation processes.

More about this soon on our to-be-released docs page!

📜 Hinting

Ssometimes the analyzers and Warp's heuristics can't figure out how to build something. Turns out, builds are hard 🙃. For example, Warp can detect Erlang tests and dependencies across all your source files, but it can't figure out what fixtures you are going to read from disk. To figure this out, we'll need to run your tests and instrument them (spoiler alert: check back on this later).

So for now we allow a small .warp file to be dropped near whichever file you want to add more dependencies (or runtime dependencies) to. Like this:

./src/verl.erl
./src/verl.erl.warp <- this is the hints file

In it you can add some JSON to describe what targets this file provides, and which overrides you want to supply it:

{
  "*": { // this means 'add to all targets from this file'
    "deps": [ "./src/fixtures/my_fixture.txt" ]
  }
}

Looking forward to sharing more in the next couple of months! So if you've got any feedback feel free to drop it in the box below, and in our Public Roadmap.