Skip to content

Commit

Permalink
Add cURL's boolean options and their aliases
Browse files Browse the repository at this point in the history
by parsing the output of `curl --help`
  • Loading branch information
verhovsky committed Jul 12, 2021
1 parent e396229 commit ce7c870
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 8 deletions.
67 changes: 67 additions & 0 deletions curl_opts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// This script generates a list of all of cURL's options
// by parsing `curl --help`

const { execSync } = require('child_process')

const stdin = execSync('curl --help').toString()

// https://github.com/curl/curl/pull/7378
const actuallyNotBooleanOpts = ['tlspassword', 'stderr', 'request-target', 'quote']

const booleanOpts = []
// Use Map to maintain the same order as `curl --help` to reduce churn in diffs
// TODO: format Map as object instead of having to do it by hand
const aliases = new Map()
for (const line of stdin.split('\n')) {
if (line.startsWith('Usage: ') || !line) {
continue
}
const match = line.match(/^( -(?<short>.),)? +--(?<long>\S+) /)
if (!match) {
console.error('failed to match line:', line)
continue
}
const short = match.groups.short
let long = match.groups.long

// All of cURL's short options have a long form
if (short && !long) {
console.error('short option doesn\'t have long option', line)
}

// If line looks something like
// --user-agent <name>
// or
// --proxy [protocol://]host[:port]
// it's not a boolean option.
const isBooleanOpt = !(line.match(/^( -(?<short>.),)? +--(?<long>\S+) +[[<]/)) && !actuallyNotBooleanOpts.includes(long)
// Should be checked by hand
// console.error((isBooleanOpt + '').padEnd(5), line)

if (long.startsWith('no-')) {
if (!isBooleanOpt) {
console.error('non-boolean option starts with negation prefix "no-"', line)
}
// Yargs' 'boolean-negation' (enabled by default) takes care of these.
//
// There's a -N short option which is short for --no-buffer, but because we remove the
// "no-" here, -N is incorrectly aliased to --buffer instead.
// This is okay because we don't do anything with --buffer's value, we just need yargs to
// parse it as a boolean option.
// https://github.com/yargs/yargs-parser/issues/406
long = long.slice(3)
}

if (short && long) {
aliases.set(short, long)
}
if (isBooleanOpt) {
booleanOpts.push(long)
}
}

console.dir({
boolean: booleanOpts,
alias: aliases,
configuration: {}
}, { maxArrayLength: null })
179 changes: 171 additions & 8 deletions util.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,181 @@ const parseCurlCommand = curlCommand => {
curlCommand = curlCommand.replace(/ -Xnull/, ' ')
curlCommand = curlCommand.trim()

// Parse with some understanding of the meanings of flags. In particular,
// boolean flags can be trouble if the URL to fetch follows immediately
// after, since it will be taken as an argument to the flag rather than
// interpreted as a positional argument. Someone should add all the flags
// likely to cause trouble here.
// Parse with some understanding of the meanings of flags.
const parsedArguments = yargsParser(
curlCommand,
// This is generated by curl_opts.js
{
boolean: ['I', 'head', 'compressed', 'L', 'k', 'silent', 's'],
alias: { H: 'header', A: 'user-agent' },
configuration: { 'parse-bash-ansi-c-strings': true }
// boolean flags can be trouble if the URL to fetch follows immediately
// after, since yargs will interpret the URL as an argument to the flag
// rather than interpreting it as a positional argument.
boolean: [
'anyauth',
'append',
'basic',
'cert-status',
'compressed',
'compressed-ssh',
'create-dirs',
'crlf',
'digest',
'disable',
'disable-eprt',
'disable-epsv',
'disallow-username-in-url',
'fail',
'fail-early',
'false-start',
'ftp-create-dirs',
'ftp-pasv',
'ftp-pret',
'ftp-skip-pasv-ip',
'ftp-ssl-ccc',
'ftp-ssl-control',
'get',
'globoff',
'haproxy-protocol',
'head',
'help',
'http0.9',
'http1.0',
'http1.1',
'http2',
'http2-prior-knowledge',
'ignore-content-length',
'include',
'insecure',
'ipv4',
'ipv6',
'junk-session-cookies',
'list-only',
'location',
'location-trusted',
'manual',
'metalink',
'negotiate',
'netrc',
'netrc-optional',
'next',
'alpn',
'buffer',
'keepalive',
'npn',
'sessionid',
'ntlm',
'ntlm-wb',
'path-as-is',
'post301',
'post302',
'post303',
'progress-bar',
'proxy-anyauth',
'proxy-basic',
'proxy-digest',
'proxy-insecure',
'proxy-negotiate',
'proxy-ntlm',
'proxy-ssl-allow-beast',
'proxy-tlsv1',
'proxytunnel',
'raw',
'remote-header-name',
'remote-name',
'remote-name-all',
'remote-time',
'retry-connrefused',
'sasl-ir',
'show-error',
'silent',
'socks5-basic',
'socks5-gssapi',
'socks5-gssapi-nec',
'ssl',
'ssl-allow-beast',
'ssl-no-revoke',
'ssl-reqd',
'sslv2',
'sslv3',
'styled-output',
'suppress-connect-headers',
'tcp-fastopen',
'tcp-nodelay',
'tftp-no-options',
'tlsv1',
'tlsv1.0',
'tlsv1.1',
'tlsv1.2',
'tlsv1.3',
'tr-encoding',
'trace-time',
'use-ascii',
'verbose',
'version',
'xattr'
],
alias: {
a: 'append',
E: 'cert',
K: 'config',
C: 'continue-at',
b: 'cookie',
c: 'cookie-jar',
d: 'data',
q: 'disable',
D: 'dump-header',
f: 'fail',
F: 'form',
P: 'ftp-port',
G: 'get',
g: 'globoff',
I: 'head',
H: 'header',
h: 'help',
0: 'http1.0',
i: 'include',
k: 'insecure',
4: 'ipv4',
6: 'ipv6',
j: 'junk-session-cookies',
l: 'list-only',
L: 'location',
M: 'manual',
m: 'max-time',
n: 'netrc',
':': 'next',
N: 'buffer',
o: 'output',
'#': 'progress-bar',
x: 'proxy',
U: 'proxy-user',
p: 'proxytunnel',
Q: 'quote',
r: 'range',
e: 'referer',
J: 'remote-header-name',
O: 'remote-name',
R: 'remote-time',
X: 'request',
S: 'show-error',
s: 'silent',
Y: 'speed-limit',
y: 'speed-time',
2: 'sslv2',
3: 'sslv3',
t: 'telnet-option',
z: 'time-cond',
1: 'tlsv1',
T: 'upload-file',
B: 'use-ascii',
u: 'user',
A: 'user-agent',
v: 'verbose',
V: 'version',
w: 'write-out'
},
configuration: {}
}

)

let cookieString
Expand Down

0 comments on commit ce7c870

Please sign in to comment.