top | item 40960515

(no title)

dureuill | 1 year ago

Some good advice, some bad advice in here. This is necessarily going to be opinionated.

> Provide a development container

Generally unneeded. It is expected that a Rust project can build with cargo build, don't deviate from that. People can `git clone` and `code .`.

Now, a docker might be needed for deployment. As much as I personally dislike docker, at Meilisearch we are providing a Docker image, because our users use it.

This is hard to understand to me as a Rust dev, when we provide a single executable binary, but I'm not in devops and I guess they have good reason to prefer docker images.

> Use workspaces

Yes, definitely.

> Declare your dependencies at the workspace level

Maybe, when it makes sense. Some deps have distinct versions by design.

> Don't use cargo's default folder structure

*Do* use cargo's default folder structure, because it is the default. Please, don't be a special snowflake that decides to do things differently, even with a good reason. The described hierarchy would be super confusing for me as an outsider discovering the codebase. Meanwhile, vs code pretty much doesn't care that there's an intermediate `src` directory. Not naming the root of the crate `lib.rs` also makes it hard to actually find the root component of a crate. Please don't do this.

> Don't put any code in your mod.rs and lib.rs files

Not very useful. Modern IDEs like VsCode will let you define custom patterns so that you can match `<crate-name>/src/lib.rs` to `crate <crate-name>`. Even without doing this, a lot of the time your first interaction with a crate will be through docs.rs or a manual `cargo doc`, or even just the autocomplete of your IDE. Then, finding the definition of an item is just a matter of asking the IDE (or, grepping for the definition, which is easy to do in Rust since all definitions have a prefix keyword such as `struct`, `enum`, `trait` or `fn`).

> Provide a Makefile

Please don't do this! In my experience, Makefiles are brittle, push people towards non-portable scripts (since the Makefile uses a non-portable shell by default), `make` is absent by default in certain systems, ...

Strongly prefer just working with `cargo` where possible. If not possible, Rust has a design pattern called `cargo xtask`[1] that allows adding cargo subcommands that are specific to your project, by compiling a Rust executable that has a much higher probability to be portable and better documented. If you must, use `cargo xtask`.

> Closing words

I'm surprised to not find a word about CI workflows, that are in my opinion key to sanely growing a codebase (well in Rust there's no reason not to have them even on smaller repos, but they quickly become a necessity as more code gets added).

They will ensure that the project:

- has no warning on `main` (allowed locally, error in CI)

- is correctly formatted (check format in CI)

- has passing tests (check tests in CI, + miri if you have unsafe code, +fuzzer tests)

- is linted (clippy)

[1]: https://github.com/matklad/cargo-xtask

discuss

order

lossolo|1 year ago

> This is hard to understand to me as a Rust dev, when we provide a single executable binary, but I'm not in devops and I guess they have good reason to prefer docker images.

It's mainly about isolation, orchestration and to prevent supply chain attacks.

joshka|1 year ago

+1 to everything here. TL;DR: predictable > most things

The development container idea however is useful when you're dealing with any type of distributed system as it allows you to develop against a known setup of those things (e.g. your database, website, api service(s), integration with external non-rust software etc.)

You missed pointing out the cmd folder. I suspect the author watched https://www.youtube.com/watch?v=LghqbUoXEI4 and wrote this post based on what they saw.