Skip to content
This repository has been archived by the owner on Apr 3, 2018. It is now read-only.

Commit

Permalink
Merging [MelnormeLang]
Browse files Browse the repository at this point in the history
# Conflicts:
#	documentation/ChangeLog.md

(fixes #191)
  • Loading branch information
bruno-medeiros committed Apr 29, 2016
2 parents a493411 + e561eb3 commit b4fe402
Show file tree
Hide file tree
Showing 41 changed files with 3,031 additions and 175 deletions.
1 change: 1 addition & 0 deletions documentation/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ It's now possible to specify a command other than the default one (the `go` tool
* Added a setting to invoke a special build target when a Go editor is saved.
* This allows invoking a build command (informally called a "check-build") that only checks for compiler errors, but doesn't not produce binaries. This has the potential to be faster than a full build.
* Default is `go build`. ##TODO
* Added support for modifying the environment variables of a Build Target's build command. (fixes #191)

* Fixed "IllegalStateException: The service has been unregistered" on Mars.2 when Eclipse is closed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ public void test_compositeBuildTargetSettings() throws Exception {

protected CompositeBuildTargetSettings btSettings(
String buildTargetName, String buildArguments, String artifactPath) {
CommandInvocation buildCommand = buildArguments == null ? null : new CommandInvocation(buildArguments);
return getBuiltTargetSettingsValidator(project.getName(), buildTargetName, buildCommand, artifactPath);
return getBuiltTargetSettingsValidator(project.getName(), buildTargetName, cmd(buildArguments), artifactPath);
}

protected CompositeBuildTargetSettings getBuiltTargetSettingsValidator(
Expand Down Expand Up @@ -349,15 +348,15 @@ protected void testBuildOperation_Vars(ProjectBuildInfo buildInfo, BuildTarget b

}

protected Indexable<String> getBuildOperation(ProjectBuildInfo buildInfo, BuildTarget btB, String buildArguments)
protected Iterable<String> getBuildOperation(ProjectBuildInfo buildInfo, BuildTarget btB, String buildArguments)
throws CommonException {
BuildTargetData dataCopy = btB.getDataCopy();
dataCopy.buildCommand = cmd(buildArguments);
dataCopy.buildCommand = new CommandInvocation(buildArguments);
BuildTarget newBuildTarget = buildInfo.buildMgr.createBuildTarget(buildInfo.project, dataCopy);

ToolManager toolMgr = buildInfo.buildMgr.getToolManager();
BuildTargetOperation buildOperation = newBuildTarget.getBuildOperation(toolMgr, opMonitor);
return buildOperation.getEffectiveProccessCommandLine();
return buildOperation.getConfiguredProcessBuilder().command();
}

/* ----------------- ----------------- */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,73 @@

import org.junit.Test;

import melnorme.lang.ide.core.LangCore;
import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.collections.HashMap2;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.misc.Pair;
import melnorme.utilbox.tests.CommonTest;

public class BuildTargetsSerializer_Test extends CommonTest {

private static final String STRING_ENCODING__ALL_ASCII = "value:a;b\\\"()dff{}[]";

public static CommandInvocation cmd(String commandArguments) {
return commandArguments == null ? null :new CommandInvocation(commandArguments);
if(commandArguments == null) {
return null;
}
HashMap2<String, String> map = new HashMap2<>();
map.put("MY_ENV_VAR", STRING_ENCODING__ALL_ASCII);
return new CommandInvocation(commandArguments, map, true);
}

public static CommandInvocation cmd(String commandArguments, boolean append, Pair<String, String>[] entries) {
HashMap2<String, String> envMap = null;

if(entries != null) {
envMap = new HashMap2<>();
for (Pair<String,String> pair : entries) {
envMap.put(pair.getFirst(), pair.getSecond());
}
}
return new CommandInvocation(commandArguments, envMap, append);
}

public static Pair<String, String> entry(String key, String value) {
return new Pair<>(key, value);
}

@Test
public void test_CommandInvocation() throws Exception { test_CommandInvocation$(); }
public void test_CommandInvocation$() throws Exception {
testSerializeCmd(null);
testSerializeCmd(cmd("", true, null));
testSerializeCmd(cmd("", false, null));
testSerializeCmd(cmd("asdf", true, array()));

testSerializeCmd(cmd("asdf", true, array(
entry("one", "1")
)));
testSerializeCmd(cmd("asdf", true, array(
entry("one", "")
)));
testSerializeCmd(cmd("asdf", true, array(
entry("one", "1"),
entry("two", ""),
entry(STRING_ENCODING__ALL_ASCII, STRING_ENCODING__ALL_ASCII)
)));
}

protected void testSerializeCmd(CommandInvocation command) {
CommandInvocationSerializer serializer = new CommandInvocationSerializer();
try {
String xml = serializer.writeToString(command);
assertAreEqual(command, serializer.readFromString(xml));
} catch(CommonException e) {
assertFail();
}
}


public static BuildTargetData bt(String targetName, boolean enabled, boolean autoEnabled,
String buildArguments, String executablePath) {
return btd(targetName, enabled, autoEnabled, cmd(buildArguments), executablePath);
Expand All @@ -45,19 +101,18 @@ public static BuildTargetData btd(String targetName, boolean enabled, boolean au
return bt;
}

protected final BuildManager buildMgr = LangCore.getBuildManager();
protected BuildTargetsSerializer serializer = buildMgr.createSerializer();
protected BuildTargetsSerializer serializer = new BuildTargetsSerializer();

@Test
public void test() throws Exception { test$(); }
public void test$() throws Exception {
testSerialize(new ArrayList2<>());
testSerialize(new ArrayList2<>(bt("", false, false, null, null)));
testSerialize(new ArrayList2<>(btd("", false, false, null, null)));
testSerialize(new ArrayList2<>(btd("", true, true, cmd("-opt"), "foo.exe")));
testSerialize(new ArrayList2<>(
btd("", false, true, cmd(""), ""),
btd("blah", true, false, cmd("-opt"), "foo.exe"),
bt("xxx", true, false, null, "foo/bar.ooo")
btd("xxx", true, false, null, "foo/bar.ooo")
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ public final ProcessBuilder createToolProcessBuilder(IProject project, Path tool
}

public ProcessBuilder createToolProcessBuilder(Indexable<String> commandLine, Location workingDir) {
return ProcessUtils.createProcessBuilder(commandLine, workingDir);
return modifyToolProcessBuilder(ProcessUtils.createProcessBuilder(commandLine, workingDir));
}

public ProcessBuilder modifyToolProcessBuilder(ProcessBuilder pb) {
return pb;
}

public ProcessBuilder createSimpleProcessBuilder(IProject project, String... commands)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public ProjectBuildInfo getValidBuildInfo(IProject project, boolean requireNonEm
new StringPreference("build_targets", "").getProjectPreference();

protected BuildTargetsSerializer createSerializer() {
return new BuildTargetsSerializer(this);
return new BuildTargetsSerializer();
}

protected String getBuildTargetsPref(IProject project) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import melnorme.lang.ide.core.operations.ILangOperationsListener_Default.IOperationMonitor;
import melnorme.lang.ide.core.operations.ToolManager;
import melnorme.lang.ide.core.utils.ProgressSubTaskHelper;
import melnorme.lang.tooling.data.StatusException;
import melnorme.utilbox.collections.Indexable;
import melnorme.utilbox.concurrency.OperationCancellation;
import melnorme.utilbox.core.CommonException;
Expand Down Expand Up @@ -75,16 +76,16 @@ protected String getBuildOperationName() {

public Indexable<String> getEffectiveProccessCommandLine() throws CommonException {
VariablesResolver variablesManager = toolManager.getVariablesManager(option(getProject()));
return buildCommand.getValidatedCommandArguments(variablesManager).getValidatedValue();
return buildCommand.validateCommandArguments(variablesManager);
}

public ProcessBuilder getToolProcessBuilder() throws CommonException, OperationCancellation {
return getProcessBuilder3(getEffectiveProccessCommandLine());
public ProcessBuilder getConfiguredProcessBuilder() throws StatusException {
VariablesResolver variablesManager = toolManager.getVariablesManager(option(getProject()));
return buildCommand.getProcessBuilder(variablesManager);
}

protected ProcessBuilder getProcessBuilder3(Indexable<String> commandLine)
throws CommonException, OperationCancellation {
return getToolManager().createToolProcessBuilder(commandLine, getProjectLocation());
public ProcessBuilder getToolProcessBuilder() throws CommonException, OperationCancellation {
return getToolManager().modifyToolProcessBuilder(getConfiguredProcessBuilder());
}

public void runBuildToolAndProcessOutput(ProcessBuilder pb, IProgressMonitor pm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,9 @@ public class BuildTargetsSerializer extends DocumentSerializerHelper<Indexable<?

/* ----------------- ----------------- */

protected final BuildManager buildManager;

protected final CommandInvocationSerializer commandSerializer = new CommandInvocationSerializer();

public BuildTargetsSerializer(BuildManager buildManager) {
this.buildManager = buildManager;
public BuildTargetsSerializer() {
}

public String writeProjectBuildInfo(ProjectBuildInfo projectBuildInfo) throws CommonException {
Expand All @@ -61,8 +58,14 @@ protected void writeDocument(Document doc, Indexable<? extends BuildTargetDataVi

}

@SuppressWarnings("unchecked")
@Override
public ArrayList2<BuildTargetData> readFromString(String targetsXml) throws CommonException {
return (ArrayList2<BuildTargetData>) super.readFromString(targetsXml);
}

@Override
public ArrayList2<BuildTargetData> doReadFromString(String targetsXml) throws CommonException {
Document doc = parseDocumentFromXml(targetsXml);

Node buildTargetsElem = doc.getFirstChild();
Expand Down Expand Up @@ -93,7 +96,7 @@ protected Element writeBuildTargetElement(Document doc, BuildTargetDataView btd)

commandSerializer.writeToParent(targetElem, btd.getBuildCommand());

setOptionalAttribute(targetElem, PROP_EXE_PATH, btd.getExecutablePath());
setAttribute(targetElem, PROP_EXE_PATH, btd.getExecutablePath());

return targetElem;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,36 @@
import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import static melnorme.utilbox.core.CoreUtil.areEqual;

import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.debug.core.DebugPlugin;

import melnorme.lang.tooling.data.Severity;
import melnorme.lang.tooling.data.StatusException;
import melnorme.lang.tooling.data.validation.ValidatedValueSource;
import melnorme.lang.utils.ProcessUtils;
import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.collections.HashMap2;
import melnorme.utilbox.collections.Indexable;
import melnorme.utilbox.collections.MapAccess;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.misc.HashcodeUtil;

public class CommandInvocation {

protected final String commandArguments;
protected final MapAccess<String, String> environmentVars; // Can be null
protected final boolean appendEnvironment;

public CommandInvocation(String commandArguments) {
this.commandArguments = assertNotNull(commandArguments);
this(commandArguments, null, true);
}

public String getCommandArguments() {
return commandArguments;
public CommandInvocation(String commandArguments, MapAccess<String, String> envVars, boolean appendEnv) {
this.commandArguments = assertNotNull(commandArguments);
this.environmentVars = envVars != null ? envVars : new HashMap2<>();
this.appendEnvironment = appendEnv;
}

@Override
Expand All @@ -42,16 +52,56 @@ public boolean equals(Object obj) {

CommandInvocation other = (CommandInvocation) obj;

return areEqual(commandArguments, other.commandArguments);
return
areEqual(commandArguments, other.commandArguments) &&
areEqual(environmentVars, other.environmentVars) &&
areEqual(appendEnvironment, other.appendEnvironment);
}

@Override
public int hashCode() {
return HashcodeUtil.combinedHashCode(commandArguments);
return HashcodeUtil.combinedHashCode(commandArguments, environmentVars);
}

public String getCommandArguments() {
return commandArguments;
}

public MapAccess<String, String> getEnvironmentVars() {
return environmentVars;
}

public boolean isAppendEnvironment() {
return appendEnvironment;
}

/* ----------------- ----------------- */

public ProcessBuilder getProcessBuilder(VariablesResolver variablesResolver) throws StatusException {
Indexable<String> CommandLine = validateCommandArguments(variablesResolver);

ProcessBuilder pb = ProcessUtils.createProcessBuilder(CommandLine, null);

setupEnvironment(pb.environment());

return pb;
}

public void setupEnvironment(Map<String, String> environment) {
if(!isAppendEnvironment()) {
environment.clear();
}
for (Entry<String, String> envVar : getEnvironmentVars()) {
environment.put(envVar.getKey(), envVar.getValue());
}
}

public void validate(VariablesResolver variablesResolver) throws StatusException {
getValidatedCommandArguments(variablesResolver).validate();
validateCommandArguments(variablesResolver);
}

public Indexable<String> validateCommandArguments(VariablesResolver variablesResolver) throws StatusException {
return getValidatedCommandArguments(variablesResolver).getValidatedValue();
}

public ValidatedCommandArgumentsSource getValidatedCommandArguments(VariablesResolver variablesResolver) {
Expand Down Expand Up @@ -80,17 +130,21 @@ public Indexable<String> getValidatedValue() throws StatusException {
}

public Indexable<String> doGetValidatedValue(VariablesResolver variablesResolver) throws CommonException {
if(commandArguments == null) {
handleNoCommandLine();
}

String evaluatedCommandLine = variablesResolver.performStringSubstitution(commandArguments);

if(evaluatedCommandLine.trim().isEmpty()) {
handleEmptyCommandLine();
handleNoCommandLine();
}

String[] evaluatedArguments = DebugPlugin.parseArguments(evaluatedCommandLine);
return new ArrayList2<>(evaluatedArguments);
}

protected void handleEmptyCommandLine() throws CommonException {
protected void handleNoCommandLine() throws CommonException {
throw new CommonException(MSG_NO_COMMAND_SPECIFIED);
}

Expand Down
Loading

0 comments on commit b4fe402

Please sign in to comment.