-
Notifications
You must be signed in to change notification settings - Fork 53
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
docopts API changes proposal #7
Comments
I really enjoy the propose API. One thing that I would love is self-contained bash file with no install-time python dependencies. This could be achieved à-la "make-dist" target where the python deps are embedded into a single bash file with HEREDOC. |
Could you paste a link to the code 'make-link' you mention, please? Yes handling the dependencies can be tricky, but interesting. Generally when bash programming is involving array, I switch to other languages. But for legacy code, or just is because it would be fun to have a docopt lib in every language. It can be done. As mentioned in #5 I will create a new branch with an API_proposal.md file for writing the API to reach. Array syntax is ugly in bash. |
bash syntax as a whole is ugly, I don't mind iterating over arrays. declare -a FILES=()
for ((i = 0; i < ${args[<src>,#]}; ++i)); do
FILES+=(${args[<src>,$i]})
done As for the make-dist, I just would that |
What is make-dist? |
In fact the current API (docopts 0.6.1+fix) is a quite good shell centric behavior:
I was looking what was the colon (:) in the argument format? But it's simply parsed by docopt. :-) The behavior seems already providing mostly what we expect. Just add some shell wrappers and helpers. I'm translating all examples available here into shell plus adding unit tests. |
I pushed an experimental version here which embed all code in a single file. |
I meant |
OK, for "make dist". I commited a build.sh which do it. Seems working, and effective. I also coded a --auto. For laziness repetitive shell script. It is used like this: #!/bin/bash
# Usage: doit [cmd] FILE...
#
# do somethingdo something
source ../docopts.sh --auto "$@"
for a in ${!args[@]} ; do
echo "$a = ${args[$a]}"
done I have to complete the doc, change a little the python docopts, and it seems working for now. |
Small nitpick https://github.com/Sylvain303/docopts/blob/shell-api-v2/docopts.sh#L30 Let the user decides if he wants python or python3. |
Yep of course, works also with legacy python version on legacy server… corrected. |
👍 |
I made a pull request, today #8 … |
secondary nitpick this way of doing thing https://github.com/Sylvain303/docopts/blob/shell-api-v2/docopts.sh#L30. You don't need sed here. I'd create a function function print_python_code() {
# auto generated
cat <<< __EOF__
content of docopt and docopts
__EOF__
} I find this more shell-ish and parseable by human. |
about how I chose the python <(sed -n -e '/^### EMBEDDED/,$ s/^#> // p' "$docopt_sh_me") "$@" instead of something: function print_python_code() I didn't chose this way because of the Embedding the code inside the shell script is cool, and challenging. Using <() bash's operator gives a file descriptor. And filtering by sed is cheap and fast, and lazy: I don't have to handle the temporary file. I also fall in love (tombé en amour) with this operator when I discovered it, so I share it for curious code reader: diff /etc/hosts <(ssh remote-server cat /etc/hosts) human readable… advanced bash shell scripting is a bit ugly, and not well human readable. (See bash completion's code to become as master) The embedded python is not indented to be edited in place of course. It could be a base64 block, but I don't want extra forking / piping commands. Saying that, I may try your suggestion because sed's oneliner are fragile. Also, some users may ask for compatibly with other shell, that supports different syntax. BSD's default sed may be not GNU sed for example. Thanks for your comment. |
I did some tests: builder not modified and of course broken in both branches. This one keeps the code at the end of the file docopts.sh but breaks --auto. A bash limitation that eval the code as it sources it, I suppose. So the function is not defined yet. This one works but, the code is not at the end of the file, it also disturbs code reading (big chunck of alien's code in the middle) and syntax highlighting. Having code in the middle will also complicate the build.sh to match two delete boundaries… I'm not convinced, by the But when the PR will be accepted, may be creating a dedicated issue, on this. |
Your first try can be solved by wrapping def main() {
if [[ "$1" == "--auto" ]] ; then
shift
declare -A args
eval "$(docopt_auto_parse "${BASH_SOURCE[1]}" "$@")"
fi
} And then, your last line will simply be a call to |
I don't think so:
That's why I used global instructions here for |
I wanted to ask two things:
Thanks |
@CristianCantoro I worked on a Proof of Concept of the proposed API. The go version with JSON support is disappointing in term of performance, for now. Successive call take a lot of time to parse So I'm also waiting for some return or other proposal. It is really open, be creative! And yes I will make a backward-compatibile version with the current API ( Most of the annoying thing I see in the current API, is using But it may be really personal feeling. My PoC handle both old an new API, and for this to work some tricks are involved to truncate argument for the parser. docopt lib don't allow both to work together and The actual go version is also stand-alone, no need to I'm dropping the idea to require I think this issue is too old, I need to sum-up proposal into a new dedicated issue. Regards, |
Hi @Sylvain303, thanks for the explanation. Let me begin by saying a couple of things:
@Sylvain303 said:
I am not sure I am that worried about that, personally I typically read the values of your CLI options at the beginning of my scripts and then I assign them to some variables to be ready for use. Is the performance that bad that it would impact even this use case?
What about having docopts produce the code to create (via In this example the function name is eval 'function arguments() {
local __all=false
local _b=false
local __foo=
local __help=false
local __version=false
local parname=$(echo "$1" | sed '\''s/-/_/g'\'')
echo "${!parname}"
}' and then you can use it like this:
Note that in this way the mangled variables are all confined withing the I have put an example here: example_function.sh. This is the basic idea, it remains to be seen if it works with list of arguments. Also, the sed expression above should be fixed to just convert the initial dashes
I can live with it, what I have found difficult at first was how to pass effectively the usage string to docopts, in the end I settled with defining a variable using a here document (see example.sh#L5), which is quite similar to what you do in your example, defining the
I think it is better not to be required to source C |
I close this issue and will republish some new proposal, as JSON test was to slow to be helpful in what I tested.. This issue is now too old, it's time for something new. Thanks for your interest. |
following #5
I had a look on the API proposed in the branch develop (See man ./docopts.1). Which is quite different from the current docopts API.
Old API (current)
current API in branch develop, generating temporary files for each option on the filesystem
I think about a new API, more like the python's library could be quite nice to have.
Something like the following code snippet, (to be completed…)
Specifying the associative array for $args and some shell centric behavior have to be considered, too.
and may be some shell helpers too:
Please comment and suggest. I will develop and propose some versions.
You may also be tempted to say: "bash is not capable to handle simply the complexity of the JSON parsed structure behind docopt. Consider rewriting your shell script directly in python…"
The text was updated successfully, but these errors were encountered: