import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import java.io.*; import java.util.Properties; public class Util { public static String VERSION = "v1.2.0"; // gitRemoteURL returns the remote URL for the given remote name. // e.g. "origin" -> "[email protected]:foo/bar" public static String gitRemoteURL(String repoDir, String remoteName) throws Exception { String s = exec("git remote get-url " + remoteName, repoDir).trim(); if (s.isEmpty()) { throw new Exception("no such remote"); } return s; } // configuredGitRemoteURL returns the URL of the "sourcegraph" remote, if // configured, or else the URL of the "origin" remote. An exception is // thrown if neither exists. public static String configuredGitRemoteURL(String repoDir) throws Exception { try { return gitRemoteURL(repoDir, "sourcegraph"); } catch (Exception err) { try { return gitRemoteURL(repoDir, "origin"); } catch (Exception err2) { throw new Exception("no configured git remote \"sourcegraph\" or \"origin\""); } } } // gitRootDir returns the repository root directory for any directory // within the repository. public static String gitRootDir(String repoDir) throws IOException { return exec("git rev-parse --show-toplevel", repoDir).trim(); } // gitBranch returns either the current branch name of the repository OR in // all other cases (e.g. detached HEAD state), it returns "HEAD". public static String gitBranch(String repoDir) throws IOException { return exec("git rev-parse --abbrev-ref HEAD", repoDir).trim(); } // verify that provided branch exists on remote public static boolean isRemoteBranch(String branch, String repoDir) throws IOException { return exec("git show-branch remotes/origin/" + branch, repoDir).length() > 0; } public static String sourcegraphURL(Project project) { String url = Config.getInstance(project).getUrl(); if (url == null || url.length() == 0) { Properties props = readProps(); url = props.getProperty("url", "https://sourcegraph.com/"); } return url.endsWith("/") ? url : url + "/"; } // readProps tries to read the $HOME/sourcegraph-jetbrains.properties file. private static Properties readProps() { Properties props = new Properties(); InputStream input = null; String path = System.getProperty("user.home") + File.separator + "sourcegraph-jetbrains.properties"; try{ input = new FileInputStream(path); props.load(input); } catch (IOException e) { // no-op } finally { if (input != null) { try{ input.close(); } catch (IOException e) { // no-op } } } return props; } // repoInfo returns the Sourcegraph repository URI, and the file path // relative to the repository root. If the repository URI cannot be // determined, a RepoInfo with empty strings is returned. public static RepoInfo repoInfo(String fileName) { String fileRel = ""; String remoteURL = ""; String branch = ""; try{ // Determine repository root directory. String fileDir = fileName.substring(0, fileName.lastIndexOf("/")); String repoRoot = gitRootDir(fileDir); // Determine file path, relative to repository root. fileRel = fileName.substring(repoRoot.length()+1); remoteURL = configuredGitRemoteURL(repoRoot); branch = gitBranch(repoRoot); // If on a branch that does not exist on the remote, use "master" instead. if (!isRemoteBranch(branch, repoRoot)) { branch = "master"; } } catch (Exception err) { Logger.getInstance(Util.class).info(err); err.printStackTrace(); } return new RepoInfo(fileRel, remoteURL, branch); } // exec executes the given command in the specified directory and returns // its stdout. Any stderr output is logged. public static String exec(String cmd, String dir) throws IOException { Logger.getInstance(Util.class).debug("exec cmd='" + cmd + "' dir="+dir); // Create the process. Process p = Runtime.getRuntime().exec(cmd, null, new File(dir)); BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stderr = new BufferedReader(new InputStreamReader(p.getErrorStream())); // Log any stderr ouput. Logger logger = Logger.getInstance(Util.class); String s; while ((s = stderr.readLine()) != null) { logger.debug(s); } String out = new String(); for (String l; (l = stdout.readLine()) != null; out += l + "\n"); return out; } }