##// END OF EJS Templates
fixes #316
marcink -
r1916:24aeb43b default
parent child Browse files
Show More
@@ -1,431 +1,431 b''
1 .. _changelog:
1 .. _changelog:
2
2
3 Changelog
3 Changelog
4 =========
4 =========
5
5
6
6
7 1.2.4 (**2012-01-19**)
7 1.2.4 (**2012-01-19**)
8 ======================
8 ======================
9
9
10 news
10 news
11 ----
11 ----
12
12
13 - RhodeCode is bundled with mercurial series 2.0.X by default, with
13 - RhodeCode is bundled with mercurial series 2.0.X by default, with
14 full support to largefiles extension. Enabled by default in new installations
14 full support to largefiles extension. Enabled by default in new installations
15 - #329 Ability to Add/Remove Groups to/from a Repository via AP
15 - #329 Ability to Add/Remove Groups to/from a Repository via AP
16 - added requires.txt file with requirements
16 - added requires.txt file with requirements
17
17
18 fixes
18 fixes
19 -----
19 -----
20
20
21 - fixes db session issues with celery when emailing admins
21 - fixes db session issues with celery when emailing admins
22 - #331 RhodeCode mangles repository names if the a repository group
22 - #331 RhodeCode mangles repository names if the a repository group
23 contains the "full path" to the repositories
23 contains the "full path" to the repositories
24 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
24 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
25 - DB session cleanup after hg protocol operations, fixes issues with
25 - DB session cleanup after hg protocol operations, fixes issues with
26 `mysql has gone away` errors
26 `mysql has gone away` errors
27 - #333 doc fixes for get_repo api function
27 - #333 doc fixes for get_repo api function
28 - #271 rare JSON serialization problem with statistics enabled
28 - #271 rare JSON serialization problem with statistics enabled
29 - #337 Fixes issues with validation of repository name conflicting with
29 - #337 Fixes issues with validation of repository name conflicting with
30 a group name. A proper message is now displayed.
30 a group name. A proper message is now displayed.
31 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
31 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
32 doesn't work
32 doesn't work
33
33 - #316 fixes issues with web description in hgrc files
34
34
35 1.2.3 (**2011-11-02**)
35 1.2.3 (**2011-11-02**)
36 ======================
36 ======================
37
37
38 news
38 news
39 ----
39 ----
40
40
41 - added option to manage repos group for non admin users
41 - added option to manage repos group for non admin users
42 - added following API methods for get_users, create_user, get_users_groups,
42 - added following API methods for get_users, create_user, get_users_groups,
43 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
43 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
44 get_repo, create_repo, add_user_to_repo
44 get_repo, create_repo, add_user_to_repo
45 - implements #237 added password confirmation for my account
45 - implements #237 added password confirmation for my account
46 and admin edit user.
46 and admin edit user.
47 - implements #291 email notification for global events are now sent to all
47 - implements #291 email notification for global events are now sent to all
48 administrator users, and global config email.
48 administrator users, and global config email.
49
49
50 fixes
50 fixes
51 -----
51 -----
52
52
53 - added option for passing auth method for smtp mailer
53 - added option for passing auth method for smtp mailer
54 - #276 issue with adding a single user with id>10 to usergroups
54 - #276 issue with adding a single user with id>10 to usergroups
55 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
55 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
56 - #288 fixes managing of repos in a group for non admin user
56 - #288 fixes managing of repos in a group for non admin user
57
57
58
58
59 1.2.2 (**2011-10-17**)
59 1.2.2 (**2011-10-17**)
60 ======================
60 ======================
61
61
62 news
62 news
63 ----
63 ----
64
64
65 - #226 repo groups are available by path instead of numerical id
65 - #226 repo groups are available by path instead of numerical id
66
66
67 fixes
67 fixes
68 -----
68 -----
69
69
70 - #259 Groups with the same name but with different parent group
70 - #259 Groups with the same name but with different parent group
71 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
71 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
72 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
72 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
73 - #265 ldap save fails sometimes on converting attributes to booleans,
73 - #265 ldap save fails sometimes on converting attributes to booleans,
74 added getter and setter into model that will prevent from this on db model level
74 added getter and setter into model that will prevent from this on db model level
75 - fixed problems with timestamps issues #251 and #213
75 - fixed problems with timestamps issues #251 and #213
76 - fixes #266 RhodeCode allows to create repo with the same name and in
76 - fixes #266 RhodeCode allows to create repo with the same name and in
77 the same parent as group
77 the same parent as group
78 - fixes #245 Rescan of the repositories on Windows
78 - fixes #245 Rescan of the repositories on Windows
79 - fixes #248 cannot edit repos inside a group on windows
79 - fixes #248 cannot edit repos inside a group on windows
80 - fixes #219 forking problems on windows
80 - fixes #219 forking problems on windows
81
81
82
82
83 1.2.1 (**2011-10-08**)
83 1.2.1 (**2011-10-08**)
84 ======================
84 ======================
85
85
86 news
86 news
87 ----
87 ----
88
88
89
89
90 fixes
90 fixes
91 -----
91 -----
92
92
93 - fixed problems with basic auth and push problems
93 - fixed problems with basic auth and push problems
94 - gui fixes
94 - gui fixes
95 - fixed logger
95 - fixed logger
96
96
97
97
98 1.2.0 (**2011-10-07**)
98 1.2.0 (**2011-10-07**)
99 ======================
99 ======================
100
100
101 news
101 news
102 ----
102 ----
103
103
104 - implemented #47 repository groups
104 - implemented #47 repository groups
105 - implemented #89 Can setup google analytics code from settings menu
105 - implemented #89 Can setup google analytics code from settings menu
106 - implemented #91 added nicer looking archive urls with more download options
106 - implemented #91 added nicer looking archive urls with more download options
107 like tags, branches
107 like tags, branches
108 - implemented #44 into file browsing, and added follow branch option
108 - implemented #44 into file browsing, and added follow branch option
109 - implemented #84 downloads can be enabled/disabled for each repository
109 - implemented #84 downloads can be enabled/disabled for each repository
110 - anonymous repository can be cloned without having to pass default:default
110 - anonymous repository can be cloned without having to pass default:default
111 into clone url
111 into clone url
112 - fixed #90 whoosh indexer can index chooses repositories passed in command
112 - fixed #90 whoosh indexer can index chooses repositories passed in command
113 line
113 line
114 - extended journal with day aggregates and paging
114 - extended journal with day aggregates and paging
115 - implemented #107 source code lines highlight ranges
115 - implemented #107 source code lines highlight ranges
116 - implemented #93 customizable changelog on combined revision ranges -
116 - implemented #93 customizable changelog on combined revision ranges -
117 equivalent of githubs compare view
117 equivalent of githubs compare view
118 - implemented #108 extended and more powerful LDAP configuration
118 - implemented #108 extended and more powerful LDAP configuration
119 - implemented #56 users groups
119 - implemented #56 users groups
120 - major code rewrites optimized codes for speed and memory usage
120 - major code rewrites optimized codes for speed and memory usage
121 - raw and diff downloads are now in git format
121 - raw and diff downloads are now in git format
122 - setup command checks for write access to given path
122 - setup command checks for write access to given path
123 - fixed many issues with international characters and unicode. It uses utf8
123 - fixed many issues with international characters and unicode. It uses utf8
124 decode with replace to provide less errors even with non utf8 encoded strings
124 decode with replace to provide less errors even with non utf8 encoded strings
125 - #125 added API KEY access to feeds
125 - #125 added API KEY access to feeds
126 - #109 Repository can be created from external Mercurial link (aka. remote
126 - #109 Repository can be created from external Mercurial link (aka. remote
127 repository, and manually updated (via pull) from admin panel
127 repository, and manually updated (via pull) from admin panel
128 - beta git support - push/pull server + basic view for git repos
128 - beta git support - push/pull server + basic view for git repos
129 - added followers page and forks page
129 - added followers page and forks page
130 - server side file creation (with binary file upload interface)
130 - server side file creation (with binary file upload interface)
131 and edition with commits powered by codemirror
131 and edition with commits powered by codemirror
132 - #111 file browser file finder, quick lookup files on whole file tree
132 - #111 file browser file finder, quick lookup files on whole file tree
133 - added quick login sliding menu into main page
133 - added quick login sliding menu into main page
134 - changelog uses lazy loading of affected files details, in some scenarios
134 - changelog uses lazy loading of affected files details, in some scenarios
135 this can improve speed of changelog page dramatically especially for
135 this can improve speed of changelog page dramatically especially for
136 larger repositories.
136 larger repositories.
137 - implements #214 added support for downloading subrepos in download menu.
137 - implements #214 added support for downloading subrepos in download menu.
138 - Added basic API for direct operations on rhodecode via JSON
138 - Added basic API for direct operations on rhodecode via JSON
139 - Implemented advanced hook management
139 - Implemented advanced hook management
140
140
141 fixes
141 fixes
142 -----
142 -----
143
143
144 - fixed file browser bug, when switching into given form revision the url was
144 - fixed file browser bug, when switching into given form revision the url was
145 not changing
145 not changing
146 - fixed propagation to error controller on simplehg and simplegit middlewares
146 - fixed propagation to error controller on simplehg and simplegit middlewares
147 - fixed error when trying to make a download on empty repository
147 - fixed error when trying to make a download on empty repository
148 - fixed problem with '[' chars in commit messages in journal
148 - fixed problem with '[' chars in commit messages in journal
149 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
149 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
150 - journal fork fixes
150 - journal fork fixes
151 - removed issue with space inside renamed repository after deletion
151 - removed issue with space inside renamed repository after deletion
152 - fixed strange issue on formencode imports
152 - fixed strange issue on formencode imports
153 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
153 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
154 - #150 fixes for errors on repositories mapped in db but corrupted in
154 - #150 fixes for errors on repositories mapped in db but corrupted in
155 filesystem
155 filesystem
156 - fixed problem with ascendant characters in realm #181
156 - fixed problem with ascendant characters in realm #181
157 - fixed problem with sqlite file based database connection pool
157 - fixed problem with sqlite file based database connection pool
158 - whoosh indexer and code stats share the same dynamic extensions map
158 - whoosh indexer and code stats share the same dynamic extensions map
159 - fixes #188 - relationship delete of repo_to_perm entry on user removal
159 - fixes #188 - relationship delete of repo_to_perm entry on user removal
160 - fixes issue #189 Trending source files shows "show more" when no more exist
160 - fixes issue #189 Trending source files shows "show more" when no more exist
161 - fixes issue #197 Relative paths for pidlocks
161 - fixes issue #197 Relative paths for pidlocks
162 - fixes issue #198 password will require only 3 chars now for login form
162 - fixes issue #198 password will require only 3 chars now for login form
163 - fixes issue #199 wrong redirection for non admin users after creating a repository
163 - fixes issue #199 wrong redirection for non admin users after creating a repository
164 - fixes issues #202, bad db constraint made impossible to attach same group
164 - fixes issues #202, bad db constraint made impossible to attach same group
165 more than one time. Affects only mysql/postgres
165 more than one time. Affects only mysql/postgres
166 - fixes #218 os.kill patch for windows was missing sig param
166 - fixes #218 os.kill patch for windows was missing sig param
167 - improved rendering of dag (they are not trimmed anymore when number of
167 - improved rendering of dag (they are not trimmed anymore when number of
168 heads exceeds 5)
168 heads exceeds 5)
169
169
170
170
171 1.1.8 (**2011-04-12**)
171 1.1.8 (**2011-04-12**)
172 ======================
172 ======================
173
173
174 news
174 news
175 ----
175 ----
176
176
177 - improved windows support
177 - improved windows support
178
178
179 fixes
179 fixes
180 -----
180 -----
181
181
182 - fixed #140 freeze of python dateutil library, since new version is python2.x
182 - fixed #140 freeze of python dateutil library, since new version is python2.x
183 incompatible
183 incompatible
184 - setup-app will check for write permission in given path
184 - setup-app will check for write permission in given path
185 - cleaned up license info issue #149
185 - cleaned up license info issue #149
186 - fixes for issues #137,#116 and problems with unicode and accented characters.
186 - fixes for issues #137,#116 and problems with unicode and accented characters.
187 - fixes crashes on gravatar, when passed in email as unicode
187 - fixes crashes on gravatar, when passed in email as unicode
188 - fixed tooltip flickering problems
188 - fixed tooltip flickering problems
189 - fixed came_from redirection on windows
189 - fixed came_from redirection on windows
190 - fixed logging modules, and sql formatters
190 - fixed logging modules, and sql formatters
191 - windows fixes for os.kill issue #133
191 - windows fixes for os.kill issue #133
192 - fixes path splitting for windows issues #148
192 - fixes path splitting for windows issues #148
193 - fixed issue #143 wrong import on migration to 1.1.X
193 - fixed issue #143 wrong import on migration to 1.1.X
194 - fixed problems with displaying binary files, thanks to Thomas Waldmann
194 - fixed problems with displaying binary files, thanks to Thomas Waldmann
195 - removed name from archive files since it's breaking ui for long repo names
195 - removed name from archive files since it's breaking ui for long repo names
196 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
196 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
197 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
197 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
198 Thomas Waldmann
198 Thomas Waldmann
199 - fixed issue #166 summary pager was skipping 10 revisions on second page
199 - fixed issue #166 summary pager was skipping 10 revisions on second page
200
200
201
201
202 1.1.7 (**2011-03-23**)
202 1.1.7 (**2011-03-23**)
203 ======================
203 ======================
204
204
205 news
205 news
206 ----
206 ----
207
207
208 fixes
208 fixes
209 -----
209 -----
210
210
211 - fixed (again) #136 installation support for FreeBSD
211 - fixed (again) #136 installation support for FreeBSD
212
212
213
213
214 1.1.6 (**2011-03-21**)
214 1.1.6 (**2011-03-21**)
215 ======================
215 ======================
216
216
217 news
217 news
218 ----
218 ----
219
219
220 fixes
220 fixes
221 -----
221 -----
222
222
223 - fixed #136 installation support for FreeBSD
223 - fixed #136 installation support for FreeBSD
224 - RhodeCode will check for python version during installation
224 - RhodeCode will check for python version during installation
225
225
226 1.1.5 (**2011-03-17**)
226 1.1.5 (**2011-03-17**)
227 ======================
227 ======================
228
228
229 news
229 news
230 ----
230 ----
231
231
232 - basic windows support, by exchanging pybcrypt into sha256 for windows only
232 - basic windows support, by exchanging pybcrypt into sha256 for windows only
233 highly inspired by idea of mantis406
233 highly inspired by idea of mantis406
234
234
235 fixes
235 fixes
236 -----
236 -----
237
237
238 - fixed sorting by author in main page
238 - fixed sorting by author in main page
239 - fixed crashes with diffs on binary files
239 - fixed crashes with diffs on binary files
240 - fixed #131 problem with boolean values for LDAP
240 - fixed #131 problem with boolean values for LDAP
241 - fixed #122 mysql problems thanks to striker69
241 - fixed #122 mysql problems thanks to striker69
242 - fixed problem with errors on calling raw/raw_files/annotate functions
242 - fixed problem with errors on calling raw/raw_files/annotate functions
243 with unknown revisions
243 with unknown revisions
244 - fixed returned rawfiles attachment names with international character
244 - fixed returned rawfiles attachment names with international character
245 - cleaned out docs, big thanks to Jason Harris
245 - cleaned out docs, big thanks to Jason Harris
246
246
247 1.1.4 (**2011-02-19**)
247 1.1.4 (**2011-02-19**)
248 ======================
248 ======================
249
249
250 news
250 news
251 ----
251 ----
252
252
253 fixes
253 fixes
254 -----
254 -----
255
255
256 - fixed formencode import problem on settings page, that caused server crash
256 - fixed formencode import problem on settings page, that caused server crash
257 when that page was accessed as first after server start
257 when that page was accessed as first after server start
258 - journal fixes
258 - journal fixes
259 - fixed option to access repository just by entering http://server/<repo_name>
259 - fixed option to access repository just by entering http://server/<repo_name>
260
260
261 1.1.3 (**2011-02-16**)
261 1.1.3 (**2011-02-16**)
262 ======================
262 ======================
263
263
264 news
264 news
265 ----
265 ----
266
266
267 - implemented #102 allowing the '.' character in username
267 - implemented #102 allowing the '.' character in username
268 - added option to access repository just by entering http://server/<repo_name>
268 - added option to access repository just by entering http://server/<repo_name>
269 - celery task ignores result for better performance
269 - celery task ignores result for better performance
270
270
271 fixes
271 fixes
272 -----
272 -----
273
273
274 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
274 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
275 apollo13 and Johan Walles
275 apollo13 and Johan Walles
276 - small fixes in journal
276 - small fixes in journal
277 - fixed problems with getting setting for celery from .ini files
277 - fixed problems with getting setting for celery from .ini files
278 - registration, password reset and login boxes share the same title as main
278 - registration, password reset and login boxes share the same title as main
279 application now
279 application now
280 - fixed #113: to high permissions to fork repository
280 - fixed #113: to high permissions to fork repository
281 - fixed problem with '[' chars in commit messages in journal
281 - fixed problem with '[' chars in commit messages in journal
282 - removed issue with space inside renamed repository after deletion
282 - removed issue with space inside renamed repository after deletion
283 - db transaction fixes when filesystem repository creation failed
283 - db transaction fixes when filesystem repository creation failed
284 - fixed #106 relation issues on databases different than sqlite
284 - fixed #106 relation issues on databases different than sqlite
285 - fixed static files paths links to use of url() method
285 - fixed static files paths links to use of url() method
286
286
287 1.1.2 (**2011-01-12**)
287 1.1.2 (**2011-01-12**)
288 ======================
288 ======================
289
289
290 news
290 news
291 ----
291 ----
292
292
293
293
294 fixes
294 fixes
295 -----
295 -----
296
296
297 - fixes #98 protection against float division of percentage stats
297 - fixes #98 protection against float division of percentage stats
298 - fixed graph bug
298 - fixed graph bug
299 - forced webhelpers version since it was making troubles during installation
299 - forced webhelpers version since it was making troubles during installation
300
300
301 1.1.1 (**2011-01-06**)
301 1.1.1 (**2011-01-06**)
302 ======================
302 ======================
303
303
304 news
304 news
305 ----
305 ----
306
306
307 - added force https option into ini files for easier https usage (no need to
307 - added force https option into ini files for easier https usage (no need to
308 set server headers with this options)
308 set server headers with this options)
309 - small css updates
309 - small css updates
310
310
311 fixes
311 fixes
312 -----
312 -----
313
313
314 - fixed #96 redirect loop on files view on repositories without changesets
314 - fixed #96 redirect loop on files view on repositories without changesets
315 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
315 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
316 and server crashed with errors
316 and server crashed with errors
317 - fixed large tooltips problems on main page
317 - fixed large tooltips problems on main page
318 - fixed #92 whoosh indexer is more error proof
318 - fixed #92 whoosh indexer is more error proof
319
319
320 1.1.0 (**2010-12-18**)
320 1.1.0 (**2010-12-18**)
321 ======================
321 ======================
322
322
323 news
323 news
324 ----
324 ----
325
325
326 - rewrite of internals for vcs >=0.1.10
326 - rewrite of internals for vcs >=0.1.10
327 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
327 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
328 with older clients
328 with older clients
329 - anonymous access, authentication via ldap
329 - anonymous access, authentication via ldap
330 - performance upgrade for cached repos list - each repository has it's own
330 - performance upgrade for cached repos list - each repository has it's own
331 cache that's invalidated when needed.
331 cache that's invalidated when needed.
332 - performance upgrades on repositories with large amount of commits (20K+)
332 - performance upgrades on repositories with large amount of commits (20K+)
333 - main page quick filter for filtering repositories
333 - main page quick filter for filtering repositories
334 - user dashboards with ability to follow chosen repositories actions
334 - user dashboards with ability to follow chosen repositories actions
335 - sends email to admin on new user registration
335 - sends email to admin on new user registration
336 - added cache/statistics reset options into repository settings
336 - added cache/statistics reset options into repository settings
337 - more detailed action logger (based on hooks) with pushed changesets lists
337 - more detailed action logger (based on hooks) with pushed changesets lists
338 and options to disable those hooks from admin panel
338 and options to disable those hooks from admin panel
339 - introduced new enhanced changelog for merges that shows more accurate results
339 - introduced new enhanced changelog for merges that shows more accurate results
340 - new improved and faster code stats (based on pygments lexers mapping tables,
340 - new improved and faster code stats (based on pygments lexers mapping tables,
341 showing up to 10 trending sources for each repository. Additionally stats
341 showing up to 10 trending sources for each repository. Additionally stats
342 can be disabled in repository settings.
342 can be disabled in repository settings.
343 - gui optimizations, fixed application width to 1024px
343 - gui optimizations, fixed application width to 1024px
344 - added cut off (for large files/changesets) limit into config files
344 - added cut off (for large files/changesets) limit into config files
345 - whoosh, celeryd, upgrade moved to paster command
345 - whoosh, celeryd, upgrade moved to paster command
346 - other than sqlite database backends can be used
346 - other than sqlite database backends can be used
347
347
348 fixes
348 fixes
349 -----
349 -----
350
350
351 - fixes #61 forked repo was showing only after cache expired
351 - fixes #61 forked repo was showing only after cache expired
352 - fixes #76 no confirmation on user deletes
352 - fixes #76 no confirmation on user deletes
353 - fixes #66 Name field misspelled
353 - fixes #66 Name field misspelled
354 - fixes #72 block user removal when he owns repositories
354 - fixes #72 block user removal when he owns repositories
355 - fixes #69 added password confirmation fields
355 - fixes #69 added password confirmation fields
356 - fixes #87 RhodeCode crashes occasionally on updating repository owner
356 - fixes #87 RhodeCode crashes occasionally on updating repository owner
357 - fixes #82 broken annotations on files with more than 1 blank line at the end
357 - fixes #82 broken annotations on files with more than 1 blank line at the end
358 - a lot of fixes and tweaks for file browser
358 - a lot of fixes and tweaks for file browser
359 - fixed detached session issues
359 - fixed detached session issues
360 - fixed when user had no repos he would see all repos listed in my account
360 - fixed when user had no repos he would see all repos listed in my account
361 - fixed ui() instance bug when global hgrc settings was loaded for server
361 - fixed ui() instance bug when global hgrc settings was loaded for server
362 instance and all hgrc options were merged with our db ui() object
362 instance and all hgrc options were merged with our db ui() object
363 - numerous small bugfixes
363 - numerous small bugfixes
364
364
365 (special thanks for TkSoh for detailed feedback)
365 (special thanks for TkSoh for detailed feedback)
366
366
367
367
368 1.0.2 (**2010-11-12**)
368 1.0.2 (**2010-11-12**)
369 ======================
369 ======================
370
370
371 news
371 news
372 ----
372 ----
373
373
374 - tested under python2.7
374 - tested under python2.7
375 - bumped sqlalchemy and celery versions
375 - bumped sqlalchemy and celery versions
376
376
377 fixes
377 fixes
378 -----
378 -----
379
379
380 - fixed #59 missing graph.js
380 - fixed #59 missing graph.js
381 - fixed repo_size crash when repository had broken symlinks
381 - fixed repo_size crash when repository had broken symlinks
382 - fixed python2.5 crashes.
382 - fixed python2.5 crashes.
383
383
384
384
385 1.0.1 (**2010-11-10**)
385 1.0.1 (**2010-11-10**)
386 ======================
386 ======================
387
387
388 news
388 news
389 ----
389 ----
390
390
391 - small css updated
391 - small css updated
392
392
393 fixes
393 fixes
394 -----
394 -----
395
395
396 - fixed #53 python2.5 incompatible enumerate calls
396 - fixed #53 python2.5 incompatible enumerate calls
397 - fixed #52 disable mercurial extension for web
397 - fixed #52 disable mercurial extension for web
398 - fixed #51 deleting repositories don't delete it's dependent objects
398 - fixed #51 deleting repositories don't delete it's dependent objects
399
399
400
400
401 1.0.0 (**2010-11-02**)
401 1.0.0 (**2010-11-02**)
402 ======================
402 ======================
403
403
404 - security bugfix simplehg wasn't checking for permissions on commands
404 - security bugfix simplehg wasn't checking for permissions on commands
405 other than pull or push.
405 other than pull or push.
406 - fixed doubled messages after push or pull in admin journal
406 - fixed doubled messages after push or pull in admin journal
407 - templating and css corrections, fixed repo switcher on chrome, updated titles
407 - templating and css corrections, fixed repo switcher on chrome, updated titles
408 - admin menu accessible from options menu on repository view
408 - admin menu accessible from options menu on repository view
409 - permissions cached queries
409 - permissions cached queries
410
410
411 1.0.0rc4 (**2010-10-12**)
411 1.0.0rc4 (**2010-10-12**)
412 ==========================
412 ==========================
413
413
414 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
414 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
415 - removed cache_manager settings from sqlalchemy meta
415 - removed cache_manager settings from sqlalchemy meta
416 - added sqlalchemy cache settings to ini files
416 - added sqlalchemy cache settings to ini files
417 - validated password length and added second try of failure on paster setup-app
417 - validated password length and added second try of failure on paster setup-app
418 - fixed setup database destroy prompt even when there was no db
418 - fixed setup database destroy prompt even when there was no db
419
419
420
420
421 1.0.0rc3 (**2010-10-11**)
421 1.0.0rc3 (**2010-10-11**)
422 =========================
422 =========================
423
423
424 - fixed i18n during installation.
424 - fixed i18n during installation.
425
425
426 1.0.0rc2 (**2010-10-11**)
426 1.0.0rc2 (**2010-10-11**)
427 =========================
427 =========================
428
428
429 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
429 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
430 occure. After vcs is fixed it'll be put back again.
430 occure. After vcs is fixed it'll be put back again.
431 - templating/css rewrites, optimized css. No newline at end of file
431 - templating/css rewrites, optimized css.
@@ -1,411 +1,408 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.repo
3 rhodecode.model.repo
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 Repository model for rhodecode
6 Repository model for rhodecode
7
7
8 :created_on: Jun 5, 2010
8 :created_on: Jun 5, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import os
25 import os
26 import shutil
26 import shutil
27 import logging
27 import logging
28 import traceback
28 import traceback
29 from datetime import datetime
29 from datetime import datetime
30
30
31 from sqlalchemy.orm import joinedload, make_transient
32
33 from vcs.utils.lazy import LazyProperty
31 from vcs.utils.lazy import LazyProperty
34 from vcs.backends import get_backend
32 from vcs.backends import get_backend
35
33
36 from rhodecode.lib import safe_str
34 from rhodecode.lib import safe_str, safe_unicode
37
35
38 from rhodecode.model import BaseModel
36 from rhodecode.model import BaseModel
39 from rhodecode.model.caching_query import FromCache
37 from rhodecode.model.caching_query import FromCache
40 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
38 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
41 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, Group
39 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, Group
42 from rhodecode.model.user import UserModel
43
40
44 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
45
42
46
43
47 class RepoModel(BaseModel):
44 class RepoModel(BaseModel):
48
45
49 @LazyProperty
46 @LazyProperty
50 def repos_path(self):
47 def repos_path(self):
51 """Get's the repositories root path from database
48 """Get's the repositories root path from database
52 """
49 """
53
50
54 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
51 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
55 return q.ui_value
52 return q.ui_value
56
53
57 def get(self, repo_id, cache=False):
54 def get(self, repo_id, cache=False):
58 repo = self.sa.query(Repository)\
55 repo = self.sa.query(Repository)\
59 .filter(Repository.repo_id == repo_id)
56 .filter(Repository.repo_id == repo_id)
60
57
61 if cache:
58 if cache:
62 repo = repo.options(FromCache("sql_cache_short",
59 repo = repo.options(FromCache("sql_cache_short",
63 "get_repo_%s" % repo_id))
60 "get_repo_%s" % repo_id))
64 return repo.scalar()
61 return repo.scalar()
65
62
66 def get_by_repo_name(self, repo_name, cache=False):
63 def get_by_repo_name(self, repo_name, cache=False):
67 repo = self.sa.query(Repository)\
64 repo = self.sa.query(Repository)\
68 .filter(Repository.repo_name == repo_name)
65 .filter(Repository.repo_name == repo_name)
69
66
70 if cache:
67 if cache:
71 repo = repo.options(FromCache("sql_cache_short",
68 repo = repo.options(FromCache("sql_cache_short",
72 "get_repo_%s" % repo_name))
69 "get_repo_%s" % repo_name))
73 return repo.scalar()
70 return repo.scalar()
74
71
75
72
76 def get_users_js(self):
73 def get_users_js(self):
77
74
78 users = self.sa.query(User).filter(User.active == True).all()
75 users = self.sa.query(User).filter(User.active == True).all()
79 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
76 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
80 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
77 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
81 u.lastname, u.username)
78 u.lastname, u.username)
82 for u in users])
79 for u in users])
83 return users_array
80 return users_array
84
81
85 def get_users_groups_js(self):
82 def get_users_groups_js(self):
86 users_groups = self.sa.query(UsersGroup)\
83 users_groups = self.sa.query(UsersGroup)\
87 .filter(UsersGroup.users_group_active == True).all()
84 .filter(UsersGroup.users_group_active == True).all()
88
85
89 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
86 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
90
87
91 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
88 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
92 (gr.users_group_id, gr.users_group_name,
89 (gr.users_group_id, gr.users_group_name,
93 len(gr.members))
90 len(gr.members))
94 for gr in users_groups])
91 for gr in users_groups])
95 return users_groups_array
92 return users_groups_array
96
93
97 def _get_defaults(self, repo_name):
94 def _get_defaults(self, repo_name):
98 """
95 """
99 Get's information about repository, and returns a dict for
96 Get's information about repository, and returns a dict for
100 usage in forms
97 usage in forms
101
98
102 :param repo_name:
99 :param repo_name:
103 """
100 """
104
101
105 repo_info = Repository.get_by_repo_name(repo_name)
102 repo_info = Repository.get_by_repo_name(repo_name)
106
103
107 if repo_info is None:
104 if repo_info is None:
108 return None
105 return None
109
106
110 defaults = repo_info.get_dict()
107 defaults = repo_info.get_dict()
111 group, repo_name = repo_info.groups_and_repo
108 group, repo_name = repo_info.groups_and_repo
112 defaults['repo_name'] = repo_name
109 defaults['repo_name'] = repo_name
113 defaults['repo_group'] = getattr(group[-1] if group else None,
110 defaults['repo_group'] = getattr(group[-1] if group else None,
114 'group_id', None)
111 'group_id', None)
115
112
116 # fill owner
113 # fill owner
117 if repo_info.user:
114 if repo_info.user:
118 defaults.update({'user': repo_info.user.username})
115 defaults.update({'user': repo_info.user.username})
119 else:
116 else:
120 replacement_user = User.query().filter(User.admin ==
117 replacement_user = User.query().filter(User.admin ==
121 True).first().username
118 True).first().username
122 defaults.update({'user': replacement_user})
119 defaults.update({'user': replacement_user})
123
120
124 # fill repository users
121 # fill repository users
125 for p in repo_info.repo_to_perm:
122 for p in repo_info.repo_to_perm:
126 defaults.update({'u_perm_%s' % p.user.username:
123 defaults.update({'u_perm_%s' % p.user.username:
127 p.permission.permission_name})
124 p.permission.permission_name})
128
125
129 # fill repository groups
126 # fill repository groups
130 for p in repo_info.users_group_to_perm:
127 for p in repo_info.users_group_to_perm:
131 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
128 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
132 p.permission.permission_name})
129 p.permission.permission_name})
133
130
134 return defaults
131 return defaults
135
132
136
133
137 def update(self, repo_name, form_data):
134 def update(self, repo_name, form_data):
138 try:
135 try:
139 cur_repo = self.get_by_repo_name(repo_name, cache=False)
136 cur_repo = self.get_by_repo_name(repo_name, cache=False)
140
137
141 # update permissions
138 # update permissions
142 for member, perm, member_type in form_data['perms_updates']:
139 for member, perm, member_type in form_data['perms_updates']:
143 if member_type == 'user':
140 if member_type == 'user':
144 r2p = self.sa.query(RepoToPerm)\
141 r2p = self.sa.query(RepoToPerm)\
145 .filter(RepoToPerm.user == User.get_by_username(member))\
142 .filter(RepoToPerm.user == User.get_by_username(member))\
146 .filter(RepoToPerm.repository == cur_repo)\
143 .filter(RepoToPerm.repository == cur_repo)\
147 .one()
144 .one()
148
145
149 r2p.permission = self.sa.query(Permission)\
146 r2p.permission = self.sa.query(Permission)\
150 .filter(Permission.permission_name ==
147 .filter(Permission.permission_name ==
151 perm).scalar()
148 perm).scalar()
152 self.sa.add(r2p)
149 self.sa.add(r2p)
153 else:
150 else:
154 g2p = self.sa.query(UsersGroupRepoToPerm)\
151 g2p = self.sa.query(UsersGroupRepoToPerm)\
155 .filter(UsersGroupRepoToPerm.users_group ==
152 .filter(UsersGroupRepoToPerm.users_group ==
156 UsersGroup.get_by_group_name(member))\
153 UsersGroup.get_by_group_name(member))\
157 .filter(UsersGroupRepoToPerm.repository ==
154 .filter(UsersGroupRepoToPerm.repository ==
158 cur_repo).one()
155 cur_repo).one()
159
156
160 g2p.permission = self.sa.query(Permission)\
157 g2p.permission = self.sa.query(Permission)\
161 .filter(Permission.permission_name ==
158 .filter(Permission.permission_name ==
162 perm).scalar()
159 perm).scalar()
163 self.sa.add(g2p)
160 self.sa.add(g2p)
164
161
165 # set new permissions
162 # set new permissions
166 for member, perm, member_type in form_data['perms_new']:
163 for member, perm, member_type in form_data['perms_new']:
167 if member_type == 'user':
164 if member_type == 'user':
168 r2p = RepoToPerm()
165 r2p = RepoToPerm()
169 r2p.repository = cur_repo
166 r2p.repository = cur_repo
170 r2p.user = User.get_by_username(member)
167 r2p.user = User.get_by_username(member)
171
168
172 r2p.permission = self.sa.query(Permission)\
169 r2p.permission = self.sa.query(Permission)\
173 .filter(Permission.
170 .filter(Permission.
174 permission_name == perm)\
171 permission_name == perm)\
175 .scalar()
172 .scalar()
176 self.sa.add(r2p)
173 self.sa.add(r2p)
177 else:
174 else:
178 g2p = UsersGroupRepoToPerm()
175 g2p = UsersGroupRepoToPerm()
179 g2p.repository = cur_repo
176 g2p.repository = cur_repo
180 g2p.users_group = UsersGroup.get_by_group_name(member)
177 g2p.users_group = UsersGroup.get_by_group_name(member)
181 g2p.permission = self.sa.query(Permission)\
178 g2p.permission = self.sa.query(Permission)\
182 .filter(Permission.
179 .filter(Permission.
183 permission_name == perm)\
180 permission_name == perm)\
184 .scalar()
181 .scalar()
185 self.sa.add(g2p)
182 self.sa.add(g2p)
186
183
187 # update current repo
184 # update current repo
188 for k, v in form_data.items():
185 for k, v in form_data.items():
189 if k == 'user':
186 if k == 'user':
190 cur_repo.user = User.get_by_username(v)
187 cur_repo.user = User.get_by_username(v)
191 elif k == 'repo_name':
188 elif k == 'repo_name':
192 pass
189 pass
193 elif k == 'repo_group':
190 elif k == 'repo_group':
194 cur_repo.group = Group.get(v)
191 cur_repo.group = Group.get(v)
195
192
196 else:
193 else:
197 setattr(cur_repo, k, v)
194 setattr(cur_repo, k, v)
198
195
199 new_name = cur_repo.get_new_name(form_data['repo_name'])
196 new_name = cur_repo.get_new_name(form_data['repo_name'])
200 cur_repo.repo_name = new_name
197 cur_repo.repo_name = new_name
201
198
202 self.sa.add(cur_repo)
199 self.sa.add(cur_repo)
203
200
204 if repo_name != new_name:
201 if repo_name != new_name:
205 # rename repository
202 # rename repository
206 self.__rename_repo(old=repo_name, new=new_name)
203 self.__rename_repo(old=repo_name, new=new_name)
207
204
208 self.sa.commit()
205 self.sa.commit()
209 return cur_repo
206 return cur_repo
210 except:
207 except:
211 log.error(traceback.format_exc())
208 log.error(traceback.format_exc())
212 self.sa.rollback()
209 self.sa.rollback()
213 raise
210 raise
214
211
215 def create(self, form_data, cur_user, just_db=False, fork=False):
212 def create(self, form_data, cur_user, just_db=False, fork=False):
216
213
217 try:
214 try:
218 if fork:
215 if fork:
219 repo_name = form_data['fork_name']
216 repo_name = form_data['fork_name']
220 org_name = form_data['repo_name']
217 org_name = form_data['repo_name']
221 org_full_name = org_name
218 org_full_name = org_name
222
219
223 else:
220 else:
224 org_name = repo_name = form_data['repo_name']
221 org_name = repo_name = form_data['repo_name']
225 repo_name_full = form_data['repo_name_full']
222 repo_name_full = form_data['repo_name_full']
226
223
227 new_repo = Repository()
224 new_repo = Repository()
228 new_repo.enable_statistics = False
225 new_repo.enable_statistics = False
229 for k, v in form_data.items():
226 for k, v in form_data.items():
230 if k == 'repo_name':
227 if k == 'repo_name':
231 if fork:
228 if fork:
232 v = repo_name
229 v = repo_name
233 else:
230 else:
234 v = repo_name_full
231 v = repo_name_full
235 if k == 'repo_group':
232 if k == 'repo_group':
236 k = 'group_id'
233 k = 'group_id'
237
234
238 if k == 'description':
235 if k == 'description':
239 v = v or repo_name
236 v = safe_unicode(v) or repo_name
240
237
241 setattr(new_repo, k, v)
238 setattr(new_repo, k, v)
242
239
243 if fork:
240 if fork:
244 parent_repo = self.sa.query(Repository)\
241 parent_repo = self.sa.query(Repository)\
245 .filter(Repository.repo_name == org_full_name).one()
242 .filter(Repository.repo_name == org_full_name).one()
246 new_repo.fork = parent_repo
243 new_repo.fork = parent_repo
247
244
248 new_repo.user_id = cur_user.user_id
245 new_repo.user_id = cur_user.user_id
249 self.sa.add(new_repo)
246 self.sa.add(new_repo)
250
247
251 #create default permission
248 #create default permission
252 repo_to_perm = RepoToPerm()
249 repo_to_perm = RepoToPerm()
253 default = 'repository.read'
250 default = 'repository.read'
254 for p in User.get_by_username('default').user_perms:
251 for p in User.get_by_username('default').user_perms:
255 if p.permission.permission_name.startswith('repository.'):
252 if p.permission.permission_name.startswith('repository.'):
256 default = p.permission.permission_name
253 default = p.permission.permission_name
257 break
254 break
258
255
259 default_perm = 'repository.none' if form_data['private'] else default
256 default_perm = 'repository.none' if form_data['private'] else default
260
257
261 repo_to_perm.permission_id = self.sa.query(Permission)\
258 repo_to_perm.permission_id = self.sa.query(Permission)\
262 .filter(Permission.permission_name == default_perm)\
259 .filter(Permission.permission_name == default_perm)\
263 .one().permission_id
260 .one().permission_id
264
261
265 repo_to_perm.repository = new_repo
262 repo_to_perm.repository = new_repo
266 repo_to_perm.user_id = User.get_by_username('default').user_id
263 repo_to_perm.user_id = User.get_by_username('default').user_id
267
264
268 self.sa.add(repo_to_perm)
265 self.sa.add(repo_to_perm)
269
266
270 if not just_db:
267 if not just_db:
271 self.__create_repo(repo_name, form_data['repo_type'],
268 self.__create_repo(repo_name, form_data['repo_type'],
272 form_data['repo_group'],
269 form_data['repo_group'],
273 form_data['clone_uri'])
270 form_data['clone_uri'])
274
271
275 self.sa.commit()
272 self.sa.commit()
276
273
277 #now automatically start following this repository as owner
274 #now automatically start following this repository as owner
278 from rhodecode.model.scm import ScmModel
275 from rhodecode.model.scm import ScmModel
279 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
276 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
280 cur_user.user_id)
277 cur_user.user_id)
281 return new_repo
278 return new_repo
282 except:
279 except:
283 log.error(traceback.format_exc())
280 log.error(traceback.format_exc())
284 self.sa.rollback()
281 self.sa.rollback()
285 raise
282 raise
286
283
287 def create_fork(self, form_data, cur_user):
284 def create_fork(self, form_data, cur_user):
288 from rhodecode.lib.celerylib import tasks, run_task
285 from rhodecode.lib.celerylib import tasks, run_task
289 run_task(tasks.create_repo_fork, form_data, cur_user)
286 run_task(tasks.create_repo_fork, form_data, cur_user)
290
287
291 def delete(self, repo):
288 def delete(self, repo):
292 try:
289 try:
293 self.sa.delete(repo)
290 self.sa.delete(repo)
294 self.__delete_repo(repo)
291 self.__delete_repo(repo)
295 self.sa.commit()
292 self.sa.commit()
296 except:
293 except:
297 log.error(traceback.format_exc())
294 log.error(traceback.format_exc())
298 self.sa.rollback()
295 self.sa.rollback()
299 raise
296 raise
300
297
301 def delete_perm_user(self, form_data, repo_name):
298 def delete_perm_user(self, form_data, repo_name):
302 try:
299 try:
303 self.sa.query(RepoToPerm)\
300 self.sa.query(RepoToPerm)\
304 .filter(RepoToPerm.repository \
301 .filter(RepoToPerm.repository \
305 == self.get_by_repo_name(repo_name))\
302 == self.get_by_repo_name(repo_name))\
306 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
303 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
307 self.sa.commit()
304 self.sa.commit()
308 except:
305 except:
309 log.error(traceback.format_exc())
306 log.error(traceback.format_exc())
310 self.sa.rollback()
307 self.sa.rollback()
311 raise
308 raise
312
309
313 def delete_perm_users_group(self, form_data, repo_name):
310 def delete_perm_users_group(self, form_data, repo_name):
314 try:
311 try:
315 self.sa.query(UsersGroupRepoToPerm)\
312 self.sa.query(UsersGroupRepoToPerm)\
316 .filter(UsersGroupRepoToPerm.repository \
313 .filter(UsersGroupRepoToPerm.repository \
317 == self.get_by_repo_name(repo_name))\
314 == self.get_by_repo_name(repo_name))\
318 .filter(UsersGroupRepoToPerm.users_group_id \
315 .filter(UsersGroupRepoToPerm.users_group_id \
319 == form_data['users_group_id']).delete()
316 == form_data['users_group_id']).delete()
320 self.sa.commit()
317 self.sa.commit()
321 except:
318 except:
322 log.error(traceback.format_exc())
319 log.error(traceback.format_exc())
323 self.sa.rollback()
320 self.sa.rollback()
324 raise
321 raise
325
322
326 def delete_stats(self, repo_name):
323 def delete_stats(self, repo_name):
327 try:
324 try:
328 self.sa.query(Statistics)\
325 self.sa.query(Statistics)\
329 .filter(Statistics.repository == \
326 .filter(Statistics.repository == \
330 self.get_by_repo_name(repo_name)).delete()
327 self.get_by_repo_name(repo_name)).delete()
331 self.sa.commit()
328 self.sa.commit()
332 except:
329 except:
333 log.error(traceback.format_exc())
330 log.error(traceback.format_exc())
334 self.sa.rollback()
331 self.sa.rollback()
335 raise
332 raise
336
333
337 def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False):
334 def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False):
338 """
335 """
339 makes repository on filesystem. It's group aware means it'll create
336 makes repository on filesystem. It's group aware means it'll create
340 a repository within a group, and alter the paths accordingly of
337 a repository within a group, and alter the paths accordingly of
341 group location
338 group location
342
339
343 :param repo_name:
340 :param repo_name:
344 :param alias:
341 :param alias:
345 :param parent_id:
342 :param parent_id:
346 :param clone_uri:
343 :param clone_uri:
347 """
344 """
348 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
345 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
349
346
350 if new_parent_id:
347 if new_parent_id:
351 paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
348 paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
352 new_parent_path = os.sep.join(paths)
349 new_parent_path = os.sep.join(paths)
353 else:
350 else:
354 new_parent_path = ''
351 new_parent_path = ''
355
352
356 repo_path = os.path.join(*map(lambda x:safe_str(x),
353 repo_path = os.path.join(*map(lambda x:safe_str(x),
357 [self.repos_path, new_parent_path, repo_name]))
354 [self.repos_path, new_parent_path, repo_name]))
358
355
359
356
360 # check if this path is not a repository
357 # check if this path is not a repository
361 if is_valid_repo(repo_path, self.repos_path):
358 if is_valid_repo(repo_path, self.repos_path):
362 raise Exception('This path %s is a valid repository' % repo_path)
359 raise Exception('This path %s is a valid repository' % repo_path)
363
360
364 # check if this path is a group
361 # check if this path is a group
365 if is_valid_repos_group(repo_path, self.repos_path):
362 if is_valid_repos_group(repo_path, self.repos_path):
366 raise Exception('This path %s is a valid group' % repo_path)
363 raise Exception('This path %s is a valid group' % repo_path)
367
364
368 log.info('creating repo %s in %s @ %s', repo_name, repo_path,
365 log.info('creating repo %s in %s @ %s', repo_name, repo_path,
369 clone_uri)
366 clone_uri)
370 backend = get_backend(alias)
367 backend = get_backend(alias)
371
368
372 backend(repo_path, create=True, src_url=clone_uri)
369 backend(repo_path, create=True, src_url=clone_uri)
373
370
374
371
375 def __rename_repo(self, old, new):
372 def __rename_repo(self, old, new):
376 """
373 """
377 renames repository on filesystem
374 renames repository on filesystem
378
375
379 :param old: old name
376 :param old: old name
380 :param new: new name
377 :param new: new name
381 """
378 """
382 log.info('renaming repo from %s to %s', old, new)
379 log.info('renaming repo from %s to %s', old, new)
383
380
384 old_path = os.path.join(self.repos_path, old)
381 old_path = os.path.join(self.repos_path, old)
385 new_path = os.path.join(self.repos_path, new)
382 new_path = os.path.join(self.repos_path, new)
386 if os.path.isdir(new_path):
383 if os.path.isdir(new_path):
387 raise Exception('Was trying to rename to already existing dir %s' \
384 raise Exception('Was trying to rename to already existing dir %s' \
388 % new_path)
385 % new_path)
389 shutil.move(old_path, new_path)
386 shutil.move(old_path, new_path)
390
387
391 def __delete_repo(self, repo):
388 def __delete_repo(self, repo):
392 """
389 """
393 removes repo from filesystem, the removal is acctually made by
390 removes repo from filesystem, the removal is acctually made by
394 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
391 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
395 repository is no longer valid for rhodecode, can be undeleted later on
392 repository is no longer valid for rhodecode, can be undeleted later on
396 by reverting the renames on this repository
393 by reverting the renames on this repository
397
394
398 :param repo: repo object
395 :param repo: repo object
399 """
396 """
400 rm_path = os.path.join(self.repos_path, repo.repo_name)
397 rm_path = os.path.join(self.repos_path, repo.repo_name)
401 log.info("Removing %s", rm_path)
398 log.info("Removing %s", rm_path)
402 #disable hg/git
399 #disable hg/git
403 alias = repo.repo_type
400 alias = repo.repo_type
404 shutil.move(os.path.join(rm_path, '.%s' % alias),
401 shutil.move(os.path.join(rm_path, '.%s' % alias),
405 os.path.join(rm_path, 'rm__.%s' % alias))
402 os.path.join(rm_path, 'rm__.%s' % alias))
406 #disable repo
403 #disable repo
407 shutil.move(rm_path, os.path.join(self.repos_path, 'rm__%s__%s' \
404 shutil.move(rm_path, os.path.join(self.repos_path, 'rm__%s__%s' \
408 % (datetime.today()\
405 % (datetime.today()\
409 .strftime('%Y%m%d_%H%M%S_%f'),
406 .strftime('%Y%m%d_%H%M%S_%f'),
410 repo.repo_name)))
407 repo.repo_name)))
411
408
General Comments 0
You need to be logged in to leave comments. Login now