-
Notifications
You must be signed in to change notification settings - Fork 202
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
Fix just argument splitting on pass-through recipes with complex args #4961
Conversation
IS_PROD := env_var_or_default("PROD", env_var_or_default("IS_PROD", "")) | ||
# `PROD_ENV` can be "ingestion_server" or "catalog" | ||
PROD_ENV := env_var_or_default("PROD_ENV", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These variables were used long ago when we used to deploy the ingestion server and catalog using just
. We don't do that any more, and they just add noise/complexity to this file now, so are good to remove.
p package script +args="": | ||
pnpm --filter {{ package }} run {{ script }} {{ args }} | ||
[positional-arguments] | ||
p package script *args: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A handful of scripts used +args=""
, which works, but is technically redundant. *args
expresses the same thing (optional variadic arguments to gather), and perhaps much more intentionally, especially to relay that they are optional, rather than the +
prefix which indicates at least one is required (a requirement nullified by the default blank that is passed).
2114757
to
dd43c7f
Compare
dd43c7f
to
97aeed8
Compare
Hmmm, I don't know why those render-release-drafter scripts fail in CI. They pass locally 🤔. I thought at first it was because the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't fully tested everything yet, but on an ov just recreate
, although recreate runs apparently successfully, I see this error:
just up "--force-recreate --build"
env COMPOSE_PROFILES="api,ingestion_server,frontend,catalog" docker compose -f docker-compose.yml "$@"
unknown flag: --force-recreate --build
error: Recipe `dc` failed on line 204 with exit code 16
I also get errors trying to run the catalog tests, which I was able to fix by removing the single quotes in L106 for the _mount-test
recipe.
dcc805f
to
3a9fd32
Compare
Full-stack documentation: https://docs.openverse.org/_preview/4961 Please note that GitHub pages takes a little time to deploy newly pushed code, if the links above don't work or you see old versions, wait 5 minutes and try again. You can check the GitHub pages deployment action list to see the current status of the deployments. |
This looks so close -- I've not tested everything but everything I typically use, including passing additional arguments to the various
|
Yes, it's failed in CI as well. I'm working on a fix... shouldn't be long, sorry! I will draft this until CI is passing. |
Okay, this is ready to go now, hopefully! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing! What an improvement, I hope this will save us many headaches in the future :)
ipython *args: up-deps | ||
env DC_USER="airflow" just ../run \ | ||
--workdir /opt/airflow/catalog/dags \ | ||
{{ SERVICE }} \ | ||
bash -c \'ipython {{ args }}\' | ||
bash -c "ipython ${@:2}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sarayourfriend why was ${@:2}
used here? There doesn't appear to be a positional argument that we need to ignore, and it seems like the first argument after the command provided would be swallowed (for instance ov just catalog/ipython --TerminalInteractiveShell.editing_mode=vi
would no longer work as expected because the editing_mode
argument would be ignored). Was that intentional?
Description
This PR fixes a problem we've run into several times, and never really found a suitable ("nice") solution for.
Without these changes, when we pass just's collected arguments lists (
+args
and*args
type things), the underlying bash call that just makes will cause arguments to be split on any space and follow difficult to track rules about quotation mark escaping. Commands like this, were simply impossible, without abstract levels of quote escaping:The
--conf
argument would have its quotes stripped and turn into{"index_suffix": "init"}
, passed to the underlying command, whichjust
executes using the default shell (bash
in the case ofov
). Bash would interpret this as two separate positional arguments,{index_suffix:
andinit}
, with quotation marks stripped following bash's quotation handling logic.By using
just
'spositional-arguments
setting on these recipes, we're able to pass arguments through using bash's argument array expansion, which preserves quoted arguments as single individual arguments, rather than splitting on all strings.With these changes, the commands above work perfectly and exactly as expected. The quoted arguments are preserved as a single argument, rather than split when
just
compiles the recipe template which drops the argument groups.I chose not to enable positional-arguments globally in each justfile, despite using it almost everywhere with gather args, because I didn't want to cause side effects on any recipes that weren't written with that particular setting in mind. Plus, setting it explicitly on each recipe should make it easier for folks to understand why those recipes behave the way they do compared to others (or a new one they are writing), and will give them something easy to search for in the just documentation. The global setting would be slightly harder to find and know that it was the effective difference.
Testing Instructions
Check out main and try to run the commands above to see what kind of error you get back. This helps make sure you know what goes wrong without these changes. Then, check out this branch, and run the commands above again, and they should work.
CI should pass, which is a decent indicator that I haven't broken anything 😅
Make sure to take an extra look at the recipes that use positional arguments for a final gather argument, but that also have individual named just arguments. For example, the
k6/run
recipe. The$@
split should capture only the positional arguments that aren't handled as regular just template variables.You can test this by echoing the final command instead of running it, to see the expanded arguments. For example, the diff below yields this output when running the
k6/run
recipe (via the root justfile aliask6
):Here we can see that the
pnpm run build
command has the correct namespace and test-file interpolated. Likewise in thek6 run
command. Thek6 run
command also needs to have the additional CLI args passed through betweenrun
and the script location. This is achieved with"${@:3}"
, which takes a slice of the$@
array starting at the 4th position forward. Recall that bash automatically drops from$@
what would be assigned to$0
(that is, the command that was run), unless you address it directly. However, the index still remains. If you echo"${@:0}"
and `"${@:3}" in the recipe, you will see these lines respectivelyAs you can see, while
$@
on its own does not include argv0, when slicing it as an array, you still need to consider it when deciding the index to slice from. As such, the third argument passed tojust
will be in index 3 (position 4) of$@
when sliced, so we slice from 3 onward.Here is a diff you can use to work off and explore the concepts above to better understand
$@
if you would likeChecklist
Update index.md
).main
) or a parent feature branch.ov just catalog/generate-docs
for catalogPRs) or the media properties generator (
ov just catalog/generate-docs media-props
for the catalog or
ov just api/generate-docs
for the API) where applicable.Developer Certificate of Origin
Developer Certificate of Origin