-
Notifications
You must be signed in to change notification settings - Fork 2k
[CS2] Add #! support for executable scripts on Linux. #3946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
6c48af3
221dfc4
988f2af
fa3fe8b
aee066f
3c1fb7f
a10c653
d5e8d74
062fe62
c929ed9
b1acc4b
f3ea781
200126f
7970e44
bc92ff3
7e0d9e0
0a05e0c
3c49c8e
0e1f27e
42434b4
15eb624
bb9366c
e1bcf84
7bc6591
7c4723d
768ada6
79c0e56
ca7ad49
daa5f4d
c75e2b1
23f31c6
d495841
bafa82f
9247444
b509b46
31bbeb2
7abe19c
3944d94
f41463d
356f3ad
7c17e23
179687d
5b9b786
8448a77
14df734
b9291ae
f306859
4093574
4856fd6
f7e8c2b
6fb80c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,37 +25,26 @@ exports.OptionParser = class OptionParser | |
# parsers that allow you to attach callback actions for every flag. Instead, | ||
# you're responsible for interpreting the options object. | ||
parse: (args) -> | ||
options = arguments: [] | ||
skippingArgument = no | ||
originalArgs = args | ||
args = normalizeArguments args | ||
for arg, i in args | ||
if skippingArgument | ||
skippingArgument = no | ||
continue | ||
if arg is '--' | ||
pos = originalArgs.indexOf '--' | ||
options.arguments = options.arguments.concat originalArgs[(pos + 1)..] | ||
state = | ||
argsLeft: args[..] | ||
options: {} | ||
while (arg = state.argsLeft.shift())? | ||
if (arg.match(LONG_FLAG) ? arg.match(SHORT_FLAG))? | ||
tryMatchOptionalArgument(arg, state, @rules) | ||
else if (multiMatch = arg.match(MULTI_FLAG))? | ||
# Normalize arguments by expanding merged flags into multiple | ||
# flags. This allows you to have `-wl` be the same as `--watch --lint`. | ||
normalized = "-#{multiArg}" for multiArg in multiMatch[1].split '' | ||
state.argsLeft.unshift(normalized...) | ||
else | ||
# the CS option parser is a little odd; options after the first | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comments become the annotated source, so please use sentence case (capitalize first word, use periods). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, will fix. The first two lines are actually from the original source, so I wasn't sure whether I should change them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. Never too late to fix things 😄 |
||
# non-option argument are treated as non-option arguments themselves. | ||
# executable scripts do not need to have a `--` at the end of the | ||
# shebang ("#!") line, and if they do, they won't work on Linux | ||
state.argsLeft.unshift(arg) unless arg is '--' | ||
break | ||
isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG)) | ||
# the CS option parser is a little odd; options after the first | ||
# non-option argument are treated as non-option arguments themselves | ||
seenNonOptionArg = options.arguments.length > 0 | ||
unless seenNonOptionArg | ||
matchedRule = no | ||
for rule in @rules | ||
if rule.shortFlag is arg or rule.longFlag is arg | ||
value = true | ||
if rule.hasArgument | ||
skippingArgument = yes | ||
value = args[i + 1] | ||
options[rule.name] = if rule.isList then (options[rule.name] or []).concat value else value | ||
matchedRule = yes | ||
break | ||
throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule | ||
if seenNonOptionArg or not isOption | ||
options.arguments.push arg | ||
options | ||
state.options.arguments = state.argsLeft[..] | ||
state.options | ||
|
||
# Return the help text for this **OptionParser**, listing and describing all | ||
# of the valid options, for `--help` and such. | ||
|
@@ -99,14 +88,22 @@ buildRule = (shortFlag, longFlag, description, options = {}) -> | |
isList: !!(match and match[2]) | ||
} | ||
|
||
# Normalize arguments by expanding merged flags into multiple flags. This allows | ||
# you to have `-wl` be the same as `--watch --lint`. | ||
normalizeArguments = (args) -> | ||
args = args[..] | ||
result = [] | ||
for arg in args | ||
if match = arg.match MULTI_FLAG | ||
result.push '-' + l for l in match[1].split '' | ||
else | ||
result.push arg | ||
result | ||
addArgument = (rule, options, value) -> | ||
options[rule.name] = if rule.isList | ||
(options[rule.name] ? []).concat value | ||
else value | ||
|
||
tryMatchOptionalArgument = (arg, state, rules) -> | ||
for rule in rules | ||
if arg in [rule.shortFlag, rule.longFlag] | ||
if rule.hasArgument | ||
value = state.argsLeft.shift() | ||
if not value? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, will change. |
||
throw new Error "#{arg} requires a value, but was the last argument" | ||
else | ||
value = true | ||
|
||
addArgument(rule, state.options, value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid parentheses when possible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, will fix. |
||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason to avoid the implicit return? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If not, it would eventually leave the for loop and hit the throw statement. This was dealt with previously by keeping a boolean testing whether or not the rule was matched; I thought this was cleaner here since we don't then loop over the rest of the rules if we successfully match one. |
||
|
||
throw new Error "unrecognized option: #{arg}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve been trying to avoid assignments inside conditionals. Can we just use
for arg in args
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I think about it, I think we can just do a single pass over the arguments beforehand to 1. group arguments with values (
-o [dir]
) 2. explode combined options (e.g.-abck
) 3. identify the first non-optional argument, then use afor
. I'll do that.