3 from __future__
import absolute_import
4 from __future__
import division
5 from __future__
import print_function
6 from __future__
import unicode_literals
9 Almost every FBCodeBuilder string is ultimately passed to a shell. Escaping 10 too little or too much tends to be the most common error. The utilities in 11 this file give a systematic way of avoiding such bugs: 12 - When you write literal strings destined for the shell, use `ShellQuoted`. 13 - When these literal strings are parameterized, use `ShellQuoted.format`. 14 - Any parameters that are raw strings get `shell_quote`d automatically, 15 while any ShellQuoted parameters will be left intact. 16 - Use `path_join` to join path components. 17 - Use `shell_join` to join already-quoted command arguments or shell lines. 23 from collections
import namedtuple
26 class ShellQuoted(namedtuple(
'ShellQuoted', (
'do_not_use_raw_str',))):
29 Wrap a string with this to make it transparent to shell_quote(). It 30 will almost always suffice to use ShellQuoted.format(), path_join(), 33 If you really must, use raw_shell() to access the raw string. 38 'No need to nest ShellQuoted.' 39 return super(ShellQuoted, cls).
__new__(
40 cls, s.do_not_use_raw_str
if isinstance(s, ShellQuoted)
else s
45 'One does not simply convert {0} to a string -- use path_join() ' 46 'or ShellQuoted.format() instead'.
format(repr(self))
51 self.__class__.__name__, repr(self.do_not_use_raw_str)
57 Use instead of str.format() when the arguments are either 58 `ShellQuoted()` or raw strings needing to be `shell_quote()`d. 60 Positional args are deliberately not supported since they are more 64 return ShellQuoted(self.do_not_use_raw_str.format(**dict(
65 (k,
shell_quote(v).do_not_use_raw_str)
for k, v
in kwargs.items()
70 'Quotes a string if it is not already quoted' 71 return s
if isinstance(s, ShellQuoted) \
76 'Not a member of ShellQuoted so we get a useful error for raw strings' 77 if isinstance(s, ShellQuoted):
78 return s.do_not_use_raw_str
79 raise RuntimeError(
'{0} should have been ShellQuoted'.
format(s))
83 'Joins an iterable of ShellQuoted with a delimiter between each two' 88 'Joins ShellQuoted and raw pieces of paths to make a shell-quoted path' 95 'Do not shell-escape raw strings in comments, but do handle line breaks.' 97 (
raw_shell(c)
if isinstance(c, ShellQuoted)
else c)
void BENCHFUN() replace(size_t iters, size_t arg)
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
def shell_join(delim, it)