/**
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.puppetlint.impl;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.cloudsmith.geppetto.common.os.OsUtil;
import org.cloudsmith.geppetto.common.os.StreamUtil.OpenBAStream;
import org.cloudsmith.geppetto.puppetlint.PuppetLintRunner;
/**
* A PuppetLintRunner implementation that uses an external command. This runner will require that Ruby is installed
*/
public class ExternalPuppetLintRunner implements PuppetLintRunner {
private static final Pattern issuePattern = Pattern.compile(
"^(ERROR|WARNING)\\s+([a-zA-Z0-9_-]+)\\s+#([^#]+)#:(\\d+)\\s+(.*)$", Pattern.MULTILINE);
private static final Pattern versionPattern = Pattern.compile("^[A-Za-z0-9_.-]+\\s+(\\S+)\\s*$", Pattern.MULTILINE);
private static String getPuppetLintExecutable() {
String puppetLint = System.getenv("PUPPET_LINT_EXECUTABLE");
if(puppetLint == null)
puppetLint = "puppet-lint";
return puppetLint;
}
@Override
public String getVersion() throws IOException {
// Verify that puppet-lint is installed. If not, then refuse to install this bundle
OpenBAStream out = new OpenBAStream();
OpenBAStream err = new OpenBAStream();
File home = new File(System.getProperty("user.home"));
int exitCode = OsUtil.runProcess(home, out, err, getPuppetLintExecutable(), "--version");
String outStr = out.toString(Charset.defaultCharset());
if(exitCode != 0) {
StringBuilder bld = new StringBuilder();
bld.append("Got exit code ");
bld.append(exitCode);
bld.append(" when running puppet-lint.");
outStr = outStr.trim();
if(!outStr.isEmpty()) {
bld.append(" Output \"");
bld.append(outStr);
bld.append('"');
}
String errStr = err.toString(Charset.defaultCharset()).trim();
if(!errStr.isEmpty()) {
bld.append(" Errors \"");
bld.append(errStr);
bld.append('"');
}
throw new IOException(bld.toString());
}
String version = outStr;
Matcher m = versionPattern.matcher(version);
if(m.find())
version = m.group(1);
return version;
}
@Override
public List<Issue> run(File fileOrDirectory, Option... options) throws IOException {
String pathToCheck = ".";
if(fileOrDirectory.isFile()) {
pathToCheck = fileOrDirectory.getName();
fileOrDirectory = fileOrDirectory.getParentFile();
}
List<String> params = new ArrayList<String>();
params.add(getPuppetLintExecutable());
params.add("--log-format");
params.add("%{KIND} %{check} #%{path}#:%{linenumber} %{message}");
for(Option option : options)
params.add("--" + option);
params.add(pathToCheck);
OpenBAStream out = new OpenBAStream();
OpenBAStream err = new OpenBAStream();
OsUtil.runProcess(fileOrDirectory, out, err, params.toArray(new String[params.size()]));
List<Issue> issues = new ArrayList<Issue>();
Matcher m = issuePattern.matcher(out.toString(Charset.defaultCharset()));
while(m.find()) {
String path = m.group(3);
if(path.startsWith("./") || path.startsWith(".\\"))
path = path.substring(2);
issues.add(new PuppetLintIssue(
path, Severity.valueOf(m.group(1)), m.group(2), m.group(5), Integer.parseInt(m.group(4))));
}
return issues;
}
}