This repository has been archived by the owner on Apr 14, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
397 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.idea/ | ||
.DS_Store | ||
/out | ||
IDEA-GitLab-Integration.jar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="PLUGIN_MODULE" version="4"> | ||
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/META-INF/plugin.xml" /> | ||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" /> | ||
</content> | ||
<orderEntry type="inheritedJdk" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
<orderEntry type="library" scope="PROVIDED" name="git4idea" level="application" /> | ||
</component> | ||
</module> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<idea-plugin version="2"> | ||
<id>ru.trylogic.idea.gitlab.integration</id> | ||
<name>GitLab integration</name> | ||
<version>1.0</version> | ||
<vendor email="bsideup@gmail.com" url="https://github.com/bsideup">Sergei Egorov</vendor> | ||
|
||
<description><![CDATA[ | ||
<a href="http://gitlab.org/">GitLab</a> integration plugin. | ||
Support "Open file in browser" command. | ||
]]></description> | ||
|
||
<change-notes><![CDATA[ | ||
Initial release. "Open file in browser" command. | ||
]]> | ||
</change-notes> | ||
|
||
<idea-version since-build="107.105"/> | ||
|
||
<depends>com.intellij.modules.vcs</depends> | ||
<depends>com.intellij.modules.lang</depends> | ||
<depends>Git4Idea</depends> | ||
|
||
<application-components> | ||
</application-components> | ||
|
||
<project-components> | ||
</project-components> | ||
|
||
<actions> | ||
<action id="GitLab.Open.In.Browser" | ||
class="ru.trylogic.idea.gitlab.integration.actions.GitLabOpenInBrowserAction"> | ||
<add-to-group group-id="EditorPopupMenu"/> | ||
<add-to-group group-id="ProjectViewPopupMenu"/> | ||
<add-to-group group-id="EditorTabPopupMenu"/> | ||
</action> | ||
|
||
<!--action id="GitLab.Open.Commit.In.Browser" class="ru.trylogic.idea.gitlab.integration.actions.GitLabShowCommitInBrowserFromLogAction"> | ||
<add-to-group group-id="Git.LogContextMenu" /> | ||
</action--> | ||
</actions> | ||
|
||
<extensions defaultExtensionNs="com.intellij"> | ||
</extensions> | ||
</idea-plugin> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package icons; | ||
|
||
import com.intellij.openapi.util.IconLoader; | ||
|
||
import javax.swing.*; | ||
|
||
/** | ||
* NOTE THIS FILE IS AUTO-GENERATED by the build/scripts/icons.gant | ||
* Don't repeat mistakes of others ;-) | ||
*/ | ||
public class GitlabIcons { | ||
private static Icon load(String path) { | ||
return IconLoader.getIcon(path, GitlabIcons.class); | ||
} | ||
|
||
public static final Icon Gitlab_icon = load("/ru/trylogic/idea/gitlab/gitlab_icon.png"); // 16x16 | ||
} |
25 changes: 25 additions & 0 deletions
25
src/ru/trylogic/idea/gitlab/integration/actions/AbstractGitLabShowCommitInBrowserAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package ru.trylogic.idea.gitlab.integration.actions; | ||
|
||
import com.intellij.ide.BrowserUtil; | ||
import com.intellij.openapi.project.DumbAwareAction; | ||
import com.intellij.openapi.project.Project; | ||
import git4idea.repo.GitRepository; | ||
import icons.GitlabIcons; | ||
import ru.trylogic.idea.gitlab.integration.utils.GitlabUrlUtil; | ||
|
||
abstract class AbstractGitLabShowCommitInBrowserAction extends DumbAwareAction { | ||
|
||
public AbstractGitLabShowCommitInBrowserAction() { | ||
super("Open on GitLab", "Open the selected commit in browser", GitlabIcons.Gitlab_icon); | ||
} | ||
|
||
protected static void openInBrowser(GitRepository repository, String revisionHash) { | ||
|
||
String remote = GitlabUrlUtil.findRemoteUrl(repository); | ||
final String repoUrl = GitlabUrlUtil.makeRepoUrlFromRemoteUrl(remote); | ||
|
||
String url = repoUrl + "/commit/" + revisionHash; | ||
BrowserUtil.launchBrowser(url); | ||
} | ||
|
||
} |
183 changes: 183 additions & 0 deletions
183
src/ru/trylogic/idea/gitlab/integration/actions/GitLabOpenInBrowserAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package ru.trylogic.idea.gitlab.integration.actions; | ||
|
||
import com.intellij.ide.BrowserUtil; | ||
import com.intellij.openapi.actionSystem.AnActionEvent; | ||
import com.intellij.openapi.actionSystem.PlatformDataKeys; | ||
import com.intellij.openapi.editor.Editor; | ||
import com.intellij.openapi.editor.SelectionModel; | ||
import com.intellij.openapi.project.DumbAwareAction; | ||
import com.intellij.openapi.project.Project; | ||
import com.intellij.openapi.vcs.changes.Change; | ||
import com.intellij.openapi.vcs.changes.ChangeListManager; | ||
import com.intellij.openapi.vfs.VirtualFile; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
import git4idea.GitLocalBranch; | ||
import git4idea.GitRemoteBranch; | ||
import git4idea.GitUtil; | ||
import git4idea.repo.GitRepository; | ||
import git4idea.repo.GitRepositoryManager; | ||
import ru.trylogic.idea.gitlab.integration.utils.GitlabUrlUtil; | ||
import icons.GitlabIcons; | ||
|
||
public class GitLabOpenInBrowserAction extends DumbAwareAction { | ||
|
||
public static final String CANNOT_OPEN_IN_BROWSER = "Cannot open in browser"; | ||
|
||
static void setVisibleEnabled(AnActionEvent e, boolean visible, boolean enabled) { | ||
e.getPresentation().setVisible(visible); | ||
e.getPresentation().setEnabled(enabled); | ||
} | ||
|
||
protected GitLabOpenInBrowserAction() { | ||
super("Open on GitLab", "Open corresponding link in browser", GitlabIcons.Gitlab_icon); | ||
} | ||
|
||
@Override | ||
public void update(final AnActionEvent e) { | ||
Project project = e.getData(PlatformDataKeys.PROJECT); | ||
VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); | ||
if (project == null || project.isDefault() || virtualFile == null) { | ||
setVisibleEnabled(e, false, false); | ||
return; | ||
} | ||
GitRepositoryManager manager = GitUtil.getRepositoryManager(project); | ||
|
||
final GitRepository gitRepository = manager.getRepositoryForFile(virtualFile); | ||
if (gitRepository == null) { | ||
setVisibleEnabled(e, false, false); | ||
return; | ||
} | ||
|
||
ChangeListManager changeListManager = ChangeListManager.getInstance(project); | ||
if (changeListManager.isUnversioned(virtualFile)) { | ||
setVisibleEnabled(e, true, false); | ||
return; | ||
} | ||
|
||
Change change = changeListManager.getChange(virtualFile); | ||
if (change != null && change.getType() == Change.Type.NEW) { | ||
setVisibleEnabled(e, true, false); | ||
return; | ||
} | ||
|
||
setVisibleEnabled(e, true, true); | ||
} | ||
|
||
@Override | ||
public void actionPerformed(final AnActionEvent e) { | ||
final Project project = e.getData(PlatformDataKeys.PROJECT); | ||
final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); | ||
final Editor editor = e.getData(PlatformDataKeys.EDITOR); | ||
if (virtualFile == null || project == null || project.isDisposed()) { | ||
return; | ||
} | ||
|
||
String urlToOpen = getUrl(project, virtualFile, editor); | ||
if (urlToOpen != null) { | ||
BrowserUtil.launchBrowser(urlToOpen); | ||
} | ||
} | ||
|
||
@Nullable | ||
public static String getUrl(@NotNull Project project, @NotNull VirtualFile virtualFile, @Nullable Editor editor) { | ||
|
||
GitRepositoryManager manager = GitUtil.getRepositoryManager(project); | ||
final GitRepository repository = manager.getRepositoryForFile(virtualFile); | ||
if (repository == null) { | ||
StringBuilder details = new StringBuilder("file: " + virtualFile.getPresentableUrl() + "; Git repositories: "); | ||
for (GitRepository repo : manager.getRepositories()) { | ||
details.append(repo.getPresentableUrl()).append("; "); | ||
} | ||
showError(project, CANNOT_OPEN_IN_BROWSER, "Can't find git repository", details.toString()); | ||
return null; | ||
} | ||
|
||
final String remoteUrl = GitlabUrlUtil.findRemoteUrl(repository); | ||
if (remoteUrl == null) { | ||
showError(project, CANNOT_OPEN_IN_BROWSER, "Can't find gitlab remote"); | ||
return null; | ||
} | ||
|
||
final String rootPath = repository.getRoot().getPath(); | ||
final String path = virtualFile.getPath(); | ||
if (!path.startsWith(rootPath)) { | ||
showError(project, CANNOT_OPEN_IN_BROWSER, "File is not under repository root", "Root: " + rootPath + ", file: " + path); | ||
return null; | ||
} | ||
|
||
String branch = getBranchNameOnRemote(project, repository); | ||
if (branch == null) { | ||
return null; | ||
} | ||
|
||
String relativePath = path.substring(rootPath.length()); | ||
String urlToOpen = makeUrlToOpen(editor, relativePath, branch, remoteUrl); | ||
if (urlToOpen == null) { | ||
showError(project, CANNOT_OPEN_IN_BROWSER, "Can't create properly url", remoteUrl); | ||
return null; | ||
} | ||
|
||
return urlToOpen; | ||
} | ||
|
||
private static void showError(Project project, String cannotOpenInBrowser) { | ||
showError(project, cannotOpenInBrowser, null); | ||
} | ||
|
||
private static void showError(Project project, String cannotOpenInBrowser, String s) { | ||
showError(project, cannotOpenInBrowser, s, null); | ||
} | ||
|
||
private static void showError(Project project, String cannotOpenInBrowser, String s, String s1) { | ||
System.out.println(cannotOpenInBrowser + ";" + s + ";" + s1); | ||
} | ||
|
||
@Nullable | ||
private static String makeUrlToOpen(@Nullable Editor editor, | ||
@NotNull String relativePath, | ||
@NotNull String branch, | ||
@NotNull String remoteUrl) { | ||
final StringBuilder builder = new StringBuilder(); | ||
final String repoUrl = GitlabUrlUtil.makeRepoUrlFromRemoteUrl(remoteUrl); | ||
if (repoUrl == null) { | ||
return null; | ||
} | ||
builder.append(repoUrl).append("/blob/").append(branch).append(relativePath); | ||
|
||
if (editor != null && editor.getDocument().getLineCount() >= 1) { | ||
// lines are counted internally from 0, but from 1 on gitlab | ||
SelectionModel selectionModel = editor.getSelectionModel(); | ||
final int begin = editor.getDocument().getLineNumber(selectionModel.getSelectionStart()) + 1; | ||
final int selectionEnd = selectionModel.getSelectionEnd(); | ||
int end = editor.getDocument().getLineNumber(selectionEnd) + 1; | ||
if (editor.getDocument().getLineStartOffset(end - 1) == selectionEnd) { | ||
end -= 1; | ||
} | ||
builder.append("#L").append(begin).append('-').append(end); | ||
} | ||
|
||
return builder.toString(); | ||
} | ||
|
||
@Nullable | ||
public static String getBranchNameOnRemote(@NotNull Project project, @NotNull GitRepository repository) { | ||
GitLocalBranch currentBranch = repository.getCurrentBranch(); | ||
if (currentBranch == null) { | ||
showError(project, CANNOT_OPEN_IN_BROWSER, | ||
"Can't open the file on GitLab when repository is on detached HEAD. Please checkout a branch."); | ||
return null; | ||
} | ||
|
||
GitRemoteBranch tracked = currentBranch.findTrackedBranch(repository); | ||
if (tracked == null) { | ||
showError(project, CANNOT_OPEN_IN_BROWSER, "Can't open the file on GitLab when current branch doesn't have a tracked branch.", | ||
"Current branch: " + currentBranch + ", tracked info: " + repository.getBranchTrackInfos()); | ||
return null; | ||
} | ||
|
||
return tracked.getNameForRemoteOperations(); | ||
} | ||
|
||
|
||
} |
75 changes: 75 additions & 0 deletions
75
src/ru/trylogic/idea/gitlab/integration/actions/GitLabShowCommitInBrowserFromLogAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package ru.trylogic.idea.gitlab.integration.actions; | ||
|
||
|
||
import com.intellij.openapi.actionSystem.AnActionEvent; | ||
import com.intellij.openapi.actionSystem.PlatformDataKeys; | ||
import com.intellij.openapi.project.Project; | ||
import com.intellij.openapi.vfs.VirtualFile; | ||
import git4idea.GitUtil; | ||
import git4idea.GitVcs; | ||
import git4idea.history.browser.GitCommit; | ||
import git4idea.repo.GitRepository; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
public class GitLabShowCommitInBrowserFromLogAction extends AbstractGitLabShowCommitInBrowserAction { | ||
|
||
@Nullable | ||
private static EventData collectData(AnActionEvent e) { | ||
Project project = e.getData(PlatformDataKeys.PROJECT); | ||
if (project == null || project.isDefault()) { | ||
return null; | ||
} | ||
|
||
GitCommit commit = e.getData(GitVcs.GIT_COMMIT); | ||
if (commit == null) { | ||
return null; | ||
} | ||
|
||
VirtualFile root = commit.getRoot(); | ||
GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); | ||
if (repository == null) { | ||
return null; | ||
} | ||
|
||
return new EventData(repository, commit); | ||
} | ||
|
||
@Override | ||
public void update(AnActionEvent e) { | ||
EventData eventData = collectData(e); | ||
e.getPresentation().setVisible(eventData != null); | ||
e.getPresentation().setEnabled(eventData != null); | ||
} | ||
|
||
@Override | ||
public void actionPerformed(AnActionEvent e) { | ||
EventData eventData = collectData(e); | ||
if (eventData != null) { | ||
openInBrowser(eventData.getRepository(), eventData.getCommit().getHash().getValue()); | ||
} | ||
} | ||
|
||
private static class EventData { | ||
@NotNull | ||
private final GitRepository myRepository; | ||
@NotNull | ||
private final GitCommit myCommit; | ||
|
||
private EventData(@NotNull GitRepository repository, @NotNull GitCommit commit) { | ||
myRepository = repository; | ||
myCommit = commit; | ||
} | ||
|
||
@NotNull | ||
public GitRepository getRepository() { | ||
return myRepository; | ||
} | ||
|
||
@NotNull | ||
public GitCommit getCommit() { | ||
return myCommit; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.