1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#!/usr/bin/python
__doc__="""%prog [options] [<directory>]
Removes all unversioned files from a subversion working copy directory
<directory>.
When <directory> is not specified the current directory is used.
<directory can also be a white space seperated list of directories.
"""
import os,sys,re,subprocess
from optparse import OptionParser
parser = OptionParser(__doc__)
parser.add_option("-r", "--recursive", action='store_true', dest="Recursive", default=False, help="Also clean subdirectories.")
parser.add_option("-s", "--skiputil", action='store_true', dest="SkipUtil", default=False, help="Skip util and tools directory.")
parser.add_option("-v", "--noverbose", action='store_true', dest="NoVerbose", default=False, help="No output.")
(g_Options, g_Args) = parser.parse_args()
if g_Args:
for i in range(len(g_Args)):
g_Args[i]=os.path.abspath(g_Args[i])
if not os.path.isdir(g_Args[i]):
parser.error("%s is not a valid directory"%g_Args[i])
NotWorkRe=re.compile("'\.' is not a working copy")
################################################################################
def Print (Message,NoVerbose=None,Append='\n'):
if NoVerbose!=1:
Message+=Append
sys.stdout.write(Message)
################################################################################
class RunCommandException(Exception):
def __init__(this,CommandLine,Output=None):
this.CommandLine=CommandLine
this.Output=Output
def __str__(this):
Ret="\n!!! RunCommand exception:\n-> Commandline:\n"
Ret+=this.CommandLine
if this.Output:
Ret+="\n-> Output:\n"
Ret+=this.Output
else:
Ret+="\n-> Command not found"
Ret+="\n"
return Ret
################################################################################
PIPE=subprocess.PIPE
STDOUT=subprocess.STDOUT
def RunCommand(Command):
try:
if sys.platform=='linux2':
Process=subprocess.Popen(Command, stdin=PIPE, stdout=PIPE, stderr=STDOUT, shell=True)
else:
CREATE_NO_WINDOW=0x8000000
Process=subprocess.Popen(Command, stdin=PIPE, stdout=PIPE, stderr=STDOUT, creationflags=CREATE_NO_WINDOW, shell=True)
import msvcrt
msvcrt.setmode(Process.stdout.fileno(), os.O_TEXT) # Threat output as ascii noy binary
except:
raise RunCommandException(Command)
return Process
################################################################################
def DelTreeNoJunctions(Dir):
try:
os.rmdir(Dir)
# empty dir or it was a junction, so we can return immediately
return
except:
pass
for root, dirs, files in os.walk(Dir, topdown=True):
for name in files:
os.remove(os.path.join(root,name))
for dir in dirs:
# first try just to remove the directory. This is to be sure that when it is a symbolic link
# just the link is removed and not the complete contents where it points to
try:
os.rmdir(os.path.join(root,dir))
del dirs[dir] # do not walk this directory
except:
pass # go further in the directory tree
# Now delete the empty directories left over from the previous walk
for root, dirs, files in os.walk(Dir, topdown=False):
for dir in dirs:
os.rmdir(os.path.join(root,dir))
os.rmdir(Dir)
################################################################################
def ProcessSvnLine(line,NoVerbose=None):
if line:
if NotWorkRe.search(line):
Print(NotWorkRe.sub("'%s' is not a working copy directory. Not cleaning this directory."%(re.sub(r"\\",r"\\\\",Dir)),line))
sys.exit(1)
if line[0]=='?' or line[0]=='I':
Item=re.sub("^\s+","",line[2:])
if g_Options.SkipUtil:
if Item[:5]=='util'+os.sep:
return
if Item[:6]=='tools'+os.sep:
return
if os.path.isdir(Item):
Print('Deleting directory %s'%(os.path.abspath(Item)),NoVerbose)
try:
DelTreeNoJunctions(Item)
except:
print "Error deleting directory %s. Contains read-only files?"%Item
else:
Print('Deleting file %s'%(os.path.abspath(Item)),NoVerbose)
try:
os.remove(Item)
except Exception,Details:
print "Error deleting file %s. Is read-only? "%Item
print Details
################################################################################
def CleanTree(Dir, NoVerbose=None):
Print("Cleaning '"+Dir+"'")
if g_Options.Recursive:
Command='svn st --no-ignore'
else:
Command='svn st -N --no-ignore'
Process=RunCommand(Command)
StdOut=Process.stdout
all_data=""
while 1:
done = Process.poll()
if done == None or done == 0:
line=StdOut.readline()
all_data+=line
line=line.rstrip()
ProcessSvnLine(line,NoVerbose)
if done == 0:
data=StdOut.read()
all_data+=data
for line in data.splitlines():
ProcessSvnLine(line,NoVerbose)
break
elif done != None:
#error!
print "error running svn command:", Command
print all_data, StdOut.read()
sys.exit(1)
################################################################################
if not g_Args:
g_Args=["."]
for Dir in g_Args:
os.chdir(Dir)
CleanTree(Dir, g_Options.NoVerbose)
|