Giter Site home page Giter Site logo

nfischer / shelljs-transpiler Goto Github PK

View Code? Open in Web Editor NEW
73.0 6.0 8.0 3.83 MB

:shell: Easily transpile Bash to ShellJS

Home Page: https://nfischer.github.io/shelljs-transpiler/

License: MIT License

JavaScript 45.77% HTML 53.02% Shell 0.45% CSS 0.76%
shelljs translation

shelljs-transpiler's Introduction

shelljs-transpiler

GitHub Actions Codecov npm version npm downloads Try online

"Say goodbye to those gnarly Bash scripts!" -- @arturadib, ShellJS README

Want to try out ShellJS but don't want to go through the effort of porting all your scripts? Look no further.

Easily transpile your Bash scripts to ShellJS. Try it out here on the web. Just type, copy-paste, or drag-and-drop your favorite shell script and see the results.

Have a lot of scripts to transpile? Install this globally to use sh2js to transpile scripts from the command line.

Think this is cool?

Let me know by giving it a star on Github.

Think this is really cool? ๐Ÿ˜Ž

Contributions would be awesome! I'd really like to propel this project forward, but don't have much time. You can help me out by:

  • sending me scripts you'd like to be able to translate, but haven't been able to
  • finding bugs or thinking of features
  • taking up one of the help-wanted issues
  • helping refactor the grammar so that other people can use it too.
  • spreading the word (more awareness = more contributors)

Installation

Note: this may not handle all Bash syntax until v1.0. If your script doesn't get translated successfully, please file a Github issue.

$ npm install -g shelljs-transpiler # this lets you use `sh2js`

ShellJS and NodeJS compatibility

What version of ShellJS is this compatible with? Can I run this code? Do I need a special version of Node? Will this translate anything correctly?

Your best bet are the latest versions of NodeJS and ShellJS. Some translations are significantly easier to do using ES6 features, so I use them where convenient. Also, ShellJS is still under development, so we're always adding new features to help give it the best of both JavaScript and Bash.

I'll sometimes write translations that take advantage of my not-yet-implemented ShellJS feature ideas--some of which may never get implemented. If your translated script relies on a feature that doesn't exist yet in ShellJS, let me know and I'll fix the transpiler to use a ShellJS feature that's available here and now.

sh2js CLI tool

The sh2js CLI transpiler is still somewhat experimental, but feel free to check it out! Usage:

$ sh2js [options] <shell script input> [JavaScript output]

If you want to take advantage of shelljs plugins in the translated script, you're free to do so! Simply use the --plugins flag to supply a space-separated list of the plugins you want to use.

options

short option long option behavior
-v --version Output version information and quit
-h --help Output help information and quit
N/A --plugins="<names>" Use each ShellJS plugin listed in the space-separated list <names>

Ex. usage:

$ sh2js testFile.sh outputFile.js # overwrites outputFile.js
$ sh2js testFile.sh # writes to stdout
$ sh2js --plugins="tr open clear" testFile.sh # takes advantage of these plugins

Contributing

As stated above, contributions are welcome! If you're interested in helping out, let me know by posting an issue or shooting me an email.

Running the project

First, install it (and the git submodule dependencies!)

$ git clone --recursive https://github.com/nfischer/shelljs-transpiler.git
$ cd shelljs-transpiler/
$ npm install

Next, run it in the browser using npm start, run unit tests using npm test, or try a script with path/to/shelljs-transpiler/bin/sh2js someScript.sh.

shelljs-transpiler's People

Contributors

jhen0409 avatar nfischer avatar schmavery avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

shelljs-transpiler's Issues

Add support for bash-style substitutions

