Last active
November 12, 2019 10:35
-
-
Save ankon/402d13252b3a103fe21c4612827c8547 to your computer and use it in GitHub Desktop.
VSCode: Incremental build with maven reactors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
// See https://go.microsoft.com/fwlink/?LinkId=733558 | |
// for the documentation about the tasks.json format | |
"version": "0.1.0", | |
"command": "gulp", | |
"isShellCommand": true, | |
"suppressTaskName": true, | |
"tasks": [ | |
{ | |
"taskName": "compile-server", | |
"args": [ "java:compile-server" ], | |
"showOutput": "silent", | |
"isBuildCommand": true, | |
"isWatching": true, | |
"problemMatcher": { | |
"owner": "java", | |
"fileLocation": "absolute", | |
"pattern": [ | |
{ | |
"regexp": "^\\[(ERROR|WARNING|INFO)\\]\\s(.+\\.java):\\[(\\d+,\\d+)\\]\\s(.+)$", | |
"file": 2, | |
"location": 3, | |
"severity": 1, | |
"message": 4 | |
} | |
] | |
} | |
} | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const gulp = require('gulp'); | |
const watch = require('gulp-watch'); | |
const path = require('path'); | |
const through2 = require('through2'); | |
const spawn = require('child_process').spawn; | |
const File = require('vinyl'); | |
// Map of project name to object: | |
// .last: last time it was compiled, to debounce the 'compile-server' logic | |
// .status: last know result (error/success) | |
// .running: if true, then a compile is running for this project. | |
const projects = {}; | |
function getProjectName(file) { | |
const segments = file.relative.split(path.sep); | |
if (segments.length > 1) { | |
return segments[0]; | |
} else { | |
return null; | |
} | |
} | |
function createProject(name) { | |
return { last: 0, running: false, status: 'unknown' }; | |
} | |
/** | |
* Run a maven build for each input `pom.xml` | |
* | |
* If the `pom.xml` is a module maven will be executed with `-pl <module>`, otherwise | |
* it is assumed that this is the root project. | |
* | |
* @param {boolean} [debounce] if `true` then skip silently if this has been requested recently already (ignored if this is a not a project) | |
*/ | |
function runMaven(debounce = false) { | |
return through2.obj(function(file, enc, cb) { | |
if (path.basename(file.path) !== 'pom.xml') { | |
// Ignore non-pom.xmls | |
return cb(); | |
} | |
const args = ['-q', '-B', 'compiler:compile', 'compiler:testCompile' ]; | |
let project; | |
const projectName = getProjectName(file); | |
if (projectName) { | |
project = projects[projectName]; | |
if (project.running) { | |
return cb(); | |
} | |
const now = Date.now(); | |
if (!!debounce && now - project.last < 5000) { | |
return cb(); | |
} | |
project.running = true; | |
project.last = now; | |
args.push('-pl', projectName); | |
} else { | |
args.push('--fail-at-end'); | |
} | |
const mvn = spawn('mvn', args, { shell: true }); | |
// FIXME: Maven prints the same error multiple times for reactor projects -- once in the project, and then in the summary. | |
// We really only need the error once, until VSC dedups things on its own (problemCollectors.ts) | |
mvn.stderr.pipe(process.stderr); | |
mvn.stdout.pipe(process.stdout); | |
mvn.on('close', (code) => { | |
if (project) { | |
project.running = false; | |
project.status = code === 0 ? 'success' : 'failure'; | |
} | |
return cb(); | |
}); | |
}); | |
} | |
// Compile all files once | |
gulp.task('java:compile-initial', function() { | |
function initializeProjects() { | |
return through2.obj(function(file, enc, cb) { | |
const projectName = getProjectName(file); | |
projects[projectName] = createProject(); | |
return cb(null); | |
}, function(cb) { | |
this.push(new File({ | |
cwd: process.cwd(), | |
base: process.cwd(), | |
path: "pom.xml", | |
})); | |
return cb(null); | |
}); | |
} | |
return gulp.src('*/pom.xml') | |
.pipe(initializeProjects()) | |
.pipe(runMaven()); | |
}); | |
// Task that runs continously, and feeds changed files into the 'java:compile-project' task | |
gulp.task('java:compile-server', [ 'java:compile-initial' ], function() { | |
return watch('*/src/**/*.java', { read: false }, function(f) { | |
// Determine the project | |
const projectName = getProjectName(f); | |
return gulp.src(path.join(projectName, 'pom.xml'), { read: false }) | |
.pipe(runMaven(true)); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "...", | |
"version": "...", | |
"devDependencies": { | |
"gulp": "^3.9.1", | |
"gulp-watch": "^4.3.8", | |
"through2": "^2.0.1" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Issues: