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 |