Bash has a syntax for manipulating variables as seen in this page. Examples:

  • ${foo:0:2} -> `foo.substr(0, 2)
  • ${foo#hello} -> remove leading "hello"
  • ${foo%world} -> remove trailing "world"
  • ${foo/abc/xyz} -> foo.replace('abc', 'xyz')
  • ${foo//abc/xyz} -> foo.replace(/abc/g, 'xyz')
  • and many more useful cases...

CLI does not have --version, -v option

I know this is a really small issue, but figured I would share since I have done it numerous times :-)

 $ sh2js --verison
Usage: sh2js <shell script input> [javascript file]

Improve styling and background

The white-and-black theme is getting a little old for me, so I think it's time to upgrade the styling:

  • add background image
  • style the code mirror editors
  • perhaps a different font(s)?
  • style the hints better (with <code> tags)
  • etc.

Write a toAST semantic action

So far, I've been transpiling straight from a CST. This has some nice features, since I can sometimes preserve whitespace and comments, which I think are still significant parts of the code.

But I'd like to eventually publish the grammar in its own module, once it's sufficiently general and stable. When I do this, I'd like to have a toAST operation in the package, that's somewhat similar to https://github.com/vorpaljs/bash-parser.

shift function does not work

The 'shift' function is implemented via exec('shift') - but this doesn't/can't/shouldn't change the process.argv array. thus the value of, e.g., $1 does not change after shift.

Seems that process.argv needs to be copied and $N references are to this copy.
'shift M' functions would replace this copy by a slice of it thus changing the values associated with $K

Indicate in the UI when there's a parsing error

Right now it's a parse error to write something like:

echo hello world && echo bye

The first & is interpreted as "run in background job" (obviously the wrong interpretation) and the rest of the line causes a parse error (so additional lines don't get transpiled). Errors like this should be indicated more clearly (ideally, they would be inline as code-mirror widgets). I have a similar solution at rainbows-lang.

Add support for functions

One of my goals would be transpile shx's release script. The most important thing to moving toward that is adding support for functions & function calls.

The rule for functions should be general enough:

  • make sure rules surrounding { are correct (I think this should be name allWhiteSpace+ "{" allWhiteSpace+ Cmds)
  • allow function keyword to be optional
  • allow parentheses to be optional (and what even goes inside parentheses?)

Unable to parse script

First attempted use of sh2js and it gives me;

Unable to parse script
Line 26, col 26:
25 | function isint {

26 | expr $1 + 0 >/dev/null 2>&1 && return 0
^
27 | return 1
Expected "}"
Please include this output in the bug report

The "}" it's looking for is on the next line;

# isint -  is integer?
function isint {
  expr $1 + 0 >/dev/null 2>&1 && return 0
  return 1
}
#

I agree that the above is ugly.

TypeError: Cannot read property 'rules' of undefined

Just installed and tried to apply to one of my many bash scripts, boom!

 $ sh2js new-branch.sh
Unable to parse script
/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:5763
  var description = grammar.rules[this.ruleName].description;
                           ^

TypeError: Cannot read property 'rules' of undefined
    at Apply.pexprs.Apply.toFailure (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:5763:28)
    at /usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:5776:50
    at Array.map (native)
    at Alt.pexprs.Alt.toFailure (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:5776:23)
    at Not.pexprs.Not.toFailure (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:5754:26)
    at Object.State.processFailure (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:2780:41)
    at Not.pexprs.Not.eval (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:4685:11)
    at Object.State.eval (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:2902:20)
    at Seq.pexprs.Seq.eval (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:4623:16)
    at Object.State.eval (/usr/local/lib/node_modules/shelljs-transpiler/lib/ohm/dist/ohm.js:2902:20)

Cannot parse config.guess/config.sub

Symptoms:

Unable to parse script
Unable to identify parsing failure (please include your full script in the bug report)
Please file a bug report at https://github.com/nfischer/shelljs-transpiler

Tested with versions
/usr/share/misc/config.guess:timestamp='2013-06-10'
/usr/share/misc/config.sub:timestamp='2013-08-10'
and
config.guess:timestamp='2018-01-11'
config.sub:timestamp='2018-01-11'

Current versions can be found at:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD

exec with variables as arguments should still work

Related to #23, CC @mikeerickson

The translator currently doesn't properly handle exec commands that expand variables. Something like:

branchName=master
git checkout $branchName
printf $PATH

should translate into:

var branchName = master
exec('git checkout ' + branchName);
exec('printf ' + env.PATH); // or exec('printf $PATH');

Support for complex commands inside of if/while/for bodies

This is a known issue that I haven't figured out yet.

Currently, this project doesn't support multiple commands inside of an if body. Ex:

if true; then
  echo 'foo'
  echo 'bar'
fi

Or even other complex command types:

if true; then
  echo 'foo' | grep 'o' # complex commands like pipes don't work
fi

Simple commands, however, work fine. Ex:

if true; then
  echo 'foo'
fi

Properly Handle Pipes

It would appear that B2SHJS isn't fully aware of what can go on the right side of pipes. For example:

In:

cat foo | grep

Out:

cat('foo').exec('grep');

Where as it should be (at lease once [email protected] comes out):

cat('foo').grep();

option not recognized: sed -i

Looks like sed doesn't support options. Probably a regression. The -i option is listed in the source, so I suspect this is just a bug with the convertSed() function not allowing options.

Switch & case

Add support for switch & case, including the default case (notated by *)).

This should also add support for things like:

?)
  echo "do something"
  ;;

Also, this should handle the ;& fall-through syntax (although that's less of a priority, since it's only for newer versions of bash).

Generalize the bash grammar

Modify this grammar to be less specific, and move that specificity into the semantic actions. Then the grammar can be published separately.

Allow multiple conditionals

One form I can think of is:

if [[ "$is_collaborator" ]] || [[ "$is_owner" ]]; then

(taken from the shx release script)

There are also other specific flags, like -o and things like that. All of this should probably be supported.

calls to commands starting with digits

Seems it will fail if when calling a command which name start with a digit. probably around :

CmdName = (~keyword Bashword #(~alnum))

BTW which grammar syntax are you using ?

#!/bin/bash
ang=1
while [ $ang -le 360 ]
	do
	echo "ang=$ang"
	if [ $ang -gt 180 ] 
		then
		newang=`expr $ang - 360`
	else
		newang=$ang
	fi
	3Drotate tilt=30 pan=$newang zoom=-1.5 mandril.jpg $tmp
done
	
Unable to parse script
Line 12, col 3:
  11 | 	fi
> 12 | 	3Drotate tilt=30 pan=$newang zoom=-1.5 mandril.jpg $tmp
         ^
  13 | 
Expected not an alpha-numeric character
Please include this output in the bug report
Please file a bug report at git+https://github.com/nfischer/shelljs-transpiler.git
```

