Tag: jslint4java

 

jslint4java 1.3.1

I’ve just released jslint4java 1.3.1. This is mostly thanks to Ari Shamash, who did an excellent job of telling me what needed to be done to get NetBeans to understand the output. The changes are small, but probably worth upgrading for if you’re using it.

  • Improved support for NetBeans thanks to Ari Shamash!
  • Correct line numbers (previously off by one).
  • The ant task now states the full path to the file being checked.
  • The build failure now includes the total number of errors found.
  • Updated to JSLint 2009-07-25.

jslint4maven

A real maven plugin for jslint4java would be nice. I will write one, but until then, you can always get away with using the antrun plugin. This is fairly simple to do now that jslint4java is available in the central maven repository.

Here’s a plugin definition of how to do it.

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.3</version>
        <dependencies>
          <dependency>
            <groupId>com.googlecode.jslint4java</groupId>
            <artifactId>jslint4java-ant</artifactId>
            <version>1.3</version>
          </dependency>
        </dependencies>
        <executions>
          <execution>
            <id>jslint</id>
            <phase>test</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <tasks>
                <ant antfile="${basedir}/jslint.xml">
                  <property name="root" location="${basedir}" />
                  <target name="jslint" />
                </ant>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Notice how you can add the jslint4java-ant dependency to the antrun plugin without affecting the dependencies of the project.

At the test phase, maven will now run jslint for you. This relies on a small external ant build file to actually perform the jslint task.

<!-- jslint.xml -->
<project xmlns:jsl="antlib:com.googlecode.jslint4java">
  <target name="jslint">
    <jsl:jslint>
      <formatter type="plain" />
      <fileset dir="${root}/src/main/webapp" includes="**/*.js" />
    </jsl:jslint>
  </target>
</project>

We can use the nice antlibs namespace style of declaration because the jslint4java jar is in the classpath already.

Here, I’m assuming that we’re in a war project and want to validate all the files under src/main/webapp. If this goes wrong, you’ll get an error and the build will stop. For example:

…
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0
 
[INFO] [antrun:run {execution: jslint}]
[INFO] Executing tasks
 
jslint:
[jsl:jslint] contact.js:1:8:Bad line breaking before '+'.
[jsl:jslint]         + " Nulla in felis Aliquam luctus Proin tincidunt nisi Donec suscipit"
[jsl:jslint]         ^
…
[jsl:jslint] load.js:17:6:Missing semicolon.
[jsl:jslint]     })
[jsl:jslint]       ^
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] An Ant BuildException has occured: The following error occurred while executing this line:
/Users/dom/work/someproj/jslint.xml:4: 3 files did not pass JSLint

One side note: originally, I tried to fold the jslint.xml file into the POM as well. But this failed to load the antlib. I suspect that xmlns attributes were not being passed in to the tasks definition. It’s not a big deal..

jslint4java 1.3 post-release notes

These are the things I had to do after releasing.

Firstly, I needed to create a source archive as well as the main distribution archive. Git archive makes this super-easy.

$ git archive --format=zip --prefix='jslint4java-1.3/' rel-1.3 >jslint4java-1.3-src.zip

Secondly, I had to import the latest javadoc into svn at google code (it’s handy for linking to). I extracted this from the -dist.zip that got created as part of the release.

$ cd jslint4java-1.3/docs/apidocs
$ svn import --auto-props https://jslint4java.googlecode.com/svn/apidoc/1.3

Unfortunately, I had to then fix up all the damned properties anyway. I guess my svn config must need some attention.

Naturally, I forgot to update the version in NEWS.txt. Doh.

jslint4java 1.3

I’ve finally released jslint4java 1.3. It’s available for download from google code.

The user visible improvements are few.

  • Better documentation.
  • The indent option is supported.
  • Add getEdition() call.
  • The ant task can now work with any kind of nested resource, not just files.
  • Updated to jslint 2009-07-08

I’ve moved the package names around. Everything is now in com.googlecode.jslint4java instead of net.happygiraffe.jslint. This will mainly affect ant users. The documentation should have some examples of the new form to copy.

The main change behind the scenes is that I’ve switched the build system to maven. This took me much longer than I expected. Though I’m still convinced maven is an effective tool, I can clearly see the rough edges. Still, now it’s done, it should enable more rapid releases in the future.

Publishing a subdirectory to github pages

I’ve written some HTML documentation for jslint4java. It lives in jslint4java-docs/src/main/resources in typical maven fashion. I’d like to get it published on github pages.

The starting point is similar to their documentation.

git symbolic-ref HEAD refs/heads/gh-pages
rm .git/index
git clean -fdx
echo "My GitHub Page" > index.html
git add .
git commit -a -m "First pages commit"
git push origin gh-pages

That lands us with a brand spanking new branch to play with. What I’d like to do is make a new commit on that branch, but from a tree which is already in my repository. The magic word is git commit-tree. It needs two things: the id of the tree and the id of the parent commit to attach to.

The parent to attach to is easy. It’s the tip of the gh-pages branch we just made. git show-ref will let us know the id.

$ git show-ref -s refs/heads/gh-pages
0a0c2a4ef1f9421b6f9537472c0f04fd6485d2cc

The next bit is the tree we want to commit. git ls-tree is the tool for the job.

$ git ls-tree -d HEAD jslint4java-docs/src/main/resources
040000 tree 5feb5926c39b5e6af3a51feb04750c819bf08b94	jslint4java-docs/src/main/resources

git commit-tree will return the id of the new commit it just created. All that remains is to update the gh-pages branch to point at it.

Pulling it all together, we have:

#!/bin/bash
parent_sha=$(git show-ref -s refs/heads/gh-pages)
doc_sha=$(git ls-tree -d HEAD jslint4java-docs/src/main/resources | awk '{print $3}')
new_commit=$(echo "Auto-update docs." | git commit-tree $doc_sha -p $parent_sha)
git update-ref refs/heads/gh-pages $new_commit

This isn’t ideal — it won’t automatically track updates to that directory. But it’s easy enough to run this once in a while to publish an update.

The end result is that my documentation is published.

AntUnit inside Maven

I’m in the middle of converting jslint4java to use maven as its build system (yes, really). Part of this is ensuring that the antunit tests I wrote continue to work. Maven has the antrun plugin, but it’s not 100% obvious how to use an antlib inside it.

Normally, to run an antlib extension as part of your build, you first dump the jar in ~/.ant/lib (or on the command line using a -lib flag) and then reference it in a namespace. e.g.

  <project name="foo"
           xmlns:au="antlib:org.apache.ant.antunit"></project>

This relies on ant being able to pick out org/apache/ant/antunit/antlib.xml from the classpath.

When doing this in maven through the antrun plugin, you can’t just dump stuff into ~/.ant/lib however. You need to tell ant where everything is. Originally, I was following the example of the rat ant task. This attempts to invoke a second copy of ant with the correct -lib argument. It’s ugly though. Why should we fork a second copy of the JVM? And ant may not even be installed (in maven, it’s just jar files in the local repository).

Eventually, I looked closer at the antlib documentation and found Load antlib from inside of the buildfile. This shows how a typedef is the key: You can associate a given antlib URI with a particular classpath entry. Thankfully, maven-antrun-plugin provides ${maven.test.classpath} (amongst others) which contains every entry that we need. So the solution now looks something like this.

Firstly, pom.xml.

  <project>
    <dependencies>
      <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant-antunit</artifactId>
        <version>1.0</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
    <build>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <phase>test</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <tasks>
                <ant antfile="${build.testOutputDirectory}/antunit/tests.xml"
                  inheritAll="false" inheritRefs="false">
                  <property name="test.classpath" refid="maven.test.classpath" />
                </ant>
              </tasks>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <!-- Force an upgrade to a newer ant version.  Required by antunit. -->
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.0</version>
          </dependency>
        </dependencies>
      </plugin>
    </build>
  </project>

So, when we get to the test phase, we automatically run antunit/tests.xml, passing in the correct classpath. This is what the ant file looks like:

  <project name="jslint-antunit"
           xmlns:au="antlib:org.apache.ant.antunit">
 
      <taskdef uri="antlib:org.apache.ant.antunit"
               resource="org/apache/ant/antunit/antlib.xml"
               classpath="${test.classpath}" /></project>

This appears to work quite well, and runs my tests a sight quicker than before. If anybody from the apache rat project is listening, you might want to update your POMs. 🙂

jslint4java 1.2

I’ve finally gotten around to finishing off the code that I’ve had sitting around in google code for over a year, and released jslint4java 1.2. The changes are actually pretty small:

  • Update to jslint 2008-09-04. This adds several new options.
  • Several updates to the ant task:
    • Move the antlib definition to “antlib:net.happygiraffe.jslint” (incompatible change).
    • Default to failing the build if validation fails (incompatible change).
    • Allow use of the fileset element to be more flexible about specifying where your javascript files are. This replaces several attributes on the jslint task (incompatible change).
    • Add a formatter sub-element, which can output either XML or plain text, either to the console or to a file.
    • See the documentation for some examples of the new usage.
  • Allow access to the HTML report produced by JSLint through an API.

I’ve also uploaded the javadoc directly into subversion on google code, so it’s permanently online. The google-collections guys seem to do this, so it can’t be a bad idea, right?

Typical. Five minutes after I release, I notice that it’s been compiled with 1.6 instead of 1.5. So, I’ve just released v1.2.1…

jslint4java 1.1

I’ve put out a new version of jslint4java. The changes aren’t huge, but there are a couple of note:

  • Fix Issue 1: a NullPointerException when jslint gives up. This is doubly annoying because it’s both documented and it caught me out when writing the Perl wrapper, JavaScript-JSLint.
  • I’ve added an ant task so you can verify a bunch of JavaScript files as part of a built. I was really surprised at how easy this was to throw together.
  • I’ve upgraded to the latest version of jslint. It seems to be pickier about whitespace. I do wish Douglas Crockford kept a changelog…

In the meantime, I’ve also been working on an Eclipse plugin. It’s in a “works for me” state at the moment, and needs some more love before it gets published. In particular, it needs to be able to choose whether or not to validate on a file-by-file basis, in case you have a packed JavaScript file.

jslint4java

A while ago, I wrote a small wrapper around jslint in Perl: JavaScript-JSLint. However, it’s a real pain to use. There’s a dependency on JavaScript, which in turn needs a compiled version of spidermonkey.

On a recent Java project at $WORK, I wanted to use jslint as part of our unit tests—evil JavaScript be gone! I hacked together a small junit test involving Rhino and a filewalker. It’s worked surprisingly well; our JS code has stayed quite readable.

However, I was bugged by the implementation. So, I’ve rewritten it into a slightly more sensible form. This is now available as jslint4java. The main interface is command line, which is nice as it’s completely self-contained now. But there is also an API which lets you call it from unit tests.

  % java -jar jslint+rhino.jar application.js
  jslint:application.js:11:9:Line breaking error ')'.
  jslint:application.js:11:10:Missing semicolon.

It’s also been the first time I’ve used enum classes in Java 5. They’re really cute. Being able to enumerate all possible values at run time is really handy. Plus, being able to define additional methods is really handy.

Future directions include:

  • More help towards integrating this into a junit test easily.
  • An Eclipse plugin would be nice, so that you can get the jslint warnings pop up in the Problems view.