Hacker News new | ask | show | jobs
by rbdixon 1649 days ago
doit [0] is a superb toolkit for building task-oriented tools with dependencies. It isn't too complex to get started and gives you a lot to work with. I've used it for an internal tool used by everyone in the company for 5+ years and it has never given me a headache.

[0]: https://pydoit.org

6 comments

And surprisingly underrated.

I mean, it's declarative, works on Windows, easy things are (very) easy, and because you can mix and match bash and python actions, hard things are suspiciously easy too.

Given how complicated the alternatives are (maeven, ninja, make, gulp...), you'd think it would have taken the world for years.

Yet I've only started to see people in the Python core dev team use it this year. It's only getting traction now.

"hard things are suspiciously easy too."

Care to share an example?

Here is a task that groups all static files from a web project into a directory.

It has to make sure a bunch of directories exist, run a node js command to build some files from the proper dir, then run a python command to regroup them + all static files from all django apps into one dir. Simple.

But then I had a problem I had to hack around. This required me to change an entry to a generated TOML file on the fly at every build.

doit just lets me add a 5 lines python function that does whatever I want, and insert it between my bash tasks, and I'm done.

    def task_bundle_static_files():

        def update_manifest():
            conf = Path("var/static/manifest.toml")
            data = toml.loads(conf.read_text())
            data["./src/main.js"] = data["index.html"]
            conf.write_text(toml.dumps(data))

        return {
            "actions": [
                "mkdir -p ./var/static/",
                "rm -fr ./var/static/* ",
                "cd frontend/; npm run build",
                "python manage.py collectstatic --noinput",
                update_manifest,
                "cp -r ./var/static/* ",
            ]
        }
or if you prefer rust, there's just. https://github.com/casey/just/

better yet, use both and just doit

For simple tasks — e.g. a list of commands — that are fine staying in sh, https://taskfile.dev is excellent
How does this compare to pyinvoke or they are completely different ?
The pythontic replacement for makefiles?
Yes. Like make, it lets you define tasks with dependencies and targets, and rebuild only if one of them have changed.

But I prefer it because:

- it runs anywhere you have python.

- it uses a clean syntax, and the parser is great at telling you about errors since it's python.

- you get access to python's stdlib: string formatting, maths, etc.

- you get access to python's ecosystem. Want to deal with timezone, hashing, crypto ? Sure you can.

- you get access to python's tooling (debugger, formatter, linter).

- you can still just use bash if you want. Easy things stay easy.

That would be invoke tasks. https://docs.pyinvoke.org/en/stable/getting-started.html, which I first encountered in fabric: fabfile.org, which has the fab utility and fabfiles (analogous to Makefiles) but is so much more.
It is a pain to work with invoke now. It is all find and dandy for the basic features but you going to hit the seams soon you start trying advanced stuff. Looks like the project is going to be abandoned.
What is advanced?

btw, the project is old and it is useful with the current feature set. There is an issue with the bus factor but is common for many tools.

How does this compare to snakemake?