yeti-sh
Joined 4 years ago
Joined 4 years ago
compose.up()
contains the command's stdout.In addition stdout can be redirected to a file, or to another command, or to a callable, — which will be called for chunks of stdout while the command is in operation.
- command actually executed,
- snippet of stdout
- and snippet of stderr.
They can be handled using standard exception techniques.
Experiences differ, and de gustibus on est disputandum; in my bubble, virtualenv is a must-have for Python development.
I have multiple Python projects, they run different versions of Python itself and its libraries, and for many of them Docker would be an overkill; so it is hard for me to imagine my routine without virtual environments.
I employ pyenv to manage them but venv is a venv.
Why not use native Python methods, namely endpoints, instead, and automate this away?
@pre(file_name=_file_is_in_sync)
def build(file_name: Path):
...
I believe such libraries do exist even, but I haven't yet researched the topic; if jeeves proves to be useful for the simplest use case then it will make sense to expand its scope.- Is putting a symlink to one of your project directories, probably residing in $HOME, to /usr/bin/ a good practice?
- As an alternative one can put a symlink into ~/bin; but what if you have multiple different projects?
- And they can have different jeeves commands and different plugins installed. For instance, `j lint` implementations in different projects are work on are completely different.
Because these are different projects.
Rather, I prefer to have jeeves automatically create the executable command in each virtual env, and its behavior in different virtual envs will be different.
- via direct function calls in Python code,
- or using Typer callback functions
…is easy.
There are potential approaches worth exploring (annotations, decorators, …). I might come up with a list of options with syntax examples and ask for community's thoughts about it, — but at this point jeeves, as an MVP, is already useful for me and a few people I work with, and that motivated me to share it with the community.
> just `python your_file.py`
That's actually one of the points.
j lint
is shorter than python scripts.py lint
and the letter `j` is what the index finger of your right hand is pointing to on the keyboard. There is usually a tactile bump on that key. It is something you can type very quickly. You can also install shell completion to improve the experience further.Ergonomics matters.
compose = sh.docker.compose.bake('-f', 'deploy/dev.yml')
…
compose.down()
…
compose.up('--force-recreate', '-d')
I feel this is a major improvement on top of Makefiles + shell commands in them. Nice API _matters_; it is ergonomics and therefore productivity.You can specify `_out=rich.print` and it will work but AFAIK it won't scrape ASCII terminal formatting characters.
I had to fix these characters in my `sh` based scripts but do not consider that as a big deal.
> did actually do a suitable job of replacing gnu make
The title does not say _a replacement_, it says _an alternative_. I never intended to replace GNU Make; if I said that anywhere — that was a mistake on my part.
> do improve upon those who created unix
I did not intend to improve upon UNIX ideas or philosophy. The improvements I am aiming for are:
- developer experience,
- conciseness and maintainability of the code.
…and these are being addressed for a narrow use case. For that use case, in my experience, Make is very often used.
I argue that within the bounds of this use case, this is an alternative which can be of use to improve productivity and everyday experience.
> I don't really understand the full job make does, so here is something which only does a simpler job which I do understand, and I like python
I classify these assumptions about my understanding or misunderstanding as ad hominem and unprofessional.
* jeeves is the name of the project which I'm advertising, which converts a Python file to a set of commands; * `j` is the name of executable which aformentioned project exposes; * and `sh` is the library (the correct link to which you have provided) which is an optional dependency of `jeeves` and provides a more convenient interface to calling processes and executing commands from Python than `subprocess.run()`.
However, dealing with Python mostly in my time in the industry, I scarcely ever had the need to use these particular features of Make. I used it as a task runner, guilty of that, — and that's what I wanted to reimplement in Python.
Even writing in Rust, everything I have to do is `cargo build`, — there is no need to write Makefiles for building the project.
I will consider changing that wording to set proper expectations, but I still feel that for me "a Pythonic alternative to Make" perfectly conveys the use case I daily employ this thing for.
pip install jeeves-yeti-pyproject
will provide you with jeeves, a bunch of commands, and a pack of dev dependencies which I personally happen to like and to use in my projects.I don't believe Make has plugins.
- no type hints for docs & validation, I wanted them
- Makefile in its basic form is very concise and doesn't require a @task decorator, I didn't want it either
I didn't need dependency graph much.
Python developer, interested in:
- software architecture & code quality
- linked data & semantic web (more at https://iolanta.tech)
- tools for development productivity (more at https://jeeves.sh)