Skip to content

Commit 4e57ca6

Browse files
Danny McClanahanGeoffreyBooth
Danny McClanahan
authored andcommitted
[CS2] Add #! support for executable scripts on Linux. (#3946)
* Add #! support for executable scripts on Linux. Pass arguments to executable script unchanged if using "#!/usr/bin/env coffee". (Previously, "./test.coffee -abck" would be turned into "-a -b -c -k", for example.) Fixes #1752. * refactor option parsing clean up parsing code and in the process fix oustanding bug where coffeescript modified arguments meant for an executable script * address comments * intermediate save * add note saying where OptionParser is used in coffee command * add some more work * fix flatten functions * refactor tests * make argument processing less confusing * add basic test * remove unused file * compilation now hangs * remove unnecessary changes * add tests!!! * add/fix some tests * clarify a test * fix helpers * fix opt parsing * fix infinite loop * make rule building easier to read * add tests for flag overlap * revamp argument parsing again and add more thorough testing * add tests, comment, clean unused method * address review comments * add test for direct invocation of shebang scripts * move shebang parsing test to separate file and check for browser * remove TODO * example backwards compatible warnings * add correct tests for warning 1 * add tests for warnings * commit output js libs and update docs * respond to review comments also add tests for help text * respond to review comments * fix example output * Rewrite argument parsing documentation to be more concise; add it to sidebar and body; add new output * Don’t mention deprecated syntax; clean up variable names
1 parent d287a79 commit 4e57ca6

22 files changed

+672
-213
lines changed

docs/v2/index.html

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,15 @@
306306
white-space: nowrap;
307307
}
308308

