Last updatedDec 14, 2017

Adding a column to the branch listing

Overview

Bitbucket Server provides a listing of all the branches within a repository. It is a useful view for providing relevant information associated with branches. Bitbucket Server ships with a number of useful metadata columns already but by implementing a few plugin points you can add your own.

In order to display information in the table you will need to implement three plugin points:

Example

src/main/resources/atlassian-plugin.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<atlassian-plugin name="Branch colors plugin" key="example.plugin.branch.colors" plugins-version="2">
    <plugin-info>
        <description>A plugin which labels branches with a color</description>
        <vendor name="My Company" url="http://www.mycompany.com"/>
        <version>1.0</version>
    </plugin-info>

    <!-- Metadata provider. The branch listing page will invoke this as part its rendering -->
    <ref-metadata-provider key="color" class="branch.colors.RefColorProvider" />

    <!-- Table column -->
    <client-web-section key="color-column" name="Branch list color column" weight="50" location="bitbucket.branches.extras">
        <label key="example.plugin.branches.col.color">Color</label>
    </client-web-section>

    <!-- Web panel + soy template. The location attribute must correspond to the client-web-section above -->
    <client-web-panel key="color-cell" name="Branch list color cell" location="color-column" weight="10">
        <resource name="view" type="soy" location="example.plugin.branch.colors:color-cell-templates/example.plugin.branch.colors.cell"/>
        <dependency>example.plugin.branch.colors:color-cell-templates</dependency>
    </client-web-panel>

    <client-resource key="color-cell-templates" name="Color cell templates">
        <resource type="download" name="color-cell.soy.js" location="/color-cell.soy" />
        <dependency>com.atlassian.bitbucket.server.bitbucket-web:global</dependency>
    </client-resource>

</atlassian-plugin>

src/main/java/branch/colors/RefColorProvider.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package branch.colors;

import com.atlassian.bitbucket.repository.Ref;
import com.atlassian.bitbucket.repository.RefMetadataContext;
import com.atlassian.bitbucket.repository.RefMetadataProvider;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

public class RefColorProvider implements RefMetadataProvider<String> {

    private static final String DEFAULT_COLOR = "#cccccc";

    // This provider relies on no other components but could via constructor injection

    @Override
    public Map<Ref, String> getMetadata(RefMetadataContext context) {
        Map<Ref, String> colors = new HashMap<Ref, String>(context.getRefs().size());
        for (Ref ref : context.getRefs()) {
            String color;

            try {
                MessageDigest md5 = MessageDigest.getInstance("MD5");
                color = "#" + asHex(md5.digest(ref.getId().getBytes(Charset.defaultCharset()))).substring(0, 6);
            } catch (NoSuchAlgorithmException e) {
                color = DEFAULT_COLOR;
            }

            colors.put(ref, color);
        }
        return colors;
    }

    private static String asHex(byte[] bytes) {
        StringBuilder str = new StringBuilder(bytes.length * 2);
        for (byte aByte : bytes) {
            int b = 0xff & aByte;
            if (b < 16) {
                str.append('0');
            }
            str.append(Integer.toHexString(b));
        }
        return str.toString();
    }
}

src/main/resources/color-cell.soy

1
2
3
4
5
6
7
8
9
10
{namespace example.plugin.branch.colors}

/**
 * @param branch
 **/
{template .cell}
// metadata is referenced via complete module key. The metadata may not have been successfully retrieved
// due to timeouts on the provider so we always need to provide a default.
<div style="background-color: {$branch.metadata['example.plugin.branch.colors:color'] or '#cccccc'};"> </div>
{/template}