html5-lintの出力結果をJenkinsのCheckstyleに対応させる

HTMLファイルの静的解析(構文チェック)をしようと思っていろいろ調べてみたのですが、

  • サイトにアップ前の(インターネットからアクセスできない)状態でチェックできる
  • コマンドラインで解析結果が得られる(Jenkinsとの連携を想定)

を満たすHTML5のチェックツールを見つけることができませんでした。

JavascriptならeslintCSSならcsslintがあって、これらは上記の条件を満たしているのですが、なんで肝心のHTML5用は無いんですかねぇ。
というわけで、mozilla/html5-lintをベースに、Checkstyle形式の解析結果を出力するプログラムをnode.jsでサクッと作ってみました。

実行には'html5-lint'に加えてコマンドライン解析用の'argv'が必要です。
また、The Nu Html Checker (v.Nu)をローカルで走らせ、--serviceオプションでそのURLを指定すれば、完全にオフラインでHTML5の静的解析ができます。

[html5checkstyle.js]

// parse process.argv
var argv = require( 'argv' );
var args = argv.option( [
	{ name: 'service', short: 's', type: 'string' },
	{ name: 'output', short: 'o', type: 'string' },
	{ name: 'errorsOnly', short: 'e', type: 'boolean' }
]).run();

var path = args.targets[0];
var option = { output: 'json' };
if ( args.options.service ) option.service = args.options.service;
if ( args.options.output ) option.output = args.options.output;
if ( args.options.errorsOnly ) option.errorsOnly = args.options.errorsOnly;

var fs = require( 'fs' ),
  html5Lint = require( 'html5-lint' );

fs.readFile( path, 'utf8', function( err, html ) {
  if ( err ) throw err;

  html5Lint( html, option, function( err, results ) {
    if ( err ) throw err;

    if ( typeof results.messages === 'undefined' || args.options.output ) {
      console.log( results );
      return;
    }

    // output Checkstyle format
    console.log( "<?xml version='1.0' encoding='UTF-8'?>" );
    console.log( "<checkstyle><file name='%s'>", path );
    results.messages.forEach( function( msg ) {
      var type = msg.type, // error or warning
          firstLine = msg.firstLine ? msg.firstLine : msg.lastLine,
          firstColumn = msg.firstColumn ? msg.firstColumn: msg.lastColumn;
      var message = msg.message.replace( /[&<>]/g, function( tag ) {
        return { '&': '&amp;', '<': '&lt;', '>': '&gt;', "'": '&apos;', '"': '&quote;' }[ tag ] || tag;
      });

      if ( typeof firstLine === "undefined" && typeof firstColumn === "undefined" )
        console.log( "<error severity='%s' message='%s'/>", type, message );
      else
        console.log( "<error line='%s' column='%s' severity='%s' message='%s'/>", firstLine, firstColumn, type, message );
    });
    console.log( "</file></checkstyle>" );
  });
});

[使い方]

>node html5checkstyle.js チェックしたいHTMLファイル [--service v.NuサービスのURL]

(serviceオプションを指定しない場合は規定の https://html5.validator.nu/ サービスに接続)