/*******************************************************************************
* Copyright (c) 2014 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package com.googlecode.goclipse.tooling.env;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.Map;
import com.googlecode.goclipse.tooling.GoPackageName;
import melnorme.lang.utils.EnvUtils;
import melnorme.lang.utils.ProcessUtils;
import melnorme.utilbox.collections.Indexable;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.misc.Location;
/**
* Immutable description of a Go environment, under which Go operations and semantic analysis can be run.
* (similar to a build path)
*/
public class GoEnvironment {
protected final GoRoot goRoot;
protected final GoPath goPath;
public GoEnvironment(GoRoot goRoot, GoPath goPath) {
this.goRoot = assertNotNull(goRoot);
this.goPath = assertNotNull(goPath);
}
public GoEnvironment(GoRoot goRoot, String goPath) {
this(goRoot, new GoPath(goPath));
}
public GoRoot getGoRoot() {
return goRoot;
}
public Location getGoRoot_Location() throws CommonException {
return goRoot.asLocation();
}
public GoPath getGoPath() {
return goPath;
}
public Indexable<String> getGoPathEntries() {
return goPath.getGoPathEntries();
}
public String getGoPathString() {
return goPath.getGoPathString();
}
/* ----------------- validation: ----------------- */
public void validate() throws CommonException {
goRoot.validate();
goPath.validate();
}
public static boolean isNullOrEmpty(String string) {
return string == null || string.isEmpty();
}
/* ----------------- ----------------- */
public GoPackageName findGoPackageForSourceFile(Location goSourceFileLoc) throws CommonException {
Location goPackageLocation = goSourceFileLoc.getParent();
return findGoPackageForLocation(goPackageLocation);
}
public GoPackageName findGoPackageForLocation(Location goPackageLocation) throws CommonException {
GoPackageName goPackage = goRoot.findGoPackageForLocation(goPackageLocation);
if(goPackage != null) {
return goPackage;
}
return goPath.findGoPackageForLocation(goPackageLocation);
}
protected static GoPackageName getGoPackageForLocation(Location goPackageLocation, Location sourceRoot) {
if(goPackageLocation == null || !goPackageLocation.startsWith(sourceRoot)) {
return null;
}
Path goPackageRelPath = sourceRoot.relativize(goPackageLocation);
if(goPackageRelPath.toString().isEmpty()) {
return null;
}
return GoPackageName.fromPath(goPackageRelPath);
}
public Location getBinFolderLocationForSubLocation(Location goPathSubLocation) throws CommonException {
GoWorkspaceLocation goWorkspace = getGoPath().findGoPathEntry(goPathSubLocation);
if(goWorkspace == null) {
throw new CommonException(
MessageFormat.format("Could not find path `{0}` in a GOPATH entry: ", goPathSubLocation));
}
return goWorkspace.getBinLocation();
}
/* ----------------- process builder ----------------- */
public ProcessBuilder createProcessBuilder(Indexable<String> commandLine, Location workingDir)
throws CommonException {
return createProcessBuilder(commandLine, workingDir, true);
}
public ProcessBuilder createProcessBuilder(Indexable<String> commandLine, Location workingDir, boolean goRootInPath)
throws CommonException {
ProcessBuilder pb = ProcessUtils.createProcessBuilder(commandLine, workingDir);
setupProcessEnv(pb, goRootInPath);
return pb;
}
public void setupProcessEnv(ProcessBuilder pb, boolean goRootInPath) throws CommonException {
Map<String, String> env = pb.environment();
// BM: This code setting GOROOT has been commented out, this causes problems for non-archive Go installations,
// and google information seems to indicate this should not be set at all.
// Probably this came from old code that doesn't apply anymore.
// putMapEntry(env, GoEnvironmentConstants.GOROOT, goRoot.asString());
putMapEntry(env, GoEnvironmentConstants.GOPATH, getGoPathString());
if(goRootInPath) {
// Add GoRoot to path. See #113 for rationale
EnvUtils.addLocationToPathEnv(getGoRoot_Location(), pb);
}
}
protected void putMapEntry(Map<String, String> env, String key, String value) {
if(value != null) {
env.put(key, value);
}
}
}