Skip to content

Typescript aborts on shebang. #2749

Closed
Closed

Description

Activity

  1. CyrusNajmabadi commented on Apr 13, 2015

    @CyrusNajmabadi
    Contributor

    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.

  2. mhegazy commented on Apr 13, 2015

    @mhegazy
    Contributor

    cause ppl like to write their shell scripts in ts :)

  3. jdfreder commented on Apr 13, 2015

    @jdfreder
    Author

    Two reasons:

    1. 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.');
    1. 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.
  4. jdfreder commented on Apr 13, 2015

    @jdfreder
    Author

    cause ppl like to write their shell scripts in ts :)

    +1 : )

  5. tomlarkworthy commented on Apr 14, 2015

    @tomlarkworthy

    +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.

  6. poelstra commented on Apr 15, 2015

    @poelstra

    +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:

    • 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.
  7. RyanCavanaugh commented on Apr 17, 2015

    @RyanCavanaugh
    Member

    Passing through only the first line this way seems plausible?

  8. poelstra commented on Apr 17, 2015

    @poelstra

    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.

  9. mhegazy commented on Apr 17, 2015

    @mhegazy
    Contributor

    We do not modify file properties usually. would not that be something you do in your build script?

  10. poelstra commented on Apr 17, 2015

    @poelstra

    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.

  11. CyrusNajmabadi commented on Apr 17, 2015

    @CyrusNajmabadi
    Contributor

    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.

  12. poelstra commented on Apr 18, 2015

    @poelstra

    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:

    • 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)
      • Set the executable bit (on *nix)
  13. Raynos commented on May 3, 2015

    @Raynos

    👍

  14. 25 remaining items

  15. CyrusNajmabadi commented on Aug 1, 2015

    @CyrusNajmabadi
    Contributor

    Basarat Ali Syed (@basarat)

    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.

  16. basarat commented on Aug 1, 2015

    @basarat
    Contributor

    Then we can even do nice stuff like classify this guy properly in the editor and not barf on it while formatting

    👍 🌹 SyntaxKind.ShebangTrivia

  17. basarat commented on Aug 1, 2015

    @basarat
    Contributor

    If you wanted to send me the shebang syntax (it's just #! right?), then i'd be happy to whip this up myself.

    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 🌹

  18. basarat commented on Aug 2, 2015

    @basarat
    Contributor

    I just PRed it

  19. jdfreder commented on Aug 4, 2015

    @jdfreder
    Author

    Awesome, thanks for moving forward with this everyone!

  20. mhegazy commented on Aug 4, 2015

    @mhegazy
    Contributor
  21. basarat commented on Aug 4, 2015

    @basarat
    Contributor

    🌹

  22. tomlarkworthy commented on Aug 4, 2015

    @tomlarkworthy

    [image: Office dance]

    On Tue, Aug 4, 2015 at 2:42 PM, Basarat Ali Syed notifications@github.com
    wrote:

    🌹

    —
    Reply to this email directly or view it on GitHub
    #2749 (comment)
    .

  23. woodie commented on Dec 25, 2015

    @woodie

    I came up with a simple solution, described here.
    https://medium.com/@JohnWoodell/time-for-typescript-e87b78a796d0#.a1694wfih

  24. DanielRosenwasser commented on Dec 26, 2015

    @DanielRosenwasser
    Member

    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.

  25. locked and limited conversation to collaborators on Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions