[HN Gopher] Pantheon: Parsing command line arguments
       ___________________________________________________________________
        
       Pantheon: Parsing command line arguments
        
       Author : lukastyrychtr
       Score  : 12 points
       Date   : 2024-10-05 08:20 UTC (1 days ago)
        
 (HTM) web link (traxys.me)
 (TXT) w3m dump (traxys.me)
        
       | IgorPartola wrote:
       | Ages ago I was writing a lot of daemons in Python. They all
       | needed to be well behaved UNIX processes: they needed to be able
       | to background themselves, write a PID file atomically and not
       | start a second copy of a PID file for a live process existed,
       | etc.
       | 
       | The main thing I wanted them to do is to behave well with
       | configuration both from a config file and from command line
       | arguments. Lots of libraries exist for either but none existed
       | for both: I wanted to have something that would be able to
       | correctly pull something like the PID file location from a config
       | file but also be able to be overwritten by a command line
       | argument. I also wanted to be as simple to use as possible. The
       | code is hosted at https://github.com/ipartola/groper
       | 
       | I am not sure if in today's world of systemd this is useful at
       | all. The code probably needs clean up since it was written to be
       | compatible with both Python 2 and 3 at the time. But I have to
       | say that I haven't seen anything like this since I wrote this
       | code. If there is interest I can take a look at modernizing this.
       | 
       | Also in general I appreciate programs, especially daemons that
       | are "well behaved": a sensible config file format, sensible
       | arguments parsing, sane defaults, does not background itself
       | without an explicit configuration to do so, logs to stdout and
       | stderr by default. I feel like there is less and less emphasis on
       | stuff like this lately.
        
         | bbkane wrote:
         | I'm writing something similar for Go: passed flags override env
         | vars, which override the config file, which overrides defaults
         | set in the code.
         | 
         | With 4(!) sources of configuration to keep track of, I've also
         | made --help print out current values and the source for it
         | (i.e. the password came from an environment variable and the
         | base_url came from a config file).
         | 
         | It's been tremendously satisfying to use this library for my
         | own projects, as everything works exactly the way I expect (and
         | if it doesn't I change the library).
         | 
         | Code at https://github.com/bbkane/warg if you want to compare
         | it to your library :)
        
         | o11c wrote:
         | It's definitely a field that there's still need in. I recently
         | started writing yet another argument parser, with all the
         | knowledge of my prior attempts ...
         | 
         | One thing I'm really starting to lean toward is the idea of
         | using a bespoke data file to actually define the options, and
         | having that generate the code.
         | 
         | My key observation is that actually parsing the arguments is
         | kind of secondary; the most important thing is to be able to
         | generate good --help text (I've collected many samples and want
         | to be flexible enough for them all). And for config files, to
         | be able to generate a commented "default config" + merge with
         | given command-line arguments. A GUI (or at least a JSON API for
         | the web) for interactive selection, as well as tab-completion
         | for the CLI, are also important.
         | 
         | Now, I'm currently halfway through implementing a knockoff of
         | the Unicode line-breaking algorithm so that people can
         | translate my help text properly (for a program nobody else will
         | probably ever use) ... I've basically forgotten the project
         | that needed the argument parser.
         | 
         | There are actually more sources than those you mentioned:
         | 
         | * hard-coded defaults
         | 
         | * config files
         | 
         | * ENV=variables (may be a single TOOLNAME_OPTS variable or
         | separate per-option variables)
         | 
         | * --options and @files (may be nested, beware cycles)
         | 
         | Beware of lists (default is port 8080, but I want 8000 and 8001
         | - wait, 8008 instead).
         | 
         | And parsing also needs to handle more than just GNU style
         | arguments. Single-dash long options are pretty common.
         | 
         | Some tricky tools that most libraries can't handle: chmod, dd,
         | more, ps, tar.
         | 
         | For fused arguments, make sure your testsuite includes errors
         | for `-a-b` and `-a-`.
        
           | IgorPartola wrote:
           | Those are all great points. I do like the idea of a stand-
           | alone file. Especially since then you could do code
           | generation and if you care about doing type hints you now
           | could.
           | 
           | groper uses getopt built into the Python standard library as
           | well as the ini file parser. This way there are no
           | dependencies on external stuff. And it automatically
           | generates help text with all the options and can
           | automatically generate a sample config file with all the
           | default options hard coded in the code. Those two things have
           | made it invaluable for me when I used it extensively. I think
           | adding environment variables to the mix would be a good idea.
           | 
           | I am not sure what you mean by --options. By @files do you
           | mean like what curl can do? If so I have always solved that
           | by just doing something like --in or --file or just making
           | the input file the last argument to the command.
           | 
           | Lists are definitely tricky but if I recall correctly the
           | version I put on GitHub allows you to specify the same option
           | multiple times in order to get a list but I'm not sure that's
           | the cleanest way to do this. Possibly having custom option
           | types that do splitting on a delimiter for something like
           | port numbers could be good.
           | 
           | In either case it's good to know that this space still could
           | use some work because that'll be the motivation for me to
           | dust off this project.
        
       ___________________________________________________________________
       (page generated 2024-10-06 23:01 UTC)