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

Add key-value parameters #482

Closed
user-name-is-taken opened this issue Jan 5, 2024 · 6 comments
Closed

Add key-value parameters #482

user-name-is-taken opened this issue Jan 5, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@user-name-is-taken
Copy link

user-name-is-taken commented Jan 5, 2024

Description

Add the ability to parse key value pairs for parameters. For example I want to be able to do this:

command --flag flagKey=flagValue --flag flagKey2=flagValue2

or this

command argKey=argValue argKey2=argValue2

It would also be good to have allowedKeys and allowedValues lists so the keys and/or values can be validated similar to how flags and args are currently validated.

@user-name-is-taken user-name-is-taken added the enhancement New feature or request label Jan 5, 2024
@DannyBen
Copy link
Owner

DannyBen commented Jan 5, 2024

  1. This is very nonnstandard. Can you share examples of one or two notable command line tools that do it?
  2. This requires a nested dictionary as the receiver: args[--flag][flagKey]=flagValue, which does not exist in bash.

@user-name-is-taken
Copy link
Author

user-name-is-taken commented Jan 6, 2024

Here are some examples:

gcc --param name=value -D name=definition -A predicate=answer
objcopy --set-section-flags sectionpattern=flags      # AND MANY OTHERS
ps -o pid=X,comm=Y
openssh -header name=value
ssh-keygen -M generate -O bits=2048 moduli-2048.candidates
python -X  utf8=0
awk -v var=value -W random=num -W sprintf=num
kubectl config view -o jsonpath='{.users[].name}'
docker [container|network|plugin] ls --filter key=value
docker run --label key=value
docker volume create --driver local --opt type=btrfs --opt device=/dev/sda2
curl --data-urlencode name=val https://example.com
blkid --match-token NAME=value

man --regex -K "\-[a-z]+ [a-z]+\=" will show a more exhaustive list.

Key-value argument options I feel are more common, but are also more difficult to search for. Here are some examples I could think of:

env key=value
set
systemd-notify MAINPID=$PID

Parsing to a dictionary may be unnecessary. Allowing the user to set environment variables as done in the example commands is sufficient for what I'm doing and seems to be standard.

@DannyBen
Copy link
Owner

DannyBen commented Jan 6, 2024

Well - nothing in bashly prevents you from doing this. The only difference is terminology, and who is responsible for parsing the values.

From a framework perspective, your x=y pairs are values, either for a flag, or as an argument:

command  argument=value  --flag key=value      
         +------------+         +-------+
         arg value              flag value

Parsing these further to extract the two sides of the key=value pair is left up to you.

Bashly conforms to this standard:

  • one dash for short flags
  • two dashes for long flags
  • everything else is an argument

and supports these alternative formats:

  • -abc same as -a -b -c
  • -a=arg same as -a arg
  • --flag=arg same as --flag arg

As there is no data structure in bash that can hold this nested dictionary - I am curious, how do you expect to receive this user input?

In a richer language, I would expect --flag key=value to be optionally parsed into a nested hash:

args = {
  '--flag' => {
    'key' => 'value'
  }
}

# or in other words:
args['--flag']['key'] = 'value'

but this cannot be done in bash.

At any rate, I believe you should use one of these options:

  • library functions - to define this type of parsing in one place, as a reusable function.
  • function hooks - in case you always want to run something before function execution (like additional parsing).
  • custom filters - in case you wish to validate the input is in the format you want them to be, with a filter that is not already supported natively.

@user-name-is-taken
Copy link
Author

user-name-is-taken commented Jan 6, 2024

As far as I see it there are 2 good options for how to receive the input:

  1. As environment variables
  2. As an array of [key,value,key,value].... This option may be better because it would allow you to do something like command --flag key=value,key=value,key=value which would also be useful for people who want to do command --flag value1,value2,value3 instead of command --flag value1 --flag value2 --flag value3. If you did this you would probably want to add a "delimiter" option for people who don't want to use commas as their delimiter.

@DannyBen
Copy link
Owner

DannyBen commented Jan 6, 2024

No, none of these are good in my opinion.

  1. Environment variable is just a string - further parsing will be warranted, so you better parse the value of ${args['--flag']} as it was provided already by bashly.
  2. This is yet another invented structure that requires users of bashly to understand, and yet again parse themselves.

Nothing stops you from having any value (with equal signs, commas) in bashly. However, how you parse it and how you store it is up to you, and should be quite easy, especially using one of the facilities I mentioned earlier.

@DannyBen
Copy link
Owner

DannyBen commented Jan 7, 2024

I have created the key-value-pairs example to demonstrate how to easily support key=value pairs either for arguments or flags.

Hope this helps.

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

No branches or pull requests

2 participants