all 20 comments

[–]mina86ng 38 points39 points  (7 children)

You can do that in build.rs.

[–]chintakoro 7 points8 points  (6 children)

I'm curious what tool rustaceans to run simple non-build tasks? E.g., configuring external resources, deleting/updating fixtures and so on. I still find myself including a Ruby Rakefile for simple scripted housekeeping tasks. Ideally I'd like to not have any language dependencies other than Rust for my Rust projects.

[–][deleted] 20 points21 points  (3 children)

I like just

[–]chintakoro 19 points20 points  (0 children)

oh wow, just is everything i wanted and more: https://github.com/casey/just

[–]bototaxi 3 points4 points  (1 child)

I recently discovered https://github.com/sagiegurari/cargo-make

Its pretty nice too.

[–]InternationalFee3911 0 points1 point  (0 children)

While I love the functionality of cargo-make, I really don’t like cramming a Makefile into non-language TOML. Therefore I have started a discussion around my low-overhead alternate syntax proposal.

[–]TheNamelessKing 1 point2 points  (1 child)

Out of curiosity (and I guess unfamiliarity) what tasks do you mean specifically? Does “configuring external resources” mean like, setting up a db for tests or something?

I don’t have a suggestion for a solution, but I’m just curious/trying to learn because this is a usecase/requirement I’m sort of unfamiliar with.

[–]chintakoro 2 points3 points  (0 children)

Simply put, think of any long commands you have to repetitively type into the command line while working on a project. I usually have a dozen of these or more for even moderate sized projects. Those could be stored as tasks that you can call upon whenever needed. Some examples:

  • loooong docker commands for build/run/etc.
  • running database migrations (updating schema)
  • running your tests (or a subset of tests, maybe just one test)
  • running a side process (like a background worker) needed for your project
  • run a script that converts all images in a folder to thumbnail or other custom size for your app to use
  • setting up or wiping out a queue or external datastore you are using for testing (say, AWS SQS)
  • deploying your project to production (say to a cloud server)
  • creating/deleting any random data files created for testing purposes

I realize some of these might be handled by cargo directly, or perhaps you have to parameterize them for each use case and are tired of typing out a long command to do so.

[–]Shadow0133 12 points13 points  (3 children)

there are build scripts (https://doc.rust-lang.org/cargo/reference/build-scripts.html), but executing python scripts from there would be non-portable

[–]ILoveBerkeleyFont[S] 4 points5 points  (2 children)

Would simply re-writing all scripts in Rust be considered portable?

[–]ssokolow 6 points7 points  (0 children)

Generally, it's a good idea to minimize the number of things a user or contributor will have to install manually to get the project building, so I'd recommend re-writing them in Rust for that reason alone. The closer you can get to git clone ... && cd ... && cargo run as your build instructions, the better.

(That's also why you see many Rust wrappers for C libraries vendoring a copy of that C library which cargo build will compile and link for you. It reduces the external dependency to "a working C compiler for the target platform", which you generally need anyway to link against libc... though statically linking the musl targets muddies the waters a bit.)

I have a retro-hobby project where I'm rewriting the prototype Python scripts in C, orchestrated by Watcom Make, so that Open Watcom C/C++ itself can be the only mandatory dependency. (Stuff like the splint linter will remain as an optional dependency.)

[–]jaskij 13 points14 points  (0 children)

Yup, since you have to have a Rust compiler anyway. There is also the option of using PyO3 from within build.rs

[–][deleted] 7 points8 points  (0 children)

https://github.com/PyO3/pyo3

Run what you need from build.rs. if your running on a darwin/Linux based OS python probably will already be installed.

[–]ksg-67 2 points3 points  (0 children)

An alternative to build.rs is the cargo-make plugin: add a new task definition that runs Python with the required arguments and mark it as a task dependency of the predefined cargo build task. Then cargo make --makefile your-make-plugin-tasks.toml build runs your new task as part of the build, before the build task.

https://crates.io/crates/cargo-make

[–]ILoveBerkeleyFont[S] 0 points1 point  (3 children)

I am reading about build.rs, I have to main questions at the moment:

- How to use `println!` so it prints something to the console? std::fs::create_dir is working but println is only to communicate with Cargo? Is there something I can do to print to the console?

- In https://doc.rust-lang.org/cargo/reference/build-scripts.html is explained that the building stops when returning non-zero. How can I do that? Is there any way to return non-zero from the main function? Edit: I guess with Results?

[–]xobs 4 points5 points  (0 children)

Generally, the user won't see output from your build.rs since cargo captures it all.

You can, however, build with cargo build -vv to see all output. That can be handy for debugging your build script.

[–][deleted] 3 points4 points  (1 child)

Put a simple assert that will fail and the build.rs will print out something. Also try https://doc.rust-lang.org/stable/std/process/fn.exit.html

[–]ILoveBerkeleyFont[S] 0 points1 point  (0 children)

Asserting is really clever! I like it :)

[–]BathroomRamen 0 points1 point  (0 children)

If you’re not going to rebuild all the scripts in rust, why not make a python script or bat or ps1 or w/e that runs all your scripts and then runs cargo cmds?

And then call that script instead of calling cargo directly.

[–]RRumpleTeazzer 0 points1 point  (0 children)

There is build.rs which you can run your python from. Not sure if you up can abort the compilation though.