]> source.dussan.org Git - gitblit.git/commitdiff
Unit testing. Documentation. Simplified settings classes.
authorJames Moger <james.moger@gitblit.com>
Thu, 9 Jun 2011 23:04:24 +0000 (19:04 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 9 Jun 2011 23:04:24 +0000 (19:04 -0400)
14 files changed:
docs/00_index.mkd
src/com/gitblit/FileSettings.java
src/com/gitblit/GitBlit.java
src/com/gitblit/IStoredSettings.java
src/com/gitblit/WebXmlSettings.java
src/com/gitblit/utils/DiffUtils.java
src/com/gitblit/utils/StringUtils.java
src/com/gitblit/wicket/pages/CommitPage.java
src/com/gitblit/wicket/pages/RepositoryPage.java
src/com/gitblit/wicket/resources/gitblit.css
tests/com/gitblit/tests/DiffUtilsTest.java
tests/com/gitblit/tests/GitBlitTest.java
tests/com/gitblit/tests/JGitUtilsTest.java
tests/com/gitblit/tests/StringUtilsTest.java

index 2f15b38c4e00d9c6621579c7b122d6cf3c09ad7a..fbd736a2172b8c2923371e5352f1e1875664a6c1 100644 (file)
@@ -31,18 +31,17 @@ sources @ [Github][gitbltsrc]
 - Repository Owners may edit repositories through the web UI\r
 - Automatically generates a self-signed certificate for https communications\r
 - Git-notes support\r
-- Branch metrics\r
+- Branch metrics (uses Google Charts)\r
 - Blame annotations view\r
 - Dates can optionally be displayed using the browser's reported timezone\r
-- Author and Committer email address display can be controlled\r
-- Search commit messages, authors, and committers\r
+- Display of Author and Committer email addresses can be disabled\r
+- Case-insensitive searching of commit messages, authors, or committers\r
 - Dynamic zip downloads feature\r
-- Markdown view support\r
-- Syntax highlighting\r
-- Customizable regular expression handling for commit messages\r
+- Markdown file view support\r
+- Syntax highlighting for popular source code types\r
+- Customizable regular expression substitution for commit messages (i.e. bug or code review link integration)\r
 - Single text file for server configuration\r
 - Single text file for users configuration\r
-- Simple repository stats and activity graph (uses Google Charts)\r
 - Optional utility pages\r
     <ul class='noBullets'>\r
     <li>![docs](book_16x16.png) Docs page which enumerates all Markdown files within a repository</li>\r
@@ -50,24 +49,23 @@ sources @ [Github][gitbltsrc]
     </ul>\r
 \r
 ### Limitations\r
-- [%JGIT%][jgit] does not [garbage collect or repack](http://www.kernel.org/pub/software/scm/git/docs/git-gc.html)\r
+- [%JGIT%][jgit] does not currently [garbage collect or repack](http://www.kernel.org/pub/software/scm/git/docs/git-gc.html)\r
 - HTTP/HTTPS are the only supported protocols\r
 - Access controls are not path-based, they are repository-based\r
 - Only Administrators can create, rename or delete repositories\r
 - Gitblit is an integrated, full-stack solution.  There is no WAR build at this time.\r
 \r
 ### Caveats\r
-- I don't know everything there is to know about [Git][git] nor [JGit][jgit].\r
 - Gitblit may eat your data.  Use at your own risk.\r
 - Gitblit may have security holes.  Patches welcome.  :)\r
 \r
 ### Todo List\r
 - Code documentation\r
 - Unit testing\r
-- Finish Blame (waiting for JGit 1.0.0 release)\r
-- Clone remote repository\r
+- Update Build.java to JGit 1.0.0, when its released\r
 \r
 ### Idea List\r
+- Consider clone remote repository feature\r
 - Consider [Apache Shiro](http://shiro.apache.org) for authentication\r
 - Stronger Ticgit read-only integration\r
     - activity/timeline\r
@@ -88,7 +86,7 @@ Gitblit is distributed under the terms of the [Apache Software Foundation licens
 \r
 ## Architecture\r
 \r
-![block diagram](architecture.png "Git Blit Architecture")\r
+![block diagram](architecture.png "Gitblit Architecture")\r
 \r
 ### Bundled Dependencies\r
 The following dependencies are bundled with the Gitblit zip distribution file.\r
@@ -116,6 +114,7 @@ The following dependencies are automatically downloaded from the Apache Maven re
 ### Other Build Dependencies\r
 - [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)\r
 - [JUnit](http://junit.org) (Common Public License)\r
+- [commons-net](http://commons.apache.org/net) (Apache 2.0)\r
 \r
 ## Building from Source\r
 [Eclipse](http://eclipse.org) is recommended for development as the project settings are preconfigured.\r
index 01176c03bd8fc2e6c18617118ded6617ddd092c8..b70daa0f0c86b78e9668cd00f48a9827b4002c4c 100644 (file)
@@ -18,144 +18,42 @@ package com.gitblit;
 import java.io.File;\r
 import java.io.FileInputStream;\r
 import java.io.FileNotFoundException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
 import java.util.Properties;\r
-import java.util.regex.PatternSyntaxException;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
 \r
 /**\r
  * Reads GitBlit settings file.\r
  * \r
  */\r
-public class FileSettings implements IStoredSettings {\r
-\r
-       private final Logger logger = LoggerFactory.getLogger(FileSettings.class);\r
+public class FileSettings extends IStoredSettings {\r
 \r
        private final File propertiesFile;\r
 \r
-       private Properties properties = new Properties();\r
+       private final Properties properties = new Properties();\r
 \r
-       private long lastread;\r
+       private volatile long lastread;\r
 \r
        public FileSettings(String file) {\r
+               super(FileSettings.class);\r
                this.propertiesFile = new File(file);\r
        }\r
 \r
        @Override\r
-       public List<String> getAllKeys(String startingWith) {\r
-               startingWith = startingWith.toLowerCase();\r
-               List<String> keys = new ArrayList<String>();\r
-               Properties props = read();\r
-               for (Object o : props.keySet()) {\r
-                       String key = o.toString().toLowerCase();\r
-                       if (key.startsWith(startingWith)) {\r
-                               keys.add(key);\r
-                       }\r
-               }\r
-               return keys;\r
-       }\r
-\r
-       @Override\r
-       public boolean getBoolean(String name, boolean defaultValue) {\r
-               Properties props = read();\r
-               if (props.containsKey(name)) {\r
-                       try {\r
-                               String value = props.getProperty(name);\r
-                               if (value != null && value.trim().length() > 0) {\r
-                                       return Boolean.parseBoolean(value);\r
-                               }\r
-                       } catch (Exception e) {\r
-                               logger.warn("No override setting for " + name + " using default of " + defaultValue);\r
-                       }\r
-               }\r
-               return defaultValue;\r
-       }\r
-\r
-       @Override\r
-       public int getInteger(String name, int defaultValue) {\r
-               Properties props = read();\r
-               if (props.containsKey(name)) {\r
-                       try {\r
-                               String value = props.getProperty(name);\r
-                               if (value != null && value.trim().length() > 0) {\r
-                                       return Integer.parseInt(value);\r
-                               }\r
-                       } catch (Exception e) {\r
-                               logger.warn("No override setting for " + name + " using default of " + defaultValue);\r
-                       }\r
-               }\r
-               return defaultValue;\r
-       }\r
-\r
-       @Override\r
-       public String getString(String name, String defaultValue) {\r
-               Properties props = read();\r
-               if (props.containsKey(name)) {\r
-                       try {\r
-                               String value = props.getProperty(name);\r
-                               if (value != null) {\r
-                                       return value;\r
-                               }\r
-                       } catch (Exception e) {\r
-                               logger.warn("No override setting for " + name + " using default of " + defaultValue);\r
-                       }\r
-               }\r
-               return defaultValue;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStrings(String name) {\r
-               return getStrings(name, " ");\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStringsFromValue(String value) {\r
-               return getStringsFromValue(value, " ");\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStrings(String name, String separator) {\r
-               List<String> strings = new ArrayList<String>();\r
-               Properties props = read();\r
-               if (props.containsKey(name)) {\r
-                       String value = props.getProperty(name);\r
-                       strings = getStringsFromValue(value, separator);\r
-               }\r
-               return strings;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStringsFromValue(String value, String separator) {\r
-               List<String> strings = new ArrayList<String>();\r
-               try {\r
-                       String[] chunks = value.split(separator);\r
-                       for (String chunk : chunks) {\r
-                               chunk = chunk.trim();\r
-                               if (chunk.length() > 0) {\r
-                                       strings.add(chunk);\r
-                               }\r
-                       }\r
-               } catch (PatternSyntaxException e) {\r
-                       logger.error("Failed to parse " + value, e);\r
-               }\r
-               return strings;\r
-       }\r
-\r
-       private synchronized Properties read() {\r
+       protected synchronized Properties read() {\r
                if (propertiesFile.exists() && (propertiesFile.lastModified() > lastread)) {\r
                        FileInputStream is = null;\r
                        try {\r
-                               properties = new Properties();\r
+                               Properties props = new Properties();\r
                                is = new FileInputStream(propertiesFile);\r
-                               properties.load(is);\r
+                               props.load(is);\r
+                               \r
+                               // load properties after we have successfully read file\r
+                               properties.clear();\r
+                               properties.putAll(props);\r
                                lastread = propertiesFile.lastModified();\r
                        } catch (FileNotFoundException f) {\r
                                // IGNORE - won't happen because file.exists() check above\r
                        } catch (Throwable t) {\r
-                               t.printStackTrace();\r
+                               logger.error("Failed to read " + propertiesFile.getName(), t);\r
                        } finally {\r
                                if (is != null) {\r
                                        try {\r
index dcf5a6b2ca59d5e307c86a184c7ee5107dd82e27..01326230cf6b84a031cbe1e1d0d5f241d2f7ebc7 100644 (file)
@@ -312,17 +312,6 @@ public class GitBlit implements ServletContextListener {
                return false;\r
        }\r
 \r
-       public boolean renameRepository(RepositoryModel model, String newName) {\r
-               File folder = new File(repositoriesFolder, model.name);\r
-               if (folder.exists() && folder.isDirectory()) {\r
-                       File newFolder = new File(repositoriesFolder, newName);\r
-                       if (folder.renameTo(newFolder)) {\r
-                               return loginService.renameRole(model.name, newName);\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-\r
        public void configureContext(IStoredSettings settings) {\r
                logger.info("Reading configuration from " + settings.toString());\r
                this.storedSettings = settings;\r
@@ -334,6 +323,7 @@ public class GitBlit implements ServletContextListener {
        @Override\r
        public void contextInitialized(ServletContextEvent contextEvent) {\r
                if (storedSettings == null) {\r
+                       // for running gitblit as a traditional webapp in a servlet container\r
                        WebXmlSettings webxmlSettings = new WebXmlSettings(contextEvent.getServletContext());\r
                        configureContext(webxmlSettings);\r
                }\r
@@ -341,6 +331,6 @@ public class GitBlit implements ServletContextListener {
 \r
        @Override\r
        public void contextDestroyed(ServletContextEvent contextEvent) {\r
-               logger.info("GitBlit context destroyed by servlet container.");\r
+               logger.info("Gitblit context destroyed by servlet container.");\r
        }\r
 }\r
index 07d21e2506d738fa69b43dc762387f812408e6c4..7108c068dc5502772a645233bdaaa090d5c7a68f 100644 (file)
  */\r
 package com.gitblit;\r
 \r
+import java.util.ArrayList;\r
 import java.util.List;\r
+import java.util.Properties;\r
 \r
-public interface IStoredSettings {\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 \r
-       List<String> getAllKeys(String startingWith);\r
+import com.gitblit.utils.StringUtils;\r
 \r
-       boolean getBoolean(String name, boolean defaultValue);\r
+public abstract class IStoredSettings {\r
 \r
-       int getInteger(String name, int defaultValue);\r
+       protected final Logger logger;\r
+       \r
+       public IStoredSettings(Class<? extends IStoredSettings> clazz) {\r
+               logger = LoggerFactory.getLogger(clazz);\r
+       }\r
+               \r
+       protected abstract Properties read();\r
 \r
-       String getString(String name, String defaultValue);\r
+       public List<String> getAllKeys(String startingWith) {\r
+               startingWith = startingWith.toLowerCase();\r
+               List<String> keys = new ArrayList<String>();\r
+               Properties props = read();\r
+               for (Object o : props.keySet()) {\r
+                       String key = o.toString();\r
+                       if (key.toLowerCase().startsWith(startingWith)) {\r
+                               keys.add(key);\r
+                       }\r
+               }\r
+               return keys;\r
+       }\r
 \r
-       List<String> getStrings(String name);\r
+       public boolean getBoolean(String name, boolean defaultValue) {\r
+               Properties props = read();\r
+               if (props.containsKey(name)) {\r
+                       String value = props.getProperty(name);\r
+                       if (!StringUtils.isEmpty(value)) {\r
+                               return Boolean.parseBoolean(value);\r
+                       }\r
+               }\r
+               return defaultValue;\r
+       }\r
 \r
-       List<String> getStringsFromValue(String value);\r
+       public int getInteger(String name, int defaultValue) {\r
+               Properties props = read();\r
+               if (props.containsKey(name)) {\r
+                       try {\r
+                               String value = props.getProperty(name);\r
+                               if (!StringUtils.isEmpty(value)) {\r
+                                       return Integer.parseInt(value);\r
+                               }\r
+                       } catch (NumberFormatException e) {\r
+                               logger.warn("Failed to parse integer for " + name + " using default of "\r
+                                               + defaultValue);\r
+                       }\r
+               }\r
+               return defaultValue;\r
+       }\r
 \r
-       List<String> getStrings(String name, String separator);\r
+       public String getString(String name, String defaultValue) {\r
+               Properties props = read();\r
+               if (props.containsKey(name)) {\r
+                       String value = props.getProperty(name);\r
+                       if (value != null) {\r
+                               return value;\r
+                       }\r
+               }\r
+               return defaultValue;\r
+       }\r
 \r
-       List<String> getStringsFromValue(String value, String separator);\r
+       public List<String> getStrings(String name) {\r
+               return getStrings(name, " ");\r
+       }\r
 \r
+       public List<String> getStrings(String name, String separator) {\r
+               List<String> strings = new ArrayList<String>();\r
+               Properties props = read();\r
+               if (props.containsKey(name)) {\r
+                       String value = props.getProperty(name);\r
+                       strings = StringUtils.getStringsFromValue(value, separator);\r
+               }\r
+               return strings;\r
+       }\r
 }
\ No newline at end of file
index 6ca38f78ed7703597b50761f607dacddf066d677..0ff2a3e76ceddb587b06a2f5344f2f3583dc1e9f 100644 (file)
  */\r
 package com.gitblit;\r
 \r
-import java.util.List;\r
+import java.util.Enumeration;\r
+import java.util.Properties;\r
 \r
 import javax.servlet.ServletContext;\r
 \r
-public class WebXmlSettings implements IStoredSettings {\r
+public class WebXmlSettings extends IStoredSettings {\r
 \r
+       private final Properties properties = new Properties();\r
+       \r
        public WebXmlSettings(ServletContext context) {\r
-\r
-       }\r
-\r
-       @Override\r
-       public List<String> getAllKeys(String startingWith) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public boolean getBoolean(String name, boolean defaultValue) {\r
-               // TODO Auto-generated method stub\r
-               return false;\r
-       }\r
-\r
-       @Override\r
-       public int getInteger(String name, int defaultValue) {\r
-               // TODO Auto-generated method stub\r
-               return 0;\r
-       }\r
-\r
-       @Override\r
-       public String getString(String name, String defaultValue) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStrings(String name) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStringsFromValue(String value) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStrings(String name, String separator) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public List<String> getStringsFromValue(String value, String separator) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
+               super(WebXmlSettings.class);\r
+               Enumeration<?> keys = context.getInitParameterNames();\r
+               while (keys.hasMoreElements()) {\r
+                       String key = keys.nextElement().toString();\r
+                       String value = context.getInitParameter(key);\r
+                       properties.put(key, value);\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       protected Properties read() {\r
+               return properties;\r
        }\r
 \r
        @Override\r
index 0f569074684750bf76e75e07068cbb13a0ee51c8..c1401f962d79eb9b5a72dc1276d3ca4368bd5678 100644 (file)
@@ -25,6 +25,7 @@ import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffFormatter;\r
 import org.eclipse.jgit.diff.RawText;\r
 import org.eclipse.jgit.diff.RawTextComparator;\r
+import org.eclipse.jgit.lib.Constants;\r
 import org.eclipse.jgit.lib.Repository;\r
 import org.eclipse.jgit.revwalk.RevCommit;\r
 import org.eclipse.jgit.revwalk.RevTree;\r
@@ -69,6 +70,7 @@ public class DiffUtils {
 \r
        public static String getDiff(Repository r, RevCommit baseCommit, RevCommit commit, String path,\r
                        DiffOutputType outputType) {\r
+               String diff = null;\r
                try {\r
                        RevTree baseTree;\r
                        if (baseCommit == null) {\r
@@ -107,18 +109,17 @@ public class DiffUtils {
                        df.setRepository(r);\r
                        df.setDiffComparator(cmp);\r
                        df.setDetectRenames(true);\r
-                       List<DiffEntry> diffs = df.scan(baseTree, commitTree);\r
+                       List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);\r
                        if (path != null && path.length() > 0) {\r
-                               for (DiffEntry diff : diffs) {\r
-                                       if (diff.getNewPath().equalsIgnoreCase(path)) {\r
-                                               df.format(diff);\r
+                               for (DiffEntry diffEntry : diffEntries) {\r
+                                       if (diffEntry.getNewPath().equalsIgnoreCase(path)) {\r
+                                               df.format(diffEntry);\r
                                                break;\r
                                        }\r
                                }\r
                        } else {\r
-                               df.format(diffs);\r
+                               df.format(diffEntries);\r
                        }\r
-                       String diff;\r
                        if (df instanceof GitWebDiffFormatter) {\r
                                // workaround for complex private methods in DiffFormatter\r
                                diff = ((GitWebDiffFormatter) df).getHtml();\r
@@ -126,15 +127,15 @@ public class DiffUtils {
                                diff = os.toString();\r
                        }\r
                        df.flush();\r
-                       return diff;\r
                } catch (Throwable t) {\r
                        LOGGER.error("failed to generate commit diff!", t);\r
                }\r
-               return null;\r
+               return diff;\r
        }\r
 \r
        public static String getCommitPatch(Repository r, RevCommit baseCommit, RevCommit commit,\r
                        String path) {\r
+               String diff = null;\r
                try {\r
                        RevTree baseTree;\r
                        if (baseCommit == null) {\r
@@ -159,29 +160,31 @@ public class DiffUtils {
                        df.setRepository(r);\r
                        df.setDiffComparator(cmp);\r
                        df.setDetectRenames(true);\r
-                       List<DiffEntry> diffs = df.scan(baseTree, commitTree);\r
+                       List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);\r
                        if (path != null && path.length() > 0) {\r
-                               for (DiffEntry diff : diffs) {\r
-                                       if (diff.getNewPath().equalsIgnoreCase(path)) {\r
-                                               df.format(diff);\r
+                               for (DiffEntry diffEntry : diffEntries) {\r
+                                       if (diffEntry.getNewPath().equalsIgnoreCase(path)) {\r
+                                               df.format(diffEntry);\r
                                                break;\r
                                        }\r
                                }\r
                        } else {\r
-                               df.format(diffs);\r
+                               df.format(diffEntries);\r
                        }\r
-                       String diff = df.getPatch(commit);\r
+                       diff = df.getPatch(commit);\r
                        df.flush();\r
-                       return diff;\r
                } catch (Throwable t) {\r
                        LOGGER.error("failed to generate commit diff!", t);\r
                }\r
-               return null;\r
+               return diff;\r
        }\r
 \r
        public static List<AnnotatedLine> blame(Repository r, String blobPath, String objectId) {\r
                List<AnnotatedLine> lines = new ArrayList<AnnotatedLine>();\r
                try {\r
+                       if (StringUtils.isEmpty(objectId)) {\r
+                               objectId = Constants.HEAD;\r
+                       }\r
                        BlameCommand blameCommand = new BlameCommand(r);\r
                        blameCommand.setFilePath(blobPath);\r
                        blameCommand.setStartCommit(r.resolve(objectId));\r
index a881b58c4e79d2c55d7bde22b7cae88d90636283..fa84fe8fc543a3aaf41c8dfa4dd5996c50fd86ec 100644 (file)
@@ -18,7 +18,9 @@ package com.gitblit.utils;
 import java.io.UnsupportedEncodingException;\r
 import java.security.MessageDigest;\r
 import java.security.NoSuchAlgorithmException;\r
+import java.util.ArrayList;\r
 import java.util.List;\r
+import java.util.regex.PatternSyntaxException;\r
 \r
 public class StringUtils {\r
 \r
@@ -142,4 +144,24 @@ public class StringUtils {
                }\r
                return relativePath;\r
        }\r
+       \r
+       public static List<String> getStringsFromValue(String value) {\r
+               return getStringsFromValue(value, " ");\r
+       }\r
+               \r
+       public static List<String> getStringsFromValue(String value, String separator) {\r
+               List<String> strings = new ArrayList<String>();\r
+               try {\r
+                       String[] chunks = value.split(separator);\r
+                       for (String chunk : chunks) {\r
+                               chunk = chunk.trim();\r
+                               if (chunk.length() > 0) {\r
+                                       strings.add(chunk);\r
+                               }\r
+                       }\r
+               } catch (PatternSyntaxException e) {\r
+                       throw new RuntimeException(e);\r
+               }\r
+               return strings;\r
+       }\r
 }\r
index 02956001a5266ed846183aab2e707cedd08fdd90..6da962ef0b336d922ee5223e54407500ce5b1bd4 100644 (file)
@@ -38,7 +38,6 @@ import com.gitblit.models.GitNote;
 import com.gitblit.models.PathModel.PathChangeModel;\r
 import com.gitblit.utils.JGitUtils;\r
 import com.gitblit.utils.JGitUtils.SearchType;\r
-import com.gitblit.utils.StringUtils;\r
 import com.gitblit.wicket.WicketUtils;\r
 import com.gitblit.wicket.panels.CommitHeaderPanel;\r
 import com.gitblit.wicket.panels.CommitLegendPanel;\r
@@ -129,7 +128,7 @@ public class CommitPage extends RepositoryPage {
                                                SearchType.AUTHOR));\r
                                item.add(WicketUtils.createTimestampLabel("authorDate", entry.notesRef\r
                                                .getAuthorIdent().getWhen(), getTimeZone()));\r
-                               item.add(new Label("noteContent", StringUtils.breakLinesForHtml(entry.content))\r
+                               item.add(new Label("noteContent", substituteText(entry.content))\r
                                                .setEscapeModelStrings(false));\r
                        }\r
                };\r
index e2120f7762c220470ce1c7e90d27f99cf6ff00db..cff59f26acb46de0c1d7902c94e0a17869aa7204 100644 (file)
@@ -227,40 +227,48 @@ public abstract class RepositoryPage extends BasePage {
        }\r
 \r
        protected void addFullText(String wicketId, String text, boolean substituteRegex) {\r
-               String html = StringUtils.breakLinesForHtml(text);\r
+               String html;\r
                if (substituteRegex) {\r
-                       Map<String, String> map = new HashMap<String, String>();\r
-                       // global regex keys\r
-                       if (GitBlit.getBoolean(Keys.regex.global, false)) {\r
-                               for (String key : GitBlit.getAllKeys(Keys.regex.global)) {\r
-                                       if (!key.equals(Keys.regex.global)) {\r
-                                               String subKey = key.substring(key.lastIndexOf('.') + 1);\r
-                                               map.put(subKey, GitBlit.getString(key, ""));\r
-                                       }\r
+                       html = substituteText(text);\r
+               } else {\r
+                       html = StringUtils.breakLinesForHtml(text);\r
+               }\r
+               add(new Label(wicketId, html).setEscapeModelStrings(false));\r
+       }\r
+\r
+       protected String substituteText(String text) {\r
+               String html = StringUtils.breakLinesForHtml(text);\r
+               Map<String, String> map = new HashMap<String, String>();\r
+               // global regex keys\r
+               if (GitBlit.getBoolean(Keys.regex.global, false)) {\r
+                       for (String key : GitBlit.getAllKeys(Keys.regex.global)) {\r
+                               if (!key.equals(Keys.regex.global)) {\r
+                                       String subKey = key.substring(key.lastIndexOf('.') + 1);\r
+                                       map.put(subKey, GitBlit.getString(key, ""));\r
                                }\r
                        }\r
+               }\r
 \r
-                       // repository-specific regex keys\r
-                       List<String> keys = GitBlit.getAllKeys(Keys.regex._ROOT + "."\r
-                                       + repositoryName.toLowerCase());\r
-                       for (String key : keys) {\r
-                               String subKey = key.substring(key.lastIndexOf('.') + 1);\r
-                               map.put(subKey, GitBlit.getString(key, ""));\r
-                       }\r
+               // repository-specific regex keys\r
+               List<String> keys = GitBlit.getAllKeys(Keys.regex._ROOT + "."\r
+                               + repositoryName.toLowerCase());\r
+               for (String key : keys) {\r
+                       String subKey = key.substring(key.lastIndexOf('.') + 1);\r
+                       map.put(subKey, GitBlit.getString(key, ""));\r
+               }\r
 \r
-                       for (Entry<String, String> entry : map.entrySet()) {\r
-                               String definition = entry.getValue().trim();\r
-                               String[] chunks = definition.split("!!!");\r
-                               if (chunks.length == 2) {\r
-                                       html = html.replaceAll(chunks[0], chunks[1]);\r
-                               } else {\r
-                                       logger.warn(entry.getKey()\r
-                                                       + " improperly formatted.  Use !!! to separate match from replacement: "\r
-                                                       + definition);\r
-                               }\r
+               for (Entry<String, String> entry : map.entrySet()) {\r
+                       String definition = entry.getValue().trim();\r
+                       String[] chunks = definition.split("!!!");\r
+                       if (chunks.length == 2) {\r
+                               html = html.replaceAll(chunks[0], chunks[1]);\r
+                       } else {\r
+                               logger.warn(entry.getKey()\r
+                                               + " improperly formatted.  Use !!! to separate match from replacement: "\r
+                                               + definition);\r
                        }\r
                }\r
-               add(new Label(wicketId, html).setEscapeModelStrings(false));\r
+               return html;\r
        }\r
 \r
        protected abstract String getPageName();\r
index 4309458809bf48925202ea9b9d4666f5b0349349..7143f8549625f0a03efafae5e2734699e3943ece 100644 (file)
@@ -249,6 +249,10 @@ div.commit_message {
        border-width: 1px 0px 0px;\r
 }\r
 \r
+div.commit_message a {\r
+       font-family: monospace;\r
+}\r
+\r
 div.bug_open, span.bug_open {\r
        padding: 2px;\r
        background-color: #803333;\r
index e60a2a4e39535207b157e3d2f4bdf1315d1d2c1b..84353c19333f58816184f7e9becebd92bd90e56f 100644 (file)
  */\r
 package com.gitblit.tests;\r
 \r
+import java.util.List;\r
+\r
 import junit.framework.TestCase;\r
 \r
 import org.eclipse.jgit.lib.Repository;\r
 import org.eclipse.jgit.revwalk.RevCommit;\r
 \r
+import com.gitblit.models.AnnotatedLine;\r
 import com.gitblit.utils.DiffUtils;\r
 import com.gitblit.utils.DiffUtils.DiffOutputType;\r
 import com.gitblit.utils.JGitUtils;\r
 \r
 public class DiffUtilsTest extends TestCase {\r
 \r
+       public void testDiffOutputTypes() throws Exception {\r
+               assertTrue(DiffOutputType.forName("plain").equals(DiffOutputType.PLAIN));\r
+               assertTrue(DiffOutputType.forName("gitweb").equals(DiffOutputType.GITWEB));\r
+               assertTrue(DiffOutputType.forName("gitblit").equals(DiffOutputType.GITBLIT));\r
+               assertTrue(DiffOutputType.forName(null) == null);\r
+       }\r
+       \r
        public void testParentCommitDiff() throws Exception {\r
                Repository repository = GitBlitSuite.getHelloworldRepository();\r
                RevCommit commit = JGitUtils.getCommit(repository,\r
@@ -97,4 +107,12 @@ public class DiffUtilsTest extends TestCase {
                String expected = "-            system.out.println(\"Hello World\");\n+         System.out.println(\"Hello World\"";\r
                assertTrue(patch.indexOf(expected) > -1);\r
        }\r
+       \r
+       public void testBlame() throws Exception {\r
+               Repository repository = GitBlitSuite.getHelloworldRepository();\r
+               List<AnnotatedLine> lines = DiffUtils.blame(repository, "java.java", "1d0c2933a4ae69c362f76797d42d6bd182d05176");\r
+               repository.close();\r
+               assertTrue(lines.size() > 0);\r
+               assertTrue(lines.get(0).commitId.equals("c6d31dccf5cc75e8e46299fc62d38f60ec6d41e0"));\r
+       }\r
 }\r
index 853ca39a1049c13703edb5ed8bf6cdfb9aa5c8cf..13705f1d0f05ec378d1b8cea3e59e90aaa8e8955 100644 (file)
@@ -19,6 +19,8 @@ import java.util.List;
 \r
 import junit.framework.TestCase;\r
 \r
+import com.gitblit.Constants.AccessRestrictionType;\r
+import com.gitblit.FileSettings;\r
 import com.gitblit.GitBlit;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.models.UserModel;\r
@@ -47,10 +49,84 @@ public class GitBlitTest extends TestCase {
                assertTrue(model.toString().equals("admin"));\r
                assertTrue("Admin missing #admin role!", model.canAdmin);\r
                model.canAdmin = false;\r
-               assertFalse("Admin should not hae #admin!", model.canAdmin);\r
+               assertFalse("Admin should not have #admin!", model.canAdmin);\r
                String repository = GitBlitSuite.getHelloworldRepository().getDirectory().getName();\r
                assertFalse("Admin can still access repository!", model.canAccessRepository(repository));\r
                model.addRepository(repository);\r
                assertTrue("Admin can't access repository!", model.canAccessRepository(repository));\r
        }\r
+       \r
+       public void testAccessRestrictionTypes() throws Exception {\r
+               assertTrue(AccessRestrictionType.PUSH.exceeds(AccessRestrictionType.NONE));\r
+               assertTrue(AccessRestrictionType.CLONE.exceeds(AccessRestrictionType.PUSH));\r
+               assertTrue(AccessRestrictionType.VIEW.exceeds(AccessRestrictionType.CLONE));\r
+\r
+               assertFalse(AccessRestrictionType.NONE.exceeds(AccessRestrictionType.PUSH));\r
+               assertFalse(AccessRestrictionType.PUSH.exceeds(AccessRestrictionType.CLONE));\r
+               assertFalse(AccessRestrictionType.CLONE.exceeds(AccessRestrictionType.VIEW));\r
+\r
+               assertTrue(AccessRestrictionType.PUSH.atLeast(AccessRestrictionType.NONE));\r
+               assertTrue(AccessRestrictionType.CLONE.atLeast(AccessRestrictionType.PUSH));\r
+               assertTrue(AccessRestrictionType.VIEW.atLeast(AccessRestrictionType.CLONE));\r
+\r
+               assertFalse(AccessRestrictionType.NONE.atLeast(AccessRestrictionType.PUSH));\r
+               assertFalse(AccessRestrictionType.PUSH.atLeast(AccessRestrictionType.CLONE));\r
+               assertFalse(AccessRestrictionType.CLONE.atLeast(AccessRestrictionType.VIEW));\r
+               \r
+               assertTrue(AccessRestrictionType.PUSH.toString().equals("PUSH"));\r
+               assertTrue(AccessRestrictionType.CLONE.toString().equals("CLONE"));\r
+               assertTrue(AccessRestrictionType.VIEW.toString().equals("VIEW"));\r
+\r
+               assertTrue(AccessRestrictionType.fromName("none").equals(AccessRestrictionType.NONE));\r
+               assertTrue(AccessRestrictionType.fromName("push").equals(AccessRestrictionType.PUSH));\r
+               assertTrue(AccessRestrictionType.fromName("clone").equals(AccessRestrictionType.CLONE));\r
+               assertTrue(AccessRestrictionType.fromName("view").equals(AccessRestrictionType.VIEW));\r
+       }\r
+       \r
+       public void testFileSettings() throws Exception {\r
+               FileSettings settings = new FileSettings("distrib/gitblit.properties");\r
+               assertTrue(settings.getBoolean("missing", true) == true);\r
+               assertTrue(settings.getString("missing", "default").equals("default"));\r
+               assertTrue(settings.getInteger("missing", 10) == 10);\r
+               assertTrue(settings.getInteger("realm.realmFile", 5) == 5);\r
+               \r
+               assertTrue(settings.getBoolean("git.enableGitServlet", false) == true);\r
+               assertTrue(settings.getString("realm.realmFile", null).equals("users.properties"));\r
+               assertTrue(settings.getInteger("realm.minPasswordLength", 0) == 5);\r
+               List<String> mdExtensions = settings.getStrings("web.markdownExtensions");\r
+               assertTrue(mdExtensions.size() > 0);\r
+               assertTrue(mdExtensions.contains("md"));\r
+               \r
+               List<String> keys = settings.getAllKeys("server");\r
+               assertTrue(keys.size() > 0);\r
+               assertTrue(keys.contains("server.httpsPort"));\r
+       }\r
+       \r
+       public void testGitblitSettings() throws Exception {\r
+               // These are already tested by above test method.\r
+               assertTrue(GitBlit.getBoolean("missing", true) == true);\r
+               assertTrue(GitBlit.getString("missing", "default").equals("default"));\r
+               assertTrue(GitBlit.getInteger("missing", 10) == 10);\r
+               assertTrue(GitBlit.getInteger("realm.realmFile", 5) == 5);\r
+               \r
+               assertTrue(GitBlit.getBoolean("git.enableGitServlet", false) == true);\r
+               assertTrue(GitBlit.getString("realm.realmFile", null).equals("users.properties"));\r
+               assertTrue(GitBlit.getInteger("realm.minPasswordLength", 0) == 5);\r
+               List<String> mdExtensions = GitBlit.getStrings("web.markdownExtensions");\r
+               assertTrue(mdExtensions.size() > 0);\r
+               assertTrue(mdExtensions.contains("md"));\r
+               \r
+               List<String> keys = GitBlit.getAllKeys("server");\r
+               assertTrue(keys.size() > 0);\r
+               assertTrue(keys.contains("server.httpsPort"));\r
+       }\r
+       \r
+       public void testAuthentication() throws Exception  {\r
+               assertTrue(GitBlit.self().authenticate("admin", "admin".toCharArray()) != null);\r
+       }\r
+       \r
+       public void testRepositories() throws Exception  {\r
+               assertTrue(GitBlit.self().getRepository("missing") == null);\r
+               assertTrue(GitBlit.self().getRepositoryModel("missing") == null);\r
+       }\r
 }\r
index 1b57585646e1cac06ddb57aa5206f16c06c5bbc8..19a4847491fbd44d2f3637723fe53be6af00c9da 100644 (file)
@@ -122,6 +122,7 @@ public class JGitUtilsTest extends TestCase {
                        List<RefModel> list = entry.getValue();\r
                        for (RefModel ref : list) {\r
                                if (ref.displayName.equals("refs/tags/spearce-gpg-pub")) {\r
+                                       assertTrue(ref.toString().equals("refs/tags/spearce-gpg-pub"));\r
                                        assertTrue(ref.getObjectId().getName()\r
                                                        .equals("8bbde7aacf771a9afb6992434f1ae413e010c6d8"));\r
                                        assertTrue(ref.getAuthorIdent().getEmailAddress().equals("spearce@spearce.org"));\r
index df51a4bbafe3b079a25a9b824a96d5428c557e2e..b0d9a1ff5306d2a9ca75b11368aabe39ce824fd8 100644 (file)
@@ -16,6 +16,7 @@
 package com.gitblit.tests;\r
 \r
 import java.util.Arrays;\r
+import java.util.List;\r
 \r
 import junit.framework.TestCase;\r
 \r
@@ -76,4 +77,13 @@ public class StringUtilsTest extends TestCase {
                assertTrue(StringUtils.getRootPath(input).equals(output));\r
                assertTrue(StringUtils.getRootPath("repository").equals(""));\r
        }\r
+       \r
+       public void testStringsFromValue() throws Exception {\r
+               List<String> strings = StringUtils.getStringsFromValue("A B C D");\r
+               assertTrue(strings.size() == 4);\r
+               assertTrue(strings.get(0).equals("A"));\r
+               assertTrue(strings.get(1).equals("B"));\r
+               assertTrue(strings.get(2).equals("C"));\r
+               assertTrue(strings.get(3).equals("D"));\r
+       }\r
 }\r