Skip to content

Instantly share code, notes, and snippets.

@huntc
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huntc/8911360 to your computer and use it in GitHub Desktop.
Save huntc/8911360 to your computer and use it in GitHub Desktop.
Minimising plugin code for sbt
object JSHintPlugin extends NodeJsPlugin {
object JshintKeys {
val jshint = TaskKey[Unit]("jshint", "Perform JavaScript linting.")
val jshintOptions = TaskKey[String]("jshint-options", "An array of jshint options to pass to the linter. This options are found via jshint-resolved-config. If there is no config then the options will be specified such that the JSHint defaults are used.")
val config = SettingKey[Option[File]]("jshint-config", "The location of a JSHint configuration file.")
val resolvedConfig = TaskKey[Option[File]]("jshint-resolved-config", "The actual location of a JSHint configuration file if present. If jshint-config is none then the task will seek a .jshintrc in the project folder. If that's not found then .jshintrc will be searched for in the user's home folder. This behaviour is consistent with other JSHint tooling.")
}
import WebKeys._
import JshintKeys._
implicit val opInputHasher =
OpInputHasher[File](source => OpInputHash.hashString(source + "|" + jshintOptions))
def jshintSettings = nodeJsSettings ++ Seq(
config := None,
resolvedConfig := {
config.value.orElse {
val JsHintRc = ".jshintrc"
val projectRc = baseDirectory.value / JsHintRc
if (projectRc.exists()) {
Some(projectRc)
} else {
val homeRc = file(System.getProperty("user.home")) / JsHintRc
if (homeRc.exists()) {
Some(homeRc)
} else {
None
}
}
}: Option[File]
},
jshintOptions := {
resolvedConfig.value
.map(config => IO.read(config))
.getOrElse("{}"): String
},
jshint in Assets := jsTask(Assets, jsFilter, jshintOptions, "JavaScript linting"),
jshint in TestAssets := jsTask(TestAssets, jsFilter, jshintOptions, "JavaScript test linting"),
compile in Compile := (compile in Compile).dependsOn(jshint in Assets).value,
test in Test := (test in Test).dependsOn(jshint in Assets, jshint in TestAssets).value
)
}
/*global process, require */
/*
* Lint a number of files.
*
* Arguments:
* 0 - name given to the command invoking the script (unused)
* 1 - filepath of this script (unused)
* 2 - array of file paths to the files to lint
* 3 - jshint options as a Json object
*
* Json array tuples are sent to stdout for each file in error (if any). Each tuple is an array where the
* element 0 corresponds to the file path of the file linted, and element 1 is JSHINT.errors.
*/
(function () {
"use strict";
var args = process.argv;
var console = require("console");
var fs = require("fs");
var jshint = require("jshint");
var SOURCE_FILE_PATHS_ARG = 2;
var OPTIONS_ARG = 3;
var options = JSON.parse(args[OPTIONS_ARG]);
var sourceFilePaths = JSON.parse(args[SOURCE_FILE_PATHS_ARG]);
var sourceFilesToProcess = sourceFilePaths.length;
var results = [];
var problems = [];
sourceFilePaths.forEach(function (sourceFilePath) {
fs.readFile(sourceFilePath, "utf8", function (e, source) {
if (e) {
console.error("Error while trying to read " + source, e);
} else {
var status = jshint.JSHINT(source, options);
results.push({
source: sourceFilePath,
result: status ? null : {filesRead: [sourceFilePath], filesWritten: []}
});
jshint.JSHINT.errors.forEach(function(e) {
problems.push({
message: e.reason,
severity: e.id.substring(1, e.id.length - 1),
lineNumber: e.line,
characterOffset: e.character - 1,
lineContent: e.evidence,
source: sourceFilePath
});
});
}
if (--sourceFilesToProcess === 0) {
console.log(JSON.stringify({results: results, problems: problems}));
}
});
});
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment