##// END OF EJS Templates
fixed docstring on cleanup command
marcink -
r3704:45177757 default
parent child Browse files
Show More
@@ -1,153 +1,153 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 package.rhodecode.lib.cleanup
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 rhodecode.lib.paster_commands.cleanup
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 cleanup-repos paster command for RhodeCode
7 7
8 8
9 9 :created_on: Jul 14, 2012
10 10 :author: marcink
11 11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26 from __future__ import with_statement
27 27
28 28 import os
29 29 import sys
30 30 import re
31 31 import shutil
32 32 import logging
33 33 import datetime
34 34
35 35 from os.path import dirname as dn, join as jn
36 36 #to get the rhodecode import
37 37 rc_path = dn(dn(dn(os.path.realpath(__file__))))
38 38 sys.path.append(rc_path)
39 39 from rhodecode.lib.utils import BasePasterCommand, ask_ok, REMOVED_REPO_PAT
40 40
41 41 from rhodecode.lib.utils2 import safe_str
42 42 from rhodecode.model.db import RhodeCodeUi
43 43
44 44
45 45 log = logging.getLogger(__name__)
46 46
47 47
48 48 class Command(BasePasterCommand):
49 49
50 50 max_args = 1
51 51 min_args = 1
52 52
53 53 usage = "CONFIG_FILE"
54 54 group_name = "RhodeCode"
55 55 takes_config_file = -1
56 56 parser = BasePasterCommand.standard_parser(verbose=True)
57 57 summary = "Cleanup deleted repos"
58 58
59 59 def _parse_older_than(self, val):
60 60 regex = re.compile(r'((?P<days>\d+?)d)?((?P<hours>\d+?)h)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')
61 61 parts = regex.match(val)
62 62 if not parts:
63 63 return
64 64 parts = parts.groupdict()
65 65 time_params = {}
66 66 for (name, param) in parts.iteritems():
67 67 if param:
68 68 time_params[name] = int(param)
69 69 return datetime.timedelta(**time_params)
70 70
71 71 def _extract_date(self, name):
72 72 """
73 73 Extract the date part from rm__<date> pattern of removed repos,
74 74 and convert it to datetime object
75 75
76 76 :param name:
77 77 """
78 78 date_part = name[4:19] # 4:19 since we don't parse milisecods
79 79 return datetime.datetime.strptime(date_part, '%Y%m%d_%H%M%S')
80 80
81 81 def command(self):
82 82 #get SqlAlchemy session
83 83 self._init_session()
84 84
85 85 repos_location = RhodeCodeUi.get_repos_location()
86 86 to_remove = []
87 87 for dn, dirs, f in os.walk(safe_str(repos_location)):
88 88 alldirs = list(dirs)
89 89 del dirs[:]
90 90 if ('.hg' in alldirs or
91 91 'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)):
92 92 continue
93 93 for loc in alldirs:
94 94 if REMOVED_REPO_PAT.match(loc):
95 95 to_remove.append([os.path.join(dn, loc),
96 96 self._extract_date(loc)])
97 97 else:
98 98 dirs.append(loc)
99 99
100 100 #filter older than (if present)!
101 101 now = datetime.datetime.now()
102 102 older_than = self.options.older_than
103 103 if older_than:
104 104 to_remove_filtered = []
105 105 older_than_date = self._parse_older_than(older_than)
106 106 for name, date_ in to_remove:
107 107 repo_age = now - date_
108 108 if repo_age > older_than_date:
109 109 to_remove_filtered.append([name, date_])
110 110
111 111 to_remove = to_remove_filtered
112 112 print >> sys.stdout, 'removing %s deleted repos older than %s (%s)' \
113 113 % (len(to_remove), older_than, older_than_date)
114 114 else:
115 115 print >> sys.stdout, 'removing all [%s] deleted repos' \
116 116 % len(to_remove)
117 117 if self.options.dont_ask or not to_remove:
118 118 # don't ask just remove !
119 119 remove = True
120 120 else:
121 121 remove = ask_ok('the following repositories will be deleted completely:\n%s\n'
122 122 'are you sure you want to remove them [y/n]?'
123 123 % ', \n'.join(['%s removed on %s'
124 124 % (safe_str(x[0]), safe_str(x[1])) for x in to_remove]))
125 125
126 126 if remove:
127 127 for path, date_ in to_remove:
128 128 print >> sys.stdout, 'removing repository %s' % path
129 129 shutil.rmtree(path)
130 130 else:
131 131 print 'nothing done exiting...'
132 132 sys.exit(0)
133 133
134 134 def update_parser(self):
135 135 self.parser.add_option(
136 136 '--older-than',
137 137 action='store',
138 138 dest='older_than',
139 139 help=("only remove repos that have been removed "
140 140 "at least given time ago. "
141 141 "The default is to remove all removed repositories. "
142 142 "Possible suffixes: "
143 143 "d (days), h (hours), m (minutes), s (seconds). "
144 144 "For example --older-than=30d deletes repositories "
145 145 "removed more than 30 days ago.")
146 146 )
147 147
148 148 self.parser.add_option(
149 149 '--dont-ask',
150 150 action="store_true",
151 151 dest="dont_ask",
152 152 help="remove repositories without asking for confirmation."
153 153 )
General Comments 0
You need to be logged in to leave comments. Login now