{"id":783,"date":"2012-08-01T23:01:20","date_gmt":"2012-08-01T23:01:20","guid":{"rendered":"http:\/\/joelinoff.com\/blog\/?p=783"},"modified":"2012-09-25T18:28:27","modified_gmt":"2012-09-25T18:28:27","slug":"installing-jshint-and-rhino-for-command-line-javascript-analysis","status":"publish","type":"post","link":"https:\/\/joelinoff.com\/blog\/?p=783","title":{"rendered":"Installing jshint and rhino for command line javascript analysis"},"content":{"rendered":"<p>I recently had to install jshint and rhino. It was a bit of a challenge because they needed ant and npm (node package manager). This blog describes what I did and provides a bash shell script that you can use.<br \/>\n<!--more--><br \/>\nJshint (<a href=\"http:\/\/www.jshint.com\">http:\/\/www.jshint.com<\/a>) is a tool that allows you to statically analyze javascript code. It is useful for detecting ertors and enforcing coding standards.<\/p>\n<p>Rhino is a command line interpreter for javascript (<a href=\"http:\/\/mozilla.org\/rhino\">http:\/\/mozilla.org\/rhino<\/a>) that is written in java. It can be used for testing and for server side implementations.<\/p>\n<p>You do not have to be root to install these tools.<\/p>\n<h1>1 Download<\/h1>\n<p>Here are the links to the project code:<\/p>\n<table>\n<thead>\n<tr>\n<td>Archive<\/td>\n<td>Size<\/td>\n<td>Extract Command<\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"http:\/\/downloads.joelinoff.com\/jsdev.tar.bz2\">jsdev.tar.bz2<\/a><\/td>\n<td>4.6K<\/td>\n<td><code>tar jxf jsdev.tar.bz2<\/code><\/td>\n<\/tr>\n<tr>\n<td><a href=\"http:\/\/downloads.joelinoff.com\/jsdev.tar.gz\">jsdev.tar.gz<\/a><\/td>\n<td>4.6K<\/td>\n<td><code>tar zxf jsdev.tar.gz<\/code><\/td>\n<\/tr>\n<tr>\n<td><a href=\"http:\/\/downloads.joelinoff.com\/jsdev.zip\">jsdev.zip<\/a><\/td>\n<td>6.0K<\/td>\n<td><code>unzip jsdev.zip<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h1>2 Extract<\/h1>\n<p>Use the appropriate command from the previous to table to extract the contents of the archive. When you are finished it will look like this:<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<code>jsdev\/Makefile<br \/>\njsdev\/conf\/std.conf<br \/>\njsdev\/tests\/test.sh<br \/>\njsdev\/tests\/test01.js<br \/>\njsdev\/tests\/test02.js<br \/>\njsdev\/setup.sh<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h1>3 Build<\/h1>\n<p>Build the system using <code>make<\/code>. It requires you to have make and java to be installed.<\/p>\n<p>When the build it complete, the tools will be in jsdev\/rtf\/bin directory. You will need to add this directory to your path environment variable as shown in next section to use the tools.<\/p>\n<h1>4 Usage<\/h1>\n<p>The example below takes you through the entire process of downloading, installing and using the tools.<br \/>\n[crayon lang=&#8221;bash&#8221; toolbar=&#8221;always&#8221; title=&#8221;jshint and rhino&#8221;]<br \/>\n$ bash -version<br \/>\n$ mkdir \/home\/me\/work<br \/>\n$ cd \/home\/me\/work<br \/>\n$ wget http:\/\/downloads.joelinoff.com\/jsdev.tar.bz2<br \/>\n<output snipped><br \/>\n$ tar jxf jsdev.tar.bz2<br \/>\n<output snipped><br \/>\n$ rm -f jsdev.tar.bz2<br \/>\n$ cd jsdev<br \/>\n$ make<br \/>\n<output snipped><br \/>\n$ export PATH=&#8221;\/home\/me\/work\/rtf\/bin:${PATH}&#8221;<br \/>\n$ which jshint<br \/>\n\/home\/me\/work\/rtf\/bin\/jshint<br \/>\n$ which rhino<br \/>\n\/home\/me\/work\/rtf\/bin\/rhino<br \/>\n$ rhino -e &#8216;print(&#8220;hello, world!&#8221;);&#8217;<br \/>\nhello, world!<br \/>\n$ cat >test.js <<EOF\n\/\/ Contains intentional errors.\n\n\/\/ Missing semi-colon:\nvar x=42\n\n\/\/ Bad conditional expression:\nif (x=2) {\n    print('GOOD');\n}\nEOF\n$ jshint test.js\n\/tmp\/x.js: line 4, col 9, Missing semicolon.\n\/tmp\/x.js: line 7, col 6, Expected a conditional expression and instead saw an assignment.\n\n2 errors\n$ \n[\/crayon]\n\n\n<h1>5 Trouble Shooting<\/h1>\n<p>I have only tested this on a CentOS 5.5 system.<\/p>\n<p>If something goes wrong, take a look at the setup.sh script. It is most likely because there are some packages missing.<\/p>\n<p>Furthermore, you can remove the sections for ant and\/or npm if you already have them installed.<\/p>\n<h1>6 Manual Steps<\/h1>\n<p>Here are the manual steps.<\/p>\n<ol>\n<li>Install ant.<\/li>\n<li>Install npm (node).<\/li>\n<li>Install jshost using npm.<\/li>\n<li>Install rhino using ant.<\/li>\n<li>Create the rhino tool.<\/li>\n<\/ol>\n<blockquote><p>If you want to install in a directory like \/usr\/local\/bin change the rtf variable assignment at line 43.<\/p><\/blockquote>\n<p>[crayon lang=&#8221;bash&#8221; toolbar=&#8221;always&#8221; title=&#8221;setup script&#8221;]<br \/>\n#!\/bin\/bash<\/p>\n<p># Make a complete javascript test environment consisting<br \/>\n# of rhino and jshint.<\/p>\n<p># ================================================================<br \/>\n# Useful command.<br \/>\n# ================================================================<br \/>\nfunction docmd() {<br \/>\n    local cmd=&#8221;$*&#8221;<br \/>\n    echo<br \/>\n    echo &#8220;# ================================================================&#8221;<br \/>\n    echo &#8220;# CMD: $cmd&#8221;<br \/>\n    echo &#8220;# PWD: &#8220;`pwd`<br \/>\n    echo &#8220;# ================================================================&#8221;<br \/>\n    $cmd<br \/>\n    local st=$?<br \/>\n    if (( $st )) ; then<br \/>\n        echo &#8220;EXIT: Command exited with status $st (FAILED).&#8221;<br \/>\n\techo &#8221;      CMD: $cmd&#8221;<br \/>\n\texit 1<br \/>\n    else<br \/>\n        echo &#8220;EXIT: Command exited with status $st (PASSED).&#8221;<br \/>\n    fi<br \/>\n}<\/p>\n<p># ================================================================<br \/>\n# my-wget<br \/>\n# ================================================================<br \/>\nfunction my-wget() {<br \/>\n    local src=&#8221;$1&#8243;<br \/>\n    local dst=&#8221;$2&#8243;<br \/>\n    if [ ! -f $dst ] ; then<br \/>\n\tdocmd wget $src -O $dst<br \/>\n    fi<br \/>\n}<\/p>\n<p># ================================================================<br \/>\n# Setup<br \/>\n# ================================================================<br \/>\nmedir=$(dirname &#8212; $(readlink -f $0))<br \/>\nrootdir=$medir<br \/>\nrtf=$rootdir\/rtf<br \/>\narchive=$rootdir\/archives<br \/>\nexport PATH=&#8221;${rtf}\/bin:${PATH}&#8221;<br \/>\nrds=(&#8216;pkgs&#8217; &#8216;rtf&#8217; &#8216;archives&#8217;)<br \/>\nfor rd in ${rds[@]} ; do<br \/>\n    if [ ! -d $rd ] ; then<br \/>\n\tdocmd mkdir $rd<br \/>\n    fi<br \/>\ndone<\/p>\n<p># ================================================================<br \/>\n# ant &#8212; needed for rhino<br \/>\n# ================================================================<br \/>\nfn=apache-ant-1.8.4-bin.tar.bz2<br \/>\narpath=$archive\/$fn<br \/>\nmy-wget http:\/\/mirror.nexcess.net\/apache\/ant\/binaries\/$fn $arpath<\/p>\n<p>if [ ! -d pkgs\/apache-ant-1.8.4 ] ; then<br \/>\n    pushd pkgs<br \/>\n    docmd tar jxf $arpath<br \/>\n    popd<br \/>\nfi<\/p>\n<p># Very simple install, just copy over the bin and lib dirs.<br \/>\nif [ ! -f $rtf\/bin\/ant ] ; then<br \/>\n    pushd pkgs<br \/>\n    docmd rsync -avz apache-ant-1.8.4\/bin $rtf\/<br \/>\n    docmd rsync -avz apache-ant-1.8.4\/lib $rtf\/<br \/>\n    popd<br \/>\nfi<br \/>\ntest -f $rtf\/bin\/ant<\/p>\n<p># ================================================================<br \/>\n# node (npm) &#8212; needed for jhint<br \/>\n# ================================================================<br \/>\nfn=node-v0.8.4.tar.gz<br \/>\narpath=$archive\/$fn<br \/>\nmy-wget http:\/\/nodejs.org\/dist\/v0.8.4\/$fn $arpath<\/p>\n<p>if [ ! -d pkgs\/node-v0.8.4 ] ; then<br \/>\n    pushd pkgs<br \/>\n    docmd tar zxf $arpath<br \/>\n    popd<br \/>\nfi<\/p>\n<p>if [ ! -f $rtf\/bin\/node ] ; then<br \/>\n    pushd pkgs\/node-v0.8.4<br \/>\n    docmd .\/configure &#8211;help<br \/>\n    docmd .\/configure &#8211;prefix=$rtf<br \/>\n    docmd make<br \/>\n    docmd make install<br \/>\n    popd<br \/>\nfi<br \/>\ntest -f $rtf\/bin\/node<\/p>\n<p># ================================================================<br \/>\n# jshint<br \/>\n# ================================================================<br \/>\nif [ ! -d pkgs\/node-jshint ] ; then<br \/>\n    pushd pkgs<br \/>\n    docmd env GIT_SSL_NO_VERIFY=true git clone https:\/\/github.com\/jshint\/node-jshint.git<br \/>\n    popd<br \/>\nfi<\/p>\n<p>if [ ! -f $rtf\/bin\/jshint ] ; then<br \/>\n    pushd pkgs\/node-jshint<br \/>\n    docmd .\/configure &#8211;prefix=$rtf<br \/>\n    popd<br \/>\nfi<br \/>\ntest -f $rtf\/bin\/jshint<\/p>\n<p># ================================================================<br \/>\n# rhino &#8212; javascript interpreter<br \/>\n# ================================================================<br \/>\nif [ ! -d pkgs\/rhino ] ; then<br \/>\n    pushd pkgs<br \/>\n    docmd env GIT_SSL_NO_VERIFY=true git clone https:\/\/github.com\/mozilla\/rhino.git<br \/>\n    popd<br \/>\nfi<\/p>\n<p>if [ ! -d rhino\/build ] ; then<br \/>\n    pushd pkgs\/rhino<br \/>\n    docmd ant<br \/>\n    docmd ant compile-all<br \/>\n    docmd ant jar<br \/>\n    popd<br \/>\nfi<\/p>\n<p>if [ ! -d $rtf\/rhino ] ; then<br \/>\n    docmd rsync -avz pkgs\/rhino\/build $rtf\/rhino\/<br \/>\nfi<\/p>\n<p>if [ ! -d $rtf\/bin\/rhino ] ; then<br \/>\n    cat >$rtf\/bin\/rhino <<EOF\n#!\/bin\/bash\n\n# This should handle spaces in arguments:\n#   rhino -e 'print(\"Hello, world!\")''\ni=0\nargv=()\nfor arg in \"\\$@\"; do\n    argv[\\$i]=\"\\$arg\"\n    i=\\$((i + 1))\ndone\n\n# Now execute the command.\njava -jar $rtf\/rhino\/build\/rhino1_7R5pre\/js.jar \"\\${argv[@]}\"\nEOF\n    chmod a+x $rtf\/bin\/rhino\nfi\ntest -f $rtf\/rhino\ntest -f $rtf\/bin\/rhino\n\n# ================================================================\n# Installation tests.\n# ================================================================\nif [ ! -f .OK ] ; then\n    docmd rhino -e 'print(\"hello\");'\n    cat >$$.js <<EOF\nprint(\"hello, world\");\nEOF\n    docmd jshint $$.js\n    rm -f $$.js\n    touch .OK\nfi\n[\/crayon]\nI hope that this is helpful.\n\n\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently had to install jshint and rhino. It was a bit of a challenge because they needed ant and npm (node package manager). This blog describes what I did and provides a bash shell script that you can use.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[15,4,5,16],"tags":[28],"_links":{"self":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/783"}],"collection":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=783"}],"version-history":[{"count":18,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/783\/revisions"}],"predecessor-version":[{"id":851,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/783\/revisions\/851"}],"wp:attachment":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}