You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2013/06/08 01:41:56 UTC

[01/27] git commit: [#6218] Fixed failing test due to added tag

Updated Branches:
  refs/heads/db/6276 dd29d3e19 -> 269d59572


[#6218] Fixed failing test due to added tag

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/28f8651e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/28f8651e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/28f8651e

Branch: refs/heads/db/6276
Commit: 28f8651e107f8e317d1a9f35ebc7c40094dd3840
Parents: 6a3753d
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri May 24 14:35:10 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:46:06 2013 +0000

----------------------------------------------------------------------
 ForgeGit/forgegit/tests/model/test_repository.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f8651e/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index e0026b7..bae667c 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -76,7 +76,7 @@ class TestNewGit(unittest.TestCase):
         assert self.rev.tree._id == self.rev.tree_id
         assert self.rev.summary == self.rev.message.splitlines()[0]
         assert self.rev.shorthand_id() == '[1e146e]'
-        assert self.rev.symbolic_ids == (['master', 'zz'], [])
+        assert self.rev.symbolic_ids == (['master', 'zz'], ['foo'])
         assert self.rev.url() == (
             '/p/test/src-git/ci/'
             '1e146e67985dcd71c74de79613719bef7bddca4a/')


[12/27] git commit: [#6325] using jinja2.TemplateNotFound for bad paths

Posted by tv...@apache.org.
[#6325] using jinja2.TemplateNotFound for bad paths

Signed-off-by: Nicholas Bollweg (Nick) <ni...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ca90e5c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ca90e5c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ca90e5c7

Branch: refs/heads/db/6276
Commit: ca90e5c761f9c500daae23b799cc1a44aeeeac25
Parents: cf0d391
Author: Nicholas Bollweg (Nick) <ni...@gmail.com>
Authored: Fri Mar 2 17:14:35 2012 -0500
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/package_path_loader.py |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ca90e5c7/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index aee8e1a..fe3f4b9 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -43,7 +43,8 @@ For the examples, assume the following directory structure:
                    |- file.html     <- actual template
 
 To override the above example, a Tool implementer would
-add the following line to their Tool's setup.py:
+add the following line to their Tool's setup.py (assuming usage in Allura,
+with the default app_cfg):
 
     [allura.theme.override]
     newtool = newtool.app:NewToolApp
@@ -195,6 +196,7 @@ class PackagePathLoader(jinja2.BaseLoader):
         package, path = None, None
         src = None
         bits = template.split(':')
+
         if len(bits) == 2:
             # splitting out the Python module name from the template string...
             # the default allura behavior
@@ -206,14 +208,15 @@ class PackagePathLoader(jinja2.BaseLoader):
             path = bits[0]
             path_fragment = os.path.join(self.override_root, path)
         else:
-            raise Exception('malformed template path')
+            raise jinja2.TemplateNotFound(
+                'Malformed template path %s' % template)
 
         # look in all of the customized search locations...
         try:
             src = self.fs_loader.get_source(environment, path_fragment)
-        except Exception:
-            # no Tool implemented an override... not even sure if this will
-            # throw an error, but we're ready for it!
+        except jinja2.TemplateNotFound:
+            # ...this doesn't mean it's really not found... it's probably
+            # just specified in the Allura-normal manner
             pass
 
         # ...but if you don't find anything, fall back to the explicit package
@@ -221,11 +224,13 @@ class PackagePathLoader(jinja2.BaseLoader):
         if src is None and package is not None:
             # gets the absolute filename of the template
             filename = pkg_resources.resource_filename(package, path)
-            # get the filename relative to the fs root (/).. if this fails
-            # this error is not caught, so should get propagated normally
+            # get the filename relative to the root: (default '/').. if this
+            # fails this error is not caught, so should get propagated
+            # normally
             src = self.fs_loader.get_source(environment, filename)
         elif src is None:
-            raise Exception(('Template %s not found in search path ' +
+            raise jinja2.TemplateNotFound(
+                ('Template %s not found in search path ' +
                   'and no module specified') % (
                     path,
                   ))


[06/27] git commit: [#6218] Fixed failing test due to added tag

Posted by tv...@apache.org.
[#6218] Fixed failing test due to added tag

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/3889e9e2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3889e9e2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3889e9e2

Branch: refs/heads/db/6276
Commit: 3889e9e25d5a977968d63d08f1828afc212d8a76
Parents: 401803b
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri May 24 14:35:10 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:59:58 2013 +0000

----------------------------------------------------------------------
 ForgeGit/forgegit/tests/model/test_repository.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3889e9e2/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 4afe27f..b3b920a 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -75,7 +75,7 @@ class TestNewGit(unittest.TestCase):
         assert self.rev.tree._id == self.rev.tree_id
         assert self.rev.summary == self.rev.message.splitlines()[0]
         assert self.rev.shorthand_id() == '[1e146e]'
-        assert self.rev.symbolic_ids == (['master'], ['foo']), self.rev.symbolic_ids
+        assert self.rev.symbolic_ids == (['master', 'zz'], ['foo'])
         assert self.rev.url() == (
             '/p/test/src-git/ci/'
             '1e146e67985dcd71c74de79613719bef7bddca4a/')


[02/27] git commit: [#6218] Get branches and tags directly from SCM

Posted by tv...@apache.org.
[#6218] Get branches and tags directly from SCM

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6a3753d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6a3753d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6a3753d7

Branch: refs/heads/db/6276
Commit: 6a3753d773045b66b319941ec6a264dbd20575d0
Parents: f9d1c45
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Thu May 23 23:35:00 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:46:06 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/repository.py                    |   27 +++++++++------
 Allura/allura/model/repository.py                  |   10 +++++
 ForgeGit/forgegit/model/git_repo.py                |    6 +++
 .../forgegit/tests/data/testgit.git/refs/tags/foo  |    1 +
 ForgeGit/forgegit/tests/model/test_repository.py   |   20 +++++++++++
 ForgeSVN/forgesvn/model/svn.py                     |    6 +++
 6 files changed, 59 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 3a432ec..afd5557 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -130,29 +130,34 @@ class RepositoryApp(Application):
                         self.repo.upstream_repo.name + 'merge-requests/',
                         small=pending_upstream_merges))
         ref_url = self.repo.url_for_commit(self.default_branch_name, url_type='ref')
-        if self.repo.branches:
+        branches = self.repo.get_branches()
+        if branches:
             links.append(SitemapEntry('Branches'))
+            for branch in branches:
+                if branch.name == self.default_branch_name:
+                    branches.remove(branch)
+                    branches.insert(0, branch)
+                    break
             max_branches = 10
-            for b in self.repo.branches[:max_branches]:
+            for branch in branches[:max_branches]:
                 links.append(SitemapEntry(
-                        b.name,
-                        quote(self.repo.url_for_commit(b.name) + 'tree/'),
-                        small=b.count))
-            if len(self.repo.branches) > max_branches:
+                        branch.name,
+                        quote(self.repo.url_for_commit(branch.name) + 'tree/')))
+            if len(branches) > max_branches:
                 links.append(
                     SitemapEntry(
                         'More Branches',
                         ref_url + 'branches/',
                         ))
-        if self.repo.repo_tags:
+        tags = self.repo.get_tags()
+        if tags:
             links.append(SitemapEntry('Tags'))
             max_tags = 10
-            for b in self.repo.repo_tags[:max_tags]:
+            for b in tags[:max_tags]:
                 links.append(SitemapEntry(
                         b.name,
-                        quote(self.repo.url_for_commit(b.name) + 'tree/'),
-                        small=b.count))
-            if len(self.repo.repo_tags) > max_tags:
+                        quote(self.repo.url_for_commit(b.name) + 'tree/')))
+            if len(tags) > max_tags:
                 links.append(
                     SitemapEntry(
                         'More Tags',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 1b6cfc4..1960d59 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -214,6 +214,12 @@ class RepositoryImplementation(object):
         os.chmod(magic_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
         self._setup_hooks(source_path)
 
+    def get_branches(self):
+        return self.repo.branches
+
+    def get_tags(self):
+        return self.repo.tags
+
 class Repository(Artifact, ActivityObject):
     BATCH_SIZE=100
     class __mongometa__:
@@ -326,6 +332,10 @@ class Repository(Artifact, ActivityObject):
         return self._impl.last_commit_ids(commit, paths)
     def is_empty(self):
         return self._impl.is_empty()
+    def get_branches(self):
+        return self._impl.get_branches()
+    def get_tags(self):
+        return self._impl.get_tags()
 
     def _log(self, rev, skip, limit):
         head = self.commit(rev)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index c656dfd..5683296 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -361,6 +361,12 @@ class GitImplementation(M.RepositoryImplementation):
     def is_empty(self):
         return not self._git or len(self._git.heads) == 0
 
+    def get_branches(self):
+        return [Object(name=b.name,object_id=b.commit.hexsha) for b in self._git.heads]
+
+    def get_tags(self):
+        return [Object(name=t.name, object_id=t.commit.hexsha) for t in self._git.tags]
+
 
 class _OpenedGitBlob(object):
     CHUNK_SIZE=4096

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/ForgeGit/forgegit/tests/data/testgit.git/refs/tags/foo
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/data/testgit.git/refs/tags/foo b/ForgeGit/forgegit/tests/data/testgit.git/refs/tags/foo
new file mode 100644
index 0000000..7e970a5
--- /dev/null
+++ b/ForgeGit/forgegit/tests/data/testgit.git/refs/tags/foo
@@ -0,0 +1 @@
+1e146e67985dcd71c74de79613719bef7bddca4a

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 46be17f..e0026b7 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -339,6 +339,26 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
             ThreadLocalORMSession.flush_all()
             assert repo2.is_empty()
 
+class TestGitImplementation(unittest.TestCase):
+    def test_get_branches(self):
+        repo_dir = pkg_resources.resource_filename(
+            'forgegit', 'tests/data/testgit.git')
+        repo = mock.Mock(full_fs_path=repo_dir)
+        impl = GM.git_repo.GitImplementation(repo)
+        self.assertEqual(impl.get_branches(), [
+                Object(name='master', object_id='1e146e67985dcd71c74de79613719bef7bddca4a'),
+                Object(name='zz', object_id='5c47243c8e424136fd5cdd18cd94d34c66d1955c')
+            ])
+
+    def test_get_tags(self):
+        repo_dir = pkg_resources.resource_filename(
+            'forgegit', 'tests/data/testgit.git')
+        repo = mock.Mock(full_fs_path=repo_dir)
+        impl = GM.git_repo.GitImplementation(repo)
+        self.assertEqual(impl.get_tags(), [
+                Object(name='foo', object_id='1e146e67985dcd71c74de79613719bef7bddca4a'),
+            ])
+
 
 class TestGitCommit(unittest.TestCase):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a3753d7/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index 811380a..f017f0b 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -698,5 +698,11 @@ class SVNImplementation(M.RepositoryImplementation):
             else:
                 raise
 
+    def get_branches(self):
+        return []
+
+    def get_tags(self):
+        return []
+
 
 Mapper.compile_all()


[20/27] git commit: [#6314] Changed ShortURLs to be unique to the app instance instead of globally unique

Posted by tv...@apache.org.
[#6314] Changed ShortURLs to be unique to the app instance instead of globally unique

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/2b74a7de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/2b74a7de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/2b74a7de

Branch: refs/heads/db/6276
Commit: 2b74a7de63284c6135803928bf9c3e168da9c6bb
Parents: 445b640
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jun 5 16:27:38 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jun 6 18:00:15 2013 +0000

----------------------------------------------------------------------
 ForgeShortUrl/forgeshorturl/model/shorturl.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b74a7de/ForgeShortUrl/forgeshorturl/model/shorturl.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/model/shorturl.py b/ForgeShortUrl/forgeshorturl/model/shorturl.py
index e765802..a16ef69 100644
--- a/ForgeShortUrl/forgeshorturl/model/shorturl.py
+++ b/ForgeShortUrl/forgeshorturl/model/shorturl.py
@@ -27,7 +27,7 @@ class ShortUrl(M.Artifact):
 
     class __mongometa__:
         name = 'short_urls'
-        unique_indexes = ['short_name']
+        unique_indexes = [('short_name', 'app_config_id')]
 
     type_s = 'ShortUrl'
     full_url = FieldProperty(str)


[07/27] git commit: [#6218] Fix tests

Posted by tv...@apache.org.
[#6218] Fix tests

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8bff68a7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8bff68a7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8bff68a7

Branch: refs/heads/db/6276
Commit: 8bff68a7fd2848a4cbb37f971497c769f645c730
Parents: d7c8fc1
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jun 4 18:45:16 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 19:01:54 2013 +0000

----------------------------------------------------------------------
 ForgeUserStats/forgeuserstats/tests/test_model.py |   60 ++++++++--------
 ForgeUserStats/forgeuserstats/tests/test_stats.py |    2 +-
 2 files changed, 31 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8bff68a7/ForgeUserStats/forgeuserstats/tests/test_model.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_model.py b/ForgeUserStats/forgeuserstats/tests/test_model.py
index a6526e1..2203469 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_model.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_model.py
@@ -99,7 +99,7 @@ class TestUserStats(unittest.TestCase):
         assert art_by_type['Wiki']['modified'] == init_art_by_type['Wiki']['modified']
         assert lm_art_by_type['Wiki']['created'] == init_lm_art_by_type['Wiki']['created'] + 1
         assert lm_art_by_type['Wiki']['modified'] == init_lm_art_by_type['Wiki']['modified']
-        
+
         #In that case, last month stats should not be changed
         new_date = datetime.utcnow() + timedelta(-32)
         self.user.stats.addNewArtifact('Wiki', new_date, p)
@@ -119,7 +119,7 @@ class TestUserStats(unittest.TestCase):
         assert art_by_type['Wiki']['modified'] == init_art_by_type['Wiki']['modified']
         assert lm_art_by_type['Wiki']['created'] == init_lm_art_by_type['Wiki']['created'] + 1
         assert lm_art_by_type['Wiki']['modified'] == init_lm_art_by_type['Wiki']['modified']
-        
+
         p.trove_topic = [topic._id]
 
         self.user.stats.addNewArtifact('Wiki', datetime.utcnow(), p)
@@ -176,7 +176,7 @@ class TestUserStats(unittest.TestCase):
         assert art_by_type['Wiki']['modified'] == init_art_by_type['Wiki']['modified'] + 1
         assert lm_art_by_type['Wiki']['created'] == init_lm_art_by_type['Wiki']['created']
         assert lm_art_by_type['Wiki']['modified'] == init_lm_art_by_type['Wiki']['modified'] + 1
-        
+
         #In that case, last month stats should not be changed
         new_date = datetime.utcnow() + timedelta(-32)
         self.user.stats.addModifiedArtifact('Wiki', new_date, p)
@@ -186,9 +186,9 @@ class TestUserStats(unittest.TestCase):
         art_by_type = self.user.stats.getArtifactsByType()
         lm_art_by_type = self.user.stats.getLastMonthArtifactsByType()
 
-        assert lm_art['created'] == init_lm_art['created'] 
+        assert lm_art['created'] == init_lm_art['created']
         assert lm_art['modified'] == init_lm_art['modified'] + 1
-        assert artifacts['created'] == init_art['created'] 
+        assert artifacts['created'] == init_art['created']
         assert artifacts['modified'] == init_art['modified'] + 2
         assert art_wiki['created'] == init_art_wiki['created']
         assert art_wiki['modified'] == init_art_wiki['modified'] + 2
@@ -196,7 +196,7 @@ class TestUserStats(unittest.TestCase):
         assert art_by_type['Wiki']['modified'] == init_art_by_type['Wiki']['modified'] + 2
         assert lm_art_by_type['Wiki']['created'] == init_lm_art_by_type['Wiki']['created']
         assert lm_art_by_type['Wiki']['modified'] == init_lm_art_by_type['Wiki']['modified'] + 1
-        
+
         p.trove_topic = [topic._id]
 
         self.user.stats.addModifiedArtifact('Wiki', datetime.utcnow(), p)
@@ -208,13 +208,13 @@ class TestUserStats(unittest.TestCase):
         art_sci = self.user.stats.getArtifacts(category=topic._id)
         art_by_cat = self.user.stats.getArtifactsByCategory(detailed=True)
 
-        assert lm_art['created'] == init_lm_art['created'] 
+        assert lm_art['created'] == init_lm_art['created']
         assert lm_art['modified'] == init_lm_art['modified'] + 2
         assert artifacts['created'] == init_art['created']
         assert artifacts['modified'] == init_art['modified'] + 3
         assert art_wiki['created'] == init_art_wiki['created']
         assert art_wiki['modified'] == init_art_wiki['modified'] + 3
-        assert art_by_type['Wiki']['created'] == init_art_by_type['Wiki']['created'] 
+        assert art_by_type['Wiki']['created'] == init_art_by_type['Wiki']['created']
         assert art_by_type['Wiki']['modified'] == init_art_by_type['Wiki']['modified'] + 3
         assert lm_art_by_type['Wiki']['created'] == init_lm_art_by_type['Wiki']['created']
         assert lm_art_by_type['Wiki']['modified'] == init_lm_art_by_type['Wiki']['modified'] +2
@@ -247,39 +247,39 @@ class TestUserStats(unittest.TestCase):
         assert tickets_art['modified'] == init_tickets_art['modified']
         assert tickets_sci_art['created'] == tickets_sci_art['created']
         assert tickets_sci_art['modified'] == tickets_sci_art['modified']
-        
+
         p.trove_topic = [topic._id]
 
         self.user.stats.addAssignedTicket(create_time, p)
         tickets = self.user.stats.getTickets()
         lm_tickets = self.user.stats.getLastMonthTickets()
 
-        assert tickets['assigned'] == init_tickets['assigned'] + 1 
+        assert tickets['assigned'] == init_tickets['assigned'] + 1
         assert tickets['revoked'] == init_tickets['revoked']
-        assert tickets['solved'] == init_tickets['solved'] 
-        assert tickets['averagesolvingtime'] is None 
-        assert lm_tickets['assigned'] == init_lm_tickets['assigned'] + 1 
+        assert tickets['solved'] == init_tickets['solved']
+        assert tickets['averagesolvingtime'] is None
+        assert lm_tickets['assigned'] == init_lm_tickets['assigned'] + 1
         assert lm_tickets['revoked'] == init_lm_tickets['revoked']
-        assert lm_tickets['solved'] == init_lm_tickets['solved'] 
-        assert lm_tickets['averagesolvingtime'] is None 
+        assert lm_tickets['solved'] == init_lm_tickets['solved']
+        assert lm_tickets['averagesolvingtime'] is None
 
         self.user.stats.addRevokedTicket(create_time + timedelta(-32), p)
         tickets = self.user.stats.getTickets()
 
-        assert tickets['assigned'] == init_tickets['assigned'] + 1 
+        assert tickets['assigned'] == init_tickets['assigned'] + 1
         assert tickets['revoked'] == init_tickets['revoked'] + 1
-        assert tickets['solved'] == init_tickets['solved'] 
-        assert tickets['averagesolvingtime'] is None 
-        assert lm_tickets['assigned'] == init_lm_tickets['assigned'] + 1 
+        assert tickets['solved'] == init_tickets['solved']
+        assert tickets['averagesolvingtime'] is None
+        assert lm_tickets['assigned'] == init_lm_tickets['assigned'] + 1
         assert lm_tickets['revoked'] == init_lm_tickets['revoked']
-        assert lm_tickets['solved'] == init_lm_tickets['solved'] 
-        assert lm_tickets['averagesolvingtime'] is None 
+        assert lm_tickets['solved'] == init_lm_tickets['solved']
+        assert lm_tickets['averagesolvingtime'] is None
 
         self.user.stats.addClosedTicket(create_time, create_time + timedelta(1), p)
         tickets = self.user.stats.getTickets()
         lm_tickets = self.user.stats.getLastMonthTickets()
 
-        assert tickets['assigned'] == init_tickets['assigned'] + 1 
+        assert tickets['assigned'] == init_tickets['assigned'] + 1
         assert tickets['revoked'] == init_tickets['revoked'] + 1
         assert tickets['solved'] == init_tickets['solved'] + 1
 
@@ -297,7 +297,7 @@ class TestUserStats(unittest.TestCase):
 
         solving_time = dict(seconds=0,minutes=0,days=2,hours=0)
 
-        assert tickets['assigned'] == init_tickets['assigned'] + 1 
+        assert tickets['assigned'] == init_tickets['assigned'] + 1
         assert tickets['revoked'] == init_tickets['revoked'] + 1
         assert tickets['solved'] == init_tickets['solved'] + 2
         assert tickets['averagesolvingtime'] == solving_time
@@ -310,7 +310,7 @@ class TestUserStats(unittest.TestCase):
         lm_by_cat = self.user.stats.getLastMonthTicketsByCategory()
         solving_time=dict(days=1,hours=0,minutes=0,seconds=0)
 
-        assert by_cat[topic]['assigned'] == 1 
+        assert by_cat[topic]['assigned'] == 1
         assert by_cat[topic]['revoked'] == 1
         assert by_cat[topic]['solved'] == 1
         assert by_cat[topic]['averagesolvingtime'] == solving_time
@@ -329,7 +329,7 @@ class TestUserStats(unittest.TestCase):
         self.user.set_password('testpassword')
         addr = M.EmailAddress.upsert('rcopeland@geek.net')
         self.user.claim_address('rcopeland@geek.net')
-        
+
         repo_dir = pkg_resources.resource_filename(
             'forgeuserstats', 'tests/data')
 
@@ -337,7 +337,7 @@ class TestUserStats(unittest.TestCase):
         c.app.repo.name = 'testgit.git'
         repo = c.app.repo
         repo.refresh()
-        commit = repo.commit()
+        commit = repo.commit('HEAD')
 
         init_commits = self.user.stats.getCommits()
         assert init_commits['number'] == 4
@@ -377,20 +377,20 @@ class TestUserStats(unittest.TestCase):
     def test_login_stats(self):
         init_logins = self.user.stats.tot_logins_count
         init_lm_logins = self.user.stats.getLastMonthLogins()
-        
+
         login_datetime = datetime.utcnow()
         self.user.stats.addLogin(login_datetime)
         logins = self.user.stats.tot_logins_count
         lm_logins = self.user.stats.getLastMonthLogins()
-        assert logins == init_logins + 1 
-        assert lm_logins == init_lm_logins + 1 
+        assert logins == init_logins + 1
+        assert lm_logins == init_lm_logins + 1
         assert abs(self.user.stats.last_login - login_datetime) < timedelta(seconds=1)
 
         self.user.stats.addLogin(datetime.utcnow() + timedelta(-32))
         logins = self.user.stats.tot_logins_count
         lm_logins = self.user.stats.getLastMonthLogins()
         assert logins == init_logins + 2
-        assert lm_logins == init_lm_logins + 1 
+        assert lm_logins == init_lm_logins + 1
         assert abs(self.user.stats.last_login - login_datetime) < timedelta(seconds=1)
 
     def test_start_date(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8bff68a7/ForgeUserStats/forgeuserstats/tests/test_stats.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_stats.py b/ForgeUserStats/forgeuserstats/tests/test_stats.py
index 0e747f0..b2b20ce 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_stats.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_stats.py
@@ -192,7 +192,7 @@ class TestGitCommit(TestController, unittest.TestCase):
         c.app.repo.name = 'testgit.git'
         self.repo = c.app.repo
         self.repo.refresh()
-        self.rev = self.repo.commit()
+        self.rev = self.repo.commit('HEAD')
 
     @td.with_user_project('test-admin')
     def test_commit(self):


[25/27] git commit: [#6276] use mock SMTP server instead of real one during tests

Posted by tv...@apache.org.
[#6276] use mock SMTP server instead of real one during tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/3ba5a1ab
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3ba5a1ab
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3ba5a1ab

Branch: refs/heads/db/6276
Commit: 3ba5a1ab68f4ac59f4d1023ac9d1529ce867006b
Parents: afe5b38
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Jun 4 18:20:31 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Fri Jun 7 21:19:38 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/decorators.py |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3ba5a1ab/Allura/allura/tests/decorators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/decorators.py b/Allura/allura/tests/decorators.py
index eed0a65..745b008 100644
--- a/Allura/allura/tests/decorators.py
+++ b/Allura/allura/tests/decorators.py
@@ -16,12 +16,16 @@
 #       under the License.
 
 from functools import wraps
-
-from allura import model as M
+import contextlib
 
 from ming.orm.ormsession import ThreadLocalORMSession
-
 from pylons import tmpl_context as c
+from mock import patch
+import tg
+from paste.deploy.converters import asbool
+
+from allura import model as M
+
 
 def with_user_project(username):
     def _with_user_project(func):
@@ -40,6 +44,12 @@ def with_user_project(username):
         return wrapped
     return _with_user_project
 
+
+@contextlib.contextmanager
+def NullContextManager():
+    yield
+
+
 def with_tool(project_shortname, ep_name, mount_point=None, mount_label=None,
         ordinal=None, post_install_hook=None, username='test-admin',
         **override_options):
@@ -53,8 +63,14 @@ def with_tool(project_shortname, ep_name, mount_point=None, mount_label=None,
                 c.app = p.install_app(ep_name, mount_point, mount_label, ordinal, **override_options)
                 if post_install_hook:
                     post_install_hook(c.app)
-                while M.MonQTask.run_ready('setup'):
-                    pass
+
+                if asbool(tg.config.get('smtp.mock')):
+                    smtp_mock = patch('allura.lib.mail_util.smtplib.SMTP')
+                else:
+                    smtp_mock = NullContextManager()
+                with smtp_mock:
+                    while M.MonQTask.run_ready('setup'):
+                        pass
                 ThreadLocalORMSession.flush_all()
                 ThreadLocalORMSession.close_all()
             elif mount_point:


[03/27] git commit: [#6218] Added docstring to get_heads/branches/tags explaining why it's not a property

Posted by tv...@apache.org.
[#6218] Added docstring to get_heads/branches/tags explaining why it's not a property

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d0105e07
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d0105e07
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d0105e07

Branch: refs/heads/db/6276
Commit: d0105e079624f13fb17b0abcddba701eb1c3e1c0
Parents: 7437ce5
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jun 3 19:18:39 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:53:08 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/repository.py |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d0105e07/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 78e16e2..dfb92f1 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -331,10 +331,31 @@ class Repository(Artifact, ActivityObject):
     def is_empty(self):
         return self._impl.is_empty()
     def get_heads(self):
+        """
+        Return list of heads for the repo.
+
+        It's get_heads() instead of a heads (lazy) property because it would
+        conflict with the now deprecated heads field.  Eventually, we should
+        try to remove the deprecated fields and clean this up.
+        """
         return self._impl.heads
     def get_branches(self):
+        """
+        Return list of branches for the repo.
+
+        It's get_branches() instead of a branches (lazy) property because it
+        would conflict with the now deprecated branches field.  Eventually, we
+        should try to remove the deprecated fields and clean this up.
+        """
         return self._impl.branches
     def get_tags(self):
+        """
+        Return list of tags for the repo.
+
+        It's get_tags() instead of a tags (lazy) property because it
+        would conflict with the now deprecated tags field.  Eventually, we
+        should try to remove the deprecated fields and clean this up.
+        """
         return self._impl.tags
 
     def _log(self, rev, skip, limit):


[13/27] git commit: [#6325] Added tests for PPL, refactored, and fixed issue with partial ordering of EP overrides

Posted by tv...@apache.org.
[#6325] Added tests for PPL, refactored, and fixed issue with partial ordering of EP overrides


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/af325d92
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/af325d92
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/af325d92

Branch: refs/heads/db/6276
Commit: af325d9223adc5238a953bdba4a0ef279705f2bd
Parents: b2093db
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jun 3 14:23:32 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py                       |   65 +++++
 Allura/allura/lib/package_path_loader.py           |  215 +++++++++------
 .../allura/tests/unit/test_package_path_loader.py  |  203 ++++++++++++++
 requirements-common.txt                            |    2 +-
 4 files changed, 395 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/af325d92/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index c821301..6c0a863 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -28,6 +28,7 @@ import logging
 import cPickle as pickle
 from hashlib import sha1
 from datetime import datetime, timedelta
+from collections import defaultdict
 
 import tg
 import genshi.template
@@ -725,3 +726,67 @@ def log_output(log):
     finally:
         sys.stdout = _stdout
         sys.stderr = _stderr
+
+def topological_sort(items, partial_order):
+    """Perform topological sort.
+       items is a list of items to be sorted.
+       partial_order is a list of pairs. If pair (a,b) is in it, it means
+       that item a should appear before item b.
+       Returns a list of the items in one of the possible orders, or None
+       if partial_order contains a loop.
+
+       Modified from: http://www.bitformation.com/art/python_toposort.html
+    """
+
+    def add_arc(graph, fromnode, tonode):
+        """Add an arc to a graph. Can create multiple arcs.
+           The end nodes must already exist."""
+        graph[fromnode].append(tonode)
+        # Update the count of incoming arcs in tonode.
+        graph[tonode][0] = graph[tonode][0] + 1
+
+    # step 1 - create a directed graph with an arc a->b for each input
+    # pair (a,b).
+    # The graph is represented by a dictionary. The dictionary contains
+    # a pair item:list for each node in the graph. /item/ is the value
+    # of the node. /list/'s 1st item is the count of incoming arcs, and
+    # the rest are the destinations of the outgoing arcs. For example:
+    #           {'a':[0,'b','c'], 'b':[1], 'c':[1]}
+    # represents the graph:   c <-- a --> b
+    # The graph may contain loops and multiple arcs.
+    # Note that our representation does not contain reference loops to
+    # cause GC problems even when the represented graph contains loops,
+    # because we keep the node names rather than references to the nodes.
+    graph = defaultdict(lambda:[0])
+    for a,b in partial_order:
+        add_arc(graph, a, b)
+
+    # Step 2 - find all roots (nodes with zero incoming arcs).
+    roots = [n for n in items if graph[n][0] == 0]
+    roots.reverse()  # keep sort stable
+
+    # step 3 - repeatedly emit a root and remove it from the graph. Removing
+    # a node may convert some of the node's direct children into roots.
+    # Whenever that happens, we append the new roots to the list of
+    # current roots.
+    sorted = []
+    while roots:
+        # If len(roots) is always 1 when we get here, it means that
+        # the input describes a complete ordering and there is only
+        # one possible output.
+        # When len(roots) > 1, we can choose any root to send to the
+        # output; this freedom represents the multiple complete orderings
+        # that satisfy the input restrictions. We arbitrarily take one of
+        # the roots using pop(). Note that for the algorithm to be efficient,
+        # this operation must be done in O(1) time.
+        root = roots.pop()
+        sorted.append(root)
+        for child in graph[root][1:]:
+            graph[child][0] = graph[child][0] - 1
+            if graph[child][0] == 0:
+                roots.append(child)
+        del graph[root]
+    if len(graph) > 0:
+        # There is a loop in the input.
+        return None
+    return sorted

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/af325d92/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index 53b6fb7..0efde59 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -1,3 +1,19 @@
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
 '''
 A Jinja template loader which allows for:
  - dotted-notation package loading
@@ -93,8 +109,12 @@ The positioners are:
 '''
 import pkg_resources
 import os
+from collections import defaultdict
 
 import jinja2
+from ming.utils import LazyProperty
+
+from allura.lib.helpers import topological_sort
 
 
 class PackagePathLoader(jinja2.BaseLoader):
@@ -113,7 +133,7 @@ class PackagePathLoader(jinja2.BaseLoader):
         # TODO: How does one handle project-theme?
         if default_paths is None:
             default_paths = [
-                    #['projec-theme', None],
+                    #['project-theme', None],
                     ['site-theme', None],
                     ['allura', '/'],
                 ]
@@ -122,72 +142,108 @@ class PackagePathLoader(jinja2.BaseLoader):
         self.default_paths = default_paths
         self.override_root = override_root
 
-        # Finally instantiate the loader
-        self.fs_loader = jinja2.FileSystemLoader(self.init_paths())
+    @LazyProperty
+    def fs_loader(self):
+        return jinja2.FileSystemLoader(self.init_paths())
+
+    def _load_paths(self):
+        """
+        Load all the paths to be processed, including defaults, in the default order.
+        """
+        paths = self.default_paths[:]  # copy default_paths
+        paths[-1:0] = [  # insert all eps just before last item, by default
+                [ep.name, pkg_resources.resource_filename(ep.module_name, "")]
+                for ep in pkg_resources.iter_entry_points(self.override_entrypoint)
+            ]
+        return paths
+
+    def _load_rules(self):
+        """
+        Load and pre-process the rules from the entry points.
+
+        Rules are specified per-tool as a list of the form:
+
+            template_path_rules = [
+                    ['>', 'tool1'],  # this tool must be resolved before tool1
+                    ['<', 'tool2'],  # this tool must be resolved after tool2
+                    ['=', 'tool3'],  # this tool replaces all of tool3's templates
+                ]
+
+        Returns two lists of rules, order_rules and replacement_rules.
+
+        order_rules represents all of the '>' and '<' rules and are returned
+        as a list of pairs of the form ('a', 'b') indicating that path 'a' must
+        come before path 'b'.
+
+        replacement_rules represent all of the '=' rules and are returned as
+        a dictionary mapping the paths to replace to the paths to replace with.
+        """
+        order_rules = []
+        replacement_rules = {}
+        for ep in pkg_resources.iter_entry_points(self.override_entrypoint):
+            for rule in getattr(ep.load(), 'template_path_rules', []):
+                if rule[0] == '>':
+                    order_rules.append((ep.name, rule[1]))
+                elif rule[0] == '=':
+                    replacement_rules[rule[1]] = ep.name
+                elif rule[0] == '<':
+                    order_rules.append((rule[1], ep.name))
+                else:
+                    raise jinja2.TemplateError(
+                        'Unknown template path rule in %s: %s' % (
+                            ep.name, ' '.join(rule)))
+        return order_rules, replacement_rules
+
+    def _sort_paths(self, paths, rules):
+        """
+        Process all '>' and '<' rules, providing a partial ordering
+        of the paths based on the given rules.
+
+        The rules should already have been pre-processed by _load_rules
+        to a list of partial ordering pairs ('a', 'b') indicating that
+        path 'a' should come before path 'b'.
+        """
+        names = [p[0] for p in paths]
+        # filter rules that reference non-existent paths to prevent "loops" in the graph
+        rules = [r for r in rules if r[0] in names and r[1] in names]
+        ordered_paths = topological_sort(names, rules)
+        if ordered_paths is None:
+            raise jinja2.TemplateError(
+                'Loop detected in ordering of overrides')
+        return paths.sort(key=lambda p: ordered_paths.index(p[0]))
+
+    def _replace_signposts(self, paths, rules):
+        """
+        Process all '=' rules, replacing the rule target's path value with
+        the rule's entry's path value.
+
+        Multiple entries replacing the same signpost can cause indeterminate
+        behavior, as the order of the entries is not entirely defined.
+        However, if _sort_by_rules is called first, the partial ordering is
+        respected.
+
+        This mutates paths.
+        """
+        p_idx = lambda n: [e[0] for e in paths].index(n)
+        for target, replacement in rules.items():
+            try:
+                removed = paths.pop(p_idx(replacement))
+                paths[p_idx(target)][1] = removed[1]
+            except ValueError:
+                # target or replacement missing (may not be installed)
+                pass
 
     def init_paths(self):
         '''
         Set up the setuptools entry point-based paths.
         '''
-        paths = self.default_paths[:]
-
-        '''
-        Iterate through the overriders.
-        TODO: Can this be moved to allura.app_globals.Globals, or is this
-              executed before that is available?
-        '''
-        epoints = pkg_resources.iter_entry_points(self.override_entrypoint)
-        for epoint in epoints:
-            overrider = epoint.load()
-            # Get the path of the module
-            tmpl_path = pkg_resources.resource_filename(
-                overrider.__module__,
-                ""
-            )
-            # Default insert position is right before allura(/)
-            insert_position = len(paths) - 1
-
-            rules = getattr(overrider, 'template_path_rules', [])
-
-            # Check each of the rules for this overrider
-            for direction, signpost in rules:
-                sp_location = None
-
-                # Find the signpost
-                try:
-                    sp_location = [path[0] for path in paths].index(signpost)
-                except ValueError:
-                    # Couldn't find it, hope they specified another one, or
-                    # that the default is ok.
-                    continue
-
-                if direction == '=':
-                    # Set a signpost. Behavior if already set is undetermined,
-                    # as entry point ordering is undetermined
-                    paths[sp_location][1] = tmpl_path
-                    # already inserted! our work is done here
-                    insert_position = None
-                    break
-                elif direction == '>':
-                    # going to put it right before the signpost
-                    insert_position = min(sp_location, insert_position)
-                elif direction == '<':
-                    # going to put it right after the signpost
-                    insert_position = min(sp_location + 1, insert_position)
-                else:
-                    # don't know what that is!
-                    raise jinja2.TemplateError(
-                        'Unknown template path rule in %s: %s' % (
-                            overrider, direction))
+        paths = self._load_paths()
+        order_rules, repl_rules = self._load_rules()
 
-            # in the case that we've already replaced a signpost, carry on
-            if insert_position is not None:
-                # TODO: wouldn't OrderedDict be better? the allura.lib one
-                #       doesn't support ordering like the markdown one
-                paths.insert(insert_position, (epoint.name, tmpl_path))
+        self._sort_paths(paths, order_rules)
+        self._replace_signposts(paths, repl_rules)
 
-        # Get rid of None paths... not useful
-        return [path for name, path in paths if path is not None]
+        return [p[1] for p in paths if p[1] is not None]
 
     def get_source(self, environment, template):
         '''
@@ -195,40 +251,21 @@ class PackagePathLoader(jinja2.BaseLoader):
         - path/to/template.html
         - module:path/to/template.html
         '''
-        package, path = None, None
         src = None
-        bits = template.split(':')
-
-        if len(bits) == 2:
-            # splitting out the Python module name from the template string...
-            # the default allura behavior
-            package, path = template.split(':')
-            # TODO: is there a better way to do this?
-            path_fragment = os.path.join(self.override_root, package, path)
-        elif len(bits) == 1:
-            # TODO: is this even useful?
-            path = bits[0]
-            path_fragment = os.path.join(self.override_root, path)
-        else:
-            raise jinja2.TemplateNotFound(template)
 
         # look in all of the customized search locations...
         try:
-            src = self.fs_loader.get_source(environment, path_fragment)
+            parts = [self.override_root] + template.split(':')
+            if len(parts) > 2:
+                parts[1:2] = parts[1].split('.')
+            return self.fs_loader.get_source(environment, os.path.join(*parts))
         except jinja2.TemplateNotFound:
-            # ...this doesn't mean it's really not found... it's probably
-            # just specified in the Allura-normal manner
+            # fall-back to attempt non-override loading
             pass
 
-        # ...but if you don't find anything, fall back to the explicit package
-        # approach
-        if src is None and package is not None:
-            # gets the absolute filename of the template
+        if ':' in template:
+            package, path = template.split(':', 2)
             filename = pkg_resources.resource_filename(package, path)
-            # get the filename relative to the root: (default '/').. if this
-            # fails this error is not caught, so should get propagated
-            # normally
-            src = self.fs_loader.get_source(environment, filename)
-        elif src is None:
-            raise jinja2.TemplateNotFound(template)
-        return src
+            return self.fs_loader.get_source(environment, filename)
+        else:
+            return self.fs_loader.get_source(environment, template)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/af325d92/Allura/allura/tests/unit/test_package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_package_path_loader.py b/Allura/allura/tests/unit/test_package_path_loader.py
new file mode 100644
index 0000000..a5055ac
--- /dev/null
+++ b/Allura/allura/tests/unit/test_package_path_loader.py
@@ -0,0 +1,203 @@
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+
+from unittest import TestCase
+from collections import defaultdict
+
+import jinja2
+from nose.tools import assert_equal, assert_in, assert_raises
+import mock
+
+from allura.lib.package_path_loader import PackagePathLoader
+
+
+class TestPackagePathLoader(TestCase):
+
+    @mock.patch('pkg_resources.resource_filename')
+    @mock.patch('pkg_resources.iter_entry_points')
+    def test_load_paths(self, iter_entry_points, resource_filename):
+        eps = iter_entry_points.return_value.__iter__.return_value = [
+            mock.Mock(ep_name='ep0', module_name='eps.ep0'),
+            mock.Mock(ep_name='ep1', module_name='eps.ep1'),
+            mock.Mock(ep_name='ep2', module_name='eps.ep2'),
+        ]
+        for ep in eps:
+            ep.name = ep.ep_name
+        resource_filename.side_effect = lambda m, r: 'path:'+m
+
+        paths = PackagePathLoader()._load_paths()
+
+        assert_equal(paths, [
+                ['site-theme', None],
+                ['ep0', 'path:eps.ep0'],
+                ['ep1', 'path:eps.ep1'],
+                ['ep2', 'path:eps.ep2'],
+                ['allura', '/'],
+            ])
+        assert_equal(type(paths[0]), list)
+        assert_equal(resource_filename.call_args_list, [
+                mock.call('eps.ep0', ''),
+                mock.call('eps.ep1', ''),
+                mock.call('eps.ep2', ''),
+            ])
+
+    @mock.patch('pkg_resources.iter_entry_points')
+    def test_load_rules(self, iter_entry_points):
+        eps = iter_entry_points.return_value.__iter__.return_value = [
+                mock.Mock(ep_name='ep0', rules=[('>', 'allura')]),
+                mock.Mock(ep_name='ep1', rules=[('=', 'allura')]),
+                mock.Mock(ep_name='ep2', rules=[('<', 'allura')]),
+            ]
+        for ep in eps:
+            ep.name = ep.ep_name
+            ep.load.return_value.template_path_rules = ep.rules
+
+        order_rules, replacement_rules = PackagePathLoader()._load_rules()
+
+        assert_equal(order_rules, [('ep0', 'allura'), ('allura', 'ep2')])
+        assert_equal(replacement_rules, {'allura': 'ep1'})
+
+        eps = iter_entry_points.return_value.__iter__.return_value = [
+                mock.Mock(ep_name='ep0', rules=[('?', 'allura')]),
+            ]
+        for ep in eps:
+            ep.name = ep.ep_name
+            ep.load.return_value.template_path_rules = ep.rules
+        assert_raises(jinja2.TemplateError, PackagePathLoader()._load_rules)
+
+    def test_replace_signposts(self):
+        ppl = PackagePathLoader()
+        ppl._replace_signpost = mock.Mock()
+        paths = [
+                ['site-theme', None],
+                ['ep0', '/ep0'],
+                ['ep1', '/ep1'],
+                ['ep2', '/ep2'],
+                ['allura', '/'],
+            ]
+        rules = {
+                'allura': 'ep2',
+                'site-theme': 'ep1',
+                'foo': 'ep1',
+                'ep0': 'bar',
+            }
+
+        ppl._replace_signposts(paths, rules)
+
+        assert_equal(paths, [
+                ['site-theme', '/ep1'],
+                ['ep0', '/ep0'],
+                ['allura', '/ep2'],
+            ]);
+
+    def test_sort_paths(self):
+        paths = [
+                ['site-theme', None],
+                ['ep0', '/ep0'],
+                ['ep1', '/ep1'],
+                ['ep2', '/ep2'],
+                ['ep3', '/ep3'],
+                ['allura', '/'],
+            ]
+        rules = [
+                ('allura', 'ep0'),
+                ('ep3', 'ep1'),
+                ('ep2', 'ep1'),
+                ('ep4', 'ep1'),  # rules referencing missing paths
+                ('ep2', 'ep5'),
+            ]
+
+        PackagePathLoader()._sort_paths(paths, rules)
+
+        assert_equal(paths, [
+                ['site-theme', None],
+                ['ep2', '/ep2'],
+                ['ep3', '/ep3'],
+                ['ep1', '/ep1'],
+                ['allura', '/'],
+                ['ep0', '/ep0'],
+            ])
+
+    def test_init_paths(self):
+        paths =  [
+                ['root', '/'],
+                ['none', None],
+                ['tail', '/tail'],
+            ]
+        ppl = PackagePathLoader()
+        ppl._load_paths = mock.Mock(return_value=paths)
+        ppl._load_rules = mock.Mock(return_value=('order_rules','repl_rules'))
+        ppl._replace_signposts = mock.Mock()
+        ppl._sort_paths = mock.Mock()
+
+        output = ppl.init_paths()
+
+        ppl._load_paths.assert_called_once_with()
+        ppl._load_rules.assert_called_once_with()
+        ppl._sort_paths.assert_called_once_with(paths, 'order_rules')
+        ppl._replace_signposts.assert_called_once_with(paths, 'repl_rules')
+
+        assert_equal(output, ['/', '/tail'])
+
+    @mock.patch('jinja2.FileSystemLoader')
+    def test_fs_loader(self, FileSystemLoader):
+        ppl = PackagePathLoader()
+        ppl.init_paths = mock.Mock(return_value=['path1', 'path2'])
+        FileSystemLoader.return_value = 'fs_loader'
+
+        output1 = ppl.fs_loader
+        output2 = ppl.fs_loader
+
+        ppl.init_paths.assert_called_once_with()
+        FileSystemLoader.assert_called_once_with(['path1', 'path2'])
+        assert_equal(output1, 'fs_loader')
+        assert output1 is output2
+
+    @mock.patch('jinja2.FileSystemLoader')
+    def test_get_source(self, fs_loader):
+        ppl = PackagePathLoader()
+        ppl.init_paths = mock.Mock()
+        fs_loader().get_source.return_value = 'fs_load'
+
+        # override exists
+        output = ppl.get_source('env', 'allura.ext.admin:templates/audit.html')
+
+        assert_equal(output, 'fs_load')
+        fs_loader().get_source.assert_called_once_with('env', 'override/allura/ext/admin/templates/audit.html')
+
+        fs_loader().get_source.reset_mock()
+        fs_loader().get_source.side_effect = [jinja2.TemplateNotFound('test'), 'fs_load']
+
+        with mock.patch('pkg_resources.resource_filename') as rf:
+            rf.return_value = 'resource'
+            # no override, ':' in template
+            output = ppl.get_source('env', 'allura.ext.admin:templates/audit.html')
+            rf.assert_called_once_with('allura.ext.admin', 'templates/audit.html')
+
+        assert_equal(output, 'fs_load')
+        assert_equal(fs_loader().get_source.call_count, 2)
+        fs_loader().get_source.assert_called_with('env', 'resource')
+
+        fs_loader().get_source.reset_mock()
+        fs_loader().get_source.side_effect = [jinja2.TemplateNotFound('test'), 'fs_load']
+
+        # no override, ':' not in template
+        output = ppl.get_source('env', 'templates/audit.html')
+
+        assert_equal(output, 'fs_load')
+        assert_equal(fs_loader().get_source.call_count, 2)
+        fs_loader().get_source.assert_called_with('env', 'templates/audit.html')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/af325d92/requirements-common.txt
----------------------------------------------------------------------
diff --git a/requirements-common.txt b/requirements-common.txt
index f80e240..7bb0de3 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -67,7 +67,7 @@ smmap==0.8.1
 # testing & development
 datadiff==1.1.5
 ipython==0.11
-mock==0.8.0
+mock==1.0.1
 nose==1.1.2
 pyflakes==0.5.0
 WebTest==1.4.0


[04/27] git commit: [#6218] Deprecated and removed references to cached heads, branches and tags

Posted by tv...@apache.org.
[#6218] Deprecated and removed references to cached heads, branches and tags

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7437ce52
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7437ce52
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7437ce52

Branch: refs/heads/db/6276
Commit: 7437ce52a9e2339873395470937d8fc6a5bfee00
Parents: 28f8651
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue May 28 19:26:58 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:53:08 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py            |   12 ++--
 Allura/allura/lib/repository.py                    |    2 +-
 Allura/allura/model/repository.py                  |   43 ++++++-------
 ForgeGit/forgegit/model/git_repo.py                |   51 +++++----------
 .../forgegit/tests/functional/test_controllers.py  |    2 +-
 ForgeGit/forgegit/tests/model/test_repository.py   |   19 ++----
 ForgeSVN/forgesvn/model/svn.py                     |   49 +++++++--------
 ForgeSVN/forgesvn/tests/model/test_repository.py   |    9 +--
 ForgeUserStats/forgeuserstats/tests/test_model.py  |    3 +-
 ForgeUserStats/forgeuserstats/tests/test_stats.py  |    3 +-
 10 files changed, 76 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index e4832aa..084e17a 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -147,11 +147,11 @@ class RepoRootController(BaseController, FeedController):
     def mr_widget(self):
         source_branches = [
             b.name
-            for b in c.app.repo.branches + c.app.repo.repo_tags]
+            for b in c.app.repo.get_branches() + c.app.repo.get_tags()]
         with c.app.repo.push_upstream_context():
             target_branches = [
                 b.name
-                for b in c.app.repo.branches + c.app.repo.repo_tags]
+                for b in c.app.repo.get_branches() + c.app.repo.get_tags()]
         return SCMMergeRequestWidget(
             source_branches=source_branches,
             target_branches=target_branches)
@@ -162,7 +162,7 @@ class RepoRootController(BaseController, FeedController):
         security.require(security.has_access(c.app.repo, 'admin'))
         c.form = self.mr_widget
         if branch is None:
-            source_branch=c.app.repo.branches[0].name
+            source_branch=c.app.default_branch_name
         return dict(source_branch=source_branch)
 
     @expose()
@@ -205,7 +205,7 @@ class RepoRootController(BaseController, FeedController):
     @without_trailing_slash
     @expose('json:')
     def commit_browser_data(self):
-        head_ids = [ head.object_id for head in c.app.repo.heads ]
+        head_ids = [ head.object_id for head in c.app.repo.get_heads() ]
         commit_ids = list(c.app.repo.commitlog(head_ids))
         log.info('Grab %d commit objects by ID', len(commit_ids))
         commits_by_id = dict(
@@ -394,12 +394,12 @@ class BranchBrowser(BaseController):
     @expose('jinja:allura:templates/repo/tags.html')
     @with_trailing_slash
     def tags(self, **kw):
-        return dict(tags=c.app.repo.repo_tags)
+        return dict(tags=c.app.repo.get_tags())
 
     @expose('jinja:allura:templates/repo/tags.html')
     @with_trailing_slash
     def branches(self, **kw):
-        return dict(title='Branches', tags=c.app.repo.branches)
+        return dict(title='Branches', tags=c.app.repo.get_branches())
 
     @expose()
     @with_trailing_slash

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index afd5557..5798b21 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -119,7 +119,7 @@ class RepositoryApp(Application):
                     (repo_path_parts[1], repo_path_parts[-1]),
                     self.repo.upstream_repo.name)
                 ]
-            if len(c.app.repo.branches) and has_access(c.app.repo, 'admin'):
+            if not c.app.repo.is_empty() and has_access(c.app.repo, 'admin'):
                 links.append(SitemapEntry('Request Merge', c.app.url + 'request_merge',
                              ui_icon=g.icons['merge'],
                              ))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 1960d59..78e16e2 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -92,10 +92,6 @@ class RepositoryImplementation(object):
         commit'''
         raise NotImplementedError, 'commit_parents'
 
-    def refresh_heads(self): # pragma no cover
-        '''Sets repository metadata such as heads, tags, and branches'''
-        raise NotImplementedError, 'refresh_heads'
-
     def refresh_commit_info(self, oid, lazy=True): # pragma no cover
         '''Refresh the data in the commit with id oid'''
         raise NotImplementedError, 'refresh_commit_info'
@@ -173,12 +169,8 @@ class RepositoryImplementation(object):
         return '[%s]' % oid[:6]
 
     def symbolics_for_commit(self, commit):
-        '''Return symbolic branch and tag names for a commit.
-        Default generic implementation is provided, subclasses
-        may override if they have more efficient means.'''
-        branches = [b.name for b in self._repo.branches if b.object_id == commit._id]
-        tags = [t.name for t in self._repo.repo_tags if t.object_id == commit._id]
-        return branches, tags
+        '''Return symbolic branch and tag names for a commit.'''
+        raise NotImplementedError, 'symbolics_for_commit'
 
     def url_for_commit(self, commit, url_type='ci'):
         'return an URL, given either a commit or object id'
@@ -214,11 +206,17 @@ class RepositoryImplementation(object):
         os.chmod(magic_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
         self._setup_hooks(source_path)
 
-    def get_branches(self):
-        return self.repo.branches
+    @property
+    def heads(self):
+        raise NotImplementedError, 'heads'
 
-    def get_tags(self):
-        return self.repo.tags
+    @property
+    def branches(self):
+        raise NotImplementedError, 'branches'
+
+    @property
+    def tags(self):
+        raise NotImplementedError, 'tags'
 
 class Repository(Artifact, ActivityObject):
     BATCH_SIZE=100
@@ -237,9 +235,9 @@ class Repository(Artifact, ActivityObject):
     status=FieldProperty(str)
     email_address=''
     additional_viewable_extensions=FieldProperty(str)
-    heads = FieldProperty([dict(name=str,object_id=str, count=int)])
-    branches = FieldProperty([dict(name=str,object_id=str, count=int)])
-    repo_tags = FieldProperty([dict(name=str,object_id=str, count=int)])
+    heads = FieldProperty(S.Deprecated)
+    branches = FieldProperty(S.Deprecated)
+    repo_tags = FieldProperty(S.Deprecated)
     upstream_repo = FieldProperty(dict(name=str,url=str))
 
     def __init__(self, **kw):
@@ -332,10 +330,12 @@ class Repository(Artifact, ActivityObject):
         return self._impl.last_commit_ids(commit, paths)
     def is_empty(self):
         return self._impl.is_empty()
+    def get_heads(self):
+        return self._impl.heads
     def get_branches(self):
-        return self._impl.get_branches()
+        return self._impl.branches
     def get_tags(self):
-        return self._impl.get_tags()
+        return self._impl.tags
 
     def _log(self, rev, skip, limit):
         head = self.commit(rev)
@@ -531,13 +531,8 @@ class Repository(Artifact, ActivityObject):
             log.info('... %r analyzing', self)
             self.status = 'analyzing'
             session(self).flush(self)
-            self._impl.refresh_heads()
             if asbool(tg.config.get('scm.new_refresh')):
                 refresh_repo(self, all_commits, notify, new_clone)
-            for head in self.heads + self.branches + self.repo_tags:
-                ci = self.commit(head.object_id)
-                if ci is not None:
-                    head.count = self.count_revisions(ci)
         finally:
             log.info('... %s ready', self)
             self.status = 'ready'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 5683296..27b52d9 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -148,13 +148,6 @@ class GitImplementation(M.RepositoryImplementation):
 
     def commit(self, rev):
         '''Return a Commit object.  rev can be _id or a branch/tag name'''
-        # See if the rev is a named ref that we have cached, and use the sha1
-        # from the cache. This ensures that we don't return a sha1 that we
-        # don't have indexed into mongo yet.
-        for ref in self._repo.heads + self._repo.branches + self._repo.repo_tags:
-            if ref.name == rev:
-                rev = ref.object_id
-                break
         cache = getattr(c, 'model_cache', '') or M.repo.ModelCache()
         result = cache.get(M.repo.Commit, dict(_id=rev))
         if result is None:
@@ -170,8 +163,8 @@ class GitImplementation(M.RepositoryImplementation):
                 except:
                     pass
                 log.exception('Error with rev_parse(%s)%s' % (str(rev) + '^0', url))
-        if result is None: return None
-        result.set_context(self._repo)
+        if result:
+            result.set_context(self._repo)
         return result
 
     def all_commit_ids(self):
@@ -189,7 +182,7 @@ class GitImplementation(M.RepositoryImplementation):
     def new_commits(self, all_commits=False):
         graph = {}
 
-        to_visit = [ self._git.commit(rev=hd.object_id) for hd in self._repo.heads ]
+        to_visit = [ self._git.commit(rev=hd.object_id) for hd in self.heads ]
         while to_visit:
             obj = to_visit.pop()
             if obj.hexsha in graph: continue
@@ -202,21 +195,6 @@ class GitImplementation(M.RepositoryImplementation):
             to_visit += obj.parents
         return list(topological_sort(graph))
 
-    def refresh_heads(self):
-        self._repo.heads = [
-            Object(name=head.name, object_id=head.commit.hexsha)
-            for head in self._git.heads
-            if head.is_valid() ]
-        self._repo.branches = [
-            Object(name=head.name, object_id=head.commit.hexsha)
-            for head in self._git.branches
-            if head.is_valid() ]
-        self._repo.repo_tags = [
-            Object(name=tag.name, object_id=tag.commit.hexsha)
-            for tag in self._git.tags
-            if tag.is_valid() ]
-        session(self._repo).flush()
-
     def refresh_commit_info(self, oid, seen, lazy=True):
         from allura.model.repo import CommitDoc
         ci_doc = CommitDoc.m.get(_id=oid)
@@ -331,13 +309,12 @@ class GitImplementation(M.RepositoryImplementation):
         return git.Object.new_from_sha(self._git, binsha)
 
     def symbolics_for_commit(self, commit):
-        branch_heads, tags = super(self.__class__, self).symbolics_for_commit(commit)
         try:
-            containing_branches = self._git.git.branch(contains=commit._id)
+            branches = [b.name for b in self.branches if b.object_id == commit._id]
+            tags = [t.name for t in self.tags if t.object_id == commit._id]
+            return branches, tags
         except git.GitCommandError:
-            return [], tags
-        containing_branches = [br.strip(' *') for br in containing_branches.split('\n')]
-        return containing_branches, tags
+            return [], []
 
     def compute_tree_new(self, commit, tree_path='/'):
         ci = self._git.rev_parse(commit._id)
@@ -361,11 +338,17 @@ class GitImplementation(M.RepositoryImplementation):
     def is_empty(self):
         return not self._git or len(self._git.heads) == 0
 
-    def get_branches(self):
-        return [Object(name=b.name,object_id=b.commit.hexsha) for b in self._git.heads]
+    @LazyProperty
+    def heads(self):
+        return [Object(name=b.name, object_id=b.commit.hexsha) for b in self._git.heads if b.is_valid()]
+
+    @LazyProperty
+    def branches(self):
+        return [Object(name=b.name, object_id=b.commit.hexsha) for b in self._git.branches if b.is_valid()]
 
-    def get_tags(self):
-        return [Object(name=t.name, object_id=t.commit.hexsha) for t in self._git.tags]
+    @LazyProperty
+    def tags(self):
+        return [Object(name=t.name, object_id=t.commit.hexsha) for t in self._git.tags if t.is_valid()]
 
 
 class _OpenedGitBlob(object):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 204f729..32ffb69 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -467,7 +467,7 @@ class TestFork(_TestCase):
         assert 'Improve documentation' in r, r.showbrowser()
         revs = r.html.findAll('tr', attrs={'class': 'rev'})
         links = revs[0].findAll('a')
-        c_id = self.forked_repo.heads[0]['object_id']
+        c_id = self.forked_repo.get_heads()[0]['object_id']
         assert_equal(links[0].get('href'), '/p/test2/code/ci/%s/' % c_id)
         assert_equal(links[0].getText(), '[%s]' % c_id[:6])
         assert_equal(links[1].get('href'), '/p/test2/code/ci/%s/tree' % c_id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index bae667c..4afe27f 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -63,8 +63,7 @@ class TestNewGit(unittest.TestCase):
         #     tool = 'git',
         #     status = 'creating')
         self.repo.refresh()
-        self.rev = M.repo.Commit.query.get(_id=self.repo.heads[0]['object_id'])
-        self.rev.repo = self.repo
+        self.rev = self.repo.commit('master')
         ThreadLocalORMSession.flush_all()
         ThreadLocalORMSession.close_all()
 
@@ -76,7 +75,7 @@ class TestNewGit(unittest.TestCase):
         assert self.rev.tree._id == self.rev.tree_id
         assert self.rev.summary == self.rev.message.splitlines()[0]
         assert self.rev.shorthand_id() == '[1e146e]'
-        assert self.rev.symbolic_ids == (['master', 'zz'], ['foo'])
+        assert self.rev.symbolic_ids == (['master'], ['foo']), self.rev.symbolic_ids
         assert self.rev.url() == (
             '/p/test/src-git/ci/'
             '1e146e67985dcd71c74de79613719bef7bddca4a/')
@@ -234,12 +233,6 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         entry = self.repo.commit('HEAD')
         assert str(entry.authored.name) == 'Rick Copeland', entry.authored
         assert entry.message
-        # Test that sha1s for named refs are looked up in cache first, instead
-        # of from disk.
-        with mock.patch('forgegit.model.git_repo.M.repo.Commit.query') as q:
-            self.repo.heads.append(Object(name='HEAD', object_id='deadbeef'))
-            self.repo.commit('HEAD')
-            q.get.assert_called_with(_id='deadbeef')
         # test the auto-gen tree fall-through
         orig_tree = M.repo.Tree.query.get(_id=entry.tree_id)
         assert orig_tree
@@ -340,22 +333,22 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
             assert repo2.is_empty()
 
 class TestGitImplementation(unittest.TestCase):
-    def test_get_branches(self):
+    def test_branches(self):
         repo_dir = pkg_resources.resource_filename(
             'forgegit', 'tests/data/testgit.git')
         repo = mock.Mock(full_fs_path=repo_dir)
         impl = GM.git_repo.GitImplementation(repo)
-        self.assertEqual(impl.get_branches(), [
+        self.assertEqual(impl.branches, [
                 Object(name='master', object_id='1e146e67985dcd71c74de79613719bef7bddca4a'),
                 Object(name='zz', object_id='5c47243c8e424136fd5cdd18cd94d34c66d1955c')
             ])
 
-    def test_get_tags(self):
+    def test_tags(self):
         repo_dir = pkg_resources.resource_filename(
             'forgegit', 'tests/data/testgit.git')
         repo = mock.Mock(full_fs_path=repo_dir)
         impl = GM.git_repo.GitImplementation(repo)
-        self.assertEqual(impl.get_tags(), [
+        self.assertEqual(impl.tags, [
                 Object(name='foo', object_id='1e146e67985dcd71c74de79613719bef7bddca4a'),
             ])
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index f017f0b..23c1887 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -98,8 +98,7 @@ class Repository(M.Repository):
 
     def latest(self, branch=None):
         if self._impl is None: return None
-        if not self.heads: return None
-        return self._impl.commit(self.heads[0].object_id)
+        return self._impl.commit('HEAD')
 
     def tarball_filename(self, revision, path=None):
         fn = super(Repository, self).tarball_filename(revision, path)
@@ -299,42 +298,27 @@ class SVNImplementation(M.RepositoryImplementation):
             c.app.config.options['checkout_url'] = ""
         self._setup_special_files(source_url)
 
-    def refresh_heads(self):
-        info = self._svn.info2(
-            self._url,
-            revision=pysvn.Revision(pysvn.opt_revision_kind.head),
-            recurse=False)[0][1]
-        oid = self._oid(info.rev.number)
-        self._repo.heads = [ Object(name=None, object_id=oid) ]
-        # Branches and tags aren't really supported in subversion
-        self._repo.branches = []
-        self._repo.repo_tags = []
-        session(self._repo).flush(self._repo)
-
     def commit(self, rev):
         if rev in ('HEAD', None):
-            if not self._repo.heads: return None
-            oid = self._repo.heads[0].object_id
+            oid = self._oid(self.head)
         elif isinstance(rev, int) or rev.isdigit():
             oid = self._oid(rev)
         else:
             oid = rev
         result = M.repo.Commit.query.get(_id=oid)
-        if result is None: return None
-        result.set_context(self._repo)
+        if result:
+            result.set_context(self._repo)
         return result
 
     def all_commit_ids(self):
         """Return a list of commit ids, starting with the head (most recent
         commit) and ending with the root (first commit).
         """
-        if not self._repo.heads:
-            return []
-        head_revno = self._revno(self._repo.heads[0].object_id)
+        head_revno = self.head
         return map(self._oid, range(head_revno, 0, -1))
 
     def new_commits(self, all_commits=False):
-        head_revno = self._revno(self._repo.heads[0].object_id)
+        head_revno = self.head
         oids = [ self._oid(revno) for revno in range(1, head_revno+1) ]
         if all_commits:
             return oids
@@ -689,19 +673,32 @@ class SVNImplementation(M.RepositoryImplementation):
                 os.remove(tmpfilename)
 
     def is_empty(self):
+        return self.head == 0
+
+    def symbolics_for_commit(self, commit):
+        return [], []
+
+    @LazyProperty
+    def head(self):
         try:
-            return self._svn.revpropget('revision', url=self._url)[0].number == 0
+            return int(self._svn.revpropget('revision', url=self._url)[0].number)
         except pysvn.ClientError as e:
             if str(e).startswith("Unable to connect") or \
                     str(e).startswith("Unable to open"):
-                return True
+                return 0
             else:
                 raise
 
-    def get_branches(self):
+    @LazyProperty
+    def heads(self):
+        return [Object(name=None, object_id=self._oid(self.head))]
+
+    @LazyProperty
+    def branches(self):
         return []
 
-    def get_tags(self):
+    @LazyProperty
+    def tags(self):
         return []
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 0bc2f86..9751b38 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -65,8 +65,7 @@ class TestNewRepo(unittest.TestCase):
             tool = 'svn',
             status = 'creating')
         self.repo.refresh()
-        self.rev = M.repo.Commit.query.get(_id=self.repo.heads[0]['object_id'])
-        self.rev.repo = self.repo
+        self.rev = self.repo.commit('HEAD')
         ThreadLocalORMSession.flush_all()
         ThreadLocalORMSession.close_all()
 
@@ -723,10 +722,7 @@ class TestRepo(_TestWithRepo):
                         name=committer_name,
                         email=committer_email),
                     _id=oid)).m.insert()
-        def set_heads():
-            self.repo.heads = [ ming.base.Object(name='head', object_id='foo0', count=100) ]
         self.repo._impl.refresh_commit_info = refresh_commit_info
-        self.repo._impl.refresh_heads = mock.Mock(side_effect=set_heads)
         _id = lambda oid: getattr(oid, '_id', str(oid))
         self.repo.shorthand_for_commit = lambda oid: '[' + _id(oid) + ']'
         self.repo.url_for_commit = lambda oid: 'ci/' + _id(oid) + '/'
@@ -747,9 +743,6 @@ class TestRepo(_TestWithRepo):
         self.repo.count_revisions=mock.Mock(return_value=100)
         self.repo._impl.commit = mock.Mock(return_value=ci)
         self.repo._impl.new_commits = mock.Mock(return_value=['foo%d' % i for i in range(100) ])
-        def set_heads():
-            self.repo.heads = [ ming.base.Object(name='head', object_id='foo0', count=100) ]
-        self.repo._impl.refresh_heads = mock.Mock(side_effect=set_heads)
 
         # make unreadable by *anonymous, so additional notification logic executes
         self.repo.acl = []

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeUserStats/forgeuserstats/tests/test_model.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_model.py b/ForgeUserStats/forgeuserstats/tests/test_model.py
index cc67e27..a6526e1 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_model.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_model.py
@@ -337,8 +337,7 @@ class TestUserStats(unittest.TestCase):
         c.app.repo.name = 'testgit.git'
         repo = c.app.repo
         repo.refresh()
-        commit = M.repo.Commit.query.get(_id=repo.heads[0]['object_id'])
-        commit.repo = repo
+        commit = repo.commit()
 
         init_commits = self.user.stats.getCommits()
         assert init_commits['number'] == 4

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7437ce52/ForgeUserStats/forgeuserstats/tests/test_stats.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_stats.py b/ForgeUserStats/forgeuserstats/tests/test_stats.py
index 482eda8..0e747f0 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_stats.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_stats.py
@@ -192,8 +192,7 @@ class TestGitCommit(TestController, unittest.TestCase):
         c.app.repo.name = 'testgit.git'
         self.repo = c.app.repo
         self.repo.refresh()
-        self.rev = M.repo.Commit.query.get(_id=self.repo.heads[0]['object_id'])
-        self.rev.repo = self.repo
+        self.rev = self.repo.commit()
 
     @td.with_user_project('test-admin')
     def test_commit(self):


[23/27] git commit: [#6276] don't run run test setup functions extra times as if they were tests themselves

Posted by tv...@apache.org.
[#6276] don't run run test setup functions extra times as if they were tests themselves


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b2929b8e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b2929b8e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b2929b8e

Branch: refs/heads/db/6276
Commit: b2929b8e8f0d5fea9a16eb72f15c25e536048efe
Parents: 3ba5a1a
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Jun 6 17:19:06 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Fri Jun 7 21:19:38 2013 +0000

----------------------------------------------------------------------
 AlluraTesting/alluratest/controller.py |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b2929b8e/AlluraTesting/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/alluratest/controller.py b/AlluraTesting/alluratest/controller.py
index dd81b23..95d9b4b 100644
--- a/AlluraTesting/alluratest/controller.py
+++ b/AlluraTesting/alluratest/controller.py
@@ -44,6 +44,11 @@ from .validation import ValidatingTestApp
 
 DFL_APP_NAME = 'main_without_authn'
 
+# these are all helpers & base classes, and should never
+# be considered test cases when imported into some test module
+__test__ = False
+
+
 def get_config_file(config=None):
     if not config:
         config = 'test.ini'
@@ -54,6 +59,7 @@ def get_config_file(config=None):
         conf_dir = os.getcwd()
     return os.path.join(conf_dir, config)
 
+
 def setup_basic_test(config=None, app_name=DFL_APP_NAME):
     '''Create clean environment for running tests'''
     try:
@@ -68,6 +74,8 @@ def setup_basic_test(config=None, app_name=DFL_APP_NAME):
     # run all tasks, e.g. indexing from bootstrap operations
     while M.MonQTask.run_ready('setup'):
         ThreadLocalORMSession.flush_all()
+setup_basic_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
 
 def setup_functional_test(config=None, app_name=DFL_APP_NAME):
     '''Create clean environment for running tests.  Also return WSGI test app'''
@@ -77,6 +85,8 @@ def setup_functional_test(config=None, app_name=DFL_APP_NAME):
     wsgiapp = loadapp('config:%s#%s' % (config, app_name),
                       relative_to=conf_dir)
     return wsgiapp
+setup_functional_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
 
 def setup_unit_test():
     try:
@@ -97,6 +107,8 @@ def setup_unit_test():
     c.queued_messages = None
     c.model_cache = None
     ThreadLocalORMSession.close_all()
+setup_unit_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
 
 def setup_global_objects():
     setup_unit_test()


[09/27] git commit: [#6218] Fix test

Posted by tv...@apache.org.
[#6218] Fix test

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6e76882a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6e76882a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6e76882a

Branch: refs/heads/db/6276
Commit: 6e76882a088c7549a0612d9132b196a1d34d9955
Parents: 8bff68a
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jun 4 19:32:47 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 19:32:47 2013 +0000

----------------------------------------------------------------------
 ForgeGit/forgegit/tests/model/test_repository.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6e76882a/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 4afe27f..021e2f8 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -258,7 +258,7 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         n = M.Notification.query.find(
             dict(subject='[test:src-git] [1e146e] - Rick Copeland: Change README')).first()
         assert n
-        assert 'master,zz: ' in n.text
+        assert 'master: ' in n.text, n.text
         send_notifications(self.repo, ['1e146e67985dcd71c74de79613719bef7bddca4a', 'df30427c488aeab84b2352bdf88a3b19223f9d7a'])
         ThreadLocalORMSession.flush_all()
         assert M.Notification.query.find(


[16/27] git commit: [#6325] Moving fixed 'templates' to instance property, update doc

Posted by tv...@apache.org.
[#6325] Moving fixed 'templates' to instance property, update doc

Signed-off-by: Nicholas Bollweg (Nick) <ni...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/cf0d391c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/cf0d391c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/cf0d391c

Branch: refs/heads/db/6276
Commit: cf0d391c7f3edca49b6f2617a71e8c59081e859a
Parents: 2d39c61
Author: Nicholas Bollweg (Nick) <ni...@gmail.com>
Authored: Tue Feb 7 18:02:46 2012 -0500
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/package_path_loader.py |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf0d391c/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index a88a061..aee8e1a 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -45,7 +45,7 @@ For the examples, assume the following directory structure:
 To override the above example, a Tool implementer would
 add the following line to their Tool's setup.py:
 
-    [theme.override]
+    [allura.theme.override]
     newtool = newtool.app:NewToolApp
 
 Then, in the neighbor path (see below) for the file containing the
@@ -102,7 +102,9 @@ class PackagePathLoader(jinja2.BaseLoader):
     the same with other Tools.
     '''
     def __init__(self, override_entrypoint='allura.theme.override',
-                default_paths=None):
+                default_paths=None,
+                override_root='override',
+                ):
         '''
         Set up initial values... defaults are for Allura.
         '''
@@ -116,6 +118,7 @@ class PackagePathLoader(jinja2.BaseLoader):
 
         self.override_entrypoint = override_entrypoint
         self.default_paths = default_paths
+        self.override_root = override_root
 
         # Finally instantiate the loader
         self.fs_loader = jinja2.FileSystemLoader(self.init_paths())
@@ -197,11 +200,11 @@ class PackagePathLoader(jinja2.BaseLoader):
             # the default allura behavior
             package, path = template.split(':')
             # TODO: is there a better way to do this?
-            path_fragment = os.path.join('templates', package, path)
+            path_fragment = os.path.join(self.override_root, package, path)
         elif len(bits) == 1:
             # TODO: is this even useful?
             path = bits[0]
-            path_fragment = os.path.join('templates', path)
+            path_fragment = os.path.join(self.override_root, path)
         else:
             raise Exception('malformed template path')
 


[22/27] git commit: [#6314] Refactored, added tests, and removed hard-coded nbhd from ShortUrl

Posted by tv...@apache.org.
[#6314] Refactored, added tests, and removed hard-coded nbhd from ShortUrl

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/577b65f8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/577b65f8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/577b65f8

Branch: refs/heads/db/6276
Commit: 577b65f853872fb6f85a16d5790ffb490032ff2c
Parents: 9ea4661
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Jun 7 17:19:18 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Jun 7 17:19:18 2013 +0000

----------------------------------------------------------------------
 Allura/development.ini                             |    2 +-
 Allura/test.ini                                    |    4 +-
 ForgeShortUrl/forgeshorturl/main.py                |   18 +-------
 ForgeShortUrl/forgeshorturl/model/shorturl.py      |   13 ++++--
 .../forgeshorturl/tests/functional/test.py         |   31 +++++++++++++++
 5 files changed, 46 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/577b65f8/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 0ddf539..646c468 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -250,7 +250,7 @@ auto_reload_templates = true
 # pip install -e git://github.com/brondsem/html2text.git#egg=html2text
 forgeblog.exfeed = false
 
-short_url.url_pattern = {base_url}p/{project}/{mount_point}/{short_name}
+short_url.url_pattern = {base_url}/{nbhd}/{project}/{mount_point}/{short_name}
 
 [app:tool_test]
 use = egg:Allura

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/577b65f8/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index cebbe80..f1bd5f2 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -37,7 +37,7 @@ port = 5000
 use = config:development.ini#tool_test
 db_prefix = test_
 
-base_url = http://localhost/
+base_url = http://localhost
 
 # Use test MongoDB DB server
 # ming.main.master = mongo://127.0.0.1:27018/allura
@@ -107,7 +107,7 @@ support_tool_choices = wiki tickets discussion
 
 disable_csrf_protection=1
 
-short_url.url_pattern = {base_url}p/{project}/{mount_point}/{short_name}
+short_url.url_pattern = {base_url}/{nbhd}/{project}/{mount_point}/{short_name}
 
 [app:main_without_authn]
 use = main

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/577b65f8/ForgeShortUrl/forgeshorturl/main.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index 8ecce61..d26c69e 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -154,11 +154,7 @@ class RootController(BaseController):
             'limit': limit,
             'pagenum': pagenum,
             'count': count,
-            'url_len': len(config['short_url.url_pattern'].format(
-                    base_url=config['base_url'],
-                    project=c.project.shortname,
-                    mount_point=c.app.config.options.mount_point,
-                    short_name='')),
+            'url_len': len(ShortUrl.build_short_url(c.app, short_name='')),
         }
 
     @expose('jinja:forgeshorturl:templates/search.html')
@@ -180,11 +176,7 @@ class RootController(BaseController):
         d = search_app(**search_params)
         d['search_comments_disable'] = True
         d['search_history_disable'] = True
-        d['url_len'] = len(config['short_url.url_pattern'].format(
-                base_url=config['base_url'],
-                project=c.project.shortname,
-                mount_point=c.app.config.options.mount_point,
-                short_name=''))
+        d['url_len'] = len(ShortUrl.build_short_url(c.app, short_name=''))
         return d
 
     @expose()
@@ -270,8 +262,4 @@ class ShortURLAdminController(DefaultAdminController):
             redirect(request.referer)
         return dict(
                 app=self.app,
-                url_len=len(config['short_url.url_pattern'].format(
-                    base_url=config['base_url'],
-                    project=c.project.shortname,
-                    mount_point=self.app.config.options.mount_point,
-                    short_name='')))
+                url_len=len(ShortUrl.build_short_url(c.app, short_name='')))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/577b65f8/ForgeShortUrl/forgeshorturl/model/shorturl.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/model/shorturl.py b/ForgeShortUrl/forgeshorturl/model/shorturl.py
index 8a7fce7..41617bd 100644
--- a/ForgeShortUrl/forgeshorturl/model/shorturl.py
+++ b/ForgeShortUrl/forgeshorturl/model/shorturl.py
@@ -71,9 +71,14 @@ class ShortUrl(M.Artifact):
     def url(self):
         return self.app.url + self.short_name
 
-    def short_url(self):
+    @classmethod
+    def build_short_url(cls, app, short_name):
         return config['short_url.url_pattern'].format(
                 base_url=config['base_url'],
-                project=self.app.project.shortname,
-                mount_point=self.app.config.options.mount_point,
-                short_name=self.short_name)
+                nbhd=app.project.neighborhood.url_prefix.strip('/'),
+                project=app.project.shortname,
+                mount_point=app.config.options.mount_point,
+                short_name=short_name)
+
+    def short_url(self):
+        return self.build_short_url(self.app, self.short_name)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/577b65f8/ForgeShortUrl/forgeshorturl/tests/functional/test.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index 5d7f9d7..e162b38 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -16,8 +16,11 @@
 #       under the License.
 
 from pylons import tmpl_context as c
+from tg import config
 from nose.tools import assert_equal
+import mock
 
+from allura.lib import helpers as h
 from allura.tests import decorators as td
 from alluratest.controller import TestController
 
@@ -107,3 +110,31 @@ class TestRootController(TestController):
                 extra_environ=dict(username='test-user'), status=403)
         self.app.post('/admin/url/remove', params=dict(shorturl='g'),
                 extra_environ=dict(username='test-user'), status=403)
+
+    def test_build_short_url(self):
+        with h.push_config(config, **{
+                'short_url.url_pattern': '{base_url}:{nbhd}:{project}:{mount_point}:{short_name}',
+                'base_url': 'b',
+            }):
+            nbhd = mock.Mock(url_prefix='/n/')
+            project = mock.Mock(shortname='p', neighborhood=nbhd)
+            app = mock.Mock(project=project)
+            app.config.options.mount_point = 'm'
+
+            url = ShortUrl.build_short_url(app, 's')
+
+            assert_equal(url, 'b:n:p:m:s')
+
+    def test_short_url(self):
+        response = self.app.get('/admin/url/add')
+        response.form['short_url'] = 'test'
+        response.form['full_url'] = 'http://www.google.com/'
+        response.form.submit()
+
+        surl = ShortUrl.query.get(short_name='test')
+
+        with h.push_config(config, **{
+                'short_url.url_pattern': '{base_url}:{nbhd}:{project}:{mount_point}:{short_name}',
+                'base_url': 'b',
+            }):
+            assert_equal(surl.short_url(), 'b:p:test:url:test')


[11/27] git commit: [#6325] Changing TemplateNotFound Exceptions to match Jinja FSLoader style

Posted by tv...@apache.org.
[#6325] Changing TemplateNotFound Exceptions to match Jinja FSLoader style

Signed-off-by: Nicholas Bollweg (Nick) <ni...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a82cbb56
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a82cbb56
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a82cbb56

Branch: refs/heads/db/6276
Commit: a82cbb56b9c242a1322306a582cc2986136f9789
Parents: ca90e5c
Author: Nicholas Bollweg (Nick) <ni...@gmail.com>
Authored: Fri Mar 2 17:46:25 2012 -0500
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/package_path_loader.py |    9 ++-------
 1 files changed, 2 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a82cbb56/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index fe3f4b9..f09337d 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -208,8 +208,7 @@ class PackagePathLoader(jinja2.BaseLoader):
             path = bits[0]
             path_fragment = os.path.join(self.override_root, path)
         else:
-            raise jinja2.TemplateNotFound(
-                'Malformed template path %s' % template)
+            raise jinja2.TemplateNotFound(template)
 
         # look in all of the customized search locations...
         try:
@@ -229,9 +228,5 @@ class PackagePathLoader(jinja2.BaseLoader):
             # normally
             src = self.fs_loader.get_source(environment, filename)
         elif src is None:
-            raise jinja2.TemplateNotFound(
-                ('Template %s not found in search path ' +
-                  'and no module specified') % (
-                    path,
-                  ))
+            raise jinja2.TemplateNotFound(template)
         return src


[19/27] git commit: [#6325] Touched up and tied in documentation for PPL

Posted by tv...@apache.org.
[#6325] Touched up and tied in documentation for PPL

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/445b6409
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/445b6409
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/445b6409

Branch: refs/heads/db/6276
Commit: 445b6409ec581e99369cb3fe13c3088eb045c3a2
Parents: f67aaa2
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jun 4 22:16:46 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 22:16:46 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/package_path_loader.py    |   89 ++++++++++++----------
 Allura/docs/api/lib.rst                     |   27 +++++++
 Allura/docs/api/lib/package_path_loader.rst |   26 ++++++
 3 files changed, 101 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/445b6409/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index 0efde59..e4be82e 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -14,38 +14,45 @@
 #       KIND, either express or implied.  See the License for the
 #       specific language governing permissions and limitations
 #       under the License.
-'''
+"""
 A Jinja template loader which allows for:
- - dotted-notation package loading
- - search-path-based overriding of same
 
-## Dotted notation
+- dotted-notation package loading
+- search-path-based overriding of same
+
+Dotted notation
+---------------
+
 - Allow a Tool implementer to use a dotted-notation module name
-  (as occuring in the PYTONPATH), then the given path within the
-  module:
+  (as occuring in the ``PYTHONPATH``), then the given path within the
+  module::
 
-        @expose('jinja:module.name:path/within/module.html>')
+        @expose('jinja:<module.name>:<path/within/module.html>')
 
-  e.g.
+  e.g.::
 
         @expose('jinja:allura:templates/repo/file.html')
 
-## Overriding dotted notation
+Overriding dotted notation
+--------------------------
+
 Allow a Tool implementer to override the theme baseline (or any
 other Tool's) templates. This can be lighter-weight than subclassing
-allura.plugin.ThemeProvider, plus will allow for more fine-grained
+:ref:`allura.plugin.ThemeProvider`, plus will allow for more fine-grained
 changes.
 
-This will also override `extends` and `import` Jinja tags.
+This will also override ``extends`` and ``import`` Jinja tags.
 
 This approach uses a:
 
-- setup.py entry point to a class with...
-- _magic_ files and...
+- ``setup.py`` entry point to a class with...
+- *magic* files and...
 - (optionally) a class property to specify ordering
 
-### File Structure for Overriding dotted notation
-For the examples, assume the following directory structure:
+File Structure for Overriding dotted notation
+=============================================
+
+For the examples, assume the following directory structure::
 
     NewTool/
     |- setup.py                     <- entry point specified here
@@ -60,26 +67,28 @@ For the examples, assume the following directory structure:
                    |- file.html     <- actual template
 
 To override the above example, a Tool implementer would
-add the following line to their Tool's setup.py (assuming usage in Allura,
-with the default app_cfg):
+add the following line to their Tool's ``setup.py`` (assuming usage in Allura,
+with the default ``app_cfg``)::
 
     [allura.theme.override]
     newtool = newtool.app:NewToolApp
 
 Then, in the neighbor path (see below) for the file containing the
-Tool class, add the following path/file:
+Tool class, add the following path/file::
 
     override/allura/templates/repo/file.html
 
 The template will be overridden. Note that after changing
-setup.py, it would be required to re-initialize with setuptools:
+``setup.py``, it would be required to re-initialize with setuptools::
 
     python setup.py develop
 
-###  Specifying search path order with template_path_rules
+Specifying search path order with template_path_rules
+=====================================================
+
 If a highly specific ordering is required, such as if multiple Tools
 are trying to override the same template, the entry point target
-class can also contain a class property template_path_rules:
+class can also contain a class property template_path_rules::
 
     class NewToolApp(Application):
         template_path_rules = [
@@ -87,26 +96,29 @@ class can also contain a class property template_path_rules:
         ]
 
 Each rule specifies a postioner and an entry point or "signpost".
-If no rule is provided, the default is ['>', 'allura'].
+If no rule is provided, the default is ``['>', 'allura']``.
 
 The "signposts" are:
 
-- site-theme
-- allura (you probably shouldn't do this)
-- project-theme NOT IMPLEMENTED
-- tool-theme NOT IMPLEMENTED
+- Any other app's override entry point name
+- ``site-theme``
+- ``allura`` (you probably shouldn't do this)
+- ``project-theme`` **NOT IMPLEMENTED**
+- ``tool-theme`` **NOT IMPLEMENTED**
 
 The positioners are:
-- >
-    - This overrider will be found BEFORE the specified entry point
-- <
-    - This overrider will be found AFTER the specified entry point... not
-      exectly sure why you would use this.
-- =
-    - This will replace one of the "signpost" entry points... if multiple
-      entry points try to do this, the result is undefined.
-      TODO: Support multiple partial themes
-'''
+
+    >
+        This overrider will be found BEFORE the specified entry point
+    <
+        This overrider will be found AFTER the specified entry point
+    =
+        This will replace one of the "signpost" entry points (if multiple apps
+        try to do this for the same signpost, the result is undefined)
+
+**TODO:** Support multiple partial themes
+"""
+
 import pkg_resources
 import os
 from collections import defaultdict
@@ -118,11 +130,6 @@ from allura.lib.helpers import topological_sort
 
 
 class PackagePathLoader(jinja2.BaseLoader):
-    '''
-    Implements the following extensions to the BaseLoader for locating
-    templates: dotted-notation module-based template loading, and overriding
-    the same with other Tools.
-    '''
     def __init__(self, override_entrypoint='allura.theme.override',
                 default_paths=None,
                 override_root='override',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/445b6409/Allura/docs/api/lib.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/lib.rst b/Allura/docs/api/lib.rst
new file mode 100644
index 0000000..1125fbb
--- /dev/null
+++ b/Allura/docs/api/lib.rst
@@ -0,0 +1,27 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+.. _lib_module:
+
+:mod:`allura.lib`
+--------------------------------
+
+.. toctree::
+   :maxdepth: 1
+   :glob:
+
+   lib/*

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/445b6409/Allura/docs/api/lib/package_path_loader.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/lib/package_path_loader.rst b/Allura/docs/api/lib/package_path_loader.rst
new file mode 100644
index 0000000..0646699
--- /dev/null
+++ b/Allura/docs/api/lib/package_path_loader.rst
@@ -0,0 +1,26 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+.. _package_path_loader_module:
+
+:mod:`allura.lib.package_path_loader`
+--------------------------------
+
+.. automodule:: allura.lib.package_path_loader
+
+  .. autoclass:: PackagePathLoader
+      :members:


[14/27] git commit: [#6325] updated doc to reflect defaults

Posted by tv...@apache.org.
[#6325] updated doc to reflect defaults


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b2093dbb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b2093dbb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b2093dbb

Branch: refs/heads/db/6276
Commit: b2093dbb9da36f2276c9b7f616f1ce2c3460195b
Parents: a82cbb5
Author: Nicholas Bollweg (Nick) <ni...@gmail.com>
Authored: Wed Mar 7 16:04:33 2012 -0500
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/package_path_loader.py |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b2093dbb/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index f09337d..53b6fb7 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -36,7 +36,8 @@ For the examples, assume the following directory structure:
     |- newtool/
        |- app.py                    <- entry point target here
        |- templates/
-          |- index.html             <- Tool's regular templates
+       |  |- index.html             <- Tool's regular templates
+       |- override                  <- override_root
           |- allura/                <- magic directory named after module
              |- templates/
                 |- repo/
@@ -52,7 +53,7 @@ with the default app_cfg):
 Then, in the neighbor path (see below) for the file containing the
 Tool class, add the following path/file:
 
-    templates/allura/templates/repo/file.html
+    override/allura/templates/repo/file.html
 
 The template will be overridden. Note that after changing
 setup.py, it would be required to re-initialize with setuptools:
@@ -175,8 +176,9 @@ class PackagePathLoader(jinja2.BaseLoader):
                     insert_position = min(sp_location + 1, insert_position)
                 else:
                     # don't know what that is!
-                    raise Exception('Unknown template path rule in %s: %s' % (
-                        overrider, direction))
+                    raise jinja2.TemplateError(
+                        'Unknown template path rule in %s: %s' % (
+                            overrider, direction))
 
             # in the case that we've already replaced a signpost, carry on
             if insert_position is not None:


[10/27] git commit: [#6218] Bump ForgeHg version

Posted by tv...@apache.org.
[#6218] Bump ForgeHg version

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/bf6db7ff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/bf6db7ff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/bf6db7ff

Branch: refs/heads/db/6276
Commit: bf6db7ffb7c2c2f0276f577d969cb140d29d68c1
Parents: 6e76882
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jun 4 20:02:36 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 20:02:36 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bf6db7ff/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 8792c7f..51067a0 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -4,7 +4,7 @@ akismet==0.2.0
 amqplib==0.6.1
 kombu==1.0.4
 coverage==3.5a1-20110413
-ForgeHg==0.1.11
+ForgeHg==0.1.12
 ForgePastebin==0.2.6
 mechanize==0.2.4
 mercurial==1.4.3


[08/27] git commit: [#6218] Deprecated and removed references to cached heads, branches and tags

Posted by tv...@apache.org.
[#6218] Deprecated and removed references to cached heads, branches and tags

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d7c8fc15
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d7c8fc15
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d7c8fc15

Branch: refs/heads/db/6276
Commit: d7c8fc15a6b3b256d5101bf314e92b4a7968c648
Parents: 3889e9e
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue May 28 19:26:58 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 19:01:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/repository.py                |    1 -
 ForgeGit/forgegit/tests/model/test_repository.py |    2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d7c8fc15/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 10fac8c..dfb92f1 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -218,7 +218,6 @@ class RepositoryImplementation(object):
     def tags(self):
         raise NotImplementedError, 'tags'
 
-
 class Repository(Artifact, ActivityObject):
     BATCH_SIZE=100
     class __mongometa__:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d7c8fc15/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index b3b920a..4afe27f 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -75,7 +75,7 @@ class TestNewGit(unittest.TestCase):
         assert self.rev.tree._id == self.rev.tree_id
         assert self.rev.summary == self.rev.message.splitlines()[0]
         assert self.rev.shorthand_id() == '[1e146e]'
-        assert self.rev.symbolic_ids == (['master', 'zz'], ['foo'])
+        assert self.rev.symbolic_ids == (['master'], ['foo']), self.rev.symbolic_ids
         assert self.rev.url() == (
             '/p/test/src-git/ci/'
             '1e146e67985dcd71c74de79613719bef7bddca4a/')


[17/27] git commit: [#6325] pep8 of app_cfg

Posted by tv...@apache.org.
[#6325] pep8 of app_cfg


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/2d39c619
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/2d39c619
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/2d39c619

Branch: refs/heads/db/6276
Commit: 2d39c619a7b21edbee64e9af401edd4c92205810
Parents: bf6db7f
Author: Nicholas Bollweg (Nick) <ni...@gmail.com>
Authored: Tue Feb 7 18:00:26 2012 -0500
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/config/app_cfg.py          |   22 +--
 Allura/allura/lib/package_path_loader.py |  229 +++++++++++++++++++++++++
 2 files changed, 233 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2d39c619/Allura/allura/config/app_cfg.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index 86c65b4..854ad0b 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -30,9 +30,6 @@ convert them into boolean, for example, you should use the
     setting = asbool(global_conf.get('the_setting'))
 
 """
-import logging
-import pkg_resources
-
 import tg
 import jinja2
 import pylons
@@ -45,8 +42,8 @@ import ew
 import allura
 # needed for tg.configuration to work
 from allura.lib import app_globals, helpers
+from allura.lib.package_path_loader import PackagePathLoader
 
-log = logging.getLogger(__name__)
 
 class ForgeConfig(AppConfig):
 
@@ -54,13 +51,12 @@ class ForgeConfig(AppConfig):
         AppConfig.__init__(self)
         self.root_controller = root_controller
         self.package = allura
-        self.renderers = [ 'json', 'genshi', 'jinja' ]
+        self.renderers = ['json', 'genshi', 'mako', 'jinja']
         self.default_renderer = 'genshi'
         self.use_sqlalchemy = False
         self.use_toscawidgets = True
         self.use_transaction_manager = False
-        # self.handle_status_codes = [ 403, 404 ]
-        self.handle_status_codes = [ 403, 404 ]
+        self.handle_status_codes = [403, 404]
         self.disable_request_extensions = True
 
     def after_init_config(self):
@@ -108,6 +104,7 @@ class ForgeConfig(AppConfig):
         config['pylons.strict_c'] = True
         self.render_functions.jinja = tg.render.render_jinja
 
+
 class JinjaEngine(ew.TemplateEngine):
 
     @property
@@ -129,15 +126,4 @@ class JinjaEngine(ew.TemplateEngine):
             text = template.render(**context)
             return literal(text)
 
-class PackagePathLoader(jinja2.BaseLoader):
-
-    def __init__(self):
-        self.fs_loader = jinja2.FileSystemLoader(['/'])
-
-    def get_source(self, environment, template):
-        package, path = template.split(':')
-        filename = pkg_resources.resource_filename(package, path)
-        return self.fs_loader.get_source(environment, filename)
-
-
 base_config = ForgeConfig()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2d39c619/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
new file mode 100644
index 0000000..a88a061
--- /dev/null
+++ b/Allura/allura/lib/package_path_loader.py
@@ -0,0 +1,229 @@
+'''
+A Jinja template loader which allows for:
+ - dotted-notation package loading
+ - search-path-based overriding of same
+
+## Dotted notation
+- Allow a Tool implementer to use a dotted-notation module name
+  (as occuring in the PYTONPATH), then the given path within the
+  module:
+
+        @expose('jinja:module.name:path/within/module.html>')
+
+  e.g.
+
+        @expose('jinja:allura:templates/repo/file.html')
+
+## Overriding dotted notation
+Allow a Tool implementer to override the theme baseline (or any
+other Tool's) templates. This can be lighter-weight than subclassing
+allura.plugin.ThemeProvider, plus will allow for more fine-grained
+changes.
+
+This will also override `extends` and `import` Jinja tags.
+
+This approach uses a:
+
+- setup.py entry point to a class with...
+- _magic_ files and...
+- (optionally) a class property to specify ordering
+
+### File Structure for Overriding dotted notation
+For the examples, assume the following directory structure:
+
+    NewTool/
+    |- setup.py                     <- entry point specified here
+    |- newtool/
+       |- app.py                    <- entry point target here
+       |- templates/
+          |- index.html             <- Tool's regular templates
+          |- allura/                <- magic directory named after module
+             |- templates/
+                |- repo/
+                   |- file.html     <- actual template
+
+To override the above example, a Tool implementer would
+add the following line to their Tool's setup.py:
+
+    [theme.override]
+    newtool = newtool.app:NewToolApp
+
+Then, in the neighbor path (see below) for the file containing the
+Tool class, add the following path/file:
+
+    templates/allura/templates/repo/file.html
+
+The template will be overridden. Note that after changing
+setup.py, it would be required to re-initialize with setuptools:
+
+    python setup.py develop
+
+###  Specifying search path order with template_path_rules
+If a highly specific ordering is required, such as if multiple Tools
+are trying to override the same template, the entry point target
+class can also contain a class property template_path_rules:
+
+    class NewToolApp(Application):
+        template_path_rules = [
+            ['>', 'old-tool'],
+        ]
+
+Each rule specifies a postioner and an entry point or "signpost".
+If no rule is provided, the default is ['>', 'allura'].
+
+The "signposts" are:
+
+- site-theme
+- allura (you probably shouldn't do this)
+- project-theme NOT IMPLEMENTED
+- tool-theme NOT IMPLEMENTED
+
+The positioners are:
+- >
+    - This overrider will be found BEFORE the specified entry point
+- <
+    - This overrider will be found AFTER the specified entry point... not
+      exectly sure why you would use this.
+- =
+    - This will replace one of the "signpost" entry points... if multiple
+      entry points try to do this, the result is undefined.
+      TODO: Support multiple partial themes
+'''
+import pkg_resources
+import os
+
+import jinja2
+
+
+class PackagePathLoader(jinja2.BaseLoader):
+    '''
+    Implements the following extensions to the BaseLoader for locating
+    templates: dotted-notation module-based template loading, and overriding
+    the same with other Tools.
+    '''
+    def __init__(self, override_entrypoint='allura.theme.override',
+                default_paths=None):
+        '''
+        Set up initial values... defaults are for Allura.
+        '''
+        # TODO: How does one handle project-theme?
+        if default_paths is None:
+            default_paths = [
+                    #['projec-theme', None],
+                    ['site-theme', None],
+                    ['allura', '/'],
+                ]
+
+        self.override_entrypoint = override_entrypoint
+        self.default_paths = default_paths
+
+        # Finally instantiate the loader
+        self.fs_loader = jinja2.FileSystemLoader(self.init_paths())
+
+    def init_paths(self):
+        '''
+        Set up the setuptools entry point-based paths.
+        '''
+        paths = self.default_paths[:]
+
+        '''
+        Iterate through the overriders.
+        TODO: Can this be moved to allura.app_globals.Globals, or is this
+              executed before that is available?
+        '''
+        epoints = pkg_resources.iter_entry_points(self.override_entrypoint)
+        for epoint in epoints:
+            overrider = epoint.load()
+            # Get the path of the module
+            tmpl_path = pkg_resources.resource_filename(
+                overrider.__module__,
+                ""
+            )
+            # Default insert position is right before allura(/)
+            insert_position = len(paths) - 1
+
+            rules = getattr(overrider, 'template_path_rules', [])
+
+            # Check each of the rules for this overrider
+            for direction, signpost in rules:
+                sp_location = None
+
+                # Find the signpost
+                try:
+                    sp_location = [path[0] for path in paths].index(signpost)
+                except ValueError:
+                    # Couldn't find it, hope they specified another one, or
+                    # that the default is ok.
+                    continue
+
+                if direction == '=':
+                    # Set a signpost. Behavior if already set is undetermined,
+                    # as entry point ordering is undetermined
+                    paths[sp_location][1] = tmpl_path
+                    # already inserted! our work is done here
+                    insert_position = None
+                    break
+                elif direction == '>':
+                    # going to put it right before the signpost
+                    insert_position = min(sp_location, insert_position)
+                elif direction == '<':
+                    # going to put it right after the signpost
+                    insert_position = min(sp_location + 1, insert_position)
+                else:
+                    # don't know what that is!
+                    raise Exception('Unknown template path rule in %s: %s' % (
+                        overrider, direction))
+
+            # in the case that we've already replaced a signpost, carry on
+            if insert_position is not None:
+                # TODO: wouldn't OrderedDict be better? the allura.lib one
+                #       doesn't support ordering like the markdown one
+                paths.insert(insert_position, (epoint.name, tmpl_path))
+
+        # Get rid of None paths... not useful
+        return [path for name, path in paths if path is not None]
+
+    def get_source(self, environment, template):
+        '''
+        Returns the source for jinja2 rendered templates. Can understand...
+        - path/to/template.html
+        - module:path/to/template.html
+        '''
+        package, path = None, None
+        src = None
+        bits = template.split(':')
+        if len(bits) == 2:
+            # splitting out the Python module name from the template string...
+            # the default allura behavior
+            package, path = template.split(':')
+            # TODO: is there a better way to do this?
+            path_fragment = os.path.join('templates', package, path)
+        elif len(bits) == 1:
+            # TODO: is this even useful?
+            path = bits[0]
+            path_fragment = os.path.join('templates', path)
+        else:
+            raise Exception('malformed template path')
+
+        # look in all of the customized search locations...
+        try:
+            src = self.fs_loader.get_source(environment, path_fragment)
+        except Exception:
+            # no Tool implemented an override... not even sure if this will
+            # throw an error, but we're ready for it!
+            pass
+
+        # ...but if you don't find anything, fall back to the explicit package
+        # approach
+        if src is None and package is not None:
+            # gets the absolute filename of the template
+            filename = pkg_resources.resource_filename(package, path)
+            # get the filename relative to the fs root (/).. if this fails
+            # this error is not caught, so should get propagated normally
+            src = self.fs_loader.get_source(environment, filename)
+        elif src is None:
+            raise Exception(('Template %s not found in search path ' +
+                  'and no module specified') % (
+                    path,
+                  ))
+        return src


[26/27] git commit: Merge branch 'db/6276' of https://git-wip-us.apache.org/repos/asf/incubator-allura into db/6276

Posted by tv...@apache.org.
Merge branch 'db/6276' of https://git-wip-us.apache.org/repos/asf/incubator-allura into db/6276


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/e695b435
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/e695b435
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/e695b435

Branch: refs/heads/db/6276
Commit: e695b435995451d556ab3692b4afbbbbe988e5da
Parents: b2929b8 dd29d3e
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Fri Jun 7 21:25:03 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Fri Jun 7 21:25:03 2013 +0000

----------------------------------------------------------------------

----------------------------------------------------------------------



[24/27] git commit: [#6276] add --solr-hosts option to reindex cmd

Posted by tv...@apache.org.
[#6276] add --solr-hosts option to reindex cmd


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/afe5b380
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/afe5b380
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/afe5b380

Branch: refs/heads/db/6276
Commit: afe5b3802dd76ada987cc2b731b92dc3feeb84b1
Parents: 577b65f
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Jun 4 16:44:17 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Fri Jun 7 21:19:38 2013 +0000

----------------------------------------------------------------------
 Allura/allura/command/show_models.py |   17 +++++++++++++----
 Allura/allura/lib/app_globals.py     |   14 +++++---------
 Allura/allura/lib/solr.py            |   19 +++++++++++++++++--
 Allura/allura/tasks/index_tasks.py   |   16 +++++++++++++---
 Allura/allura/tests/test_commands.py |   18 ++++++++++++++++++
 5 files changed, 66 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afe5b380/Allura/allura/command/show_models.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/show_models.py b/Allura/allura/command/show_models.py
index c4e49d1..68a55ac 100644
--- a/Allura/allura/command/show_models.py
+++ b/Allura/allura/command/show_models.py
@@ -68,6 +68,8 @@ class ReindexCommand(base.Command):
                       help='Run each individual index operation as a background task.  '
                            'Note: this is often better, since tasks have "request" objects '
                            'which are needed for some markdown macros to run properly')
+    parser.add_option('--solr-hosts', dest='solr_hosts',
+                      help='Override the solr host(s) to post to.  Comma-separated list of solr server URLs')
 
     def command(self):
         from allura import model as M
@@ -88,6 +90,11 @@ class ReindexCommand(base.Command):
         if not self.options.solr and not self.options.refs:
             self.options.solr = self.options.refs = True
 
+        if self.options.solr_hosts:
+            self.add_artifact_kwargs = {'solr_hosts': self.options.solr_hosts.split(',')}
+        else:
+            self.add_artifact_kwargs = {}
+
         for projects in utils.chunked_find(M.Project, q_project):
             for p in projects:
                 c.project = p
@@ -123,8 +130,9 @@ class ReindexCommand(base.Command):
                             self._chunked_add_artifacts(ref_ids)
                         else:
                             add_artifacts(ref_ids,
-                                    update_solr=self.options.solr,
-                                    update_refs=self.options.refs)
+                                          update_solr=self.options.solr,
+                                          update_refs=self.options.refs,
+                                          **self.add_artifact_kwargs)
                     except CompoundError, err:
                         base.log.exception('Error indexing artifacts:\n%r', err)
                         base.log.error('%s', err.format_error())
@@ -146,8 +154,9 @@ class ReindexCommand(base.Command):
         """
         try:
             add_artifacts.post(chunk,
-                    update_solr=self.options.solr,
-                    update_refs=self.options.refs)
+                               update_solr=self.options.solr,
+                               update_refs=self.options.refs,
+                               **self.add_artifact_kwargs)
         except InvalidDocument as e:
             # there are many types of InvalidDocument, only recurse if its expected to help
             if str(e).startswith('BSON document too large'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afe5b380/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 26e0854..bdcacf7 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -57,7 +57,7 @@ from allura.lib import helpers as h
 from allura.lib.widgets import analytics
 from allura.lib.security import Credentials
 from allura.lib.async import Connection, MockAMQ
-from allura.lib.solr import Solr, MockSOLR
+from allura.lib.solr import MockSOLR, make_solr_from_config
 from allura.lib.zarkov_helpers import ZarkovClient, zmq
 
 log = logging.getLogger(__name__)
@@ -103,14 +103,10 @@ class Globals(object):
         if asbool(config.get('solr.mock')):
             self.solr = self.solr_short_timeout = MockSOLR()
         elif self.solr_server:
-            self.solr = Solr(self.solr_server, self.solr_query_server,
-                             commit=asbool(config.get('solr.commit', True)),
-                             commitWithin=config.get('solr.commitWithin'),
-                             timeout=int(config.get('solr.long_timeout', 60)))
-            self.solr_short_timeout = Solr(self.solr_server, self.solr_query_server,
-                                           commit=asbool(config.get('solr.commit', True)),
-                                           commitWithin=config.get('solr.commitWithin'),
-                                           timeout=int(config.get('solr.short_timeout', 10)))
+            self.solr = make_solr_from_config(self.solr_server, self.solr_query_server)
+            self.solr_short_timeout = make_solr_from_config(
+                self.solr_server, self.solr_query_server,
+                timeout=int(config.get('solr.short_timeout', 10)))
         else: # pragma no cover
             self.solr = None
             self.solr_short_timeout = None

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afe5b380/Allura/allura/lib/solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/solr.py b/Allura/allura/lib/solr.py
index e1e9567..4fa0c77 100644
--- a/Allura/allura/lib/solr.py
+++ b/Allura/allura/lib/solr.py
@@ -16,8 +16,24 @@
 #       under the License.
 
 import shlex
+
+from tg import config
+from paste.deploy.converters import asbool
 import pysolr
-from pysolr import SolrError
+
+
+def make_solr_from_config(push_servers, query_server=None, **kwargs):
+    """
+    Make a :class:`Solr <Solr>` instance from config defaults.  Use
+    `**kwargs` to override any value
+    """
+    solr_kwargs = dict(
+        commit=asbool(config.get('solr.commit', True)),
+        commitWithin=config.get('solr.commitWithin'),
+        timeout=int(config.get('solr.long_timeout', 60)),
+    )
+    solr_kwargs.update(kwargs)
+    return Solr(push_servers, query_server, **solr_kwargs)
 
 
 class Solr(object):
@@ -131,4 +147,3 @@ class MockSOLR(object):
         elif kwargs.get('q', None):
             for doc in self.search(kwargs['q']):
                 self.delete(id=doc['id'])
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afe5b380/Allura/allura/tasks/index_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/index_tasks.py b/Allura/allura/tasks/index_tasks.py
index ac5049c..27ada83 100644
--- a/Allura/allura/tasks/index_tasks.py
+++ b/Allura/allura/tasks/index_tasks.py
@@ -23,14 +23,24 @@ from pylons import app_globals as g
 
 from allura.lib.decorators import task
 from allura.lib.exceptions import CompoundError
+from allura.lib.solr import make_solr_from_config
 
 log = logging.getLogger(__name__)
 
 @task
-def add_artifacts(ref_ids, update_solr=True, update_refs=True):
-    '''Add the referenced artifacts to SOLR and shortlinks'''
+def add_artifacts(ref_ids, update_solr=True, update_refs=True, solr_hosts=None):
+    '''
+    Add the referenced artifacts to SOLR and shortlinks.
+
+    :param solr_hosts: a list of solr hosts to use instead of the defaults
+    :type solr_hosts: [str]
+    '''
     from allura import model as M
     from allura.lib.search import find_shortlinks, solarize
+    if solr_hosts:
+        solr = make_solr_from_config(solr_hosts)
+    else:
+        solr = g.solr
     exceptions = []
     solr_updates = []
     with _indexing_disabled(M.session.artifact_orm_session._get()):
@@ -50,7 +60,7 @@ def add_artifacts(ref_ids, update_solr=True, update_refs=True):
             except Exception:
                 log.error('Error indexing artifact %s', ref._id)
                 exceptions.append(sys.exc_info())
-        g.solr.add(solr_updates)
+        solr.add(solr_updates)
 
     if len(exceptions) == 1:
         raise exceptions[0][0], exceptions[0][1], exceptions[0][2]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afe5b380/Allura/allura/tests/test_commands.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py
index fee6e21..1d72ff6 100644
--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -362,6 +362,21 @@ class TestReindexCommand(object):
         cmd.run([test_config, '-p', 'test', '--solr', '--skip-solr-delete'])
         assert not g.solr.delete.called, 'solr.delete() must not be called'
 
+    @patch('pysolr.Solr')
+    def test_solr_hosts_1(self, Solr):
+        cmd = show_models.ReindexCommand('reindex')
+        cmd.run([test_config, '-p', 'test', '--solr', '--solr-hosts=http://blah.com/solr/forge'])
+        assert_equal(Solr.call_args[0][0], 'http://blah.com/solr/forge')
+
+    @patch('pysolr.Solr')
+    def test_solr_hosts_list(self, Solr):
+        cmd = show_models.ReindexCommand('reindex')
+        cmd.run([test_config, '-p', 'test', '--solr', '--solr-hosts=http://blah.com/solr/forge,https://other.net/solr/forge'])
+        # check constructors of first and second Solr() instantiations
+        assert_equal(set([Solr.call_args_list[0][0][0], Solr.call_args_list[1][0][0]]),
+                     set(['http://blah.com/solr/forge', 'https://other.net/solr/forge'])
+                     )
+
     @patch('allura.command.show_models.utils')
     def test_project_regex(self, utils):
         cmd = show_models.ReindexCommand('reindex')
@@ -373,6 +388,7 @@ class TestReindexCommand(object):
     def test_chunked_add_artifacts(self, add_artifacts):
         cmd = show_models.ReindexCommand('reindex')
         cmd.options = Mock()
+        cmd.add_artifact_kwargs = {}
         ref_ids = list(range(100 * 1000 * 2 + 20))
         cmd._chunked_add_artifacts(ref_ids)
         assert_equal(len(add_artifacts.post.call_args_list), 3)
@@ -389,6 +405,7 @@ class TestReindexCommand(object):
         add_artifacts.post.side_effect = on_post
         cmd = show_models.ReindexCommand('reindex')
         cmd.options = Mock()
+        cmd.add_artifact_kwargs = {}
         cmd._post_add_artifacts(range(5))
         kw = {'update_solr': cmd.options.solr, 'update_refs': cmd.options.refs}
         expected = [
@@ -411,5 +428,6 @@ class TestReindexCommand(object):
         add_artifacts.post.side_effect = on_post
         cmd = show_models.ReindexCommand('reindex')
         cmd.options = Mock()
+        cmd.add_artifact_kwargs = {}
         with td.raises(pymongo.errors.InvalidDocument):
             cmd._post_add_artifacts(range(5))


[27/27] git commit: [#6276] Test fixes for new base_url in test.ini

Posted by tv...@apache.org.
[#6276] Test fixes for new base_url in test.ini

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/269d5957
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/269d5957
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/269d5957

Branch: refs/heads/db/6276
Commit: 269d5957245311b0152b0cb323a61099557d7ebe
Parents: e695b43
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Fri Jun 7 23:41:02 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Fri Jun 7 23:41:02 2013 +0000

----------------------------------------------------------------------
 ForgeGit/forgegit/tests/model/test_repository.py |    4 ++--
 ForgeSVN/forgesvn/tests/model/test_repository.py |    8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/269d5957/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 021e2f8..9509fb2 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -187,7 +187,7 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         assert os.path.exists(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive'))
         assert os.stat(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive'))[0] & stat.S_IXUSR
         with open(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive')) as f: c = f.read()
-        self.assertIn('curl -s http://localhost//auth/refresh_repo/p/test/src-git/\n', c)
+        self.assertIn('curl -s http://localhost/auth/refresh_repo/p/test/src-git/\n', c)
         self.assertIn('exec $DIR/post-receive-user\n', c)
         shutil.rmtree(dirname)
 
@@ -216,7 +216,7 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
             assert os.path.exists(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive'))
             assert os.stat(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive'))[0] & stat.S_IXUSR
             with open(os.path.join(g.tmpdir, 'testgit.git/hooks/post-receive')) as f: c = f.read()
-            self.assertIn('curl -s http://localhost//auth/refresh_repo/p/test/src-git/\n', c)
+            self.assertIn('curl -s http://localhost/auth/refresh_repo/p/test/src-git/\n', c)
             self.assertIn('exec $DIR/post-receive-user\n', c)
             shutil.rmtree(dirname)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/269d5957/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 9751b38..ddc6c75 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -165,7 +165,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         assert os.access(os.path.join(g.tmpdir, 'testsvn/hooks/post-commit'), os.X_OK)
         with open(os.path.join(g.tmpdir, 'testsvn/hooks/post-commit')) as f:
             c = f.read()
-        self.assertIn('curl -s http://localhost//auth/refresh_repo/p/test/src/\n', c)
+        self.assertIn('curl -s http://localhost/auth/refresh_repo/p/test/src/\n', c)
         self.assertIn('exec $DIR/post-commit-user "$@"\n', c)
 
         repo.refresh(notify=False)
@@ -212,7 +212,7 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         assert os.access(os.path.join(g.tmpdir, 'testsvn/hooks/post-commit'), os.X_OK)
         with open(os.path.join(g.tmpdir, 'testsvn/hooks/post-commit')) as f:
             c = f.read()
-        self.assertIn('curl -s http://localhost//auth/refresh_repo/p/test/src/\n', c)
+        self.assertIn('curl -s http://localhost/auth/refresh_repo/p/test/src/\n', c)
         self.assertIn('exec $DIR/post-commit-user "$@"\n', c)
 
         repo.refresh(notify=False)
@@ -538,7 +538,7 @@ class TestSVNRev(unittest.TestCase):
         n = M.Notification.query.find(
             dict(subject='[test:src] [r1] - rick446: Create readme')).first()
         assert n
-        assert_equal(n.text, 'Create readme http://localhost//p/test/src/1/')
+        assert_equal(n.text, 'Create readme http://localhost/p/test/src/1/')
 
 
 class _Test(unittest.TestCase):
@@ -725,7 +725,7 @@ class TestRepo(_TestWithRepo):
         self.repo._impl.refresh_commit_info = refresh_commit_info
         _id = lambda oid: getattr(oid, '_id', str(oid))
         self.repo.shorthand_for_commit = lambda oid: '[' + _id(oid) + ']'
-        self.repo.url_for_commit = lambda oid: 'ci/' + _id(oid) + '/'
+        self.repo.url_for_commit = lambda oid: '/ci/' + _id(oid) + '/'
         self.repo.refresh()
         ThreadLocalORMSession.flush_all()
         notifications = M.Notification.query.find().all()


[15/27] git commit: [#6325] Fixed errantly removed logger

Posted by tv...@apache.org.
[#6325] Fixed errantly removed logger


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/33f66731
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/33f66731
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/33f66731

Branch: refs/heads/db/6276
Commit: 33f667317349cf3b1009a0016231c36df9dc2208
Parents: af325d9
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jun 3 15:31:12 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:51:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/config/app_cfg.py |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/33f66731/Allura/allura/config/app_cfg.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index 854ad0b..5cc93f7 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -30,6 +30,8 @@ convert them into boolean, for example, you should use the
     setting = asbool(global_conf.get('the_setting'))
 
 """
+import logging
+
 import tg
 import jinja2
 import pylons
@@ -44,6 +46,7 @@ import allura
 from allura.lib import app_globals, helpers
 from allura.lib.package_path_loader import PackagePathLoader
 
+log = logging.getLogger(__name__)
 
 class ForgeConfig(AppConfig):
 


[05/27] git commit: [#6218] Get branches and tags directly from SCM

Posted by tv...@apache.org.
[#6218] Get branches and tags directly from SCM

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/401803b6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/401803b6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/401803b6

Branch: refs/heads/db/6276
Commit: 401803b6ec74aeba417edb7dbff87b2dfa8d7282
Parents: d0105e0
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Thu May 23 23:35:00 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jun 4 18:57:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/repository.py |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/401803b6/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index dfb92f1..10fac8c 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -218,6 +218,7 @@ class RepositoryImplementation(object):
     def tags(self):
         raise NotImplementedError, 'tags'
 
+
 class Repository(Artifact, ActivityObject):
     BATCH_SIZE=100
     class __mongometa__:


[21/27] git commit: [#6314] Add config option for short_url.url_pattern and refactor short url form widget

Posted by tv...@apache.org.
[#6314] Add config option for short_url.url_pattern and refactor short url form widget

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/9ea46614
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/9ea46614
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/9ea46614

Branch: refs/heads/db/6276
Commit: 9ea46614682f1ac7e650b1a8386cc860192c733f
Parents: 2b74a7d
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jun 5 20:58:12 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jun 6 18:00:15 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/form_fields.py           |    3 +-
 Allura/allura/templates/widgets/lightbox.html      |    8 ++-
 Allura/development.ini                             |    2 +
 Allura/test.ini                                    |    2 +
 ForgeShortUrl/forgeshorturl/main.py                |   36 +++++++---
 ForgeShortUrl/forgeshorturl/model/shorturl.py      |    8 ++
 ForgeShortUrl/forgeshorturl/templates/add.html     |   33 ---------
 ForgeShortUrl/forgeshorturl/templates/form.html    |   53 +++++++++++++++
 ForgeShortUrl/forgeshorturl/templates/index.html   |   48 +++----------
 ForgeShortUrl/forgeshorturl/templates/master.html  |   36 ++++------
 .../forgeshorturl/tests/functional/test.py         |    7 ++-
 ForgeShortUrl/forgeshorturl/widgets/short_url.py   |   14 +---
 12 files changed, 130 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 3571b04..1accf93 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -435,7 +435,8 @@ class Lightbox(ew_core.Widget):
     defaults=dict(
         name=None,
         trigger=None,
-        content='')
+        content='',
+        content_template=None)
 
     def resources(self):
         yield ew.JSLink('js/jquery.lightbox_me.js')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/Allura/allura/templates/widgets/lightbox.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/lightbox.html b/Allura/allura/templates/widgets/lightbox.html
index e251a16..4c5210d 100644
--- a/Allura/allura/templates/widgets/lightbox.html
+++ b/Allura/allura/templates/widgets/lightbox.html
@@ -18,5 +18,9 @@
 -#}
 <div id="lightbox_{{name}}" class="modal" style="display:none">
   <b data-icon="{{g.icons['close'].char}}" class="ico {{g.icons['close'].css}} close"></b>
-  {{content|safe}}
-</div>
\ No newline at end of file
+  {% if content_template %}
+    {% include content_template with context %}
+  {% else %}
+    {{content|safe}}
+  {% endif %}
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index b3c084f..0ddf539 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -250,6 +250,8 @@ auto_reload_templates = true
 # pip install -e git://github.com/brondsem/html2text.git#egg=html2text
 forgeblog.exfeed = false
 
+short_url.url_pattern = {base_url}p/{project}/{mount_point}/{short_name}
+
 [app:tool_test]
 use = egg:Allura
 override_root=basetest_project_root

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index b3d9760..cebbe80 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -107,6 +107,8 @@ support_tool_choices = wiki tickets discussion
 
 disable_csrf_protection=1
 
+short_url.url_pattern = {base_url}p/{project}/{mount_point}/{short_name}
+
 [app:main_without_authn]
 use = main
 skip_authentication = True

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/main.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index 1ce62d8..8ecce61 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from tg import expose, validate, redirect, flash, request
+from tg import expose, validate, redirect, flash, request, config
 from tg.decorators import without_trailing_slash
 
 from allura.app import Application, SitemapEntry, DefaultAdminController
@@ -47,10 +47,7 @@ class W:
     search_help = SearchHelp(comments=False, history=False)
     page_list = ffw.PageList()
     page_size = ffw.PageSize()
-    create_short_url_lightbox = suw.CreateShortUrlWidget(
-            name='create_short_url',
-            trigger='#sidebar a.add_short_url')
-    update_short_url_lightbox = suw.UpdateShortUrlWidget()
+    short_url_lightbox = suw.ShortUrlFormWidget()
 
 
 class ForgeShortUrlApp(Application):
@@ -81,7 +78,7 @@ class ForgeShortUrlApp(Application):
     @h.exceptionless([], log)
     def sitemap(self):
         menu_id = self.config.options.mount_label
-        return [SitemapEntry(menu_id, '.')[self.sidebar_menu()]]
+        return [SitemapEntry(menu_id, '.')]
 
     def sidebar_menu(self):
         links = []
@@ -91,7 +88,7 @@ class ForgeShortUrlApp(Application):
             links = [SitemapEntry('Add Short URL',
                                   url,
                                   ui_icon=g.icons['plus'],
-                                  className="add_short_url"), ]
+                                  className="add-short-url"), ]
         return links
 
     def admin_menu(self):
@@ -132,8 +129,7 @@ class ForgeShortUrlApp(Application):
 
 class RootController(BaseController):
     def __init__(self):
-        c.create_short_url_lightbox = W.create_short_url_lightbox
-        c.update_short_url_lightbox = W.update_short_url_lightbox
+        c.short_url_lightbox = W.short_url_lightbox
 
     def _check_security(self):
         require_access(c.app, 'read')
@@ -157,7 +153,12 @@ class RootController(BaseController):
             'short_urls': short_urls,
             'limit': limit,
             'pagenum': pagenum,
-            'count': count
+            'count': count,
+            'url_len': len(config['short_url.url_pattern'].format(
+                    base_url=config['base_url'],
+                    project=c.project.shortname,
+                    mount_point=c.app.config.options.mount_point,
+                    short_name='')),
         }
 
     @expose('jinja:forgeshorturl:templates/search.html')
@@ -179,6 +180,11 @@ class RootController(BaseController):
         d = search_app(**search_params)
         d['search_comments_disable'] = True
         d['search_history_disable'] = True
+        d['url_len'] = len(config['short_url.url_pattern'].format(
+                base_url=config['base_url'],
+                project=c.project.shortname,
+                mount_point=c.app.config.options.mount_point,
+                short_name=''))
         return d
 
     @expose()
@@ -214,7 +220,7 @@ class ShortURLAdminController(DefaultAdminController):
             'short_name': shorturl})
         return dict(status='ok')
 
-    @expose('jinja:forgeshorturl:templates/add.html')
+    @expose('jinja:forgeshorturl:templates/form.html')
     @validate(dict(full_url=All(validators.URL(add_http=True),
                                 validators.NotEmpty()),
                    short_url=validators.NotEmpty()))
@@ -262,4 +268,10 @@ class ShortURLAdminController(DefaultAdminController):
 
             M.AuditLog.log(msg)
             redirect(request.referer)
-        return dict(app=self.app)
+        return dict(
+                app=self.app,
+                url_len=len(config['short_url.url_pattern'].format(
+                    base_url=config['base_url'],
+                    project=c.project.shortname,
+                    mount_point=self.app.config.options.mount_point,
+                    short_name='')))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/model/shorturl.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/model/shorturl.py b/ForgeShortUrl/forgeshorturl/model/shorturl.py
index a16ef69..8a7fce7 100644
--- a/ForgeShortUrl/forgeshorturl/model/shorturl.py
+++ b/ForgeShortUrl/forgeshorturl/model/shorturl.py
@@ -16,6 +16,7 @@
 #       under the License.
 
 import pymongo
+from tg import config
 from pylons import tmpl_context as c
 from ming.orm import FieldProperty, ForeignIdProperty, session
 from datetime import datetime
@@ -69,3 +70,10 @@ class ShortUrl(M.Artifact):
 
     def url(self):
         return self.app.url + self.short_name
+
+    def short_url(self):
+        return config['short_url.url_pattern'].format(
+                base_url=config['base_url'],
+                project=self.app.project.shortname,
+                mount_point=self.app.config.options.mount_point,
+                short_name=self.short_name)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/templates/add.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/add.html b/ForgeShortUrl/forgeshorturl/templates/add.html
deleted file mode 100644
index 4deece9..0000000
--- a/ForgeShortUrl/forgeshorturl/templates/add.html
+++ /dev/null
@@ -1,33 +0,0 @@
-{#-
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--#}
-{# fixes identation #}    <form method="post" action="{{c.project.url()}}admin/{{app.config.options.mount_point}}/add">
-        <label class="grid-13">Short name</label>
-        <div class="grid-13"><input type = "text" name = "short_url" style="width: 250px"></div>
-        <label class="grid-13">Full URL</label>
-        <div class="grid-13"><input type = "text" name = "full_url" style="width: 250px"></div>
-        <label class="grid-13">Description</label>
-        <div class="grid-13"><textarea name = "description" style="width: 250px; height: 100px"></textarea></div>
-        <div class="grid-1"><input type = "checkbox" name="private" id="private"></div>
-        <label for="private" class="grid-12">Private</label>
-        <div class="grid-13">&nbsp;</div>
-        <hr>
-        <div class="grid-13"><div class="grid-13">&nbsp;</div>
-        <input type="submit" value="Save">
-        <a href="#" class="close">Cancel</a></div>
-    </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/templates/form.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/form.html b/ForgeShortUrl/forgeshorturl/templates/form.html
new file mode 100644
index 0000000..fa39b92
--- /dev/null
+++ b/ForgeShortUrl/forgeshorturl/templates/form.html
@@ -0,0 +1,53 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
+{% set app = app or c.app %}
+<div>
+    <h1 id="short-url-form-title" style="display:none"><span id="short-url-form-action-label">Add</span> Short URL</h1>
+    <form method="post" action="{{c.project.url()}}admin/{{app.config.options.mount_point}}/add" id="short-url-form">
+        <input type="hidden" name="update"/>
+        <label class="grid-13">Short Name</label>
+        <div class="grid-13"><input type="text" name="short_url" style="width: 250px"/> &nbsp;<span class="name_len">0</span> / <span class="url_len">{{url_len}}</span>
+        </div>
+        <label class="grid-13">Full URL</label>
+        <div class="grid-13"><input type="text" name="full_url" style="width: 250px"/></div>
+        <label class="grid-13">Description</label>
+        <div class="grid-13"><textarea name="description" style="width: 250px; height: 100px"></textarea></div>
+        <div class="grid-1"><input type="checkbox" name="private" id="private"></div>
+        <label for="private" class="grid-12">Private</label>
+        <div class="grid-13">&nbsp;</div>
+        <hr>
+        <div class="grid-13"><div class="grid-13">&nbsp;</div>
+        <input type="submit" value="Save">
+        <a href="#" class="close">Cancel</a></div>
+    </form>
+</div>
+
+{% block extra_js %}
+<script type="text/javascript">
+    $(function() {
+        $('#short-url-form input[name="short_url"]').keyup(function(e) {
+            var form = $('#short-url-form');
+            var name_len = $(this).val().length;
+            var url_len = name_len + {{url_len}};
+            form.find('.name_len').text(name_len);
+            form.find('.url_len').text(url_len);
+        });
+    });
+</script>
+{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/index.html b/ForgeShortUrl/forgeshorturl/templates/index.html
index 85b94af..5478214 100644
--- a/ForgeShortUrl/forgeshorturl/templates/index.html
+++ b/ForgeShortUrl/forgeshorturl/templates/index.html
@@ -20,33 +20,6 @@
 
 {% set can_update = c.user and h.has_access(c.app, 'update') %}
 
-{% block extra_js %}
-  {{ super() }}
-
-  {{ c.update_short_url_lightbox.display(content='''
-<div>
-<h1>Update Short URL</h1>
-<form method="post" action="" id="update-short-url-form">
-  <input type="hidden" name="update" value="update">
-  <input type="hidden" name="short_url">
-  <label class="grid-13">Short name</label>
-  <div class="grid-13"><input type="text" name="short_url_display" style="width: 250px" disabled="disabled"></div>
-  <label class="grid-13">Full URL</label>
-  <div class="grid-13"><input type="text" name="full_url" style="width: 250px"></div>
-  <label class="grid-13">Description</label>
-  <div class="grid-13"><textarea name="description" style="width: 250px; height: 100px"></textarea></div>
-  <div class="grid-13"><input type="checkbox" name="private" id="update-checkbox-private"><label for="update-checkbox-private">Private</label></div>
-  <div class="grid-13">&nbsp;</div>
-  <hr>
-  <div class="grid-13"><div class="grid-13">&nbsp;</div>
-  <input type="submit" value="Save">
-    <a href="#" class="close">Cancel</a>
-  </div>
-</form>
-</div>
-''') }}
-{% endblock %}
-
 {% block content %}
 <table>
     <thead>
@@ -70,7 +43,7 @@
         {% endif %}
 
         <td><small>{{ su.user.username }}</small></td>
-        <td><small><a href="{{ c.app.url+su.short_name }}">{{ request.scheme+'://'+request.host+su.url()}}</a></small></td>
+        <td><small><a href="{{ su.short_url() }}">{{ su.short_url() }}</a></small></td>
         <td><small>{{ su.full_url|urlize(20) }}</small></td>
         <td><small>{{ su.description }}</small></td>
         <td><small>{{ lib.abbr_date(su.created) }}</small></td>
@@ -78,22 +51,23 @@
         {% if can_update %}
         <td>
           <small>
-            <a class="update-url" id="update-url-{{su.short_name}}" href="{{c.project.url()}}admin/{{c.app.config.options.mount_point}}/add/">
+            <a class="update-short-url" id="update-url-{{su.short_name}}" href="{{c.project.url()}}admin/{{c.app.config.options.mount_point}}/add/">
               Update
             </a>
             <script>
               $(function() {
-                var upform = $('#update-short-url-form');
+                var modal = $('#lightbox_short-url-modal');
                 $('#update-url-{{su.short_name}}').click(function() {
-                  upform.attr('action', this.href);
-                  upform.find('input[name="short_url"]').val('{{ su.short_name }}');
-                  upform.find('input[name="short_url_display"]').val('{{ su.short_name }}');
-                  upform.find('input[name="full_url"]').val('{{ su.full_url }}');
-                  upform.find('textarea[name="description"]').val('{{su.description|replace("\n", "\\n")|replace("\r", "\\r")}}');
+                  modal.find('#short-url-form-title').show();
+                  modal.find('#short-url-form-action-label').text('Update');
+                  modal.find('input[name="update"]').val('True');
+                  modal.find('input[name="short_url"]').val('{{ su.short_name }}').attr('readonly', true).trigger('keyup');
+                  modal.find('input[name="full_url"]').val('{{ su.full_url }}');
+                  modal.find('textarea[name="description"]').val('{{su.description|replace("\n", "\\n")|replace("\r", "\\r")}}');
                   if ('{{ su.private }}' == 'True') {
-                    $('#update-checkbox-private').attr('checked', 'checked');
+                    modal.find('input[name="private"]').attr('checked', 'checked');
                   } else {
-                    $('#update-checkbox-private').removeAttr('checked');
+                    modal.find('input[name="private"]').removeAttr('checked');
                   }
                   return false;
                 });

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/templates/master.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/master.html b/ForgeShortUrl/forgeshorturl/templates/master.html
index fcad187..98186ec 100644
--- a/ForgeShortUrl/forgeshorturl/templates/master.html
+++ b/ForgeShortUrl/forgeshorturl/templates/master.html
@@ -23,29 +23,19 @@
 {% block short_url_content %}{% endblock %}
 
 {% block extra_js %}
-{{c.create_short_url_lightbox.display(content='''
-<div>
-    <h1>Add Short URL</h1>
-    <form method="post" action="" id="add_url_form">
-        <label class="grid-13">Short name</label>
-        <div class="grid-13"><input type = "text" name = "short_url" style="width: 250px"></div>
-        <label class="grid-13">Full URL</label>
-        <div class="grid-13"><input type = "text" name = "full_url" style="width: 250px"></div>
-        <label class="grid-13">Description</label>
-        <div class="grid-13"><textarea name = "description" style="width: 250px; height: 100px"></textarea></div>
-        <div class="grid-1"><input type = "checkbox" name="private" id="private"></div>
-        <label for="private" class="grid-12">Private</label>
-        <div class="grid-13">&nbsp;</div>
-        <hr>
-        <div class="grid-13"><div class="grid-13">&nbsp;</div>
-            <input type="submit" value="Save">
-            <a href="#" class="close">Cancel</a></div>
-    </form>
-</div>
-''')}}
+{{c.short_url_lightbox.display(url_len=url_len)}}
 <script type="text/javascript">
-    /*<![CDATA[*/
-    $('#add_url_form').attr("action",$('#sidebar a.add_short_url').attr('href'));
-    /*]]>*/
+    $(function() {
+        $('a.add-short-url').click(function() {
+            var modal = $('#lightbox_short-url-modal');
+            modal.find('#short-url-form-title').show();
+            modal.find('#short-url-form-action-label').text('Add');
+            modal.find('input[name="update"]').val('False');
+            modal.find('input[name="short_url"]').val('').removeAttr('readonly').trigger('keyup');
+            modal.find('input[name="full_url"]').val('');
+            modal.find('textarea[name="description"]').val('');
+            modal.find('input[name="private"]').removeAttr('checked');
+        });
+    });
 </script>
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/tests/functional/test.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index f9fa225..5d7f9d7 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -16,6 +16,8 @@
 #       under the License.
 
 from pylons import tmpl_context as c
+from nose.tools import assert_equal
+
 from allura.tests import decorators as td
 from alluratest.controller import TestController
 
@@ -48,13 +50,14 @@ class TestRootController(TestController):
         assert redirected.request.url == 'http://www.google.com/'
 
         response = self.app.get('/url/')
-        form = response.forms['update-short-url-form']
+        form = response.forms['short-url-form']
+        form['update'] = 'True'
         form['short_url'] = 'g'
         form['full_url'] = 'http://www.yahoo.com/'
         form.action = '/admin/url/add/'
         form.submit()
         redirected = self.app.get('/url/g').follow()
-        assert redirected.request.url == 'http://www.yahoo.com/'
+        assert_equal(redirected.request.url, 'http://www.yahoo.com/')
 
     def test_shorturl_not_found(self):
         self.app.post('/admin/url/add',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9ea46614/ForgeShortUrl/forgeshorturl/widgets/short_url.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/widgets/short_url.py b/ForgeShortUrl/forgeshorturl/widgets/short_url.py
index d1e3529..51f14f4 100644
--- a/ForgeShortUrl/forgeshorturl/widgets/short_url.py
+++ b/ForgeShortUrl/forgeshorturl/widgets/short_url.py
@@ -18,15 +18,9 @@
 from allura.lib.widgets import form_fields as ffw
 
 
-class CreateShortUrlWidget(ffw.Lightbox):
-
-    def resources(self):
-        for r in super(CreateShortUrlWidget, self).resources():
-            yield r
-
-
-class UpdateShortUrlWidget(ffw.Lightbox):
+class ShortUrlFormWidget(ffw.Lightbox):
     defaults = dict(
             ffw.Lightbox.defaults,
-            name='update-short-url-modal',
-            trigger='a.update-url')
+            name='short-url-modal',
+            trigger='a.add-short-url, a.update-short-url',
+            content_template='forgeshorturl:templates/form.html')


[18/27] git commit: [#6325] Added correct attribution for toposort

Posted by tv...@apache.org.
[#6325] Added correct attribution for toposort

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f67aaa2a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f67aaa2a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f67aaa2a

Branch: refs/heads/db/6276
Commit: f67aaa2ab9c80287631b2bce3de218e56a406153
Parents: 33f6673
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jun 4 20:52:26 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jun 4 20:52:26 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f67aaa2a/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 6c0a863..9f87115 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -737,6 +737,7 @@ def topological_sort(items, partial_order):
 
        Modified from: http://www.bitformation.com/art/python_toposort.html
     """
+    # Original topological sort code written by Ofer Faigon (www.bitformation.com) and used with permission
 
     def add_arc(graph, fromnode, tonode):
         """Add an arc to a graph. Can create multiple arcs.