You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm confused. Why would this be part of the typescript compiler? As your link shows, the more appropriate thing to do would be to add the script directive as part of the compilation pipeline with another tool.
Even though shebangs may not be official Javascript spec, I'd expect Typescript to support Node.js Javascript fully, since Typescript is a Javascript superset and Node.js is popular Javascript platform. The following is parsed by node, but not Typescript.
#!/usr/bin/env node
console.log('Hello world.');
Is it not easier to ignore the shebang in the Typescript compiler (only one in existence), than it is to add kludge compilation step that prepends the shebang (for N projects that use Typescript for node.js CLIs)? ... I guess you could counter argue N is small, but I think it's actually big.
+1 it be nice to build fully functioning shell scripts written in Typescript like I do with Python or Bash or Javascript, without involving an additional build step.
I would very much like not having to type "node ..." in front of every TS CLI util / 'shell script', or having to create an almost-empty .js wrapper for them.
compile-on-save tools like Visual Studio, Atom Typescript or Sublimetext cannot be used on these files
it's not as easy as simply catting a line in front of it: it also e.g. involves updating the sourcemap
it either requires some kind of naming convention, or a manually maintained list of files that would need this transformation in the 'makefile'. I find such lists to be cumbersome, typically leading to unnecessary merge conflicts (like a Visual Studio project, or tsconfig's files property).
I filed this on codeplex quite a while back, and apparently so did this user.
As noted in my codeplex issue though, there are some things to take into consideration:
it's a bit dubious whether having #!/bin/env node at the top of a .ts file actually makes sense (because Node cannot run the .ts file directly). This is in contrast to e.g. Javascript or Python files, which can actually be directly run by their respective interpreter. Still, I'd rather have this than doing it 'manually' as a build step :)
the line-ending of such a line must be a Unix line-ending (even on Windows), as otherwise the shell will not correctly parse it (it will include the \r in the command's filename). This in turn will probably force all other line-endings in that file to be Unix too, to prevent messages when opening the file in an editor, source-code-control messages, etc.
on Linux, the file still won't be executable if the +x bit isn't set, so the compiler should probably do that automatically for such files.
Ryan Cavanaugh (@RyanCavanaugh) yes, but that first line must end with (just) a line-feed, and the emitted file needs to have the executable bit set on *nix.
We could extend the TS language to call "#..." another form of trivia. We'd could then preserve it in the same way that we preserve copyright comments at the top of the file.
For reference, our use-case at work is that we have quite a few handy little utils in our codebase, to restart services, initialize databases, etc. Often these very tools are used and developed in your typical edit-compile-run cycle while working on the main library that the tool interacts with.
For that scenario, it would be great not having to run the build system over-and-over again, as it takes at least a few seconds to run (even though we try to skip compilation for unmodified files etc).
At >100k lines of TS code, it takes quite some time just to 'initialize' gulp, and at this moment, the compile pipeline (TS, browserify, uglify, copyright, sourcemaps, etc.) is deemed too complex to 'fork' the pipeline to have a separate watch-version.
Visual Studio's compile-on-save produces almost instantaneous results, and we typically don't need more than that for most of these edit-compile-run cycles.
We develop and test on Windows, but use MSysGit's Bash as commandline. We also run all tests on a Linux machine.
So, our source files are stored with CRLF, and the emitted .js file contains CRLF. Having a simple passthrough, or 'exactly preserved' trivia will thus lead to that shebang line ending in CRLF. This doesn't work when trying to run the script in (MSysGit) Bash; many projects seem to have run into this.
On Windows, having the file output just LF would fix it: MSysGit can't use an executable bit, so it appears to read the first line of a file to see if it's a shebang, and if so, effectively assumes it's an executable.
On Linux, it's the other way around: the file would already be output with LF, but it still wouldn't be executable due to the missing +x bit. It's not that weird for compilers to set an executable bit though, that's basically what every C-compiler does too ;)
Not sure how hard this would be to add to the compiler though. I'd gladly give this up for solid CommonJS module support, to be honest ;)
TL;DR I think this would be the ingredients:
Detect the "#!..." (note the "!" too, just "#" is invalid) at the start of a file (only then), and store it as trivia
When emitting the file and it starts with that type of trivia:
Force line-endings to LF (to make it work on Windows)
Output that trivia as the first bytes of the file (e.g. no BOM)
This is very similar to how babel does it as well (calls parseShebang at the start, and if the first line matches the regex stores it in a shebang property on what is effectively its sourceFile and then writes it out on emit). Would you be okay with a PR?
Sounds good. However, i would prefer you parse it out as trivia instead of adding it as a special field on sourceFile. As an example of where we have specialized trivia parsing, see the code i added so we can detect and handle git merge markers (i.e. "<<<<<< HEAD"). Then we can even do nice stuff like classify this guy properly in the editor and not barf on it while formatting. yadda yadda yadda.
If you wanted to send me the shebang syntax (it's just #! <stuff to end of line> right?), then i'd be happy to whip this up myself.
Activity
CyrusNajmabadi commentedon Apr 13, 2015
I'm confused. Why would this be part of the typescript compiler? As your link shows, the more appropriate thing to do would be to add the script directive as part of the compilation pipeline with another tool.
mhegazy commentedon Apr 13, 2015
cause ppl like to write their shell scripts in ts :)
jdfreder commentedon Apr 13, 2015
Two reasons:
jdfreder commentedon Apr 13, 2015
+1 : )
tomlarkworthy commentedon Apr 14, 2015
+1 it be nice to build fully functioning shell scripts written in Typescript like I do with Python or Bash or Javascript, without involving an additional build step.
poelstra commentedon Apr 15, 2015
+1
I would very much like not having to type "node ..." in front of every TS CLI util / 'shell script', or having to create an almost-empty .js wrapper for them.
Cyrus Najmabadi (@CyrusNajmabadi): arguments for handling it in the compiler:
I filed this on codeplex quite a while back, and apparently so did this user.
As noted in my codeplex issue though, there are some things to take into consideration:
#!/bin/env nodeat the top of a .ts file actually makes sense (because Node cannot run the .ts file directly). This is in contrast to e.g. Javascript or Python files, which can actually be directly run by their respective interpreter. Still, I'd rather have this than doing it 'manually' as a build step :)RyanCavanaugh commentedon Apr 17, 2015
Passing through only the first line this way seems plausible?
poelstra commentedon Apr 17, 2015
Ryan Cavanaugh (@RyanCavanaugh) yes, but that first line must end with (just) a line-feed, and the emitted file needs to have the executable bit set on *nix.
mhegazy commentedon Apr 17, 2015
We do not modify file properties usually. would not that be something you do in your build script?
poelstra commentedon Apr 17, 2015
Mohamed Hegazy (@mhegazy) yes, but then the script is still not executable (on non-Windows), so it won't help for the compile-on-save scenario.
CyrusNajmabadi commentedon Apr 17, 2015
We could extend the TS language to call "#..." another form of trivia. We'd could then preserve it in the same way that we preserve copyright comments at the top of the file.
poelstra commentedon Apr 18, 2015
That would be a useful part of the solution yes.
For reference, our use-case at work is that we have quite a few handy little utils in our codebase, to restart services, initialize databases, etc. Often these very tools are used and developed in your typical edit-compile-run cycle while working on the main library that the tool interacts with.
For that scenario, it would be great not having to run the build system over-and-over again, as it takes at least a few seconds to run (even though we try to skip compilation for unmodified files etc).
At >100k lines of TS code, it takes quite some time just to 'initialize' gulp, and at this moment, the compile pipeline (TS, browserify, uglify, copyright, sourcemaps, etc.) is deemed too complex to 'fork' the pipeline to have a separate watch-version.
Visual Studio's compile-on-save produces almost instantaneous results, and we typically don't need more than that for most of these edit-compile-run cycles.
We develop and test on Windows, but use MSysGit's Bash as commandline. We also run all tests on a Linux machine.
So, our source files are stored with CRLF, and the emitted .js file contains CRLF. Having a simple passthrough, or 'exactly preserved' trivia will thus lead to that shebang line ending in CRLF. This doesn't work when trying to run the script in (MSysGit) Bash; many projects seem to have run into this.
On Windows, having the file output just LF would fix it: MSysGit can't use an executable bit, so it appears to read the first line of a file to see if it's a shebang, and if so, effectively assumes it's an executable.
On Linux, it's the other way around: the file would already be output with LF, but it still wouldn't be executable due to the missing +x bit. It's not that weird for compilers to set an executable bit though, that's basically what every C-compiler does too ;)
Not sure how hard this would be to add to the compiler though. I'd gladly give this up for solid CommonJS module support, to be honest ;)
TL;DR I think this would be the ingredients:
Raynos commentedon May 3, 2015
👍
25 remaining items
CyrusNajmabadi commentedon Aug 1, 2015
Basarat Ali Syed (@basarat)
Sounds good. However, i would prefer you parse it out as trivia instead of adding it as a special field on sourceFile. As an example of where we have specialized trivia parsing, see the code i added so we can detect and handle git merge markers (i.e. "<<<<<< HEAD"). Then we can even do nice stuff like classify this guy properly in the editor and not barf on it while formatting. yadda yadda yadda.
If you wanted to send me the shebang syntax (it's just
#! <stuff to end of line>right?), then i'd be happy to whip this up myself.basarat commentedon Aug 1, 2015
👍 🌹
SyntaxKind.ShebangTriviabasarat commentedon Aug 1, 2015
Cyrus Najmabadi (@CyrusNajmabadi) Yup. I have some work on the scanner based on your suggestion that might be helpful https://github.com/Microsoft/TypeScript/compare/master...basarat:feat/shebang?expand=1
Looking forward to your work 🌹
basarat commentedon Aug 2, 2015
I just PRed it
jdfreder commentedon Aug 4, 2015
Awesome, thanks for moving forward with this everyone!
mhegazy commentedon Aug 4, 2015
thanks Basarat Ali Syed (@basarat)
basarat commentedon Aug 4, 2015
🌹
tomlarkworthy commentedon Aug 4, 2015
[image: Office dance]
On Tue, Aug 4, 2015 at 2:42 PM, Basarat Ali Syed notifications@github.com
wrote:
woodie commentedon Dec 25, 2015
I came up with a simple solution, described here.
https://medium.com/@JohnWoodell/time-for-typescript-e87b78a796d0#.a1694wfih
DanielRosenwasser commentedon Dec 26, 2015
John Woodell (@woodie) nice. As a heads up, check out our wiki's editor support page to get some vim plugins and more updated sytnax files.