- 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
</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
\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
### 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
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
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
@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
\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
*/\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
*/\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
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
\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
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
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
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
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
}\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
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
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
}\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
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
*/\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
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
\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
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
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
package com.gitblit.tests;\r
\r
import java.util.Arrays;\r
+import java.util.List;\r
\r
import junit.framework.TestCase;\r
\r
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