-
Notifications
You must be signed in to change notification settings - Fork 500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Executable Justfiles #367
Comments
Heyo! Thanks for your thoughtful comments! I think allowing a shebang in the first level Justfile is a good idea. You're right that it's illegal to avoid confusion with the #355 should land soon, which would make it unnecessary to supply What do you see executable justfiles as being good for? Just curious, since I don't see any downside in allowing them.
I think that this might be problematic. For example, if there's a file called I'm definitely open to the idea of allowing multiple files. Recipes can't be slash separated though (like I'm not sure how I feel about loading justfiles without some kind of I think it would be good to figure out a minimal design that makes multiple files useful, to avoid trying to do too much at once. Unfortunately, I'm very busy with other responsibilities for the time being, so I wouldn't be able to do much in the way of implementation, and reviews and merges would probably be slow. |
Hey! Thanks for the thoughtful reply, and sorry for the long delay. Work/holidays and whatnot. I'm glad you like the shebang. It did seem like a design oversight, but I wasn't sure if there had been a strong reason to keep it out. I would love to submit a PR, but I don't know rust. I've always fancied learning it, but never could quite find the time. Maybe I'll find sometime to learn what i need in the coming month or two.
Essentially, I see it as a script with self-documenting CLI. The tasks/targets are composable functions. A justfile itself can be either a single executable or a module/library depending on usage. A build process is really just another kind of data-processing program, after all. Just, like Make before it, is a declarative programming language. This is a design that is well suited to writing build/tool scripts. Unfortunately, it (like it's predecessor) lacks many of the conveniences of more conventional programming languages, namely modularity and flexible composition. That's what I'm aiming to address with this set of improvement suggestions.
For this context is everything, but syntax should be uniform. The resolution order I'd imagine is
The one in the current directory. The
When considering multiple An exception to this process might by that if a
I don't see why not. If that's how you would refer to in on the CLI, why should it be any different in the task recipes? Uniformity is a boon and should only be discarded with good reason. Where possible, I'd like the syntax for referring to a target in another file from a recipe to work as if I'd invoked
With respect to a fully specified target, it only matters that it be possible to refer to the specific file in which to look for the target. All other constraints are free. From there, of the three ways to specify target
I think that's a good design constraint to have. Though, I don't think it's necessary since requiring inter-file tasks to be fully qualified makes them already stand out. Having a special statement calling it out is redundant, though it could aid in debugging task resolution problems. There may also be performance/implementation advantages to resolving the includes ahead of task parsing. Overall, I'm for it. Syntax TBD.
Given what we've discussed so far, and aside from the shebang, it sounds like the MVP would have the following features:
Things left out of the MVP:
That's alright. :) I am too. Though, bits of "free" time occasionally pop up here and there. If I can get to it, I'll try to. I really just wanted to get your feedback on my idea/s and try to get it in the pipeline. In the interim, I have my own hacky workarounds. |
Motivation
I use Make to make simple script tools. I find it's much easier to use (and maintain) than my previous solution -- bash switch blocks. Recently I've been porting these Makefiles to Just. But, Just has one weakness, I can't make a single file executable like I can with shell scripts. This means that when I want to distribute my tools to others I have to explain how to them how to use them, how it's like a Makefile, and how it's not. Being similar to a Makefile, creates friction, as I find that many devs don't like seeing Makefiles for things other than building code. To me the structure of a Makefile is ideal for writing composable scripts. For more complex tooling I even have multiple Makefiles in a directory tree acting like modules, separating out different common utilities into each file. If you think that this sounds like madness, take a look at BuildRoot. It's a production codebase that's almost entirely written in Makefiles!
I also spend some amount of time using and maintaining a large recursive-make build script. This may cause some to shudder, but that's just how it is. One day, I'd like to port this to Just, as I think it has the potential to smooth out many of the developer pain points. The similarity in syntax makes this especially appealing over other alternatives that would require a larger rewrite. However, I think Just lacks some really killer features that would make this work more justifiable (pun intended).
Features
Just has many advantages over Make as pointed out by its docs, but I suggest here some features that could make it even more useful for writing declarative tooling scripts and handling complex builds. Though they may seem unrelated, they are really two sides of the same coin.
Top Level Shebang
This is very simple, and at most would require some low-level changes to how Just handles file inputs. What I want to support is having a line like the following at the top of the file.
This should look and act just like a regular shebang you may see in a single-file python/js/shell script. The
<args>
is a placeholder for whatever args Just might need to support this feature. For example, the way Just is written right now it would likely need--working-directory
to be supplied; though it could easily default to the CWD.Currently this kind of usage is explicitly blocked with an error:
I understand this is likely done to avoid confusion with the shebangs allowed in recipes, but it shouldn't be too hard to disambiguate, especially if you only allow shebangs on the first line. I think dropping this error is probably about all you need to make this work.
Alternate Naming Convention
If a justfile is to be executable, it makes sense to allow for it to be named something other than
Justfile
. Here I'd suggest the*.just
extension. Supporting this may be more about editor support more than anything, but within Just I'd at least hope that it would support opening*.just
files by default if noJustfiles
orjustfile
is present in in the CWD.Ideally, I'd hope that multiple
*.just
files could be selected from based on target, logically acting like one largeJustfile
. Collisions between targets in separate files could be disambiguated with a fully qualified (Make compatible) target likepath/to/filename@target
. See below for more.Inter-file Targets
The dream-usage I'm aiming for is that one could execute a top-level
*.just
file that could call out to other "child"*.just
files by specifying target alone. This would be similar to the recursive make idiom, except with a few huge advantages.Target Inlining: Using something like
$(MAKE)
to execute dependent targets makes those actions opaque and increases process overhead. In a large build, the cost of creating all those extra processes can be rather burdensome. Hoisting the target up into the recipe makes it much easier to introspect the dependency graph and perform optimizations.Introspection: While you'd probably only want to supply targets from the CWDs file/s by default when
--list
or--summary
is used, this behavior could be changed with a--recursive
flag. The upshot of this being that the entire graph can be inspected and debugged by the programmer, without having to execute any recipes. Anyone who's spent time working with a recursive-make build knows how much of a lifesaver this would be.The text was updated successfully, but these errors were encountered: