|
a/ForgeSVN/forgesvn/model/svn.py |
|
b/ForgeSVN/forgesvn/model/svn.py |
|
... |
|
... |
8 |
from datetime import datetime
|
8 |
from datetime import datetime
|
9 |
|
9 |
|
10 |
import tg
|
10 |
import tg
|
11 |
import pysvn
|
11 |
import pysvn
|
12 |
from pymongo.errors import DuplicateKeyError
|
12 |
from pymongo.errors import DuplicateKeyError
|
|
|
13 |
from pylons import c
|
13 |
|
14 |
|
14 |
from ming.base import Object
|
15 |
from ming.base import Object
|
15 |
from ming.orm import Mapper, FieldProperty, session
|
16 |
from ming.orm import Mapper, FieldProperty, session
|
16 |
from ming.utils import LazyProperty
|
17 |
from ming.utils import LazyProperty
|
17 |
|
18 |
|
18 |
from allura import model as M
|
19 |
from allura import model as M
|
19 |
from allura.lib import helpers as h
|
20 |
from allura.lib import helpers as h
|
20 |
from allura.model.repository import GitLikeTree
|
21 |
from allura.model.repository import GitLikeTree
|
|
|
22 |
from allura.model.auth import User
|
21 |
|
23 |
|
22 |
log = logging.getLogger(__name__)
|
24 |
log = logging.getLogger(__name__)
|
23 |
|
25 |
|
24 |
class Repository(M.Repository):
|
26 |
class Repository(M.Repository):
|
25 |
tool_name='SVN'
|
27 |
tool_name='SVN'
|
|
... |
|
... |
35 |
|
37 |
|
36 |
def _log(self, rev, skip, max_count):
|
38 |
def _log(self, rev, skip, max_count):
|
37 |
ci = self.commit(rev)
|
39 |
ci = self.commit(rev)
|
38 |
if ci is None: return []
|
40 |
if ci is None: return []
|
39 |
return ci.log(int(skip), int(max_count))
|
41 |
return ci.log(int(skip), int(max_count))
|
|
|
42 |
|
|
|
43 |
def clone_command(self, category, username=''):
|
|
|
44 |
'''Return a string suitable for copy/paste that would clone this repo locally
|
|
|
45 |
category is one of 'ro' (read-only), 'rw' (read/write), or 'https' (read/write via https)
|
|
|
46 |
'''
|
|
|
47 |
if not username and c.user not in (None, User.anonymous()):
|
|
|
48 |
username = c.user.username
|
|
|
49 |
tpl = string.Template(tg.config.get('scm.clone.%s.%s' % (category, self.tool)) or
|
|
|
50 |
tg.config.get('scm.clone.%s' % self.tool))
|
|
|
51 |
return tpl.substitute(dict(username=username,
|
|
|
52 |
source_url=self.clone_url(category, username)+c.app.config.options.get('checkout_url'),
|
|
|
53 |
dest_path=self.suggested_clone_dest_path()))
|
40 |
|
54 |
|
41 |
def compute_diffs(self): return
|
55 |
def compute_diffs(self): return
|
42 |
|
56 |
|
43 |
def count(self, *args, **kwargs):
|
57 |
def count(self, *args, **kwargs):
|
44 |
return super(Repository, self).count(None)
|
58 |
return super(Repository, self).count(None)
|
|
... |
|
... |
104 |
else:
|
118 |
else:
|
105 |
object_id = commit.object_id
|
119 |
object_id = commit.object_id
|
106 |
return '%s%d/' % (
|
120 |
return '%s%d/' % (
|
107 |
self._repo.url(), self._revno(object_id))
|
121 |
self._repo.url(), self._revno(object_id))
|
108 |
|
122 |
|
109 |
def init(self):
|
123 |
def init(self, default_dirs=True):
|
110 |
fullname = self._setup_paths()
|
124 |
fullname = self._setup_paths()
|
111 |
log.info('svn init %s', fullname)
|
125 |
log.info('svn init %s', fullname)
|
112 |
if os.path.exists(fullname):
|
126 |
if os.path.exists(fullname):
|
113 |
shutil.rmtree(fullname)
|
127 |
shutil.rmtree(fullname)
|
114 |
subprocess.call(['svnadmin', 'create', self._repo.name],
|
128 |
subprocess.call(['svnadmin', 'create', self._repo.name],
|
|
... |
|
... |
117 |
stderr=subprocess.PIPE,
|
131 |
stderr=subprocess.PIPE,
|
118 |
cwd=self._repo.fs_path)
|
132 |
cwd=self._repo.fs_path)
|
119 |
self._setup_special_files()
|
133 |
self._setup_special_files()
|
120 |
self._repo.status = 'ready'
|
134 |
self._repo.status = 'ready'
|
121 |
# make first commit with dir structure
|
135 |
# make first commit with dir structure
|
|
|
136 |
if default_dirs:
|
122 |
self._repo._impl._svn.checkout('file://'+fullname, fullname+'/tmp')
|
137 |
self._repo._impl._svn.checkout('file://'+fullname, fullname+'/tmp')
|
123 |
os.mkdir(fullname+'/tmp/trunk')
|
138 |
os.mkdir(fullname+'/tmp/trunk')
|
124 |
os.mkdir(fullname+'/tmp/tags')
|
139 |
os.mkdir(fullname+'/tmp/tags')
|
125 |
os.mkdir(fullname+'/tmp/branches')
|
140 |
os.mkdir(fullname+'/tmp/branches')
|
126 |
self._repo._impl._svn.add(fullname+'/tmp/trunk')
|
141 |
self._repo._impl._svn.add(fullname+'/tmp/trunk')
|
127 |
self._repo._impl._svn.add(fullname+'/tmp/tags')
|
142 |
self._repo._impl._svn.add(fullname+'/tmp/tags')
|
128 |
self._repo._impl._svn.add(fullname+'/tmp/branches')
|
143 |
self._repo._impl._svn.add(fullname+'/tmp/branches')
|
129 |
self._repo._impl._svn.checkin([fullname+'/tmp/trunk',fullname+'/tmp/tags',fullname+'/tmp/branches'],'Initial commit')
|
144 |
self._repo._impl._svn.checkin([fullname+'/tmp/trunk',fullname+'/tmp/tags',fullname+'/tmp/branches'],'Initial commit')
|
130 |
shutil.rmtree(fullname+'/tmp')
|
145 |
shutil.rmtree(fullname+'/tmp')
|
131 |
|
146 |
|
132 |
def clone_from(self, source_url):
|
147 |
def clone_from(self, source_url):
|
133 |
'''Initialize a repo as a clone of another using svnsync'''
|
148 |
'''Initialize a repo as a clone of another using svnsync'''
|
134 |
self.init()
|
149 |
self.init(default_dirs=False)
|
135 |
log.info('Initialize %r as a clone of %s',
|
150 |
log.info('Initialize %r as a clone of %s',
|
136 |
self._repo, source_url)
|
151 |
self._repo, source_url)
|
137 |
p = subprocess.call(['svnsync', 'init', self._url, source_url],
|
152 |
p = subprocess.call(['svnsync', 'init', self._url, source_url],
|
138 |
stdin=subprocess.PIPE,
|
153 |
stdin=subprocess.PIPE,
|
139 |
stdout=subprocess.PIPE,
|
154 |
stdout=subprocess.PIPE,
|