Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] Unifying option passing conventions in the PMS
Date: Mon, 01 Sep 2014 10:55:05
Message-Id: 20140901125249.69e80f39@pomiot.lan
1 Hello again, developers.
2
3 Don't worry, this is the last e-mail I was planning to send :).
4 Currently, PMS doesn't have any convention for option passing.
5 In particular, we have:
6
7 a. has_version and best_version having long '--host-root' (no
8 parameters).
9
10 b. dodoc, doheader, doins have short '-r' option. docompress has short
11 '-x' option.
12
13 c. dohtml has whole lot of short options, some taking parameters.
14
15 d. doman has -i18n=LANG old-style long option.
16
17 (econf, emake, einstall are pass-through so they don't count)
18
19 In other words, it's an inconsistent mess. I think we should set up
20 a few basic rules for functions in PMS, and hopefully spread them into
21 eclasses as well.
22
23
24 While normally I'd suggest following getopt_long() as close
25 as possible, I don't think this is the best way here since:
26
27 1. I'm not ware of any sane, dep-free, portable way of reusing
28 getopt_long() from bash.
29
30 2. Implementing the whole option parsing would introduce a lot of extra
31 code for each function.
32
33 3. Most of the helpers take no or at most a single option.
34
35 4. We can assume that ebuilds are supposed to use canonical command
36 lines.
37
38
39 That said, I suggest the following basic rules:
40
41 1. Options must precede positional parameters on the command-line.
42 Interspersing options and positional parameters is not allowed.
43
44 2. Each short option must be specified as a separate parameter.
45 Specifying multiple short options in one parameter is not allowed.
46
47 3. If a helper supports any options, then the positional parameters may
48 not resemble options. In particular, passing any positional parameters
49 beginning with '-' is not allowed.
50
51 4. [optionally] If a helper supports any options, '--' option may be
52 used to terminate option parsing. All parameters following it will be
53 treated as positional parameters, and rule 3. doesn't apply to
54 parameters following '--'.
55
56 5. Helpers should define both short and long variants for each option
57 they provide.
58
59 6. If the option takes a parameter, it should be passed as
60 the parameter immediately following it. Concatenating option
61 and the parameter is not allowed. Interspersing multiple options
62 and their parameters is not allowed.
63
64
65 Explanation and rationale;
66
67 (1) Interspersing options and positional parameters is not that useful
68 in scripts. It's helpful in interactive shell when you may forget to
69 pass some option and add it after files but in ebuild you'd rather use
70 the canonical option order. It would also decrease readability.
71
72 Disallowing this allows us to use very simple parsers for single-option
73 commands, like:
74
75 if [[ ${1} == -r ]]; then ...; fi
76
77 (2) Specifying multiple options via a single parameter (e.g. '-ab' for
78 '-a -b') makes parsing quite hard and also decreases readability. I'd
79 dare say simplicity in using the 'longer' form outweighs the gain of
80 shortening command lines.
81
82 That said, most of our commands take no more than a single option :).
83
84 (3) This one is quite understandable but it may become blurry with all
85 the restrictions given above. In particular, one may assume that
86 'foo -a bar -b' will treat '-b' as positional parameter. Since this
87 will be very unreadable and unpredictable, we should ban that use.
88
89 Similarly, to keep option parsing simple we may not implement any
90 specific checks for invalid options. Then, 'foo -a -b' would treat
91 unsupported '-b' option as a positional parameter, and we don't want to
92 support that.
93
94 The extra 'if a helper supports any options' is mostly supposed to
95 handle output helpers like elog that may accidentally start a line with
96 '-'. Since they are not supposed to handle any options, and mostly
97 resemble the 'echo' built-in (thinking of the POSIX one, not the ugly
98 bashism), I don't feel like we should require '--' in them.
99
100 (4) I don't have a strong opinion about that. It is rather unlikely
101 that we will ever need to support positional parameters that start with
102 '-' but supporting this when option parsing is in-place is rather
103 simple:
104
105 if [[ ${1} == -- ]]; then shift; break; fi
106
107 As for the functions that are more likely to meet rogue '-', i.e. elog
108 and friends, I think we oughtn't support option parsing at all. For
109 these functions, '--' will be treated literally -- that's the reason
110 for the 'if a helper supports any option' clause.
111
112 (5) This is pretty much a open field for dicussion. Implementing more
113 than one alias for a option is rather straightforward. Either:
114
115 [[ ${1} == -r || ${1} == --recursive ]]
116
117 or:
118
119 -r|--recursive) ...;;
120
121 in a case statement.
122
123 Most of the developers will prefer the short forms. However, the long
124 forms are more readable and could be useful in case of the more
125 confusing options. For example, 'die --respect-nonfatal' is the only
126 sane way of explaining what the option does I can think of ;).
127
128 If developers don't feel like we ought to support both long and short
129 options, we should probably go for short options only.
130
131 (6) Long story short, '-a foo -b bar', not '-afoo -bbar' and definitely
132 not '-a -b foo bar' :). Because they are confusing and very confusing,
133 respectively.
134
135 Additionally, we may not want to support '--foo=bar' to avoid extra
136 code in option parsing, e.g.:
137
138 --foo) sth=${2}; shift;;
139 --foo=*) sth=${1#*=};;
140
141 However, I don't have a strong opinion on this since it's relatively
142 simple to achieve.
143
144
145 What are your thoughts?
146
147 --
148 Best regards,
149 Michał Górny

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies