Package ro.redeul.google.go.sdk

Source Code of ro.redeul.google.go.sdk.GoSdkUtil

package ro.redeul.google.go.sdk;

import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.CapturingProcessHandler;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ro.redeul.google.go.GoIcons;
import ro.redeul.google.go.config.sdk.*;
import ro.redeul.google.go.ide.GoGlobalSettings;
import ro.redeul.google.go.ide.GoProjectSettings;
import ro.redeul.google.go.lang.stubs.GoNamesCache;
import ro.redeul.google.go.util.GoUtil;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.String.format;

public class GoSdkUtil {

    public static final String PACKAGES = "src/pkg";

    private static final Logger LOG = Logger.getInstance(
            "ro.redeul.google.go.sdk.GoSdkUtil");
    private static final String TEST_SDK_PATH = "go.test.sdk.home";

    private static final String DEFAULT_MOCK_PATH = "go/default";

    private static final String ENV_GO_ROOT = "GOROOT";

    // release: "xx"
    private static final Pattern RE_APP_ENGINE_VERSION_MATCHER =
            Pattern.compile("^release: \"([^\"]+)\"$", Pattern.MULTILINE);

    private static final Pattern RE_APP_ENGINE_TIMESTAMP_MATCHER =
            Pattern.compile("^timestamp: ([0-9]+)$", Pattern.MULTILINE);

    private static final Pattern RE_APP_ENGINE_API_VERSIONS_MATCHER =
            Pattern.compile("^api_versions: \\[([^\\]]+)\\]$", Pattern.MULTILINE);

    private static final Pattern RE_OS_MATCHER =
            Pattern.compile("^(?:set )?GOOS=\"?(darwin|freebsd|linux|windows)\"?$",
                    Pattern.MULTILINE);

    private static final Pattern RE_ARCH_MATCHER =
            Pattern.compile("^(?:set )?GOARCH=\"?(386|amd64|arm)\"?$",
                    Pattern.MULTILINE);

    private static final Pattern RE_HOSTOS_MATCHER =
            Pattern.compile("^(?:set )?GOHOSTOS=\"?(darwin|freebsd|openbsd|linux|windows)\"?$",
                    Pattern.MULTILINE);

    private static final Pattern RE_HOSTARCH_MATCHER =
            Pattern.compile("^(?:set )?GOHOSTARCH=\"?(386|amd64|arm)\"?$",
                    Pattern.MULTILINE);

    private static final Pattern RE_ROOT_MATCHER =
            Pattern.compile("^(?:set )?GOROOT=\"?([^\"]+)\"?$", Pattern.MULTILINE);

    public static GoSdkData testGoogleGoSdk(String path) {

        if (!checkFolderExists(path)) {
            LOG.warn("GO SDK: Could not find root directory @ "+path);
            return null;
        }

        if (!checkFolderExists(path, "src")) {
            LOG.warn("GO SDK: Could not find src directory @ "+path+"/src");
            return null;
        }

        if (!checkFolderExists(path, "pkg")) {
            LOG.warn("GO SDK: Could not find src directory @ "+path+"/pkg");
            return null;
        }

        String goCommand = findGoExecutable(path);
        if (goCommand.equals("")) {
            LOG.warn("GO SDK: Could not find go binary in expected locations.");
            return null;
        }

        GoSdkData data = findHostOsAndArch(path, goCommand, new GoSdkData());

        data = findVersion(path, goCommand, data);

        if (data != null) {
            data.GO_GOROOT_PATH = path;
            data.GO_BIN_PATH = goCommand;
            data.version = GoSdkData.LATEST_VERSION;
        }

        return data;
    }

    public static String findGoExecutable(String path) {
        String goCommand = path + "/bin/go";
        if (checkFileExists(goCommand)) {
            return goCommand;
        }

        // Perhaps we're on Windows?
        goCommand = path + "/bin/go.exe";
        if (checkFileExists(goCommand)) {
            return goCommand;
        }

        // Perhaps we are not on Windows but the packers have a different idea
        // on how this should work...
        goCommand = "/usr/bin/go";
        if (checkFileExists(goCommand)) {
            return goCommand;
        }

        // Well then no go executable for us :(
        return "";
    }

    public static VirtualFile getSdkSourcesRoot(Sdk sdk) {
        final VirtualFile homeDirectory = sdk.getHomeDirectory();

        if (checkFolderExists(homeDirectory.getPath(), "src")) {
            return homeDirectory.findFileByRelativePath("src/pkg");
        }
        LOG.warn("Could not find GO SDK sources root (src/pkg)");
        return null;
    }

    private static GoSdkData findVersion(final String path, String goCommand, GoSdkData data) {

        if (data == null)
            return null;

        try {
            GeneralCommandLine command = new GeneralCommandLine();
            command.setExePath(goCommand);
            command.addParameter("version");
            command.withWorkDirectory(path);
            command.getEnvironment().put("GOROOT", path);

            ProcessOutput output = new CapturingProcessHandler(
                    command.createProcess(),
                    Charset.defaultCharset(),
                    command.getCommandLineString()).runProcess();

            if (output.getExitCode() != 0) {
                LOG.error("Go compiler exited with invalid exit code: " +
                        output.getExitCode());
                return null;
            }

            data.VERSION_MAJOR = output.getStdout().replaceAll("go version", "").trim();
            return data;
        } catch (Exception e) {
            LOG.error("Exception while executing the process:", e);
            return null;
        }
    }

    private static GoSdkData findHostOsAndArch(final String path, String goCommand, GoSdkData data) {

        if (data == null)
            return data;

        try {
            GeneralCommandLine command = new GeneralCommandLine();
            command.setExePath(goCommand);
            command.addParameter("env");
            command.withWorkDirectory(path);
            command.getEnvironment().put("GOROOT", path);

            ProcessOutput output = new CapturingProcessHandler(
                    command.createProcess(),
                    Charset.defaultCharset(),
                    command.getCommandLineString()).runProcess();

            if (output.getExitCode() != 0) {
                LOG.error(
                        format(
                                "%s env command exited with invalid exit code: %d",
                                goCommand, output.getExitCode()));
                return null;
            }

            String outputString = output.getStdout();

            Matcher matcher;
            matcher = RE_HOSTOS_MATCHER.matcher(outputString);
            if (matcher.find()) {
                data.TARGET_OS = GoTargetOs.fromString(matcher.group(1));
            }

            matcher = RE_HOSTARCH_MATCHER.matcher(outputString);
            if (matcher.find()) {
                data.TARGET_ARCH = GoTargetArch.fromString(matcher.group(1));
            }
        } catch (ExecutionException e) {
            LOG.error("Exception while executing the process:", e);
            return null;
        }

        if (data.TARGET_ARCH != null && data.TARGET_OS != null)
            return data;

        LOG.warn("Could not determine Target Arch or OS");
        return null;
    }

    public static GoAppEngineSdkData testGoAppEngineSdk(String path) {

        if (!checkFolderExists(path)
                || !checkFileExists(path, "dev_appserver.py")
                || !(checkFileExists(path, "goapp") || checkFileExists(path, "goapp.bat"))
                || !checkFolderExists(path, "goroot")
                || !checkFolderExists(path, "goroot", "pkg"))
            return null;

        if (!checkFileExists(path, "VERSION"))
            return null;


        GoAppEngineSdkData sdkData = new GoAppEngineSdkData();

        sdkData.SDK_HOME_PATH = path;
        sdkData.GOAPP_BIN_PATH = getGoAppBinPath(path);
        sdkData.GO_HOME_PATH = format("%s%sgoroot", path, File.separator);

        String execName = sdkData.GO_HOME_PATH + "/bin/go";
        if (isHostOsWindows()) {
            execName += ".exe";
        }
        String homePath = sdkData.GO_HOME_PATH + "/bin";

        GeneralCommandLine command = new GeneralCommandLine();
        if (checkFileExists(execName)) {
            execName = sdkData.GO_HOME_PATH + "/../goapp";
            if (isHostOsWindows()) {
                execName += ".bat";
            }
            homePath = sdkData.GO_HOME_PATH + "/..";

            if (!checkFileExists(execName)) {
                return null;
            }
        }

        command.setExePath(execName);
        command.withWorkDirectory(homePath);
        command.addParameter("env");

        sdkData.TARGET_ARCH = GoTargetArch._amd64;
        sdkData.TARGET_OS = GoTargetOs.Linux;

        try {
            ProcessOutput output = new CapturingProcessHandler(
                    command.createProcess(),
                    Charset.defaultCharset(),
                    command.getCommandLineString()).runProcess();

            if (output.getExitCode() != 0) {
                LOG.error("Go command exited with invalid exit code: " +
                        output.getExitCode());
                return null;
            }

            String outputString = output.getStdout();

            Matcher matcher = RE_OS_MATCHER.matcher(outputString);
            if (matcher.find()) {
                sdkData.TARGET_OS = GoTargetOs.fromString(matcher.group(1));
            }

            matcher = RE_ARCH_MATCHER.matcher(outputString);
            if (matcher.find()) {
                sdkData.TARGET_ARCH = GoTargetArch.fromString(matcher.group(1));
            }
        } catch (ExecutionException e) {
            LOG.error("Exception while executing the process:", e);
        }

        try {
            String fileContent =
                    VfsUtil.loadText(VfsUtil.findFileByIoFile(new File(format("%s/VERSION", path)), true));

            Matcher matcher = RE_APP_ENGINE_VERSION_MATCHER.matcher(
                    fileContent);

            if (!matcher.find())
                return null;
            sdkData.VERSION_MAJOR = matcher.group(1);

            matcher = RE_APP_ENGINE_TIMESTAMP_MATCHER.matcher(fileContent);
            if (!matcher.find())
                return null;
            sdkData.VERSION_MINOR = matcher.group(1);

            matcher = RE_APP_ENGINE_API_VERSIONS_MATCHER.matcher(fileContent);
            if (!matcher.find())
                return null;

            sdkData.API_VERSIONS = matcher.group(1);

            sdkData.version = GoAppEngineSdkData.LATEST_VERSION;

        } catch (IOException e) {
            return null;
        }

        return sdkData;
    }

    @NotNull
    public static String getGoAppBinPath(String goAppPath) {
        String goExecName = goAppPath + File.separator + "goapp";

        if (isHostOsWindows()) {
            goExecName = goExecName.concat(".exe");
        }

        return goExecName;
    }

    private static boolean checkFileExists(String path, String child) {
        return checkFileExists(new File(path, child));
    }

    public static boolean checkFileExists(String path) {
        return checkFileExists(new File(path));
    }

    public static boolean checkFileExists(File file) {
        return file.exists() && file.isFile();
    }

    public static boolean checkFolderExists(String path) {
        return checkFolderExists(new File(path));
    }

    public static boolean checkFolderExists(File file) {
        return file.exists() && file.isDirectory();
    }

    public static boolean checkFolderExists(String path, String child) {
        return checkFolderExists(new File(path, child));
    }

    public static boolean checkFolderExists(String path, String child, String child2) {
        return checkFolderExists(new File(new File(path, child), child2));
    }

    private static String getArchivePackerName() {
        return "gopack";
    }

    public static String getCompilerName(GoTargetArch arch) {
        return getBinariesDesignation(arch) + "g";
    }

    public static String getLinkerName(GoTargetArch arch) {
        return getBinariesDesignation(arch) + "l";
    }

    public static String getBinariesDesignation(GoTargetArch arch) {

        switch (arch) {
            case _386:
                return "8";

            case _amd64:
                return "6";

            case _arm:
                return "5";
        }

        return "unknown";
    }

    public static Sdk getGoogleGoSdkForModule(Module module) {

        ModuleRootModel moduleRootModel = ModuleRootManager.getInstance(module);

        Sdk sdk;
        if (!moduleRootModel.isSdkInherited()) {
            sdk = moduleRootModel.getSdk();
        } else {
            sdk = ProjectRootManager.getInstance(module.getProject())
                    .getProjectSdk();
        }

        if (GoSdkType.isInstance(sdk)) {
            return sdk;
        }

        return null;
    }

    public static Sdk getGoogleGoSdkForProject(Project project) {

        Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk();

        if (GoSdkType.isInstance(sdk)) {
            return sdk;
        }

        return null;
    }

    public static Sdk getGoogleGAESdkForProject(Project project) {

        Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk();

        if (GoAppEngineSdkType.isInstance(sdk)) {
            return sdk;
        }

        return null;
    }

    public static Sdk getGoogleGoSdkForFile(PsiFile file) {
        ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(
                file.getProject()).getFileIndex();
        Module module = projectFileIndex.getModuleForFile(
                file.getVirtualFile());

        return getGoogleGoSdkForModule(module);
    }

    public static String getToolName(GoTargetArch arch, GoSdkTool tool) {

        String binariesDesignation = getBinariesDesignation(arch);

        switch (tool) {
            case GoCompiler:
                return binariesDesignation + "g";
            case GoLinker:
                return binariesDesignation + "l";
            case GoArchivePacker:
                return "pack";
            case GoMake:
                return "gomake";
            case GoFmt:
                return "gofmt";
        }

        return "";
    }

    public static String resolvePotentialGoogleGoAppEngineHomePath() {

        if (!isSdkRegistered(
                PathManager.getHomePath() + "/bundled/go-appengine-sdk",
                GoAppEngineSdkType
                        .getInstance())) {
            return PathManager.getHomePath() + "/bundled/go-appengine-sdk";
        }

        String path = System.getenv("PATH");
        if (path == null) {
            return null;
        }

        String[] parts = path.split("[:;]+");
        for (String part : parts) {
            if (!isSdkRegistered(part, GoAppEngineSdkType.getInstance())) {
                return part;
            }
        }

        return SystemProperties.getUserHome();
    }


    public static String resolvePotentialGoogleGoHomePath() {

        if (!isSdkRegistered(PathManager.getHomePath() + "/bundled/go-sdk",
                GoSdkType.getInstance())) {
            return PathManager.getHomePath() + "/bundled/go-sdk";
        }

        String goRoot = System.getenv(ENV_GO_ROOT);
        if (goRoot != null && !isSdkRegistered(goRoot,
                GoSdkType.getInstance())) {
            return goRoot;
        }

        String command = "go";
        if (GoUtil.testGoHomeFolder("/usr/lib/go") &&
                new File("/usr/lib/go/bin/go").canExecute()) {
            command = "/usr/lib/go/bin/go";
        } else if (GoUtil.testGoHomeFolder("/usr/local/go") &&
                new File("/usr/local/go/bin/go").canExecute()) {
            command = "/usr/local/go/bin/go";
        }

        GeneralCommandLine goCommandLine = new GeneralCommandLine();

        goCommandLine.setExePath(command);
        goCommandLine.addParameter("env");

        LOG.info("command: " + command);

        try {
            ProcessOutput output = new CapturingProcessHandler(
                    goCommandLine.createProcess(),
                    Charset.defaultCharset(),
                    goCommandLine.getCommandLineString()).runProcess();

            if (output.getExitCode() == 0) {
                String outputString = output.getStdout();

                LOG.info("Output:\n" + outputString);
                Matcher matcher = RE_ROOT_MATCHER.matcher(outputString);
                if (matcher.find()) {
                    LOG.info("Matched: " + matcher.group(1));
                    return matcher.group(1);
                }
            }
        } catch (ExecutionException e) {
            //
        }

        return SystemProperties.getUserHome();
    }

    private static boolean isSdkRegistered(String homePath, SdkType sdkType) {

        VirtualFile homePathAsVirtualFile;
        homePathAsVirtualFile = VfsUtil.findFileByIoFile(new File(homePath),true);
        /* Use the above because the following does not work on Windows:
        try {
            homePathAsVirtualFile = VfsUtil.findFileByURL(
                    new URL(VfsUtil.pathToUrl(homePath)));
        } catch (MalformedURLException e) {
            return true;
        }*/

        if (homePathAsVirtualFile == null || !homePathAsVirtualFile.isDirectory()) {
            return true;
        }

        List<Sdk> registeredSdks = GoSdkUtil.getSdkOfType(sdkType);

        for (Sdk registeredSdk : registeredSdks) {
            if (homePathAsVirtualFile.equals(
                    registeredSdk.getHomeDirectory())) {
                return true;
            }
        }

        return false;
    }


    public static List<Sdk> getSdkOfType(SdkType sdkType) {
        return getSdkOfType(sdkType, ProjectJdkTable.getInstance());
    }

    public static List<Sdk> getSdkOfType(SdkType sdkType, ProjectJdkTable table) {
        Sdk[] sdks = table.getAllJdks();

        List<Sdk> goSdks = new LinkedList<Sdk>();
        for (Sdk sdk : sdks) {
            if (sdk.getSdkType() == sdkType) {
                goSdks.add(sdk);
            }
        }

        return goSdks;
    }

    public static String prependToGoPath(String prependedPath) {
        String sysGoPath = getGoPath();
        return sysGoPath.isEmpty()
                ? prependedPath
                : format("%s%s%s", prependedPath, File.pathSeparator, sysGoPath);
    }

    public static String appendToGoPath(String appendedPath) {
        String sysGoPath = getGoPath();
        return sysGoPath.isEmpty()
                ? appendedPath
                : format("%s%s%s", sysGoPath, File.pathSeparator, appendedPath);
    }

    public static String getProjectGoPath(String projectDir, boolean prependSysGoPath, boolean appendSysGoPath) {
        String goPath = projectDir;
        String sysGoPath = getGoPath();
        if (!sysGoPath.isEmpty()) {
            if (prependSysGoPath) {
                goPath = format("%s%s%s", sysGoPath, File.pathSeparator, goPath);
            }
            if (appendSysGoPath) {
                goPath = format("%s%s%s", goPath, File.pathSeparator, sysGoPath);
            }
        }
        return goPath;
    }

    public static String appendGoPathToPath(String goPath) {
        String binarizedPath = "";
        String[] splitGoPath = goPath.split(File.pathSeparator);

        for (String path : splitGoPath) {
            binarizedPath += path + File.separator + "bin" + File.pathSeparator;
        }

        binarizedPath = binarizedPath.substring(0, binarizedPath.length() - 1);

        String sysPath = getEnvVariable("PATH");
        return sysPath.isEmpty()
                ? binarizedPath
                : format("%s%s%s", sysPath, File.pathSeparator, binarizedPath);
    }

    @NotNull
    public static String getAppEngineDevServer() {
        return getEnvVariable("APPENGINE_DEV_APPSERVER");
    }
    @NotNull
    public static String getSysGoRootPath() {
        return getEnvVariable("GOROOT");
    }

    @NotNull
    public static String getSysGoPathPath() {
        return getEnvVariable("GOPATH").split(File.pathSeparator)[0];
    }

    public static String getGoPath() {
        String savedsGoPath = GoGlobalSettings.getInstance().getGoPath();

        if (!savedsGoPath.isEmpty()) {
            return savedsGoPath;
        }

        return getSysGoPathPath();
    }

    @NotNull
    private static String getEnvVariable(String varName) {
        String variable = System.getenv(varName);
        return variable == null ? "" : variable;
    }

    public static boolean isImportedPackage(Project project, String packageName) {
        if (GoNamesCache.getInstance(project).isGoDefaultPackage(packageName)) {
            return false;
        }

        String topPackageName = packageName.split("/")[0];

        if (!topPackageName.contains(".")) {
            return false;
        }

        return checkFolderExists(getGoPath() + File.separator + "src" + File.separator + topPackageName);
    }

    @NotNull
    public static String getPathToDisplay(final VirtualFile file) {
        if (file == null) {
            return "";
        }
        return FileUtil.toSystemDependentName(file.getPath());
    }

    public static VirtualFile getVirtualFile(String path) {
        File pluginPath = new File(path);

        if (!pluginPath.exists()) {
            return null;
        }

        String url = VfsUtil.pathToUrl(pluginPath.getAbsolutePath());

        return VirtualFileManager.getInstance().findFileByUrl(url);
    }

    public static Map<String, String> getExtendedSysEnv(GoSdkData sdkData, String projectDir, String envVars) {
        boolean prependSysGoPath = false;
        boolean appendSysGoPath = false;

        Project[] projects = ProjectManager.getInstance().getOpenProjects();
        Project project = null;

        for (Project p : projects) {
            if (p.getBasePath().equals(projectDir)) {
                project = p;
                break;
            }
        }

        if (project != null) {
            GoProjectSettings.GoProjectSettingsBean settings = GoProjectSettings.getInstance(project).getState();
            prependSysGoPath = settings.prependGoPath;
            appendSysGoPath = settings.useGoPath;
        }

        return getExtendedSysEnv(sdkData, projectDir, envVars, prependSysGoPath, appendSysGoPath);
    }

    public static Map<String, String> getExtendedSysEnv(GoSdkData sdkData, String projectDir, String envVars, boolean prependSysGoPath, boolean appendSysGoPath) {
        Map<String, String> sysEnv = new HashMap<String, String>(System.getenv());
        String goRoot = getSdkRootPath(sdkData);
        String goPath = getProjectGoPath(projectDir, prependSysGoPath, appendSysGoPath);
        sysEnv.put("GOROOT", goRoot);
        sysEnv.put("GOPATH", goPath);
        sysEnv.put("PATH", appendGoPathToPath(goRoot + File.pathSeparator + goPath));

        if (envVars.length() > 0) {
            String[] envVarsArray = envVars.split(";");
            for (String envVar : envVarsArray) {
                if (!envVar.contains("=")) {
                    continue;
                }
                String[] splitEnvVars = envVar.split("=");
                if (splitEnvVars.length != 2) {
                    continue;
                }
                sysEnv.put(splitEnvVars[0], splitEnvVars[1]);
            }
        }

        return sysEnv;
    }

    public static Map<String, String> getExtendedSysEnv(GoAppEngineSdkData sdkData, String projectDir, String envVars) {
        return getExtendedSysEnv(sdkData, projectDir, envVars, true, false);
    }

    public static Map<String, String> getExtendedSysEnv(GoAppEngineSdkData sdkData, String projectDir, String envVars, boolean prependSysGoPath, boolean appendSysGoPath) {
        Map<String, String> sysEnv = new HashMap<String, String>(System.getenv());
        String goRoot = getSdkRootPath(sdkData);
        String goPath = getProjectGoPath(projectDir, prependSysGoPath, appendSysGoPath);

        sysEnv.put("GOROOT", goRoot);
        sysEnv.put("GOPATH", goPath);
        sysEnv.put("PATH", appendGoPathToPath(goRoot + File.pathSeparator + goPath));

        if (envVars.length() > 0) {
            String[] envVarsArray = envVars.split(";");
            for (String envVar : envVarsArray) {
                if (!envVar.contains("=")) {
                    continue;
                }
                String[] splitEnvVars = envVar.split("=");
                if (splitEnvVars.length != 2) {
                    continue;
                }
                sysEnv.put(splitEnvVars[0], splitEnvVars[1]);
            }
        }

        return sysEnv;
    }

    public static String[] convertEnvMapToArray(Map<String, String> envMap) {
        String[] goEnv = new String[envMap.size()];

        Iterator it = envMap.entrySet().iterator();
        int i = 0;
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            goEnv[i] = pairs.getKey() + "=" + pairs.getValue();
            i++;
        }

