James Moger
2012-05-10 7c1cdc8b2f3686626de0f1a523965f5555f469d7
Revisions to custom fields
12 files modified
120 ■■■■ changed files
docs/01_setup.mkd 10 ●●●●● patch | view | raw | blame | history
groovy/blockpush.groovy 3 ●●●●● patch | view | raw | blame | history
groovy/jenkins.groovy 3 ●●●●● patch | view | raw | blame | history
groovy/localclone.groovy 3 ●●●●● patch | view | raw | blame | history
groovy/protect-refs.groovy 3 ●●●●● patch | view | raw | blame | history
groovy/sendmail.groovy 3 ●●●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java 14 ●●●●● patch | view | raw | blame | history
src/com/gitblit/IStoredSettings.java 18 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.properties 2 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_ja.properties 2 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/EditRepositoryPage.html 6 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/EditRepositoryPage.java 53 ●●●● patch | view | raw | blame | history
docs/01_setup.mkd
@@ -398,6 +398,16 @@
Hook contributions and improvements are welcome.
### Custom Fields
*SINCE 1.0.0*
Gitblit allows custom repository string fields to be defined in `gitblit.properties` or `web.xml`.  Entry textfields are automatically created for these fields in the Edit Repository page of Gitblit and the Edit Repository dialog of the Gitblit Manager.  These fields are accessible from your Groovy hook scripts as
    repository.customFields.myField
This feature allows you to customize the behavior of your hook scripts without hard-coding values in the hook scripts themselves.
### Pre-Receive
Pre-Receive scripts execute after the pushed objects have all been written to the Git repository but before the refs have been updated to point to these new objects.
groovy/blockpush.groovy
@@ -59,6 +59,9 @@
 *  logger            Logs messages to Gitblit     org.slf4j.Logger
 *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
 *  
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *
 */
// Indicate we have started the script
groovy/jenkins.groovy
@@ -54,6 +54,9 @@
 *  logger            Logs messages to Gitblit     org.slf4j.Logger
 *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
 *  
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *
 */
// Indicate we have started the script
logger.info("jenkins hook triggered by ${user.username} for ${repository.name}")
groovy/localclone.groovy
@@ -64,6 +64,9 @@
 *  logger            Logs messages to Gitblit     org.slf4j.Logger
 *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
 *  
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *
 */
// Indicate we have started the script
groovy/protect-refs.groovy
@@ -65,6 +65,9 @@
 *  logger            Logs messages to Gitblit     org.slf4j.Logger
 *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
 *  
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *
 */
// map of protected command types to returned results type
groovy/sendmail.groovy
@@ -60,6 +60,9 @@
 *  logger            Logs messages to Gitblit     org.slf4j.Logger
 *  clientLogger    Logs messages to Git client    com.gitblit.utils.ClientLogger
 *  
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *
 */
// Indicate we have started the script
src/com/gitblit/GitBlit.java
@@ -30,6 +30,7 @@
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -252,6 +253,17 @@
     */
    public static List<String> getStrings(String key) {
        return self().settings.getStrings(key);
    }
    /**
     * Returns a map of space-separated key-value pairs from the specified key.
     *
     * @see IStoredSettings.getStrings(String key)
     * @param name
     * @return map of string, string
     */
    public static Map<String, String> getMap(String key) {
        return self().settings.getMap(key);
    }
    /**
@@ -859,7 +871,7 @@
                    Constants.CONFIG_GITBLIT, null, "indexBranch")));
            
            // Custom defined properties
            model.customFields = new HashMap<String, String>();
            model.customFields = new LinkedHashMap<String, String>();
            for (String aProperty : config.getNames(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS)) {
                model.customFields.put(aProperty, config.getString(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS, aProperty));
            }
src/com/gitblit/IStoredSettings.java
@@ -16,6 +16,7 @@
package com.gitblit;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -205,6 +206,23 @@
    }
    /**
     * Returns a map of strings from the specified key.
     *
     * @param name
     * @return map of string, string
     */
    public Map<String, String> getMap(String name) {
        Map<String, String> map = new LinkedHashMap<String, String>();
        for (String string : getStrings(name)) {
            String[] kvp = string.split("=", 2);
            String key = kvp[0];
            String value = kvp[1];
            map.put(key,  value);
        }
        return map;
    }
    /**
     * Override the specified key with the specified value.
     * 
     * @param key
src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -203,7 +203,7 @@
gb.postReceiveScripts = post-receive scripts
gb.hookScripts = hook scripts
gb.customFields = custom fields
gb.customFieldsDescription = custom fields available to groovy hooks
gb.customFieldsDescription = custom fields available to Groovy hooks
gb.accessPermissions = access permissions
gb.filters = filters
gb.generalDescription = common settings
src/com/gitblit/wicket/GitBlitWebApp_ja.properties
@@ -202,6 +202,8 @@
gb.preReceiveScripts = pre-receive \u30b9\u30af\u30ea\u30d7\u30c8
gb.postReceiveScripts = post-receive \u30b9\u30af\u30ea\u30d7\u30c8
gb.hookScripts = \u30d5\u30c3\u30af\u30b9\u30af\u30ea\u30d7\u30c8
gb.customFields = custom fields
gb.customFieldsDescription = custom fields available to Groovy hooks
gb.accessPermissions = \u30a2\u30af\u30bb\u30b9\u6a29\u9650
gb.filters = \u30d5\u30a3\u30eb\u30bf\u30fc
gb.generalDescription = \u4e00\u822c\u7684\u306a\u8a2d\u5b9a
src/com/gitblit/wicket/pages/EditRepositoryPage.html
@@ -36,11 +36,11 @@
                <tr><td colspan="2"><h3><wicket:message key="gb.hookScripts"></wicket:message> &nbsp;<small><wicket:message key="gb.hookScriptsDescription"></wicket:message></small></h3></td></tr>    
                <tr><th style="vertical-align: top;"><wicket:message key="gb.preReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPreReceive"></span></th><td style="padding:2px;"><span wicket:id="preReceiveScripts"></span></td></tr>
                <tr><th style="vertical-align: top;"><wicket:message key="gb.postReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPostReceive"></span></th><td style="padding:2px;"><span wicket:id="postReceiveScripts"></span></td></tr>
                <div wicket:id="customFiledsSection">
                <div wicket:id="customFieldsSection">
                    <tr><td colspan="2"><h3><wicket:message key="gb.customFields"></wicket:message> &nbsp;<small><wicket:message key="gb.customFieldsDescription"></wicket:message></small></h3></td></tr>
                    <tr wicket:id="customFieldsListView"><th style="vertical-align: top;"><span wicket:id="customFieldLabel"></span></th><td class="edit"><input class="span8" type="text" wicket:id="customFieldValue" size="30" tabindex="16" /></td></tr>
                    <tr wicket:id="customFieldsListView"><th><span wicket:id="customFieldLabel"></span></th><td class="edit"><input class="span8" type="text" wicket:id="customFieldValue" /></td></tr>
                </div>
                <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="17" /> &nbsp; <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="18" /></div></td></tr>
                <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" /> &nbsp; <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /></div></td></tr>
            </tbody>
        </table>
    </form>    
src/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -16,15 +16,14 @@
package com.gitblit.wicket.pages;
import java.text.MessageFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.wicket.PageParameters;
@@ -39,7 +38,6 @@
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListItemModel;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
@@ -157,22 +155,24 @@
                        .self().getPostReceiveScriptsUnused(repositoryModel)),
                new StringChoiceRenderer(), 12, true);
        
        // Dynamic Custom Defined Properties Properties
        final List<Entry<String, String>> definedProperties = new ArrayList<Entry<String, String>>();
        List<String> customFields = GitBlit.getStrings(Keys.repository.customFields);
        for (String customFieldDef : customFields) {
            String[] customFieldProperty = customFieldDef.split("=");
            definedProperties.add(new AbstractMap.SimpleEntry<String, String>(customFieldProperty[0], customFieldProperty[1]));
        }
        // custom fields
        final Map<String, String> customFieldsMap = GitBlit.getMap(Keys.groovy.customFields);
        List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet());
        final ListView<String> customFieldsListView = new ListView<String>("customFieldsListView", customKeys) {
        
        final ListView<Entry<String, String>> customFieldsListView = new ListView<Entry<String, String>>("customFieldsListView", definedProperties) {
            private static final long serialVersionUID = 1L;
            @Override
            protected void populateItem(ListItem<Entry<String, String>> item) {
                String value = repositoryModel.customFields.get(item.getModelObject().getKey());
            protected void populateItem(ListItem<String> item) {
                String key = item.getModelObject();
                item.add(new Label("customFieldLabel", customFieldsMap.get(key)));
                
                item.add(new Label(item.getModelObject().getKey(), item.getModelObject().getValue()));        // Used to get the key later
                item.add(new Label("customFieldLabel", item.getModelObject().getValue()));
                item.add(new TextField<String>("customFieldValue", new Model<String>(value)));
                String value = "";
                if (repositoryModel.customFields != null && repositoryModel.customFields.containsKey(key)) {
                    value = repositoryModel.customFields.get(key);
                }
                TextField<String> field = new TextField<String>("customFieldValue", new Model<String>(value));
                item.add(field);
            }
        };
        customFieldsListView.setReuseItems(true);
@@ -277,11 +277,14 @@
                    }
                    repositoryModel.postReceiveScripts = postReceiveScripts;
                    
                    // Loop over each of the user defined properties
                    // custom fields
                    repositoryModel.customFields = new LinkedHashMap<String, String>();
                    for (int i = 0; i < customFieldsListView.size(); i++) {
                        ListItem<ListItemModel<String>> item = (ListItem<ListItemModel<String>>) customFieldsListView.get(i);
                        String key = item.get(0).getId();        // Item 0 is our 'fake' label
                        String value = ((TextField<String>)item.get(2)).getValue();        // Item 2 is out text box
                        ListItem<String> child = (ListItem<String>) customFieldsListView.get(i);
                        String key = child.getModelObject();
                        TextField<String> field = (TextField<String>) child.get("customFieldValue");
                        String value = field.getValue();
                        
                        repositoryModel.customFields.put(key, value);
                    }
@@ -371,13 +374,9 @@
        form.add(new BulletListPanel("inheritedPostReceive", "inherited", GitBlit.self()
                .getPostReceiveScriptsInherited(repositoryModel)));
        
        WebMarkupContainer customFiledsSection = new WebMarkupContainer("customFiledsSection") {
            public boolean isVisible() {
                return GitBlit.getString(Keys.repository.customFields, "").isEmpty() == false;
            };
        };
        customFiledsSection.add(customFieldsListView);
        form.add(customFiledsSection);
        WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection");
        customFieldsSection.add(customFieldsListView);
        form.add(customFieldsSection.setVisible(!GitBlit.getString(Keys.groovy.customFields, "").isEmpty()));
        form.add(new Button("save"));
        Button cancel = new Button("cancel") {