[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)