Skip to content
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

Catch Functionality #2583

Open
ArchieAtkinson opened this issue Jan 17, 2025 · 2 comments
Open

Catch Functionality #2583

ArchieAtkinson opened this issue Jan 17, 2025 · 2 comments

Comments

@ArchieAtkinson
Copy link
Contributor

ArchieAtkinson commented Jan 17, 2025

There is no current way in standard Just to run additional commands if the execution of a recipe fails to allow clean-up. This is available in other languages with keywords like catch. This type of feature is useful when you have a multistage process that produces an output like building and running a container or server.

The current best method is to use the trap shell command which forces you to make your recipe a shell script.

test-in-container:
    #!/usr/bin/env sh
    trap 'docker rm -f test-container' EXIT
    docker run -d --name test-container test-image
    docker exec test-container run-tests

Another current solution is using an ||:

test-in-container:
    docker run -d --name test-container test-image
    docker exec test-container run-tests || (docker rm -f test-container && exit 1)
    docker rm -f test-container

However, this only works on a single line and gets repetitive for longer recipes.

Below I've thought of some possible ways this could be implemented in Just while maintaining backwards compatibility:

Using an attribute:

[catch: docker rm -f test-container]
test-in-container:
    docker run -d --name test-container test-image
    docker exec test-container run-tests

Where the command after catch: would run if the recipe errored.

Using a keyword:

test-in-container:
    docker run -d --name test-container test-image
    docker exec test-container run-tests
    ::catch::
   docker rm -f test-container

Where all the commands after ::catch:: would run if the recipe errored.

Extend the dependency system:

test-in-container-cleanup:
    docker rm -f test-container

test-in-container: !& test-in-container-cleanup
    docker run -d --name test-container test-image
    docker exec test-container run-tests

Where recipes after the!& would run if the recipe errored.

The attribute method would likely be the most straightforward to implement, while extending the dependency system with !& does seem more elegant. However, I can think of some potential complications already, which might be tricky to solve.

This could also be extended with a finally type feature that would run at the end of a recipe error or not.

While I acknowledge this functionality is already available through other methods, and adding it might introduce unnecessary complexity, I believe it would be a useful addition that could help keep more recipes within the standard Just framework.

I'm curious about everyone's opinions on this, and if there's interest, I'd be willing to attempt to create an implementation.

@ArchieAtkinson ArchieAtkinson changed the title Finally/Defer Functionality Catch Functionality Jan 17, 2025
@casey
Copy link
Owner

casey commented Jan 22, 2025

I've had a || syntax in mind for dependencies that should run if a recipe fails:

foo: || bar

bar would only run if foo terminates unsuccessfully.

But it sounds like this is for dependencies that run regardless of whether a recipe succeeds or fails?

I'm not a huge fan of !&, since it's not very familiar, but it seems like a good feature.

@ArchieAtkinson
Copy link
Contributor Author

But it sounds like this is for dependencies that run regardless of whether a recipe succeeds or fails?

No, you got the right idea. A way to run a certain recipe if your recipe fails. This could then expand to also have one that runs no matter what.

I like || for fail case. I'll have a look this weekend at trying to come up with a possible implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants