\r
Hook contributions and improvements are welcome.\r
\r
+### Custom Fields\r
+\r
+*SINCE 1.0.0*\r
+\r
+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\r
+\r
+ repository.customFields.myField\r
+\r
+This feature allows you to customize the behavior of your hook scripts without hard-coding values in the hook scripts themselves.\r
+\r
### Pre-Receive\r
\r
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.\r
* url Base url for Gitblit String\r
* logger Logs messages to Gitblit org.slf4j.Logger\r
* clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger\r
+ *\r
+ * Accessing Gitblit Custom Fields:\r
+ * def myCustomField = repository.customFields.myCustomField\r
* \r
*/\r
\r
* url Base url for Gitblit String\r
* logger Logs messages to Gitblit org.slf4j.Logger\r
* clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger\r
+ *\r
+ * Accessing Gitblit Custom Fields:\r
+ * def myCustomField = repository.customFields.myCustomField\r
* \r
*/\r
// Indicate we have started the script\r
* url Base url for Gitblit String\r
* logger Logs messages to Gitblit org.slf4j.Logger\r
* clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger\r
+ *\r
+ * Accessing Gitblit Custom Fields:\r
+ * def myCustomField = repository.customFields.myCustomField\r
* \r
*/\r
\r
* url Base url for Gitblit String\r
* logger Logs messages to Gitblit org.slf4j.Logger\r
* clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger\r
+ *\r
+ * Accessing Gitblit Custom Fields:\r
+ * def myCustomField = repository.customFields.myCustomField\r
* \r
*/\r
\r
* url Base url for Gitblit String\r
* logger Logs messages to Gitblit org.slf4j.Logger\r
* clientLogger Logs messages to Git client com.gitblit.utils.ClientLogger\r
+ *\r
+ * Accessing Gitblit Custom Fields:\r
+ * def myCustomField = repository.customFields.myCustomField\r
* \r
*/\r
\r
import java.util.Collections;\r
import java.util.Date;\r
import java.util.HashMap;\r
+import java.util.LinkedHashMap;\r
import java.util.LinkedHashSet;\r
import java.util.List;\r
import java.util.Map;\r
return self().settings.getStrings(key);\r
}\r
\r
+ /**\r
+ * Returns a map of space-separated key-value pairs from the specified key.\r
+ * \r
+ * @see IStoredSettings.getStrings(String key)\r
+ * @param name\r
+ * @return map of string, string\r
+ */\r
+ public static Map<String, String> getMap(String key) {\r
+ return self().settings.getMap(key);\r
+ }\r
+\r
/**\r
* Returns the list of keys whose name starts with the specified prefix. If\r
* the prefix is null or empty, all key names are returned.\r
Constants.CONFIG_GITBLIT, null, "indexBranch")));\r
\r
// Custom defined properties\r
- model.customFields = new HashMap<String, String>();\r
+ model.customFields = new LinkedHashMap<String, String>();\r
for (String aProperty : config.getNames(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS)) {\r
model.customFields.put(aProperty, config.getString(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS, aProperty));\r
}\r
package com.gitblit;\r
\r
import java.util.ArrayList;\r
+import java.util.LinkedHashMap;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Properties;\r
}\r
return strings;\r
}\r
+ \r
+ /**\r
+ * Returns a map of strings from the specified key.\r
+ * \r
+ * @param name\r
+ * @return map of string, string\r
+ */\r
+ public Map<String, String> getMap(String name) {\r
+ Map<String, String> map = new LinkedHashMap<String, String>();\r
+ for (String string : getStrings(name)) {\r
+ String[] kvp = string.split("=", 2);\r
+ String key = kvp[0];\r
+ String value = kvp[1]; \r
+ map.put(key, value);\r
+ }\r
+ return map;\r
+ }\r
\r
/**\r
* Override the specified key with the specified value.\r
gb.postReceiveScripts = post-receive scripts\r
gb.hookScripts = hook scripts\r
gb.customFields = custom fields\r
-gb.customFieldsDescription = custom fields available to groovy hooks\r
+gb.customFieldsDescription = custom fields available to Groovy hooks\r
gb.accessPermissions = access permissions\r
gb.filters = filters\r
gb.generalDescription = common settings\r
gb.preReceiveScripts = pre-receive \u30b9\u30af\u30ea\u30d7\u30c8\r
gb.postReceiveScripts = post-receive \u30b9\u30af\u30ea\u30d7\u30c8\r
gb.hookScripts = \u30d5\u30c3\u30af\u30b9\u30af\u30ea\u30d7\u30c8\r
+gb.customFields = custom fields\r
+gb.customFieldsDescription = custom fields available to Groovy hooks\r
gb.accessPermissions = \u30a2\u30af\u30bb\u30b9\u6a29\u9650\r
gb.filters = \u30d5\u30a3\u30eb\u30bf\u30fc\r
gb.generalDescription = \u4e00\u822c\u7684\u306a\u8a2d\u5b9a\r
<tr><td colspan="2"><h3><wicket:message key="gb.hookScripts"></wicket:message> <small><wicket:message key="gb.hookScriptsDescription"></wicket:message></small></h3></td></tr> \r
<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>\r
<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>\r
- <div wicket:id="customFiledsSection">\r
+ <div wicket:id="customFieldsSection">\r
<tr><td colspan="2"><h3><wicket:message key="gb.customFields"></wicket:message> <small><wicket:message key="gb.customFieldsDescription"></wicket:message></small></h3></td></tr>\r
- <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>\r
+ <tr wicket:id="customFieldsListView"><th><span wicket:id="customFieldLabel"></span></th><td class="edit"><input class="span8" type="text" wicket:id="customFieldValue" /></td></tr>\r
</div>\r
- <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" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="18" /></div></td></tr>\r
+ <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" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /></div></td></tr>\r
</tbody>\r
</table>\r
</form> \r
package com.gitblit.wicket.pages;\r
\r
import java.text.MessageFormat;\r
-import java.util.AbstractMap;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.Collections;\r
import java.util.HashSet;\r
import java.util.Iterator;\r
+import java.util.LinkedHashMap;\r
import java.util.List;\r
import java.util.Map;\r
-import java.util.Map.Entry;\r
import java.util.Set;\r
\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.markup.html.form.IChoiceRenderer;\r
import org.apache.wicket.markup.html.form.TextField;\r
import org.apache.wicket.markup.html.list.ListItem;\r
-import org.apache.wicket.markup.html.list.ListItemModel;\r
import org.apache.wicket.markup.html.list.ListView;\r
import org.apache.wicket.model.CompoundPropertyModel;\r
import org.apache.wicket.model.IModel;\r
.self().getPostReceiveScriptsUnused(repositoryModel)),\r
new StringChoiceRenderer(), 12, true);\r
\r
- // Dynamic Custom Defined Properties Properties\r
- final List<Entry<String, String>> definedProperties = new ArrayList<Entry<String, String>>();\r
- List<String> customFields = GitBlit.getStrings(Keys.repository.customFields);\r
- for (String customFieldDef : customFields) {\r
- String[] customFieldProperty = customFieldDef.split("=");\r
- definedProperties.add(new AbstractMap.SimpleEntry<String, String>(customFieldProperty[0], customFieldProperty[1]));\r
- }\r
- \r
- final ListView<Entry<String, String>> customFieldsListView = new ListView<Entry<String, String>>("customFieldsListView", definedProperties) {\r
+ // custom fields\r
+ final Map<String, String> customFieldsMap = GitBlit.getMap(Keys.groovy.customFields);\r
+ List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet());\r
+ final ListView<String> customFieldsListView = new ListView<String>("customFieldsListView", customKeys) {\r
+ \r
+ private static final long serialVersionUID = 1L;\r
+\r
@Override\r
- protected void populateItem(ListItem<Entry<String, String>> item) {\r
- String value = repositoryModel.customFields.get(item.getModelObject().getKey());\r
+ protected void populateItem(ListItem<String> item) {\r
+ String key = item.getModelObject();\r
+ item.add(new Label("customFieldLabel", customFieldsMap.get(key)));\r
\r
- item.add(new Label(item.getModelObject().getKey(), item.getModelObject().getValue())); // Used to get the key later\r
- item.add(new Label("customFieldLabel", item.getModelObject().getValue()));\r
- item.add(new TextField<String>("customFieldValue", new Model<String>(value)));\r
+ String value = "";\r
+ if (repositoryModel.customFields != null && repositoryModel.customFields.containsKey(key)) {\r
+ value = repositoryModel.customFields.get(key);\r
+ }\r
+ TextField<String> field = new TextField<String>("customFieldValue", new Model<String>(value));\r
+ item.add(field);\r
}\r
};\r
customFieldsListView.setReuseItems(true);\r
}\r
repositoryModel.postReceiveScripts = postReceiveScripts;\r
\r
- // Loop over each of the user defined properties\r
+ // custom fields\r
+ repositoryModel.customFields = new LinkedHashMap<String, String>();\r
for (int i = 0; i < customFieldsListView.size(); i++) {\r
- ListItem<ListItemModel<String>> item = (ListItem<ListItemModel<String>>) customFieldsListView.get(i);\r
- String key = item.get(0).getId(); // Item 0 is our 'fake' label\r
- String value = ((TextField<String>)item.get(2)).getValue(); // Item 2 is out text box\r
+ ListItem<String> child = (ListItem<String>) customFieldsListView.get(i);\r
+ String key = child.getModelObject();\r
+\r
+ TextField<String> field = (TextField<String>) child.get("customFieldValue");\r
+ String value = field.getValue();\r
\r
repositoryModel.customFields.put(key, value);\r
}\r
form.add(new BulletListPanel("inheritedPostReceive", "inherited", GitBlit.self()\r
.getPostReceiveScriptsInherited(repositoryModel)));\r
\r
- WebMarkupContainer customFiledsSection = new WebMarkupContainer("customFiledsSection") {\r
- public boolean isVisible() {\r
- return GitBlit.getString(Keys.repository.customFields, "").isEmpty() == false;\r
- };\r
- };\r
- customFiledsSection.add(customFieldsListView);\r
- form.add(customFiledsSection);\r
+ WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection");\r
+ customFieldsSection.add(customFieldsListView);\r
+ form.add(customFieldsSection.setVisible(!GitBlit.getString(Keys.groovy.customFields, "").isEmpty()));\r
\r
form.add(new Button("save"));\r
Button cancel = new Button("cancel") {\r