Skip to content

Commit

Permalink
Support gitblit ben-gibson#26
Browse files Browse the repository at this point in the history
- uses pattern configuration code from my NetBeans plugin https://github.com/markiewb/nb-git-open-in-external-repoviewer
  • Loading branch information
markiewb authored and Ben Gibson committed Dec 12, 2016
1 parent 1031b67 commit eec974c
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ All Notable changes to `Open in Git host` will be documented in this file
## 1.5.7 - 2016-12-05

- Fixed: Select target action now uses the correct line number when used from the editor. (#24 PR by markiewb)

## 1.6.0 - 2016-12-08

- Support GitBlit #26
6 changes: 3 additions & 3 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin version="2">
<id>uk.co.ben-gibson.remote.repository.mapper</id>
<name>Open in Git host</name>
<version>1.5.7</version>
<version>1.6.0</version>
<vendor url="https://github.com/ben-gibson/jetbrains-open-in-git-host">Ben Gibson</vendor>

<description><![CDATA[
Expand All @@ -10,7 +10,7 @@
<br />
<br />
After installing select your remote host in Settings &rarr; Other Settings &rarr; Open in Git host
(currently supports GitHub, Stash, BitBucket and GitLab). Make sure you have registered your project's root under the version control settings.
(currently supports GitHub, Stash, BitBucket, GitLab and GitBlit). Make sure you have registered your project's root under the version control settings.
Preferences → Version Control (see unregistered roots)
<br />
<br />
Expand All @@ -27,7 +27,7 @@
<change-notes><![CDATA[
<ul>
<li>
Fixed: Select target action now uses the correct line number when used from the editor. <a href="https://github.com/ben-gibson/jetbrains-open-in-git-host/issues/24">#24</a>
Support GitBlit <a href="https://github.com/ben-gibson/jetbrains-open-in-git-host/issues/26">#26</a>.
</li>
</ul>
]]>
Expand Down
3 changes: 2 additions & 1 deletion src/uk/co/ben_gibson/repositorymapper/Host/Host.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ public enum Host
STASH("Stash"),
GIT_HUB("GitHub"),
BITBUCKET("Bitbucket"),
GITLAB("GitLab");
GITLAB("GitLab"),
GITBLIT("GitBlit");

private final String name;

Expand Down
148 changes: 148 additions & 0 deletions src/uk/co/ben_gibson/repositorymapper/Host/Url/Factory/GitBlit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package uk.co.ben_gibson.repositorymapper.Host.Url.Factory;

import com.intellij.util.containers.hash.LinkedHashMap;
import org.jetbrains.annotations.NotNull;
import uk.co.ben_gibson.repositorymapper.Context.Context;
import uk.co.ben_gibson.repositorymapper.Host.Url.Exception.ProjectNotFoundException;
import uk.co.ben_gibson.repositorymapper.Repository.Exception.RemoteNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Creates a URL in a format expected by GitBlit.
*/
public class GitBlit implements Factory {

/**
* {@inheritDoc}
*
* Mapping logic from https://github.com/markiewb/nb-git-open-in-external-repoviewer
*/
@Override
@NotNull
public URL createUrl(@NotNull Context context, boolean forceSSL) throws URISyntaxException, UnsupportedEncodingException, MalformedURLException, RemoteNotFoundException, ProjectNotFoundException {

String remoteUrl = context.getRepository().getOrigin().getFirstUrl();

for (Map.Entry<String, String> urlPattern : this.getUrlPatternsForContext(context).entrySet()) {

String pattern = urlPattern.getKey();
String url = urlPattern.getValue();

Matcher matcher = Pattern.compile(pattern).matcher(remoteUrl);

// if the remote URL doesn't match the pattern then move onto the next one.
if (!matcher.find()) {
continue;
}

// Get the placeholder values for the URL
Map<String, String> placeholders = this.getPlaceholdersForContext(context);

placeholders.put("<protocol>", (forceSSL) ? "https" : this.getGroupFromMatcher(matcher, "protocol"));
placeholders.put("<server>", this.getGroupFromMatcher(matcher, "server"));
placeholders.put("<repo>", this.getGroupFromMatcher(matcher, "repo"));
placeholders.put("<repo\\|replaceSlashWithBang >", this.replaceSlashWithBang(this.getGroupFromMatcher(matcher, "repo")));

// Replace the URL placeholders
for (Map.Entry<String, String> placeHolder : placeholders.entrySet()) {
url = url.replaceAll(placeHolder.getKey(), placeHolder.getValue());
}

return new URL(url);
}

throw new IllegalArgumentException(remoteUrl + " could not be parsed correctly");
}

/**
* Get URL patterns relevant to the context.
*
* Note: Use LinkedHashMap because ordering the patterns have a priority
*
* @param context The context to get relevant URL patterns for.
*
* @return Map
*/
@NotNull
private Map<String, String> getUrlPatternsForContext(@NotNull Context context)
{
Map<String, String> patterns = new LinkedHashMap<>();

if (context.getFilePathRelativeToRepository().isEmpty()) {
patterns.put("(?<protocol>http|https)://(?<username>.+?@)?(?<server>.+?)/(git/r)/(?<repo>.+)\\.git", "<protocol>://<server>/git/commitdiff/<repo|replaceSlashWithBang >.git/<revision>");
patterns.put("(?<protocol>http|https)://(?<username>.+?@)?(?<server>.+?)/(git|r)/(?<repo>.+)\\.git", "<protocol>://<server>/commitdiff/<repo|replaceSlashWithBang >.git/<revision>");
} else {
patterns.put("(?<protocol>http|https)://(?<username>.+?@)?(?<server>.+?)/(git/r)/(?<repo>.+)\\.git", "<protocol>://<server>/git/blob/<repo|replaceSlashWithBang >.git/<revision>/<fullfilepath|replaceSlashWithBang >#L<linenumber|1based>");
patterns.put("(?<protocol>http|https)://(?<username>.+?@)?(?<server>.+?)/(git|r)/(?<repo>.+)\\.git", "<protocol>://<server>/blob/<repo|replaceSlashWithBang >.git/<revision>/<fullfilepath|replaceSlashWithBang >#L<linenumber|1based>");
}

return patterns;
}

/**
* Get placeholders for a given context.
*
* @param context The context to get placeholders for.
*
* @return Map
*/
@NotNull
private Map<String, String> getPlaceholdersForContext(@NotNull Context context) throws RemoteNotFoundException
{
Map<String, String> placeholders = new HashMap<>();

String revision = (context.getCommitHash() != null) ? context.getCommitHash() : context.getBranch();
String line = (context.getCaretLinePosition() == null) ? "1" : context.getCaretLinePosition().toString();

placeholders.put("<revision>", revision);
placeholders.put("<linenumber\\|1based>", line);

String path = context.getFilePathRelativeToRepository();

if (path.startsWith("/")) {
path = path.substring(1);
}

placeholders.put("<fullfilepath>", path);
placeholders.put("<fullfilepath\\|replaceSlashWithBang >", this.replaceSlashWithBang(path));

return placeholders;
}

/**
* Get a selected group from a matcher.
*
* @param matcher The matcher to get a group from.
* @param name The group to get from the matcher.
*
* @return String
*/
private String getGroupFromMatcher(Matcher matcher, String name)
{
try {
return matcher.group(name);
} catch (IllegalArgumentException | IllegalStateException e) {
return "";
}
}

/**
* Replace forward slash character with bang.
*
* @param string The string to replace forward slash characters.
*
* @return String
*/
@NotNull
private String replaceSlashWithBang (@NotNull String string)
{
return string.replaceAll("/", "!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public Factory getForHost(Host host) throws UnsupportedHostException
return new Stash();
} else if (host == Host.BITBUCKET) {
return new BitBucket();
} else if (host == Host.GITBLIT) {
return new GitBlit();
}

throw new UnsupportedHostException(host);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public URL getRemoteUrl(@NotNull Remote remote, boolean forceSSL) throws Malform
* @return Remote
*/
@NotNull
private Remote getOrigin() throws RemoteNotFoundException
public Remote getOrigin() throws RemoteNotFoundException
{
return new Remote(this.getRawOrigin());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public enum RepositoryProvider
STASH("Stash"),
GIT_HUB("GitHub"),
BITBUCKET("Bitbucket"),
GITBLIT("Gitblit"),
GITLAB("GitLab");

private final String name;
Expand Down
3 changes: 3 additions & 0 deletions src/uk/co/ben_gibson/repositorymapper/Settings/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ public void loadState(Settings state)
case GITLAB:
this.setHost(Host.GITLAB);
break;
case GITBLIT:
this.setHost(Host.GITBLIT);
break;
case BITBUCKET:
this.setHost(Host.BITBUCKET);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static Context getMockedContext(String remoteURL, String branch, String f

when(context.getFilePathRelativeToRepository()).thenReturn(filePath);
when(context.getRepository().getOriginUrl(anyBoolean())).thenReturn(new URL(remoteURL));
when(context.getRepository().getOrigin().getFirstUrl()).thenReturn(remoteURL);
when(context.getBranch()).thenReturn(branch);
when(context.getCaretLinePosition()).thenReturn(caretLinePosition);
when(context.getCommitHash()).thenReturn(commitHash);
Expand Down
Loading

0 comments on commit eec974c

Please sign in to comment.