tweag / topiary

https://topiary.tweag.io/
MIT License
549 stars 24 forks source link

Tree-sitter grammars must maintain compatibility with specific Tree-sitter #684

Open Xophmeister opened 7 months ago

Xophmeister commented 7 months ago

tree-sitter is a direct dependency of Topiary. Each Tree-sitter grammar (e.g., tree-sitter-json, tree-sitter-rust, etc.) has a transitive dependency on tree-sitter. The direct dependency and transitive dependencies must maintain API compatibility, otherwise Topiary won't build.

Currently, we are using Tree-sitter 0.20. v0.21 is now available and some grammars allow this, which causes Cargo to build both 0.20 and 0.21 for Topiary and subsequently fail. We can use the [patch] directive in our Cargo.toml to pin the transitive dependency (e.g., e91534b0aa).

This might be more of a "Cargo problem", than a Topiary one, but it would be nice if there were some tooling around this. Perhaps, at least, a CI step that checks there's only one version of tree-sitter in the Cargo.lock...

(#4 will definitely be impacted by this.)

yannham commented 7 months ago

Would pinning the git dependencies on those grammars help, or even with a pinned dep, cargo would still somehow fetch a newer version of tree-sitter if available?

Xophmeister commented 7 months ago

Would pinning the git dependencies on those grammars help, or even with a pinned dep, cargo would still somehow fetch a newer version of tree-sitter if available?

Pinning both the grammar and its transitive dependency on Tree-sitter appears to work in practice. It's a bit verbose, mind you:

[dependencies]
tree-sitter = "= X"
tree-sitter-foo = { git = "https://github.com/tree-sitter-foo/tree-sitter-foo.git", rev = "Y" }

[patch."https://github.com/tree-sitter-foo/tree-sitter-foo"]
tree-sitter = "= X"

Obviously, one has to pick a rev Y for which Tree-sitter X will work.

yannham commented 7 months ago

I see, you still need to patch part, which is a bit unfortunate.