-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathresholve.1
268 lines (268 loc) · 8.57 KB
/
resholve.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
.Dd September 03, 2023
.Dt RESHOLVE 1
.Os
.Sh NAME
.Nm resholve
.Nd resolve external command/script references in shell scripts
.Sh SYNOPSIS
.Nm
.Op Ar options
.Ar script
.No ...
.Nm
.Op Ar options
.No <
.Ar script
.Sh DESCRIPTION
.Nm
replaces bare references (subject to a PATH search at runtime) to external commands and scripts with absolute paths.
.Pp
This small super-power helps ensure script dependencies are declared, present, and don't unexpectedly shift when the PATH changes.
.Pp
.Nm
is developed to enable the Nix package manager to package and integrate Shell projects, but its features are not Nix-specific and inevitably have other applications.
.Sh REQUIRED ARGUMENTS
.Bl -tag -width 1n
.It Ar script
.Bl -bullet -compact
.It
given as input on <stdin>, write resolved script to <stdout>
.It
as a path, write to
.Ar script.resolved
(or
.Ar script
if
.Fl Fl overwrite
is used)
.El
.It Fl Fl interpreter Cm none | Ar path
The absolute interpreter
.Ar path
for the script's shebang. The special value
.Cm none
ensures there is no shebang.
See
.Xr execve 2
.It Fl Fl path Ar path | Pf RESHOLVE_PATH= Ar path
A PATH-format list of directories and/or files to resolve external dependencies from.
You may also use aliases
.Fl Fl inputs
or
.Ev RESHOLVE_INPUTS
.El
.Sh OPTIONS
.Bd -literal
.Fl Fl fake Ar directives
.Fl Fl fix Ar directives
.Fl Fl keep Ar directives
.Ed
.Bd -ragged -offset 3n -compact
Adjust how resolution is performed. See
.Sx CONTROLLING RESOLUTION .
.Ed
.Bd -literal
.Fl Fl lore Ar directory
.Fl Fl execer Ar statements
.Fl Fl wrapper Ar statements
.Ed
.Bd -ragged -offset 3n -compact
Adjust when nested resolution is performed. See
.Sx NESTED RESOLUTION .
.Ed
.Bl -tag -width x
.It Fl Fl overwrite
Resolve script in-place (useful for out-of-tree builds).
.It Fl Fl help
Show brief syntax help.
.It Fl Fl version
Show version number.
.El
.Sh CONTROLLING RESOLUTION
If resholve can't figure something out, you can often help it along with a mix
of fake, fix, and keep
.Ar directives Ns
\&. \
If quoted, directives can be separated
by a space:
.Eo ' Ns Ar directive Ns [
.Ar directive ] Ns ... Ec Ns '
.Bl -tag -width 1n
.It Fl Fl fake Eo ' Ns Ar directives Ec Ns ' | Pf RESHOLVE_FAKE= Eo ' Ns Ar directives Ec Ns '
Pretend some commands exist. \
There are 2 directive forms:
.Bl -tag -width 1n
.It Ar type : Ns Ar name Ns [; Ns Ar name ] Ns ...
Treat
.Ar name(s)
of
.Ar type
as defined;
.Ar type
is the full word or first letter of:
.Ar a Ns lias Ns
,
.Ar b Ns uiltin Ns
,
.Ar e Ns xternal Ns
,
.Ar f Ns unction Ns
,
.Ar k Ns eyword Ns
, or
.Ar s Ns ource Ns
.It Ex: Fl Fl fake No 'f:setUp;tearDown builtin:setopt source:/etc/bashrc'
.El
.It Fl Fl fix Eo ' Ns Ar directives Ec Ns ' | Pf RESHOLVE_FIX= Eo ' Ns Ar directives Ec Ns '
Fix things we can't auto-fix/ignore. \
There are 5 directive forms:
.Bl -tag -width 1n
.It $ Ns Ar variable : Ns Ar command No (Note: $ may need escaping )
replace parameter expansions of
.No $ Ns Ar variable
with
.Ar command
.It Ar absolute_path
treat
.Ar absolute_path
as a bare reference that must be resolved
.It Cm aliases
resolve into alias definitions
.It Ar command
(nix-only) ignore security-wrapper error for
.Ar command
.It Ex: Fl Fl fix No 'aliases $GIT:gix /bin/bash'
.El
.It Fl Fl keep Eo ' Ns Ar directives Ec Ns ' | Pf RESHOLVE_KEEP= Eo ' Ns Ar directives Ec Ns '
Keep things we can't auto-fix/ignore. \
There are 6 directive forms:
.Bl -tag -width 1n
.It Ar command : Ns $ Ns Ar variable Ns [; Ns $ Ns Ar variable ] Ns ... No (Note: $ may need escaping )
ignore
.No $ Ns Ar variable
in the arguments to
.Ar command
.It $ Ns Ar variable No (Note: $ may need escaping )
ignore
.No $ Ns Ar variable
or
.No $ Ns Ar {variable}
used as all or part of a first word (command)
.Pp
Such as: `$GIT status` or `$BUSYBOX/ls`
.It Ar absolute_path
ignore a specific
.Ar absolute_path
.It Ar ~/path
ignore a specific
.Ar home-relative_path
.It Ar ./path
ignore a specific
.Ar PWD-relative_path
.It Ex: Fl Fl keep No 'source:$HOME /etc/bashrc ~/.bashrc'
.El
.El
.Sh NESTED RESOLUTION
Initially, resolution of commands in the arguments to command-executing commands was limited to one level for a hard-coded list of builtins and external commands. Version 0.6.0 (June 2021) adds recursive resolution.
.Pp
This task is complex. The main components of the current approach are:
.Bl -bullet
.It
To pick out a sub-command among other flags, options, and arguments,
.Nm
has a small collection per-command rules.
.Pp
This collection will need to grow, but I only intend to include fairly-common commands. I'm not sure yet if there will be a user-facing mechanism for customizing this; I'm not sure the current implementation is fully-baked, and I'd like to see how often it's needed. If you encounter instances of commands you think deserve explicit support, please report them.
.It
To meet the goal of blocking builds when all dependencies are not known,
.Nm
needs a way to discover command-executing executables that it lacks per-command rules for (a sub-command might be present, but it is unable to disambiguate).
.Pp
The discovery process is outsourced. Only the result--a directory of "lore"--is passed via the
.Fl Fl lore
flag or
.Ev RESHOLVE_LORE .
.Pp
.Nm
requires lore for every executable it finds in a script. \
See
.Sx Lore
for more on this format.
.El
.Pp
Nested resolution is much more rigorous--but (at least for now) it adds complexity that some users will need to wrestle with.
.Ss Lore
.Pp
Outsourcing discovery makes it easy to save/cache this lore and avoid repeating expensive work each run. \
It also makes it possible to hand-write or even generate it with tools that meet your own needs.
.Pp
Most users of the Nix API should be spared from needing to understand lore in detail. \
It automatically uses binlore (https://github.com/abathur/binlore) to generate lore for the executables in each input's bin/ directory, merge them into a combined copy, and pass it via RESHOLVE_LORE. \
If you find mis-identified executables, please report them to the binlore project.
.Pp
On the command-line, you can supply lore directly with two flags:
.Bl -tag -width x
.It Fl Fl execer Eo ' Ns Ar directives Ec Ns ' | Pf RESHOLVE_EXECER= Eo ' Ns Ar directives Ec Ns '
Each execer-lore directive indicates whether an executable sub-executes its arguments with a verdict:abspath pair, where verdict is one of can, cannot, or might. \
This information enables
.Nm
to raise an error when it encounters a command with a can|might verdict unless it has rules for figuring out whether the invocation includes a nested command.
.It Fl Fl wrapper Eo ' Ns Ar directives Ec Ns ' | Pf RESHOLVE_WRAPPER= Eo ' Ns Ar directives Ec Ns '
Each wrapper-lore directive indicates whether one executable is just an exec wrapper for another with a wrapper_abspath:wrapped_abspath pair.
.Nm
uses this information to substitute the wrapped executable's verdict whenever it encounters a wrapper. \
(Executables are often wrapped in nixpkgs, but it's also common in packages. In gnugrep, for example, both egrep and fgrep are wrappers of grep.)
.El
.Sh ENVIRONMENT
Most options can also be passed via environment variables. For example,
all of the following are supported:
.Pp
.Bl -tag -width "RESHOLVE_INTERPRETER" -compact
.It RESHOLVE_INTERPRETER
.It RESHOLVE_PATH
.It RESHOLVE_FAKE
.It RESHOLVE_FIX
.It RESHOLVE_KEEP
.It RESHOLVE_LORE
.It RESHOLVE_EXECER
.It RESHOLVE_WRAPPER
.It RESHOLVE_PROLOGUE
.It RESHOLVE_EPILOGUE
.It RESHOLVE_OVERWRITE
.El
.Sh EXIT STATUS
.Ex -std
.Pp
Error statuses are not yet systematic or stable (use them if they help you--but expect changes). Generally:
.Bl -tag -width "xx"
.It Sy 1
non-resholve error (ex: from the OSH parser)
.It Sy 2
invocation/argument error
.It Sy 3+
resolution error
.El
.Sh EXAMPLES
Basic invocations:
.Bd -literal
$ resholve --interpreter "$(which bash)" --path "$PATH" script.sh
$ resholve --interpreter "$(which bash)" --path "$PATH" < script.sh
$ resholve --interpreter "$(which bash)" --path "$PATH" script1.sh script2.sh
.Ed
.Sh LIMITATIONS
.Bl -bullet
.It
.Nm
is built on the bash-compatible OSH parser (from the Oil shell project). It can't handle any script OSH can't parse.
.It
Support for non-bash shells is a happy side-effect of how similar POSIX-ish shell languages are. If you run into a parse error with any non-bash syntax, your only real option is changing the script.
.It
If you run into a parse error with valid bash syntax, check Oil's issue tracker (https://github.com/oilshell/oil/issues) to see if the issue is known and whether it is likely to be fixed. If it won't be fixed, your only recourse is changing the script.
.El
.Sh "SEE ALSO"
.Xr bash 1 ,
.Xr osh 1 ,
.Xr sh 1 ,
.Xr execve 2
.Sh AUTHORS
.An Travis A. Everett Aq Mt [email protected]