        return goEnv;
    }

    public static String[] getExtendedGoEnv(GoSdkData sdkData, String projectDir, String envVars) {
        return convertEnvMapToArray(getExtendedSysEnv(sdkData, projectDir, envVars));
    }

    public static String[] getExtendedGAEEnv(GoAppEngineSdkData sdkData, String projectDir, String envVars) {
        return convertEnvMapToArray(getExtendedSysEnv(sdkData, projectDir, envVars));
    }

    public static String[] getExtendedGoEnv(GoSdkData sdkData, String projectDir, String envVars, boolean prependSysGoPath, boolean appendSysGoPath ) {
        return convertEnvMapToArray(getExtendedSysEnv(sdkData, projectDir, envVars, prependSysGoPath, appendSysGoPath));
    }

    public static String[] getExtendedGAEEnv(GoAppEngineSdkData sdkData, String projectDir, String envVars, boolean prependSysGoPath, boolean appendSysGoPath) {
        return convertEnvMapToArray(getExtendedSysEnv(sdkData, projectDir, envVars, prependSysGoPath, appendSysGoPath));
    }

    public static String getSdkRootPath(GoSdkData sdkData) {
        if (sdkData.GO_GOROOT_PATH.isEmpty()) {
            File possibleRoot = new File(sdkData.GO_BIN_PATH).getParentFile();
            try {
                if (new File(possibleRoot.getCanonicalPath().concat("/src")).exists()) {
                    return possibleRoot.getCanonicalPath();
                }
            } catch (IOException ignored) {
                return "";
            }

            try {
                return possibleRoot.getParentFile().getCanonicalPath();
            } catch (IOException e) {
                return "";
            }
        }
        return sdkData.GO_GOROOT_PATH;
    }

    public static String getSdkRootPath(GoAppEngineSdkData sdkData) {
        if (sdkData.GO_HOME_PATH.isEmpty()) {
            File possibleRoot = new File(sdkData.GO_HOME_PATH);
            try {
                if (new File(possibleRoot.getCanonicalPath().concat("/src")).exists()) {
                    return possibleRoot.getCanonicalPath();
                }
            } catch (IOException ignored) {
                return "";
            }

            try {
                return possibleRoot.getParentFile().getCanonicalPath();
            } catch (IOException e) {
                return "";
            }
        }
        return sdkData.GO_HOME_PATH;
    }

    public static Boolean isHostOsWindows() {
        return SystemInfo.isWindows;
    }

    @NotNull
    public static String getGaeExePath() {
        String gaeExec = "goapp";
        if (isHostOsWindows()) {
            gaeExec += ".exe";
        }

        String[] sysPaths = getEnvVariable("PATH").split(File.pathSeparator);

        for (String sysPath : sysPaths) {
            if (!checkFileExists(sysPath + File.separator + gaeExec)) {
                continue;
            }

            return sysPath;
        }

        return "/usr/lib/go_appengine";
    }

    @Nullable
    public static Sdk getProjectSdk(Project project){
        Sdk sdk = GoSdkUtil.getGoogleGoSdkForProject(project);
        if (sdk != null) {
            return sdk;
        }

        return GoSdkUtil.getGoogleGAESdkForProject(project);
    }

    @Nullable
    public static String getGoExecName(Sdk sdk) {
        if (sdk.getSdkType() instanceof GoSdkType) {
            GoSdkData sdkData = (GoSdkData) sdk.getSdkAdditionalData();
            if (sdkData == null) {
                return null;
            }

            return sdkData.GO_BIN_PATH;
        } else if (sdk.getSdkAdditionalData() instanceof GoAppEngineSdkData) {
            GoAppEngineSdkData sdkData = (GoAppEngineSdkData) sdk.getSdkAdditionalData();
            return sdkData.GOAPP_BIN_PATH;
        }

        return null;
    }

    @Nullable
    public static String[] getGoEnv(Sdk sdk, String projectDir) {
        if (sdk.getSdkType() instanceof GoSdkType) {
            GoSdkData sdkData = (GoSdkData) sdk.getSdkAdditionalData();
            if (sdkData == null) {
                return null;
            }

            return GoSdkUtil.getExtendedGoEnv(sdkData, projectDir, "");
        } else if (sdk.getSdkAdditionalData() instanceof GoAppEngineSdkData) {
            GoAppEngineSdkData sdkData = (GoAppEngineSdkData) sdk.getSdkAdditionalData();
            return GoSdkUtil.getExtendedGAEEnv(sdkData, projectDir, "");
        }

        return null;
    }

    @Nullable
    public static Icon getProjectIcon(Sdk sdk) {
        return getProjectIcon(sdk, 16);
    }

    @Nullable
    public static Icon getProjectIcon(Sdk sdk, Integer size) {
        if (sdk.getSdkType() instanceof GoSdkType) {
            GoSdkData sdkData = (GoSdkData) sdk.getSdkAdditionalData();
            if (sdkData == null) {
                return null;
            }

            switch (size) {
                case 13: return GoIcons.GO_ICON_13x13;
                case 24: return GoIcons.GO_ICON_24x24;
                case 32: return GoIcons.GO_ICON_32x32;
                case 48: return GoIcons.GO_ICON_48x48;
                default: return GoIcons.GO_ICON_16x16;
            }
        } else if (sdk.getSdkAdditionalData() instanceof GoAppEngineSdkData) {
            switch (size) {
                case 13: return GoIcons.GAE_ICON_13x13;
                case 24: return GoIcons.GAE_ICON_24x24;
                case 32: return GoIcons.GAE_ICON_32x32;
                case 48: return GoIcons.GAE_ICON_48x48;
                default: return GoIcons.GAE_ICON_16x16;
            }
        }

        return null;
    }

    public static String[] computeGoCommand(String goName, String goArgs) {
        List<String> result = new ArrayList<String>();
        result.add(goName);

        Pattern pattern = Pattern.compile("((([^\"\\s\\\\]+(\\\\[^\\\\])*)+)|(\"([^\"\\\\]*|\\\\\")*\"))+", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(goArgs);
        while (matcher.find()) {
            String group = matcher.group();
            if (group.indexOf('"') == 0 || group.indexOf("'") == 0) {
                result.add(group.substring(1, group.length() - 1));
            } else if (group.indexOf('-') == 0 && group.indexOf(' ') != -1) {
                Collections.addAll(result, group.split(" "));
            } else {
                result.add(group);
            }
        }

        String[] arrRes = new String[result.size()];
        result.toArray(arrRes);

        return arrRes;
    }

    public static String[] computeGoBuildCommand(String goExecName, String goBuilderArgs, String targetName, String goMainFile) {
        String goArgs = String.format(
                "%s %s %s %s %s",
                "build",
                "-o",
                targetName,
                goBuilderArgs,
                goMainFile
        );

        return computeGoCommand(goExecName, goArgs);
    }

    public static String[] computeGoGetCommand(String goExecName, String goGetArgs, String packageName) {
        String goArgs = String.format(
                "%s %s %s",
                "get",
                goGetArgs,
                packageName
        );

        return computeGoCommand(goExecName, goArgs);
    }

    /**
     * Returns the Package, which the file belongs to
     * @param projectRoot Folder, where the project is located
     * @param file The file, which package we want to find out
     * @return String
     */
    public static String getPackageOfFile(String projectRoot, String file) {
        String pkg = null;

        // More portable solution than "file.startsWith(projectRoot)" as in Windows it creates problem
        // due to path separator character
        String root = new File(projectRoot).getAbsolutePath();
        String child = new File(file).getAbsolutePath();

        if(child.startsWith(root)) {
            String src = File.separator + "src" + File.separator;

            String fileFolder = new File(file).getParent();

            String relativePath = fileFolder.substring(projectRoot.length());
            if(relativePath.startsWith(src)) {
                pkg = relativePath.substring(src.length());
            } else {
                pkg = relativePath;
            }
        }

        return pkg;
    }

    public static String[] computeGoRunCommand(String goExecName, String goBuilderArgs, String goMainFile, String appArgs) {
        String goArgs = String.format(
                "%s %s %s %s",
                "run",
                goBuilderArgs,
                goMainFile,
                appArgs
        );

        return computeGoCommand(goExecName, goArgs);
    }

    public static String getGoImportsExec(String goimportsPath) {
        String execPath;

        if (!goimportsPath.equals("")) {
            execPath = goimportsPath;
        } else {
            execPath = GoSdkUtil.getGoPath() + File.separator + "bin";
        }

        execPath = execPath + File.separator + "goimports";
        if (isHostOsWindows()) {
            execPath += ".exe";
        }

        return execPath;
    }
}
TOP

Related Classes of ro.redeul.google.go.sdk.GoSdkUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.