309-
h2, h3 {
309+
h2, h3, h4 {
310310
margin-top: 1.3em;
311311
margin-bottom: 0.6em;
312312
font-family: 'Alegreya Sans';
313313
}
314314
h2 {
315315
font-weight: 800;
316316
}
317-
h3, h2 time {
317+
h3, h4, h2 time {
318318
font-weight: 400;
319319
}
320320

@@ -734,6 +734,9 @@
734734
<li class="nav-item">
735735
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
736736
</li>
737+
<li class="nav-item">
738+
<a href="#breaking-changes-argument-parsing-and-shebang-lines" class="nav-link" data-action="sidebar-nav">Argument Parsing and <code>#!</code> Lines</a>
739+
</li>
737740
</ul>
738741
</li>
739742
<li class="nav-item">
@@ -858,7 +861,7 @@ <h2>Overview</h2>
858861
<section id="coffeescript-2">
859862
<h2>CoffeeScript 2</h2>
860863
<h3>What’s New In CoffeeScript 2?</h3>
861-
<p>The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript <code>=&gt;</code> becomes an ES <code>=&gt;</code>, a CoffeeScript <code>class</code> becomes an ES <code>class</code> and so on. With the exception of modules (<code>import</code> and <code>export</code> statements), all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. You can <a href="http://coffeescript.org/v2/test.html">run the tests in your browser</a> to see if your browser can do the same; Chrome has supported all features since version 55.</p>
864+
<p>The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript <code>=&gt;</code> becomes an ES <code>=&gt;</code>, a CoffeeScript <code>class</code> becomes an ES <code>class</code> and so on. With the exception of <a href="#modules">modules</a> (<code>import</code> and <code>export</code> statements) and <a href="#jsx">JSX</a>, all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. You can <a href="http://coffeescript.org/v2/test.html">run the tests in your browser</a> to see if your browser can do the same; Chrome has supported all features since version 55.</p>
862865
<p>Support for ES2015+ syntax is important to ensure compatibility with frameworks that assume ES2015. Now that CoffeeScript compiles classes to the ES <code>class</code> keyword, it’s possible to <code>extend</code> an ES class; that wasn’t possible in CoffeeScript 1. Parity in how language features work is also important on its own; CoffeeScript “is just JavaScript,” and so things like <a href="#breaking-changes-default-values">function parameter default values</a> should behave the same in CoffeeScript as in JavaScript.</p>
863866
<p>Many ES2015+ features have been backported to CoffeeScript 1.11 and 1.12, including <a href="#modules">modules</a>, <a href="#generator-iteration"><code>for…of</code></a>, and <a href="#tagged-template-literals">tagged template literals</a>. Major new features unique to CoffeeScript 2 are support for ES2017’s <a href="#async-functions">async functions</a> and for <a href="#jsx">JSX</a>. More details are in the <a href="#changelog">changelog</a>.</p>
864867
<p>There are very few <a href="#breaking-changes">breaking changes from CoffeeScript 1.x to 2</a>; we hope the upgrade process is smooth for most projects.</p>
@@ -3244,7 +3247,7 @@ <h2>JSX</h2>
32443247
</div>
32453248

32463249
</aside>
3247-
<p>Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a <code>.cjsx</code> file extension, but this is no longer necessary; regalar <code>.coffee</code> will do.</p>
3250+
<p>Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a <code>.cjsx</code> file extension, but this is no longer necessary; regular <code>.coffee</code> will do.</p>
32483251

32493252
</section>
32503253
</section>
@@ -3619,7 +3622,7 @@ <h3>Classes are compiled to ES2015 classes</h3>
36193622
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>
36203623
constructor: <span class="function">-&gt;</span> <span class="keyword">this</span> <span class="comment"># Throws a compiler error</span>
36213624
</code></pre>
3622-
</blockquote><p>ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accomodated is calling a bound method before it is bound:</p>
3625+
</blockquote><p>ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accommodated is calling a bound method before it is bound:</p>
36233626
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">Base</span></span>
36243627
constructor: <span class="function">-&gt;</span>
36253628
@onClick() <span class="comment"># This works</span>
@@ -3787,7 +3790,7 @@ <h3><code>super</code> and <code>extends</code></h3>
37873790

37883791
</section>
37893792
<section id="breaking-changes-jsx-and-the-less-than-and-greater-than-operators">
3790-
<h3>JSX and the <code>&lt;</code> and <code>&gt;</code> Operators</h3>
3793+
<h3>JSX and the <code>&lt;</code> and <code>&gt;</code> operators</h3>
37913794
<p>With the addition of <a href="#jsx">JSX</a>, the <code>&lt;</code> and <code>&gt;</code> characters serve as both the “less than” and “greater than” operators and as the delimiters for XML tags, like <code>&lt;div&gt;</code>. For best results, in general you should always wrap the operators in spaces to distinguish them from XML tags: <code>i &lt; len</code>, not <code>i&lt;len</code>. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.</p>
37923795

37933796
</section>
@@ -3797,6 +3800,29 @@ <h3>Literate CoffeeScript parsing</h3>
37973800
<p>Code blocks should also now maintain a consistent indentation level—so an indentation of one tab (or whatever you consider to be a tab stop, like 2 spaces or 4 spaces) should be treated as your code’s “left margin,” with all code in the file relative to that column.</p>
37983801
<p>Code blocks that you want to be part of the commentary, and not executed, must have at least one line (ideally the first line of the block) completely unindented.</p>
37993802

3803+
</section>
3804+
<section id="breaking-changes-argument-parsing-and-shebang-lines">
3805+
<h3>Argument parsing and shebang (<code>#!</code>) lines</h3>
3806+
<p>In CoffeeScript 1.x, <code>--</code> was required after the path and filename of the script to be run, but before any arguments passed to that script. This convention is now deprecated. So instead of:</p>
3807+
<blockquote class="uneditable-code-block"><pre><code class="language-bash">coffee [options] path/to/script.coffee -- [args]
3808+
</code></pre>
3809+
</blockquote><p>Now you would just type:</p>
3810+
<blockquote class="uneditable-code-block"><pre><code class="language-bash">coffee [options] path/to/script.coffee [args]
3811+
</code></pre>
3812+
</blockquote><p>The deprecated version will still work, but it will print a warning before running the script.</p>
3813+
<p>On non-Windows platforms, a <code>.coffee</code> file can be made executable by adding a shebang (<code>#!</code>) line at the top of the file and marking the file as executable. For example:</p>
3814+
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="comment">#!/usr/bin/env coffee</span>
3815+
3816+
x = <span class="number">2</span> + <span class="number">2</span>
3817+
<span class="built_in">console</span>.log x
3818+
</code></pre>
3819+
</blockquote><p>If this were saved as <code>executable.coffee</code>, it could be made executable and run:</p>
3820+
<blockquote class="uneditable-code-block"><pre><code class="language-bash">▶ chmod +x ./executable.coffee
3821+
▶ ./executable.coffee
3822+
4
3823+
</code></pre>
3824+
</blockquote><p>In CoffeeScript 1.x, this used to fail when trying to pass arguments to the script. Some users on OS X worked around the problem by using <code>#!/usr/bin/env coffee --</code> as the first line of the file. That didn’t work on Linux, however, which cannot parse shebang lines with more than a single argument. While such scripts will still run on OS X, CoffeeScript will now display a warning before compiling or evaluating files that begin with a too-long shebang line. Now that CoffeeScript 2 supports passing arguments without needing <code>--</code>, we recommend simply changing the shebang lines in such scripts to just <code>#!/usr/bin/env coffee</code>.</p>
3825+
38003826
</section>
38013827
</section>
38023828
<section id="changelog">
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
### Argument parsing and shebang (`#!`) lines
2+
3+
In CoffeeScript 1.x, `--` was required after the path and filename of the script to be run, but before any arguments passed to that script. This convention is now deprecated. So instead of:
4+
5+
```bash
6+
coffee [options] path/to/script.coffee -- [args]
7+
```
8+
9+
Now you would just type:
10+
11+
```bash
12+
coffee [options] path/to/script.coffee [args]
13+
```
14+
15+
The deprecated version will still work, but it will print a warning before running the script.
16+
17+
On non-Windows platforms, a `.coffee` file can be made executable by adding a shebang (`#!`) line at the top of the file and marking the file as executable. For example:
18+
19+
```coffee
20+
#!/usr/bin/env coffee
21+
22+
x = 2 + 2
23+
console.log x
24+
```
25+
26+
If this were saved as `executable.coffee`, it could be made executable and run:
27+
28+
```bash
29+
▶ chmod +x ./executable.coffee
30+
▶ ./executable.coffee
31+
4
32+
```
33+
34+
In CoffeeScript 1.x, this used to fail when trying to pass arguments to the script. Some users on OS X worked around the problem by using `#!/usr/bin/env coffee --` as the first line of the file. That didn’t work on Linux, however, which cannot parse shebang lines with more than a single argument. While such scripts will still run on OS X, CoffeeScript will now display a warning before compiling or evaluating files that begin with a too-long shebang line. Now that CoffeeScript 2 supports passing arguments without needing `--`, we recommend simply changing the shebang lines in such scripts to just `#!/usr/bin/env coffee`.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
### JSX and the `<` and `>` Operators
1+
### JSX and the `<` and `>` operators
22

33
With the addition of [JSX](#jsx), the `<` and `>` characters serve as both the “less than” and “greater than” operators and as the delimiters for XML tags, like `<div>`. For best results, in general you should always wrap the operators in spaces to distinguish them from XML tags: `i < len`, not `i<len`. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.

documentation/sections/coffeescript_2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### What’s New In CoffeeScript 2?
44

5-
The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript `=>` becomes an ES `=>`, a CoffeeScript `class` becomes an ES `class` and so on. With the exception of modules (`import` and `export` statements), all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. You can [run the tests in your browser](http://coffeescript.org/v<%= majorVersion %>/test.html) to see if your browser can do the same; Chrome has supported all features since version 55.
5+
The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript `=>` becomes an ES `=>`, a CoffeeScript `class` becomes an ES `class` and so on. With the exception of [modules](#modules) (`import` and `export` statements) and [JSX](#jsx), all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. You can [run the tests in your browser](http://coffeescript.org/v<%= majorVersion %>/test.html) to see if your browser can do the same; Chrome has supported all features since version 55.
66

77
Support for ES2015+ syntax is important to ensure compatibility with frameworks that assume ES2015. Now that CoffeeScript compiles classes to the ES `class` keyword, it’s possible to `extend` an ES class; that wasn’t possible in CoffeeScript 1. Parity in how language features work is also important on its own; CoffeeScript “is just JavaScript,” and so things like [function parameter default values](#breaking-changes-default-values) should behave the same in CoffeeScript as in JavaScript.
88

documentation/v2/body.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@
178178
<section id="breaking-changes-literate-coffeescript">
179179
<%= htmlFor('breaking_changes_literate_coffeescript') %>
180180
</section>
181+
<section id="breaking-changes-argument-parsing-and-shebang-lines">
182+
<%= htmlFor('breaking_changes_argument_parsing_and_shebang_lines') %>
183+
</section>
181184
</section>
182185
<section id="changelog">
183186
<%= htmlFor('changelog') %>

documentation/v2/docs.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,15 @@ td code {
286286
white-space: nowrap;
287287
}
288288

289-
h2, h3 {
289+
h2, h3, h4 {
290290
margin-top: 1.3em;
291291
margin-bottom: 0.6em;
292292
font-family: 'Alegreya Sans';
293293
}
294294
h2 {
295295
font-weight: 800;
296296
}
297-
h3, h2 time {
297+
h3, h4, h2 time {
298298
font-weight: 400;
299299
}
300300

documentation/v2/sidebar.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@
171171
<li class="nav-item">
172172
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
173173
</li>
174+
<li class="nav-item">
175+
<a href="#breaking-changes-argument-parsing-and-shebang-lines" class="nav-link" data-action="sidebar-nav">Argument Parsing and <code>#!</code> Lines</a>
176+
</li>
174177
</ul>
175178
</li>
176179
<li class="nav-item">

lib/coffeescript/coffeescript.js

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/coffeescript/command.js

Lines changed: 14 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)