When `just` is invoked without args, imports are not considered when identifying the first recipe
Steps to reproduce
- Create the following justfile in some directory, say
/tmp/justtest
default:
just --list
- Create the following justfile in a subdirectory of that directory, say
/tmp/justtest/sub
import "../justfile"
foo:
@echo "foo"
- With working directory
/tmp/justtest/sub, executejust(with no arguments)
Expected behaviour
Without thinking about it too much, I expected that step (3) would identify the imported default as the first recipe, and execute just --list.
Actual behaviour
Step (3) executes the foo recipe and prints "foo".
Thoughts
My initial intuition was that default would be treated as the first recipe in the subdirectory's justfile, just as it would be if instead of using an import statement at that position, I'd pasted in the content of the parent directory's justfile. That's consistent with the idea that "imports behave as if the recipes in the imported justfile were included in the justfile directly".
However the actual behaviour also kind of makes sense in the light of the idea that "shallower definitions always override deeper definitions"
So I'm not sure whether you consider this an issue or not!
Motivations for raising this
I like the suggested pattern of just --list as a default recipe, because I almost always don't want to accidentally execute a recipe without explicitly specifying it.
Clearly it's not that hard to achieve that even with the behaviour described. I can explicitly put a default recipe as the first one in the subdirectory justfile, as long as I set allow-duplicate-recipes := true. (But if I'm allowing duplicate recipes just for the sake of having this default, I'm losing the protection I normally would against accidental overrides.)
Or I can just add the recipe to the subdirectory justfile with a slightly different name like _default, without the need to set allow-duplicate-recipes.
Going a bit off-topic, an alternative solution that would also work nicely would be an environment variable (say JUST_NO_DEFAULT) which changed the behaviour of just without arguments, so that it behaved like just --list or perhaps just --help, instead of executing the first recipe.
I know it would be a breaking change, but I also feel that when no default recipe is defined, just should list the available recipes.
Perhaps that could be controlled with something like set list-recipes-when-no-explicit-default.
Edit: My use case, that led me to this issue, was that I have a collection of justfiles used for several similar projects. In each project, there is a subdirectory with this collection of justifies, and a top-level justfile, that imports one or more of the justfiles in the subdirectory. I wanted to define a default in one of the imported justfiles. In my case, I wanted the default recipe to be just --list.
I think this is probably not a bug. I'm not sure if the current behavior is intended or not, i.e., did we even think of this when implementing import, but I can see an argument that it's a little confusing if the default recipe comes from an import.