Skip to content

Allow passing additional arguments through to --jq script, just like we can with jq --arg #10263

Open

Description

@0xdevalias

Describe the feature or problem you’d like to solve

There are times where it would be useful to be able to pass through arbitrary arguments to a --jq script without needing to result to hacks such as using shell variables/etc to unsafely inject content into the script.

⇒ jq -h

..snip..
      --arg name value      set $name to the string value;
      --argjson name value  set $name to the JSON value;
      --slurpfile name file set $name to an array of JSON values read
                            from the file;
      --rawfile name file   set $name to string contents of file;
      --args                consume remaining arguments as positional
                            string values;
      --jsonargs            consume remaining arguments as positional
                            JSON values;
..snip..

This would allow us to do things like pass through a user choice from the CLI args to a script that supports multiple options (eg. this script could support both grouped and ungrouped without resorting to "please uncomment the block you want: #659 (comment))

Proposed solution

Allowing more flexibility to safely pass arguments into the --jq scripts without resorting to hacks such as unsafely injecting shell variables into the script (and then needing to manually escape everything else the shell might interpret within the script)

Additional context

See also:

Activity

  1. self-assigned this
    on Jan 17, 2025
  2. BagToad commented on Feb 5, 2025

    @BagToad
    Member

    Sorry for the delay on this one @0xdevalias 🙏

    I think this request makes sense, but I'm going to leave this as needing further investigation from the team for now (similar situation as #10262 (comment))

  3. added and removed on Feb 5, 2025
  4. removed their assignment
    on Feb 5, 2025
  5. 0xdevalias commented on Feb 6, 2025

    @0xdevalias
    Author

    I think this request makes sense, but I'm going to leave this as needing further investigation from the team for now

    @BagToad No worries; thanks for the update :)

  6. 0xdevalias commented on Feb 7, 2025

    @0xdevalias
    Author

    Here's a recent real-world example where I needed to shell out to jq so that I could pass in an arg, rather than being able to use gh's --jq for it:

      checks_json=$(gh pr checks "$pr" --repo "$REPO" --json state,workflow,link | \
        jq --arg workflow "$WORKFLOW_NAME" '
          .[] 
          | select(.workflow == $workflow)
          | {
              workflow,
              state,
              link,
              run_id: (.link | capture("runs/(?<id>\\d+)").id),
              job_id: (.link | capture("job/(?<id>\\d+)").id)
            }
        '
      )
  7. 0xdevalias commented on Sep 22, 2025

    @0xdevalias
    Author

    Today I learned that another way of accessing variables within a jq script (without directly embedding them in the string, or using one of the --args-like options) is by using $ENV / env within the jq script itself:

    • https://jqlang.org/manual/#$env-env
      • $ENV, env

        $ENV is an object representing the environment variables as set when the jq program started.

        env outputs an object representing jq's current environment.

        At the moment there is no builtin for setting environment variables.

    Since gh uses an embedded version of jq, we should check that its supported there.

    GitHub Copilot (gpt-5-mini) seems to think it is:

    Library: gh delegates --jq to the go-gh wrapper (github.com/cli/go-gh/v2/pkg/jq: https://github.com/cli/go-gh/tree/trunk/pkg/jq) which uses itchyny's gojq (https://github.com/itchyny/gojq) under the hood.

    Environment variable support: yes. The go-gh jq wrapper compiles gojq with an environ loader that returns os.Environ(), so environment variables are provided to the gojq evaluator. In practice you can read them from the env object in expressions, e.g.

    • env.MY_VAR
    • or env["MY_VAR"]

    We can confirm that it's compiled with the environment loader here:

    https://github.com/cli/go-gh/blob/e1048dfe671b9aee9367a5e3e720831f4d64b33a/pkg/jq/jq.go#L45-L49

    So that could probably act as a better workaround in the meantime.


    Though more directly related to the topic of this issue, this could be one method of connecting the --arg style variables into gojq:

      • gojq.WithVariables allows to configure the variables which can be used in the query. Pass the values of the variables to code.Run in the same order.

    Based on:

    • https://jqlang.org/manual/#invoking-jq
      • ..snip..

        • --arg name value:

        This option passes a value to the jq program as a predefined variable. If you run jq with --arg foo bar, then $foo is available in the program and has the value "bar". Note that value will be treated as a string, so --arg foo 123 will bind $foo to "123".

        Named arguments are also available to the jq program as $ARGS.named. When the name is not a valid identifier, this is the only way to access it.

        • --argjson name JSON-text:

        This option passes a JSON-encoded value to the jq program as a predefined variable. If you run jq with --argjson foo 123, then $foo is available in the program and has the value 123.

        • --slurpfile variable-name filename:

        This option reads all the JSON texts in the named file and binds an array of the parsed JSON values to the given global variable. If you run jq with --slurpfile foo bar, then $foo is available in the program and has an array whose elements correspond to the texts in the file named bar.

        • --rawfile variable-name filename:

        This option reads in the named file and binds its contents to the given global variable. If you run jq with --rawfile foo bar, then $foo is available in the program and has a string whose contents are to the texts in the file named bar.

        • --args:

        Remaining arguments are positional string arguments. These are available to the jq program as $ARGS.positional[].

        • --jsonargs:

        Remaining arguments are positional JSON text arguments. These are available to the jq program as $ARGS.positional[].

        ..snip..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions