[HN Gopher] Just: Just a Command Runner
___________________________________________________________________
Just: Just a Command Runner
Author : thunderbong
Score : 270 points
Date : 2024-12-07 17:11 UTC (5 hours ago)
(HTM) web link (just.systems)
(TXT) w3m dump (just.systems)
| golly_ned wrote:
| I've used Just at a workplace on a project I didn't start. It
| seemed slightly simpler than make when putting together task
| dependencies. But I couldn't figure out what justifies using it
| over make.
| qznc wrote:
| The manual lists the reasons why using it over make:
| https://just.systems/man/en/
|
| The question is if those reasons are convincing to someone. The
| big advantage of Make is that it is probably already installed.
| erichdongubler wrote:
| > The big advantage of Make is that it is probably already
| installed.
|
| ...unless you're on Windows, like me!
| deaddodo wrote:
| Make is installed on Windows, if you install Microsoft's
| C/C++ dev stack (typically via installing Visual Studio).
| They just use nmake instead of GNU make. They also include
| Cmake these days, as it's the common cross platform option.
| BeetleB wrote:
| > if you install Microsoft's C/C++ dev stack (typically
| via installing Visual Studio).
|
| So I have to install this huge dependency just to use
| make, when my project is in Python?
|
| Way easier to install just :-)
| fragmede wrote:
| What does it offer over bazel?
| peterldowns wrote:
| Not making you want to shoot yourself in the head.
|
| It does one thing very well, and it has well-written and
| _useful_ documentation.
|
| It literally just runs commands in a convenient way.
| fragmede wrote:
| how well does it cache across a build farm?
| pdimitar wrote:
| Did you miss the part that says "it just runs commands in
| a convenient way" and "it is not a build system"?
| 12_throw_away wrote:
| It's not a build system, it's a command runner, it is for
| different use cases
| hgs3 wrote:
| The manual states that "just is a command runner, not a build
| system," and mentions "no need for .PHONY recipes!" This
| seems to suggest that there's no way to prevent Just from
| rebuilding targets, even if they are up-to-date. For me, one
| of the key advantages of using Make is its support for
| incremental builds, which is a major distinction from using a
| plain shell script to run some commands.
| klabb3 wrote:
| Maybe it's the stacks I'm using, but I've always had
| incremental happen with language-native tooling like `go`
| or `cargo`. So for me at least, having lazy eval features
| like that would be an unnecessary increase in scope and
| complexity. With Just, I can just throw together different
| commands and it just works cross platform. I love it.
|
| I much prefer that than the other way, ie letting language
| tooling become command runners (looking at you npm). That's
| the worst of both worlds.
| hgs3 wrote:
| > I've always had incremental happen with language-native
| tooling like `go` or `cargo`
|
| That makes sense, but for me, Make is incredibly useful
| for incremental file processing outside of programming.
| I've written tiny Makefiles that use glob patterns to
| batch-convert thousands of SVGs into PNGs and WebPs, but
| only for the modified SVG files. I've used Make to batch-
| convert modified LaTeX files to PDFs and render modified
| Blender projects into WebM videos for the web. Rendering
| videos is _very_ time-consuming, so only rendering
| modified video files is a huge win.
| guipsp wrote:
| If you need incrementalism, Just is not for you.
| pdimitar wrote:
| The programming languages that I use don't need to be told
| to not rebuild from scratch so yours is a pretty strange
| argument.
| BeetleB wrote:
| Your first sentence says:
|
| > just is a command runner, not a build system
|
| And then you go ahead and complain that it is poor at
| building.
|
| If you need a build tool, don't use just. Use make or
| something else. The purpose of just is to stop putting non-
| build stuff in Makefiles. And of course, it has a nice set
| of features that make doesn't.
| hgs3 wrote:
| I think there's been a misunderstanding.
|
| > Your first sentence says
|
| My first sentence was me quoting the Just manual and my
| second sentence was my observation about what that
| suggests. I wasn't asserting whether it's true or not,
| just sharing my interpretation, as I'm not familiar with
| Just.
|
| > And then you go ahead and complain that it is poor at
| building.
|
| I did not "complain" I stated that incremental builds,
| regardless of whether Just has them or not, is one
| feature I personally like about Make.
|
| Going by the responses I received, Just does not appear
| to support incremental builds and a simple
| acknowledgement, minus the vitriol, would have sufficed.
| badsectoracula wrote:
| > You can disable this behavior for specific targets using
| make's built-in .PHONY target name, but the syntax is verbose
| and can be hard to remember.
|
| I think this is overstating things a bit. I first read
| `.PHONY` in a Makefile while i was a teenager and i figured
| out what it does just by looking at it in practice.
|
| Makefiles do have some weirdness (e.g. tab being part of the
| syntax) but `.PHONY` is not one of them.
| nucleardog wrote:
| make is a build system and has a lot of complexity in it to
| make it optimal (or at least attempt to) for that use case.
|
| just is a "command runner" and functionally the equivalent of
| packing up a folder full of short scripts into a single file
| with a little bit of sugar on top. (E.g., by default every
| script is executed with the CWD being the folder the justfile
| is in so you don't need to go search for that stackoverflow
| answer about getting the script's folder and paste that in the
| top of every script.)
|
| If you use just as a build system, you're going to end up
| reimplementing half of make. If you try and use make as a
| command runner, you end up fighting it in many ways because
| you're not "building" things.
|
| I've generally found the most value in just in situations where
| shell is a good way to implement whatever I"m doing but it's
| grown large enough that it could benefit from some greater
| organization.
| 12_throw_away wrote:
| > search for that stackoverflow answer about getting the
| script's folder and paste that in the top of every script
|
| Ah, a fellow Person of Culture.
| BeetleB wrote:
| Having recipes just for Windows/Linux.
|
| Being able to write your recipes in another language.
|
| Not having to be in the directory where the Makefile resides.
|
| Being able to call a recipe _after_ the current recipe with &&
| syntax.
|
| Overall lower mental burden than make. make is very complex.
| just is very simple. If you know neither of the two, you'll get
| going much faster with just.
| clintonc wrote:
| For me, it's a fit-for-purpose issue. Make is great when you're
| creating artifacts and want to rebuild based on changes. Just
| is a task runner, so while there's a notion of dependent tasks,
| there's no notion of dependent artifacts. If you're using a lot
| of .PHONY targets in a Makefile, you're mostly using it as a
| task runner -- it works, but it's not ergonomic.
|
| I like that just will search upward for the nearest justfile,
| and run the command with its directory as the working directory
| (optional -- https://just.systems/man/en/attributes.html --
| with fallback available --
| https://just.systems/man/en/fallback-to-parent-
| justfiles.htm...). For example, I might use something like
| `just devserver` or `just testfe` to trigger commands, or `just
| upload` to push some assets -- these commands work from
| anywhere within the project.
|
| My life wouldn't be _that_ different if I just had to use Make
| (and I still use Make for some tasks), but I like having a
| language-agnostic, more ergonomic task runner.
| peterldowns wrote:
| As a heavy Just user, I agree with all of this -- great
| answer.
| nrclark wrote:
| Just a quick note for interested readers: you don't need to
| explicitly mark things as .PHONY in make, unless your
| Makefile lives next to files/folders with the same name as
| your targets. So unless you had some file called "install" in
| the same folder, you wouldn't need to have something like
| ".PHONY: install".
| metaltyphoon wrote:
| The moment you need to build the same software on windows its
| already justified IMO
| bsnnkv wrote:
| This is one of the most important pieces of software in my
| development stack that "just" gets out of the way and does what
| it's supposed to do. Also has excellent Windows[1] support so I
| can take it everywhere!
|
| [1]: https://github.com/LGUG2Z/komorebi/blob/master/justfile
| example justfile on my biggest and most active Windows project-
| might not seem like a lot but this has probably cumulatively
| saved me months of time
| guitarbill wrote:
| Wait, by "has excellent Windows support" you mean you have to
| set it to use Powershell or hope `sh` is installed on Windows?
| I get that your project is Windows-only, but many projects
| aren't.
|
| So not only do you need just installed, which is yet another
| dependency, but either you use the default settings and Windows
| devs need to have `sh` installed, or you set the shell to
| Powershell and macOS/Linux devs need to have that installed?
| Sorry, that doesn't sound great.
|
| Edit: Yes, this seems to be true from
| https://just.systems/man/en/:
|
| > Linux, MacOS, Windows, and other reasonable unices are
| supported with no additional dependencies. (Although if your
| system doesn't have an sh, you'll need to choose a different
| shell.)
|
| > Recipes can be written in arbitrary languages, like Python or
| NodeJS.
|
| Just no.
| bsnnkv wrote:
| > I get that your project is Windows-only, but many projects
| aren't.
|
| Nit: At this point you're better off starting a separate
| comment thread since you yourself already know that what you
| are about to talk about is not what my comment is talking
| about.
| guitarbill wrote:
| > Also has excellent Windows[1] support so I can take it
| everywhere!
|
| Nit: You mentioned it can be used "everywhere". That would
| be a useful feature! But while it's kinda true, there's
| some quite big limitations IMO
| 3eb7988a1663 wrote:
| The shell can be configured per OS. So, Windows can be set to
| use PowerShell and Linuxy systems will use sh.
|
| From the docs set windows-shell :=
| ["powershell.exe", "-NoLogo", "-Command"] hello:
| Write-Host "Hello, world!"
|
| Few things work seamlessly across platforms, and that does
| not seem like a huge burden.
| squeaky-clean wrote:
| > Wait, by "has excellent Windows support" you mean you have
| to set it to use Powershell or hope `sh` is installed on
|
| I don't get what the problem is here? Do you protest against
| shebangs too? Why does a build script for a Windows only app
| need to use sh instead of powershell? I think you're
| interpreting "excellent windows support" to mean cross
| platform, and that's not what it means.
|
| > So not only do you need just installed, which is yet
| another dependency,
|
| Yeah if you want to use some software, your computer needs
| that software. That's not a dependency. So we're talking zero
| dependencies, or one of you absolutely need sh.
| burnished wrote:
| To be fair it is another dependency for the project that
| you are using just with. Its probably not software that you
| use for its own sake.
| MatmaRex wrote:
| You can keep your commands simple enough so that they can be
| executed by both `sh` and `cmd.exe`. If you need anything
| more complex than invoking other programs, `&&`, `|` and `>`,
| it's time to rewrite your build script in a real programming
| language anyway.
| BeetleB wrote:
| You can use the usual cmd (I do). You're not limited to
| Powershell. Also, you do understand that if a tool has first
| class support for Windows, that does mean it prioritizes
| Windows tools, right? Imagine I made a command runner, and
| said it has "excellent Linux support", and then someone comes
| along and complains that you have to install Powershell on
| Linux to use Windows recipes.
|
| You can have Windows only recipes and Linux only recipes.
|
| Furthermore, if you have bash installed on Windows (e.g. via
| git bash), you can put a shebang in your recipes to use bash.
|
| We develop in Windows and deploy in Linux. Most of our
| recipes work in both OS's - either we use bash or Python for
| the recipe. The few that don't - we just mark as Windows only
| or Linux only so they're not available in the wrong OS.
|
| > So not only do you need just installed, which is yet
| another dependency,
|
| You do realize that Windows by default comes with almost _no_
| development tools, right? So yes, you do actually need to
| install things to get work done. The horror.
|
| I'll also note that while you complain about just, _you
| provide no alternative_.
|
| Weirdest rant ever.
| gurgeous wrote:
| We love just and are using it in all projects now. So great. Our
| typical justfile has around ~20 rules. Here is an example rule
| (and helper) to illustrate how we use it in ci:
| export PATH := justfile_directory() + "/node_modules/.bin:" +
| env_var('PATH') ci: @just banner yarn install
| yarn install @just banner tsc tsc --noEmit
| @just banner lint eslint src prettier --check src
| @just banner vitest vitest --run @just banner
| done! banner *ARGS: @printf '\e[42;37;1m[%s]
| %-72s \e[m\n' "$(date +%H:%M:%S)" "{{ARGS}}"
|
| This example is a bit contrived, more typically we would have a
| rule like "just lint" and you might call it from "just ci".
|
| One of the best features is that just always runs from the
| project root directory. Little things like that add up after
| you've spent years wrestling with bash scripts.
| alsetmusic wrote:
| > Little things like that add up after you've spent years
| wrestling with bash scripts.
|
| Can you please explain what you mean here? I looked at the
| GitHub examples and wondered why this would be preferable to
| Bash aliases and functions. I must be missing something.
| ricardobeat wrote:
| Bash has a thousand pitfalls, and as you accumulate layers of
| scripting they start compounding. Little things like "what
| the hell directory is this command actually running from",
| parsing input parameters, quoting rules, exit statuses,
| pipelining, etc.
|
| Tools like _just_ provide a very consistent and simple base
| to start with, and you can always still call a separate
| script, or drop directly into inline shell scripting.
| brundolf wrote:
| So it's not a fundamentally different use-case, it's just
| an admission that shell scripts suck at what they do?
| pdimitar wrote:
| Of course. Is that news to you? Not a snark, I am
| genuinely surprised, assuming that you asked seriously.
|
| I moved to ZSH some years ago but even that is not good
| enough. I thought of using Fish at one point but just
| said "frak this" and started writing Golang for anything
| that's more than 20-30 lines of bash/zsh scripting. Or
| requires their weird list / array syntaxes for iterating
| over stuff. Can't ever remember that with a gun to my
| head.
| 3eb7988a1663 wrote:
| For me, the niceties are in the built in functions[0].
| Commands to manipulate paths(!!), get cpu counts, mess with
| environment variables, string processing, hashing, etc. All
| the gyrations a more sophisticated script is going to
| eventually require. Instead of having to hack on it in shell,
| you get cross-platform utilities which are not going to blow
| up because of something as wild as a space or quote mark.
|
| [0] https://just.systems/man/en/functions.html
| jensenbox wrote:
| I have been using this for months now - way easier than Taskfile.
|
| The parameter injection and passing to commands was the thing
| that converted me.
| jcalabro wrote:
| I've been using just at work and in personal projects for almost
| a year, and I like it a lot. In particular, its self
| documentation with `just --list` makes onboarding new folks easy.
| It's also just a nicer syntax than make.
| peterldowns wrote:
| Agreed. Is it that different than Make with `.PHONY` targets?
| Yes -- it is Designed To Do Exactly What It Does, And It Does
| It Well. That counts for something in my book.
|
| All my Justfiles start with this prelude to enable positional
| arguments, and a "default" target to print all the possible
| commands when you run `just` with no target name:
| # this setting will allow passing arguments through to tasks,
| see the docs here #
| https://just.systems/man/en/chapter_24.html#positional-
| arguments set positional-arguments # print
| all available commands by default default:
| @just --list
| mike-cardwell wrote:
| I don't have my work laptop to hand to compare, but I usually
| run "just" to get a list of commands and what they do, rather
| than "just --list". Hope that saves you 7 key presses going
| forwards.
| peterldowns wrote:
| Running `just` will invoke the first recipe, so you need to
| add one that invokes `just --list` for this to work -- see
| https://just.systems/man/en/listing-available-recipes.html
| and my sibling comment.
| fmbb wrote:
| That seems like the most useless pattern to take from make,
| especially when you name your tool "just".
|
| Just what?
| TeMPOraL wrote:
| > _Just what?_
|
| "Oh... come on! _Just..._ <waving hands angrily>"
|
| Pretty clear to me :).
| layer8 wrote:
| Just execute.
| lambda wrote:
| Yeah, I've been adding `just help` as an alias for `just
| --list` and making it the first recipe for this reason.
| mike-cardwell wrote:
| Hmm. Maybe the dev that set it up made the first recipe run
| `just --list`
| pdimitar wrote:
| Not as much as 7, you can just type `just -l`.
| konfekt wrote:
| Maybe worth reminding the self-documenting Makefile [0]
| discussed here.
|
| [0] https://news.ycombinator.com/item?id=30137254
| throwaway743950 wrote:
| I recently looked at various alternatives to make and landed on
| https://taskfile.dev/
|
| It handles dependencies and conditions well without needing to be
| a full blown bash expert.
| majkinetor wrote:
| I use Invoke-Build[1] everywhere and I highly recommend it. It's
| cross-platform, uses PowerShell so we have serious programming
| language in the background and is extremely simple yet powerful:
| dependencies, integrated help, good defaults for error handling
| and starting directory, vs code support, DOT charts of task
| dependencies, incremental task, persistent builds, parallel stuff
| etc. See example usage here [2]
|
| [1]: https://github.com/nightroman/Invoke-Build
|
| [2]: https://github.com/majkinetor/mm-docs
| no_circuit wrote:
| Task is in a similar problem space.
|
| Unlike Just which clearly states it is not a build system [1],
| Task can be told about expected files so tasks can be skipped to
| avoid unnecessary work [2]. So if your task is to build software,
| IMO make and the others like Task would be better.
|
| If your tasks only care about the success code from a process,
| and/or are a Rust fan instead of Go, then Just should be fine.
| Otherwise, for specific use-cases like CI, you are likely already
| coding in a proprietary YAML/JSON/XML format.
|
| [1]
| https://github.com/casey/just/blob/e1b85d9d0bc160c1ac8ca3bca...
|
| [2] https://taskfile.dev/usage/#prevent-unnecessary-work
| jensenbox wrote:
| The one thing that converted us from Taskfile to Justfile is
| how it handle parameters injected at instantiation.
|
| https://just.systems/man/en/recipe-parameters.html just works
| better for us than https://taskfile.dev/usage/#forwarding-cli-
| arguments-to-comm...
|
| We use Docker Compose for our dev environment and were trying
| to do something like (notice the extra dash dash for separating
| the arguments out): task poetry -- add
| requests django
|
| It was not working as we expected for some of the users due to
| the argument dash dash stuff - they were forgetting due to
| muscle memory but the following does: just
| poetry add requests django
|
| under the hood it was just calling (the equivalent):
| docker compose run --rm --build poetry poetry "$@"
|
| Just arguments are more ergonomic.
|
| This is how just does it: poetry +command:
| docker compose run --rm --build poetry poetry {{command}}
| brokegrammer wrote:
| I switched from make a while ago because I was using it to run
| tasks in my Python projects, which doesn't require any of make's
| build tools.
|
| I didn't like make's complicated syntax either. Everything just
| makes more sense now.
| jascha_eng wrote:
| We recently switched pgai over to just. And are quite happy so
| far. The hierarchical nature is quite nice:
| https://github.com/timescale/pgai
| Traubenfuchs wrote:
| Why use this over .sh files?
| petesergeant wrote:
| Why use .sh files over this?
| al_borland wrote:
| Fewer tools to manage. It seems like this could also be
| replaced by some aliases in a .bashrc file.
|
| I don't like adding extra dependencies and complicating
| things if they aren't adding significant benefit. What am I
| missing here? It seems like an alias with extra steps.
| xigoi wrote:
| Because they don't require installing a new tool and learning
| new syntax.
| homebrewer wrote:
| When this tool becomes as available out of the box as POSIX
| sh (i.e. practically everywhere, including embedded systems
| and containers), then this reversed argument will make some
| sense. I'm willing to bet anything that POSIX sh will still
| be with us 50+ years from now, and 'just' will be long
| forgotten by then. You really should have a stronger argument
| for introducing another dependency into your build process
| (and onto your developers) than "it has a slightly simpler
| syntax compared to the industry standard".
| bigstrat2003 wrote:
| It's not "slightly simpler", it's _massively_ simpler.
| Shell scripts are pretty much the worst syntax in existence
| (barring esolangs that go out of their way to be weird).
| Hackbraten wrote:
| While shell syntax may be quirky, it absolutely allows
| you to write scripts that are simple, easy to understand,
| and maintainable.
| BeetleB wrote:
| It's great that POSIX sh is available everywhere except
| where it isn't (Windows).
|
| In all SW teams I've been in except one, sh was available,
| and people preferred writing things in something else
| (usually Python/Perl). I have had an order of magnitude
| more success convincing teammates to use just than
| convincing them to use sh.
|
| It may be ubiquitous, but it's useless if you can't
| convince non-shell gurus to use it.
| Fluorescence wrote:
| IMHO you'd right to be sceptical because for me, it is only a
| slightly more ergonomic way to organise and run shell scripts.
| It's difficult to make the case it's much better but I found it
| interesting how "just being a bit nicer" for a common activity
| can be a really valuable quality of life improvement.
|
| - easier - core benefit is making it nicer to implement
| multiple commands with arguments without inventing something
| equivalent in shell
|
| - convenient - with "fallback" just will search up the folder
| tree to find the just command so I don't need to be in the
| right folder. I have justfiles at multiple levels in a project
| hierarchy and my cwd works as context to pick the right command
|
| - polyglot - can use different languages as needed
|
| - predictable - it's so nice when I return to a project and I
| have recipes for setting up my env, various types of build and
| test. The consequence of being a little more ergonomic means I
| capture more useful command lines that, for whatever reason, I
| would not have made into shell scripts because of the added
| friction.
| e12e wrote:
| > with "fallback" just will search up the folder tree to find
| the just command
|
| So don't have just-files in your home directory?
| Fluorescence wrote:
| You could if you want.
|
| If you don't want just to search outside of your project
| folder then don't set fallback in your project root
| justfile and it stops there.
| IshKebab wrote:
| I don't know if this fixes the issues but some big problems
| with shell:
|
| * Very bad UX on Windows
|
| * Quoting is a disaster. I mean, the whole language is a
| disaster but quoting is an especially big wart. Make also has
| this issue; you literally can't use it with files containing
| things like spaces or colons.
|
| * Shell scripts tend to start simple and reasonable and grow
| seamlessly into something that absolutely should not be a shell
| script.
|
| My favourite solution is Deno. Zero faff to set up, easy to
| install, supports third party dependencies without metadata
| files or messing with environments, and you get to use a real
| programming language. Easily the best scripting tool for
| infrastructure tasks at the moment.
|
| Unfortunately I'm forced to use Python at work which is nowhere
| near as good as Deno, but still beats the pants off shell
| scripting.
| Hackbraten wrote:
| > Quoting is a disaster.
|
| It surprises me a bit that, of all things that are a mess in
| shell, your comment mentions quoting. It's one of the few
| things that absolutely make sense for me in shell scripting.
| Do you have an example for me where quoting feels messy to
| you?
|
| > My favourite solution is Deno. Easily the best scripting
| tool for infrastructure tasks at the moment.
|
| I don't think there's an objectively best technology for
| everyone. For example, how long-term are your infrastructure
| tasks? What are the chances your scripts are still going to
| work in 2 years? 5 years? 10 years?
|
| Suppose you're in a large enterprise embedded project which
| needs to work for 10 years or more, and the project uses
| shell scripts for infra tasks. Would you recommend to migrate
| those to Deno or Python?
| IshKebab wrote:
| Yes, this was literally from today:
|
| https://programming.dev/post/22539101
|
| Turn on shellcheck and you'll realise that nobody could get
| it right without tool assistance. In programming languages
| with "standard" quoting (Python, JavaScript, Rust, Go, C,
| etc.) you don't even really need to think about it.
|
| > What are the chances your scripts are still going to work
| in 2 years? 5 years? 10 years?
|
| 100% because I'll maintain them.
|
| > Suppose you're in a large enterprise embedded project
| which needs to work for 10 years or more, and the project
| uses shell scripts for infra tasks. Would you recommend to
| migrate those to Deno or Python?
|
| Absolutely yes. In fact the longer you expect it to last
| the stronger my recommendation would be. A shell script
| with 10 years of tech debt is a scary prospect.
| bigstrat2003 wrote:
| Because shell is absolutely miserable to work with, whereas
| Just has decent syntax.
| olejorgenb wrote:
| I know the OP said ".sh files", but you can have executable
| python files (for instance as well)
| Astronaut3315 wrote:
| I've been happy with Just at our workplace. It lets me focus more
| on the task at hand instead of Conan / Cmake incantations.
|
| It's consistent, easy to use and maintain, and keeps all relevant
| operations in one place.
| __MatrixMan__ wrote:
| I'm not a fan. It works well for what it is, but what it is is an
| additional language to know in a place where you probably already
| have one lying around.
|
| Also, like make, it encourages an imperative mode for project
| tooling and I think we should distance ourselves from that a bit
| further. It's nice that everybody is on the same page about which
| verbs are available, but those verbs likely change filesystem
| state among your .gitignored files. And since they're starting
| from an unknown state you end up with each Just command prefixed
| by other commands which prepare to run the actual command, so now
| you're sort of freestyling a package manager around each command
| in an ad-hoc way when maybe it's automation that deserves to be
| handled without depending on unspecified state in the project
| dir.
|
| None of this is Just's fault. This is people using Just poorly.
| But I do think it (and make) sort of place you on a slippery
| slope. Wherever possible I'd prefer to reframe whatever needs
| doing as a build and use something like nix which is less
| friendly up front, but less surprising later on because you know
| you're not depending on the outputs of some command that was run
| once and forgotten about--suddenly a problem because the new guy
| can't get it to work and nobody else remembers why it works on
| theirs.
| nerdponx wrote:
| I mainly don't understand how Just is any better than a run/
| directory full of executable shell scripts.
| zwerdlds wrote:
| That works too. I've done both and I currently use Just
| because it collects the entrypoints to the project into a
| single file. This can provide an advantage where there's a
| bit of interdependence across your entrypoints.
|
| E.g: You have a docker container, you might be `run`ning it,
| `exec`ing it etc. from the same compose-file. So Just gives
| you the ability to link those shared commands within the same
| file. Once the entrypoints get too numerous you can either
| break them into scripts (I do this partially depending on the
| level of behavioral complexity in the script) or partition
| your justfiles and import them into a single master.
| pdimitar wrote:
| If that works well for you, use it.
|
| I did that for 10+ years and got fed up with having to
| remember which names I gave to my scripts that month. I
| gradually evolved my views and that got reflected with the
| names of the scripts.
|
| `just` helped me finally move away from that. Now I have i.e.
| `just check` in projects in different languages that all do
| the same thing -- check types and/or run various linters. I
| can go in a directory and run `just check` and I know I have
| taken care to have all checks that I want in place. Similarly
| I can run `just test` and I know I'll have the test suite
| ran, again regardless of the programming language or
| framework.
|
| Absolutely nothing wrong with a directory full of scripts but
| I lost patience for having to scan what each does and moved
| away from them.
| lijok wrote:
| > Now I have i.e. `just check` in projects in different
| languages that all do the same thing -- check types and/or
| run various linters. I can go in a directory and run `just
| check` and I know I have taken care to have all checks that
| I want in place. Similarly I can run `just test` and I know
| I'll have the test suite ran, again regardless of the
| programming language or framework.
|
| How is that different from having a scripts dir, and a
| script called `check` or `test`?
|
| How is `just -l` different to `ls scripts`?
| pdimitar wrote:
| I believe I already addressed that this is purely a
| matter of taste and convenience, not sure why you are not
| reading my comment and are asking for more.
|
| And it was already said: if you like it more, use it.
| Nobody is holding a gun to your head. And I even
| explained that I used that in the past and moved away
| from it.
| akoboldfrying wrote:
| I also haven't seen in your previous response how Just is
| better than a subdir with shell scripts _named according
| to a convention_.
|
| AFAICT, the productivity improvements you described came
| exclusively from using a consistent naming convention,
| not from Just. And since everyone's dev env supports
| subdirectories with shell scripts already, why not simply
| use that instead of requiring Just?
| pdimitar wrote:
| I got a down arrow on my comment that's your parent a
| minute before you responded. Coincidence, or you prefer
| to press it because you are not satisfied that I'm not
| your personal documentation agent?
|
| Finally and additionally as a response: because it's also
| all in one place. I don't want 10+ scripts. For the third
| time: I used bespoke scripts and found them not good
| enough compared to Just, now for even more reasons
| clearly spelled out. Sigh.
| akoboldfrying wrote:
| I didn't downvote you, though I found your answer
| unhelpful. (I've now _received_ 2 downvotes.)
|
| 10+ scripts with standard names ("clean", "test",
| "build", etc.) in a subdir added to $PATH seems to me to
| be easier to manage -- if the scripts are independent of
| each other. If they do have dependencies on each other,
| but the dependencies are "treelike" (meaning that for
| every target you might want to run, all of its transitive
| deps are reached via a unique path), it's still easier
| (than _either_ make or Just) to have separate scripts,
| and turn each dep into a plain invocation at the top of
| each script. It 's only when that approach starts to
| invoke deps multiple times (because it has become non-
| treelike) that either make or Just starts to offer an
| advantage.
|
| I think if you look at this with clear eyes, you'll see
| that 100% of the value you feel you're getting from Just
| is actually coming from the naming convention that Just
| nudged you towards.
| lijok wrote:
| I was asking a genuine question to see if I had missed
| anything about how just works, given that I couldn't see
| the difference, and you were proclaiming that there is
| one.
|
| Your comments are coming off very deffensive and
| insecure.
| pdimitar wrote:
| My comments are frustrated because I believe a response
| was already given to the question you asked. I'll be
| grateful if you at least don't misrepresent, even if it's
| difficult to find a common language. If you don't believe
| that I responded adequately then just ask a more detailed
| question.
|
| But sure, here's one more reason for you, as said in a
| sibling subthread: I can have all my project's commands
| in one file.
|
| Also it pays off to know what `just` does. As several
| other people were told (not only by me) in the bigger
| thread, it's an aggregating task runner, more or less.
| Not a dependency manager.
| burnished wrote:
| Honestly you're coming off a bit shit here, I don't read
| the other person's responses as defensive or insecure at
| all, so I suspect you're saying that to be rude.
| kstrauser wrote:
| Tab completion. `just -l<tab>` shows all the commands and
| their descriptions.
|
| Aside from that, it has lots of built-in ergonomics like
| consistent argument parsing, functions to say what OS
| you're on, an easy way to hide helper functions, the
| ability to execute a justfile in a great-grandparent
| directory, etc.
|
| You can totally do any of those things with shell
| scripts. I prefer letting someone else invent all the
| bells and whistles there so I don't have to.
| BeetleB wrote:
| Well, for one, your recipes can be in another language (e.g.
| Python).
|
| You can build complex recipes out of simpler ones. Sure, you
| could do that by creating a new shell script that calls other
| shell scripts, but then you're reinventing just.
|
| You don't need to be in the directory to run those scripts.
|
| I think a better question for you: What's the benefit of
| putting .PHONY recipes in Makefiles, when you could just have
| a directory full of shell scripts. If you find yourself using
| .PHONY recipes, then you already have a reason to use just.
| e12e wrote:
| > Well, for one, your recipes can be in another language
| (e.g. Python).
|
| Surely this is true for stuff in a ./bin or ./scripts
| folder - binaries, python with shebang etc?
| e12e wrote:
| Ah, I see there's:
|
| https://just.systems/man/en/shebang-recipes.html
|
| Which could be done in shell, but typically rather be
| limited to oneliners (invoking awk) rather than piping a
| heredoc to an interpreter.
| akoboldfrying wrote:
| > You don't need to be in the directory to run those
| scripts.
|
| There's already an easy way to solve this: $PATH.
|
| > I think a better question for you: What's the benefit of
| putting .PHONY recipes in Makefiles, when you could just
| have a directory full of shell scripts. If you find
| yourself using .PHONY recipes, then you already have a
| reason to use just.
|
| Well, I think it's the same question, rather than a better
| question. And the answer is yes, if _all_ you need from
| make, now and in the future, is a set of .PHONY targets,
| then by all means just use shell scripts. make is used
| because often you need slightly more than this -- or you
| may do so tomorrow, and don 't want to change the syntax
| you use to accomplish tasks.
| BeetleB wrote:
| > There's already an easy way to solve this: $PATH.
|
| I have 10 projects. Each with their own set of shell
| scripts. You want me (and all other developers) to
| pollute the $PATH with 10 directories?
|
| And then you have a namespace problem. I usually have a
| "test" recipe in my justfiles. The analog would be a
| test.sh file. But with your solution, it will have to be
| projA-test.sh and projB-test.sh.
|
| And if I dump them all into the $PATH, how do I quickly
| see the scripts relevant to a particular project?
| L3viathan wrote:
| You can put `./scripts` in your $PATH, if you want.
| kstrauser wrote:
| Absolutely do not do this. That's all well and good until
| you clone a repo that 'scripts/ls' =>
| install_ransomwhere().
| olejorgenb wrote:
| You could put `.$MY-SECRET` it `PATH` and selectively
| symlink this to vetted script directories
| olejorgenb wrote:
| You can put .scripts last in PATH (or first - whichever
| disallows scripts/ls to take precedence over /usr/bin/ls)
| bbkane wrote:
| I agree, but `Just` as an incremental improvement is a much
| easier sell to teams than asking them to think about their
| builds completely differently and rewrite everything to fit
| that.
|
| Offering a cave man a flashlight is probably more helpful than
| offering them a lightbulb and asking them to wire up the cave
| to power it :D
| __MatrixMan__ wrote:
| It is definitely a very fine incremental improvement over
| make. It's just incremental progress in a direction that I
| don't want to be headed.
| pdimitar wrote:
| 1. The language is extremely simple and is consistent.
|
| 2. I agree on having to move away from imperative and go for
| declarative (if the latter was what you had in mind) -- any
| ideas for a better tool that does that and is just as easy to
| learn?
|
| 3. RE: cobbling together stuff with and around `just` is
| relatively trivial to fix f.ex. I have my own `just` recipes to
| bring up the entire set of dev dependencies for the project at
| hand, and then to tear them down. It's a very small investment
| and you get a lot of ROI.
|
| 4. RE: Nix, nah, if that's your sales pitch for it and against
| `just` then I'll just strongly disagree. Nix is a mess, has
| confusing cutesy naming terminology, has a big learning curve
| and a terrible language. All of that would be fine, mind you,
| and I could muscle through it easily but the moment I received
| several cryptic error messages that absolutely did not tell me
| what I did wrong and I had to go to forums and get yelled at,
| is the moment I gave up. `just` is simply much easier and I am
| not worried about not having Nix-like environments for my
| projects. Docker + compose work very well for this.
|
| Finally, your point about an obscure single command that people
| forget about in the future applies to literally any and all
| task runners and dependency managers, Nix included. That's not
| a valid criticism towards `just` IMO.
| __MatrixMan__ wrote:
| 1. It's a fine language but I have all kinds of "works on my
| machine" problems with it because it has no associated
| dependency manager. Other languages solve this with lockfiles
| and such, and it's likely that you're already doing that with
| one of those same languages in the same project. So just...
| Use the main language for whatever it is.
|
| 2. No, nothing's so easy, but you can get more if you're
| willing to work for it, and I think the juice is worth the
| squeeze.
|
| 3. For runtime state, I find that using just as a wrapper
| around Tilt or docker-compose or k3d or whatever just hides
| the perfectly adequate interfaces that those tools have. The
| wrapper discourages deeper tinkering with those tools. It's
| not a particularly difficult layer of abstraction to pierce,
| but it doesn't buy you enough to justify having an additional
| layer at all.
|
| 4. In the case I'm thinking of, the whole team was working
| happily because they had used a Just recipe to download a
| file from a different repo, and then somebody removed the
| recipe, but everyone (except the new guy) had the file from
| months ago, which worked. Nix wouldn't have let us
| accidentally get into a broken state and not know it. It
| would have broken as soon as we removed the derivation for
| the necessary file. I sent him the file through slack and
| then he was able to work, and only discovered later how it
| got there on my machine. That kind of uncertainty leads to
| expensive problems eventually.
| pdimitar wrote:
| 1. I don't follow. I work with Elixir, Golang and Rust and
| I use their dependency managers just fine. F.ex. I have
| `just deps` that does `mix deps.get` in Elixir and `go get
| -u ./... && go mod tidy && go mod vendor` in Golang.
| Furthermore, `just` does not claim to do dependency
| management. So what do you mean here?
|
| 2. Sure but I am not paid for it. Nobody will look at me
| with admiration if I delay an important milestone with 2
| weeks (or, more likely, 2 years) to invent such a tool. :/
| So not sure I get you here either.
|
| 3. We're veering into bikeshedding here and I will not
| argue; use whatever interface works best for you. I
| personally love having `just up` / `just down` / `just
| start` / `just stop` for my development dependencies of any
| project project. No more one big shared Postgres instance
| that if I screw it up (and homebrew did that a number of
| times!) I'll have to dig through TimeMachine for DB
| backups. I wisened up eventually and started making
| scheduled exhaustive backups of each DB... and then said to
| myself "forget it" and just started using separate
| containers for each project. For my work I found wrapping
| the tools worth it for not having to remember their bespoke
| full command lines. I standardized my tasks and I can enter
| almost any directory and run the same `just ...` commands
| and get what I expect as a result. To me that's valuable.
| But again, use whatever is convenient for you. No argument
| from me.
|
| 4. I don't disagree here and I am kind of 50/50 because on
| the one hand this is failure of process + lack of proper
| dev/ops tooling (f.ex. deleting this or that should raise
| alarms i.e. every such repository should have CI that makes
| sure everything important stays in place). On the other
| hand if Nix or anything else spares you from having to
| install those guard rails then sure, then it's a good fit
| for you. For my work and hobbies Nix is a net negative and
| I gave it more than a fair chance and I had enough of
| opinionated diva-like tools whose message is "learn
| everything about me to love me, baby". No thanks. But
| that's just a single example. Again, if there are tools
| that spare you from screwing up something accidentally, I
| usually vote strongly in favor of them.
| __MatrixMan__ wrote:
| People like Just when they're the one who is writing the
| recipes, because those recipes implicitly depend on
| whatever they have installed at the time of writing so
| everything is easy, but then other people come to the
| project and it has a culture of "IDK I just use the Just
| recipe," except that recipe doesn't work unless you've
| been around since it was written and have all of the
| right versions of things. For instance I've got all these
| errors like:
|
| > This application uses version go1.20 of the source-
| processing packages but runs version go1.23 of 'go list'.
| It may fail to process source files that rely on newer
| language features. If so, rebuild the application using a
| newer version of Go.
|
| They don't seem to be hurting anything but I'm not really
| sure how to reason about them since somebody packaged the
| commands together but didn't specify anything about the
| environment. The Justfile entry tells me that it's
| running some script in $FOO_DOWNLOAD_DIR but I've got
| some sleuthing to do to figure out where that dir
| actually is and how its contents were populated and what
| it has to do with `go list`.
|
| This is of course bad practice, but Just is the rug under
| which it is hidden and made to look like good practice.
| It's good that Just doesn't claim to manage dependencies,
| since it doesn't, but this action could instead be a go
| program in which case go _would_ be handling those
| dependencies for me.
| pdimitar wrote:
| I don't disagree. Your example is a good demonstration
| why Nix -- or a much more thorough Justfile -- would be
| needed.
|
| In my case I also supply the `.tool-versions` file so
| that only mandates the other dev to have Just and asdf /
| mise (for installing exactly the right versions of
| tools).
|
| I also tried having full Dockerized development
| environment but that proved too much of a hassle.
|
| But yep, in your scenario it seems like the other guys
| did sloppy work. Sadly 99% of everything can be misused
| by people who don't practice their craft well.
| o11c wrote:
| > like make, it encourages an imperative mode for project
| tooling and I think we should distance ourselves from that a
| bit further.
|
| Um, what? `make` is arguably the most common declarative tool
| in existence ...
|
| Whenever people complain about Make in detail, it's almost
| always either because they're violating Paul's Rules of
| Makefiles or because they're actually complaining about
| autotools (or occasionally cmake).
| AlotOfReading wrote:
| I find declarative build systems end up pretty frustrating in
| practice. What I want from a build often _isn 't_ the
| artifacts, but the side effects of producing the artifacts like
| build output or compilation time. You get this "for free" from
| an imperative tool, but represents a significant feature in a
| declarative system that's usually implemented badly if it's
| implemented at all. The problem gets worse the smarter your
| tool is.
| thfuran wrote:
| >What I want from a build often isn't the artifacts, but the
| side effects of producing the artifacts like build output or
| compilation time
|
| You frequently build things not to get binaries but to spend
| time compiling?
| AlotOfReading wrote:
| The point is that there's often no way way to express "I
| want side effects" in declarative tools, and the number of
| side effects that might be useful is vast.
|
| For example, sometimes I profiling the build times to see
| where I should focus effort.
|
| Sometimes I want to see it to quickly check for issues
| where adding some dependency header causes build times to
| explode 100% in downstream dependencies during cold builds.
|
| Another common occurrence for is trying to debug a
| platform, toolchain, or standard library issue and the
| build system either doesn't detect changes in those
| components or only makes the components readily accessible
| in an internal cache that's subject to invalidation issues.
| You'll usually get the wrong artifact or test results in
| those cases.
|
| Some other systems (e.g. bazel/blaze comes to mind)
| actively try to hide side effects like stdout.
|
| In all of these cases, the only way to actually get these
| side effects is to reach into the tool's internals by
| blowing away caches/output folders or reading live log
| files. That's a failure of the build tool.
| __MatrixMan__ wrote:
| Logs emitted during the build, or test results, or metrics
| captured during the build (such as how long it took)... these
| can all themselves be build outputs.
|
| I've got one where "deploying" means updating a few version
| strings and image reverences in a different repo. The "build"
| clones that repo and makes the changes in the necessary spots
| and makes a commit. Yes, the side effect I want is that the
| commit gets pushed--which requires my ssh key which is not a
| build input--but I sort of prefer doing that bit by hand.
| pdimitar wrote:
| I love `just` and have adopted it universally in all my projects.
| For what it does, it gets the job done fantastically.
|
| That being said, I found myself needing a tool that builds a DAG
| of dependent tasks and automatically figures out what can be ran
| in parallel and what cannot -- obviously you have to spell out
| all tasks and who depends on what first.
|
| Anybody knows such a tool?
|
| EDIT: Apparently people did not get the hint that I believe
| `make` is an over-engineered pile of metric tons of legacy and
| I'll sooner slash my wrists than to learn it in full.
|
| I did mean something ergonomic and easy to read and write. And no
| I'll never view `make` as such. I tried. Many times. I have
| better things to do in my life than to memorize exceptions of the
| exceptions.
| guipsp wrote:
| Make?
| pdimitar wrote:
| Come on, be serious. If I wanted ancient sh-isms and bash-
| isms I would have learned make to 100% some 15 years ago.
|
| I meant something ergonomic and easy to read and write.
| ofrzeta wrote:
| They are right, though, aren't they? I mean .. if you want
| something "modern", go ahead and learn Bazel. Make is quite
| a bit easier to learn, I'd say, and you don't need much
| (also no shell/bash) to express your DAG dependencies.
| pdimitar wrote:
| I'll agree on the DAG bit but I'll never use `make` again
| and I tried for no less than 10 years (on and off, not
| 24/7, otherwise I would have learned it long ago indeed).
|
| I stay away from `make` almost religiously. Its
| complications _always_ find a way to creep into your file
| one day. Always. :(
|
| So while they are technically correct and it's my fault
| for not saying I don't want `make` in the comment up-
| thread, I don't think my comment deserved the down arrows
| but oh well, I'll live through it.
| Izkata wrote:
| > If I wanted ancient sh-isms and bash-isms
|
| So don't, set make's shell to something else instead. It
| doesn't understand the recipes, it just dumps them to a
| file and runs $(SHELL) on them.
|
| For a more extreme example, just to show what's possible:
| SHELL := python3 .ONESHELL:
| foo.csv: import csv with open("$@", "w") as
| f: writer = csv.writer(f)
| writer.writerows([ ['Test1', 'Test2'],
| ['Test3', 'Test4'], ])
| pdimitar wrote:
| Not a bad idea, thanks. I did this a few times as well
| but when I analyzed the ROI I figured that just writing a
| simple-ish Golang program is just less confusing and more
| consistent in its totality when you ask yourself "do I
| really have to use Make and Python and, and, and...?".
|
| So yeah, thanks for bringing visibility to this pretty
| decent compromising approach. It worked for me for a
| while but eventually I just went all-in to either use
| `just`, some _very_ short bash/zsh scripts, or jump all
| the way to Golang.
| thechao wrote:
| I'm this years old when my life was revolutionized.
| plmpsu wrote:
| Maven, Gradle, etc.
| diggan wrote:
| Besides Make, I guess Bazel kind of fits the bill? It was very
| "Googly" last time I checked it out, but I think that was a
| decade ago and right when it was released, so it might be more
| fitting for not-Google nowadays.
| pdimitar wrote:
| I never looked at it but seen some fairly negative reviews
| here on HN. Any idea why? And why do you like it?
| bfLives wrote:
| I think this is exactly the intended use case for Ninja. It's
| discussed in this recently posted article.
|
| https://news.ycombinator.com/item?id=42268310
| pdimitar wrote:
| Thanks. That article is fairly disappointing for not having
| even one simple example file though...
| aidos wrote:
| I've not tried it but this popped up on here a while back and
| sound like it might fit the bill.
|
| https://taskfile.dev/
| pdimitar wrote:
| Thanks, this one has been in my radar for a while, I'll
| absolutely get to it at one point.
| j6m8 wrote:
| I wrote frof [1] for exactly this purpose :)
|
| Designed to be ultra-simple and with minimal "config-file
| acrobatics".
|
| It looks like this [edit, formatting]: write
| -> analyze build -> analyze write:
| echo 1 2 3 > data.txt build: compile_tool.sh >
| tool.sh analyze: tool.sh data.txt
|
| https://github.com/j6k4m8/frof/
| pdimitar wrote:
| Can you explain that one a little bit more to me, please?
|
| I don't get the first two lines of your example well. They
| seem to show the dependency but which one is the default
| task, or how do you ask for a task to be ran?
| j6m8 wrote:
| You write the file and ALL steps are run in topological
| order so that a job never runs until its dependencies have
| run. i.e., in a tool I'll have `build.frof` as a separate
| frof file than `download-dependencies.frof`, perhaps. (If
| your preference is that those belong in the same file I'd
| be down to have PRs that support that! Should be very easy,
| I'm happy to try implementing this if there's interest.)
|
| So for a file with those contents called `mygraph.frof`,
| you can (after installing) run `frof mygraph.frof` to kick
| off the jobs in the current shell (inheriting env vars
| etc).
|
| [edit] maybe a clarifying example here:
| https://blog.jordan.matelsky.com/frof-render/
| pdimitar wrote:
| OK, so for the example in your comment upthread both
| `write` and `build` will be executed sequentially?
| j6m8 wrote:
| here they'll probably be executed simultaneously, since
| they both have zero dependencies and the machine can run
| multiple jobs at the same time. (can be disabled with
| `--max_jobs=1` or `-p=1`).
|
| Here's another illustrative example: A
| -> B B -> C Z -> C
|
| In this situation, frof will schedule `Z` to run in a
| parallel thread ASAP, so it will likely run alongside
| A... and if Z takes longer to run than A, Z will continue
| running when A stops and B starts. But C will wait for
| all other jobs to finish before it can schedule.
| pdimitar wrote:
| Nice, thanks a lot. Unfortunately I am quite swamped
| recently so I will definitely cannot help you with
| feature requests and testing but I have bookmarked frof
| and absolutely will be giving it a try.
|
| Just one thing I would dislike... Python. How easy it is
| to run frof without having to fiddle with venvs and such?
| j6m8 wrote:
| no worries, good to know this would be a useful feature!
| I'll add it to my backlog. pip install
| 'git+https://github.com/j6k4m8/frof/'
|
| and then frof myfile.frof
|
| should work!
|
| Was thinking about rewriting it in Go recently... :)
| pdimitar wrote:
| I'll try the vanilla Python route but knowing our mutual
| hatred, it'll crap the bed in 0.5s. :D We'll see.
|
| > _Was thinking about rewriting it in Go recently... :)_
|
| And then I might actually contribute. :)
| burnished wrote:
| I've found prototyping in python followed by a rewrite in
| Go quite pleasant, would recommend
| matja wrote:
| FYI to some people trivializing self-harm in a technical
| discussion is rather tasteless.
| pdimitar wrote:
| It's an exaggeration to illustrate a point. Still, thanks for
| bringing in the perspective.
| sgarland wrote:
| I love just. The main benefit for me at work is that it's much
| easier to convince others to use, unlike make.
|
| I like make just fine, and it's useful to learn, but it's also a
| very opaque language to someone who may not even have very much
| shell experience. I've frequently found Makefiles scattered
| around a repo - which do still work, to be clear - with no known
| ownership, the knowledge of their creation lost with the person
| who wrote them, and subsequently left.
| soulofmischief wrote:
| Can anyone with experience with just and tools like npm/yarn
| explain if there are any benefits to use just instead of
| codifying commands into the "scripts" field of the package.json?
| Commands can also be enumerated. How often would I benefit from
| just's other features?
| zemo wrote:
| package.json is specific to node projects, just can be used for
| anything. Why learn the quirks of something you can only use
| with a single programming language? I'm also a fan of the
| shebang recipes: https://just.systems/man/en/shebang-
| recipes.html
| soulofmischief wrote:
| I place package.json files into non-node projects all the
| time just for some organizational benefits like workspaces
| and scripts. As a web-first engineer this doesn't
| particularly bother me. I'll check out shebang recipes,
| thanks!
| lolinder wrote:
| We don't use Just, but we have a Makefile that doesn't take
| advantage of any of Make's dependency features just to easily
| be able to run several commands in sequence.
|
| JSON is just a really bad format for script configuration--you
| either have to string commands together on one big line with &&
| or you have to pair package.json with some other strategy for
| organizing commands. That may end up being a `scripts`
| directory with a file per script, it could be that you use a
| framework that bakes all the complexity into shorter wrapper
| commands (a la vite), or you could use something like Just to
| sequence them.
| soulofmischief wrote:
| It's not perfect but it gets the job done. Sometimes it's
| ugly but in the end it forces me to break commands down into
| subcommands, which can increase clarity.
|
| But sometimes you do have to write a collection of script
| files for complex multi-line scripts. I assumed I would still
| do that with just? Is the idea for these to all live in a
| single just file? I like having larger programs separated as
| individual files. All good points, though. I like make too,
| but it can definitely be needlessly verbose. My main thing
| would be not wanting to need users to have another binary
| installed locally. Can just live in my repository?
|
| Edit: Nevermind! https://just.systems/man/en/nodejs-
| installation.html
|
| > `just-install` will install a local, platform-specific
| binary as part of the npm install command. This removes the
| need for every developer to install just independently using
| one of the processes mentioned above.
| gurgeous wrote:
| Actually, it was package.json scripts that pushed me toward
| just! I wanted that stuff in non-node projects (python/ruby/~),
| I wanted more complicated scripts, I wanted more logging
| output, I wanted comments... For whatever reason every project
| seems to have 10-20 little commands (often interdependent) and
| just makes that a breeze.
| sunshine-o wrote:
| I love just, this is such a great piece of software.
|
| I was thinking the other day: why don't we use just instead of
| Dockerfiles to define containers?
| diimdeep wrote:
| Just use programming language to build itself, it is even
| possible with C [0]
|
| [0] https://github.com/tsoding/nob.h
|
| If it is painful, ditch that language.
| gurgeous wrote:
| Question - mise is also incorporating a command runner. Anyone
| tried it yet? We love just, of course. Always curious about new
| tools.
| drewbitt wrote:
| I started writing my tasks in mise (https://mise.jdx.dev/tasks/)
| instead of just, but I found that others didn't want to install
| it. Something about mise being an all-in-one tool--combining
| asdf/direnv/virtualenv/global npm/task management--made
| installing it just for the task feature off-putting. At least
| that's my theory. So, I'm back to using just. I am happy that
| there isn't a ton of pushback on adding a justfile here and
| there. Maybe it's the name--'just' feels lightweight and is known
| to be fast, so people are cool with it.
| byproxy wrote:
| I'm starting to use `mise` for tooling management and task
| running on greenfield projects, myself. Anything you feel
| `just` does better with regards to running tasks?
| nunez wrote:
| Just recipes accepting command line arts and supporting
| documentation might be enough to finally push me away from Make.
| mgaunard wrote:
| I already have a command runner, it's called a shell.
|
| Apparently just also needs one to run.
| j0057 wrote:
| Can you set a variable from one task and use it from another, or
| is it a bad thing to want this?
| petabyt wrote:
| I've used make for years, even partially wrote my own make
| interpreter once, I hate it as much as anybody else. But I don't
| feel confident investing in a new tool that has widespread
| industry adoption. I wish there was a 'better make' that tries to
| replace make the same way Zig wants to replace C, where they have
| great interop and make it easy to rewrite code into the new
| language.
| dmead wrote:
| There are a ton of better makes. It still didn't matter.
| ramon156 wrote:
| Used it in my graduate internship. It really made using the
| garbage ASP.NET commands easier. Thanks!
| silasdavis wrote:
| I'm Stockholm syndrome with make at this point. I'm not sure I'd
| want it any other way.
| olvrng wrote:
| My favorite command runner setup is just a simple bash script and
| .envrc
|
| I can put my commands in a run file, which source a simple bash
| script, and use it like: run do-foo run
| build-bar
|
| You can even `run help` to list all available commands.
|
| The setup is explained here:
| https://olivernguyen.io/w/direnv.run/
| olvrng wrote:
| Create a bash script `run`: #!/bin/bash
| set -eo pipefail run-hello() { echo
| "Hello, World!" } # -------- this is the
| magic ------- # source "scripts/_cli.sh"
|
| And source a simple script `_cli.sh`:
| #!/bin/bash set -eo pipefail show-help(){
| items=() while IFS='' read -r line; do
| items+=("$line"); done < \ <(compgen -A
| "function" | grep "run-" | sed "s/run-//") printf
| -v items "\t%s\n" "${items[@]}" usage="USAGE:
| $(basename "$0") CMD [ARGUMENTS] CMD:\n$items"
| printf "$usage" } name=$1 case
| "$name" in "" | "-h" | "--help" | "help")
| show-help ;; *)
| shift if compgen -A "function" | grep
| "run-$name" >/dev/null ; then run-"${name}"
| "$@" else echo "ERROR:
| run-$name not found." exit 123
| fi ;; esac
| luismedel wrote:
| Nice. I didn't know about Just.
|
| Just (pun intended) a personal plug: I always liked the Make ease
| of use and the declarative GH Actions phylosophy. I also like to
| have the same workflows in local and in my remote CI, so I
| recently wrote a task runner with the (IMHO) ease of use of Make
| and GH Actions-like philosophy. It still lacks good docs, but I
| use it everyday on my projects and works like a charm.
|
| https://github.com/luismedel/bluish/
|
| Some day I need to do a proper Show HN :-)
| luismedel wrote:
| I wonder how this kind of post can bother someone enough to
| downvote it. I think is related with the posted link :shrug:
| burnished wrote:
| This topic appears to have sparked some furor, maybe your
| comment got caught in the crossfire?
| nrclark wrote:
| From my perspective, Just would be more useful if it had some
| ability to skip steps where the input hasn't changed.
|
| Like maybe a Justfile's recipe could produce a "<task>.complete"
| kind of file, and could decide whether to re-run the task based
| on whether the task's inputs (or its dependencies' inputs).
|
| Also if that sounds like a useful feature, consider using Make.
| maccard wrote:
| Make solves that problem. The problem that I have is that all
| of the tools I use day to day do their own dependency tracking
| and re-run tracking. Say I want to deploy a dotnet app to a k8s
| cluster - none of helm, docker, dotnet build, dotnet test
| expose their dependency tracking in a way that is
| straightforward to use with make. The most straightforward way
| to do it is to just run the commands anyway, IME.
| hobofan wrote:
| > Also if that sounds like a useful feature, consider using
| Make
|
| Just not having that feature is _the_ defining difference in
| design between the two. If just were to ever add that it would
| likely kill its appeal. Not having that is what keeps the logic
| of a just invocation simple and what keeps Justfiles from
| devolving into the mess that Makefiles tend to with entangled
| build targets.
| tgmatt wrote:
| I'm surprised nobody mentioned Rake yet. Having the full
| capability of Ruby and whatever gem you want makes it a dream for
| these kind of tasks. Absolutely love it.
| ufmace wrote:
| That's what I dropped in to say. I've used most of them, and I
| think Rake is my favorite.
|
| Pretty much all of the others are shell command runners with a
| couple of extra bits bolted on. Well and good most of the time,
| but it's another language to learn, and you're mostly SOL if it
| doesn't support something you want to do nicely.
|
| With Rake, you get the same basic ability to do pre-set shell
| commands as the others, a single one or a sequence. But you
| also have the full power of Ruby, a full-fledged programming
| language, if you want to do anything more complex.
| tomjakubowski wrote:
| One reward you get for allowing yourself to become brainwashed by
| Bazel is you get a pretty nice task runner in every project that
| you've brought into the fold.
| okanat wrote:
| Reliance over a Posix shell basically prevents me from using
| Just. Using bash from Git on Windows is a very weird choice.
| 25thhour wrote:
| I'm also using a global justfile (`-g`) [1] to serve as a
| convenient location to aggregate any convenience functions, as
| well as call out to any standalone scripts as necessary.
|
| You can also 'convert' all recipes to aliases so you get the best
| of both worlds, the ability to call with `just -g foo` or `foo`,
| from anywhere.
|
| The docs example [2] uses a `user` justfile, but the principal is
| the same for global. for recipe in `just
| --justfile ~/.user.justfile --summary`; do alias
| $recipe="just --justfile ~/.user.justfile --working-directory .
| $recipe" done
|
| Most recently I've started using `fzf` and `bat` to allow
| interactive selection of recipes with syntax highlighted
| previews: _choose: @just -g --summary | \
| tr ' ' '\n' | \ sort -r | \ fzf --multi
| --preview 'just -g --show {} | bat --color=always -l just -pp' |
| \ xargs just -g
|
| Now with a global `alias ji="just -g _choose"` I can
| interactively choose a recipe if I need a reminder of what I've
| set up.
|
| This was inspired by the native `--choose` flag which does
| something similar, but by using `--summary` here, all recipes,
| including those that take arguments *, are listed, as well as any
| nested modules.
|
| And because you can use any shebang, you can also write little
| python scripts to run with `uv`, including those with
| dependencies [5] declared in the shebang: # list
| Cloudflare accounts accounts: #!/usr/bin/env -S uv
| run --script --with cloudflare --python 3.13 from
| cloudflare import Cloudflare client = Cloudflare()
| accounts = client.accounts.list() print(accounts)
|
| ...here with inline metadata: # list Cloudflare
| accounts accounts: #!/usr/bin/env -S uv run
| --script # /// script # requires-python =
| ">=3.13" # dependencies = [ # "cloudflare",
| # ] # /// from cloudflare import Cloudflare
| client = Cloudflare() accounts = client.accounts.list()
| print(accounts)
|
| [1] https://just.systems/man/en/global-and-user-justfiles.html
| [2] https://just.systems/man/en/global-and-user-
| justfiles.html#r... [3] https://just.systems/man/en/selecting-
| recipes-to-run-with-an... [4]
| https://github.com/charmbracelet/gum?tab=readme-ov-file#inpu...
| [5] https://docs.astral.sh/uv/guides/scripts/#running-a-
| script-w...
|
| * interactively selected recipes that take arguments won't work
| by directly passing to `xargs` here, but in some cases where I
| _do_ want that flexibility I just add a condition in the recipe
| to prompt for input, with `gum input` [4]. Flexibility. This is a
| belt and braces approach and only used where necessary as the
| `fzf` preview will have made it clear that a recipe takes
| arguments. [positional-arguments] foo
| $bar="": #!/usr/bin/env bash if [ -z "$bar"
| ]; then bar=$(gum input --placeholder "bar")
| fi echo "looking up $bar"
| sebmellen wrote:
| Justfiles are really awesome for repos where you have to use a
| bunch of complex, long to type CLI integrations. Especially if
| you're using Deno scripts that all have different permission
| flags...
| PhilippGille wrote:
| Several comments mention Task/Taskfile already, which is very
| similar in that you define tasks in YAML.
|
| I think it's worth mentioning Mage/Magefile [1][2] as well, where
| your tasks are actual Go code. Similar to how Rake is for tasks
| in Ruby code.
|
| It's useful when you have complex tasks.
|
| It's like using Pulumi instead of Terraform.
|
| [1] https://magefile.org/
|
| [2] https://github.com/magefile/mage
| jmartin2683 wrote:
| I love just! Any way to avoid remembering things is great.
| rout39574 wrote:
| Why is "Just" superior to any other e.g. bash script with a bunch
| of subcommands?
___________________________________________________________________
(page generated 2024-12-07 23:00 UTC)