Open wchargin opened 4 years ago
Looks great to me! But I gotta wonder, could the same thing be implemented in Rust? 😉
Yep, that’s a reasonable question. I think the answer is, “yes, but not
with only the standard library”. We need to read a web file and run a
web server, both of which want external crates. And once you need
external crates, it’s less clear to me whether that’s the right choice
for rules_rust
itself.
For instance: how would rules_rust
depend on its zipfile and web
server crates? The natural approach for end users is cargo-raze
, but
that feels uncomfortably circular to me. The generated BUILD file
loads from @io_bazel_rules_rust
, but from within rules_rust
we’d
want it to load from just “//
”.
The runtime performance of the docs web server is not critical, so Python’s okay there. But many people might be frustrated by having to compile the whole Rust web stack and link a Rust web server (not super fast, in my experience) just to see their docs. We’d also have to go to some lengths to ensure that updating the docs doesn’t re-link the binary, since that would be quite annoying.
Since Bazel has native support for Python (native.py_binary
), it seems
reasonable to me to use Python here. What do you think?
I think the compile time cost is a good call out. Do you know how cargo doc
handles this currently? I thought it outputs static files for you to simply view in a browser. No server required. Perhaps we'd just need a running process to watch for changes on disk and output a file://
path to some html file?
Even though Bazel currently has native.py_binary
, https://github.com/bazelbuild/bazel/issues/9006 indicates that the rules library should be used instead. So if this were to be implemented using python, it should be done in a future facing manner by using the python rules.
Do you know how
cargo doc
handles this currently? I thought it outputs static files for you to simply view in a browser. No server required.
Right, cargo doc
just sticks files in target/doc/
. With the standard
Cargo toolchain, I can just
(mkdir -p target/doc/ && cd target/doc/ && python3 -m http.server) \
& cargo watch -x doc
or replace python3 -m http.server
with your favorite static server.
But with rust_doc
this isn’t an option because the contents are all
bundled up in a zip archive.
I guess it’s technically true that you can visit a file:///
URL, but
I never do so. One reason is that I’m often SSHed into a workstation,
which I can connect to if it runs a web server but not via a file URL.
Perhaps we'd just need a running process to watch for changes on disk and output a
file://
path to some html file?
Not sure what you mean; please clarify?
There’s no file:///
URL that we can emit, because the index.html
is
inside a zip archive. I don’t think that we should have a running
process that re-extracts the archive to disk every time that it changes.
Even though Bazel currently has
native.py_binary
, bazelbuild/bazel#9006 indicates that the rules library should be used instead.
Eh. That’s one interpretation. Another is that that flag was supposed to
be flipped in Bazel 2.0, and still hasn’t flipped in Bazel 3.7.0, nearly
a year later. :-) But yes, we could use rules_python
and it’d be fine.
could the same thing be implemented in Rust?
I’ve given this a shot:
With the dependencies fetched but not compiled, this clean-builds in 23.2 seconds on my workstation, and incrementally builds in 3.4 seconds. And my workstation is fairly powerful (Xeon W-2135, 6 physical cores). This is notably slower than the Python compile time of 0 seconds. ;-)
(Oh, and that pulls in 68 transitive dependencies.)
Not sure what you mean; please clarify?
I was suggesting having something like ibazel
watch for changes and automatically update the content you're looking at.
Eh. That’s one interpretation. Another is that that flag was supposed to be flipped in Bazel 2.0, and still hasn’t flipped in Bazel 3.7.0, nearly a year later. :-) But yes, we could use
rules_python
and it’d be fine.
I feel strongly that a rules repository should adhere to every incompatibility flag. If this is something that's not actually going to be flipped, then someone should ping that issue and ask for the flag to be removed.
With the dependencies fetched but not compiled, this clean-builds in 23.2 seconds on my workstation, and incrementally builds in 3.4 seconds. And my workstation is fairly powerful (Xeon W-2135, 6 physical cores). This is notably slower than the Python compile time of 0 seconds. ;-)
There's definitely no discussion to be had around the time difference of a compiled and non-compiled language. Compiling a web server was always going to come at some noticeable cost. I think the clear distinction here is you're looking for something that improves remove developer environments (ssh'ed into another machine) and not necessarily tying to address a gap in functionality between cargo doc
and these rules.
I do feel you've shined light on the issue that viewing the output of rust_doc
is cumbersome and am in favor of any efforts to improve it. As much as I dislike python, I think this approach looks good to me (so long as the script says small and the heavy lifting be done by rustdoc
and the relevant Bazel rules). 😄
I feel strongly that a rules repository should adhere to every incompatibility flag. If this is something that's not actually going to be flipped, then someone should ping that issue and ask for the flag to be removed.
Cool; that sounds pretty reasonable. Happy to comply.
Thanks for your quick responses and the helpful discussion! I’ll start with the dependent issue #471 and then move on to this one.
A
rust_doc
rule spits out a zip file, but that’s not convenient for actually consulting the docs. It would be great forrust_doc
to provide a Bazel binary that can be run to spin up a web server.Here is one approach. From the Bazel rule, provide this Python file:
Then generate a
py_binary
build target:Then, users can
bazel run :mylib_doc_server
to start a server, and optionally pass a port argument. Or, useibazel
instead ofbazel
, and then whenever you change one of the Rust sources, the Rustdoc will automatically recompile and the server will automatically restart.This depends on #471; without that fix, this will be harder.
Thoughts? Are you open to this change? Is it okay to use Python here? Note that the above simple server only uses the Python standard library. Happy to contribute a PR, and I license all this code as Apache 2.0.