&& and || operations

Add in translation for && and || as follows:

$ true && echo 'hi'
hi
$ false || echo 'hi'
hi

In general, it may be tough to get this working as nicely as possible. commands like test -f file.txt return booleans, and it would be nice to take advantage of that in translation, while other commands like exec('git status') have .code attributes that should be examined instead.

Also, this should work with other formats, such as [ "my string" ] && echo hi.

It'd be really great if better support for && and || could be worked into n_shell or ShellJS proper.

Switch to code-mirror

Refactor src/index.generator.html to use code-mirror (with syntax highlighting) instead of the plain text areas I'm currently using.

Assignment should probably trimRight()

I believe assignment should probably trimRight() or something like that.

I know that bash works like this:

foo=$(echo hello world)" # this produces a trailing newline
echo "$foo" # this doesn't have double trailing newlines, so the `\n` is not contained in the variable

I need to check if:

  • this also works like trimLeft()
  • this happens during variable assignment or during the $(...) (or when accessing the variable)

Allow Calls to be inside strings

Calls should be allowed inside strings much in the same way as references are. This is tricky, since strings are lexical rules. This might require intensive refactoring.

non-global import by default

We no longer recommend global imports for ShellJS, so this transpiler shouldn't default to that.

We should just have a different default checkbox value for "include in global namespace".


Also, we should consider moving that checkbox down below, near the plugin checkboxes. It's confusing to have controls in two different places.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.