Added more debug info at the end for files processed, cleaned up formatting. At some point will strive to make the output more UNIX friendly, parsable.

I also fixed a bug where the script would crash instead of setting the P4Client.

I need to fix the script to use a `with` construct so if you terminate the program the P4Client is returned to what it was.
This commit is contained in:
unknown 2014-10-22 12:05:57 -06:00
parent 06b0cbe426
commit e7bb65874e
3 changed files with 25 additions and 27 deletions

View File

@ -1,7 +1,10 @@
p4RemoveUnversioned p4RemoveUnversioned
=================== ===================
Removes unversioned files from perforce repository. Script is in beta, though it works. It's a little slow due to the way fstat is used, but that will be changed soon, so the speed up should be enormous once that's done, up to 100x or more. Removes unversioned files from perforce repository. Script is in beta, works well, but still going through continued testing. There are a few stats at the end, will be putting in more, like number of files/directories checked, so you have an idea how much work was required.
Concerning benchmarks: I used to have a HDD, now a SSD. So I can't provide valid comparisons to the old numbers until I do them on a computer with a HDD. That said, this single worker implementation runs faster than the old multi-threaded version. Can't wait to further update it, will only continue to get faster.
This script does parse __.p4ignore__ ignore files, compiles the fields as regex, and scans every directory and file against the local and parent __.p4ignore__ files. This is my first time doing something like this, and I just realized this isn't actually correct; I need to update how things are ignored to follow the [spec](http://www.perforce.com/perforce/r12.1/manuals/cmdref/env.P4IGNORE.html), since it's not straight up regex. This script does parse __.p4ignore__ ignore files, compiles the fields as regex, and scans every directory and file against the local and parent __.p4ignore__ files. This is my first time doing something like this, and I just realized this isn't actually correct; I need to update how things are ignored to follow the [spec](http://www.perforce.com/perforce/r12.1/manuals/cmdref/env.P4IGNORE.html), since it's not straight up regex.

View File

@ -237,8 +237,8 @@ class Console( threading.Thread ):
self.buffer_write_times.clear( ) self.buffer_write_times.clear( )
self.queue.task_done( ) self.queue.task_done( )
print(self.queue.qsize()) #print(self.queue.qsize())
print(self.queue.empty()) #print(self.queue.empty())
break break
elif event == Console.MSG.WRITE: elif event == Console.MSG.WRITE:
@ -347,7 +347,7 @@ def main( args ):
client_root = get_client_root() client_root = get_client_root()
ldirectory = directory.lower() ldirectory = directory.lower()
workspace_name = None workspace_name = None
if not ldirectory.startswith(client_root.lower()): if client_root is None or not ldirectory.startswith(client_root.lower()):
print("\nCurrent directory not in client view, checking other workspaces for user '" + username + "' ...") print("\nCurrent directory not in client view, checking other workspaces for user '" + username + "' ...")
workspace_name = parse_info_from_command('p4 info', 'Client name: ') workspace_name = parse_info_from_command('p4 info', 'Client name: ')
@ -386,6 +386,9 @@ def main( args ):
# Key is the file root, the value is the table of file regexes for that directory. # Key is the file root, the value is the table of file regexes for that directory.
files_to_ignore = PDict() files_to_ignore = PDict()
processed_file_count = 0
processed_directory_count = 0
remove_file_count = 0 remove_file_count = 0
remove_dir_count = 0 remove_dir_count = 0
warning_count = 0 warning_count = 0
@ -414,18 +417,21 @@ def main( args ):
ignore_list = get_ignore_list( root, files_to_ignore ) ignore_list = get_ignore_list( root, files_to_ignore )
if not options.quiet: if not options.quiet:
c.write( "|Checking " + root ) c.write( "|Checking " + os.path.relpath( root, directory ) )
for d in dirs: for d in dirs:
processed_directory_count += 1
path = join( root, d ) path = join( root, d )
rel_path = os.path.relpath( path, directory )
if match_in_ignore_list( path, ignore_list ): if match_in_ignore_list( path, ignore_list ):
# add option of using send2trash # add option of using send2trash
if not options.quiet: if not options.quiet:
c.write( "| ignoring " + d ) c.write( "| ignoring " + rel_path )
dirs.remove( d ) dirs.remove( d )
for f in files: for f in files:
processed_file_count += 1
path = normpath( join( root, f ) ) path = normpath( join( root, f ) )
if path not in files_in_depot: if path not in files_in_depot:
@ -451,18 +457,20 @@ def main( args ):
ignore_list = get_ignore_list( root, files_to_ignore ) ignore_list = get_ignore_list( root, files_to_ignore )
for d in dirs: for d in dirs:
processed_directory_count += 1
path = os.path.join( root, d ) path = os.path.join( root, d )
rel_path = os.path.relpath( path, directory )
if match_in_ignore_list( path, ignore_list ): if match_in_ignore_list( path, ignore_list ):
# add option of using send2trash # add option of using send2trash
if not options.quiet: if not options.quiet:
c.write( "| ignoring " + path ) c.write( "| ignoring " + rel_path )
dirs.remove( d ) dirs.remove( d )
try: try:
os.rmdir(path) os.rmdir(path)
remove_dir_count += 1 remove_dir_count += 1
if not options.quiet: if not options.quiet:
c.write( "| " + path + " was removed." ) c.write( "| " + rel_path + " was removed." )
except OSError: except OSError:
# Fails on non-empty directory # Fails on non-empty directory
pass pass
@ -484,7 +492,10 @@ def main( args ):
c.write("|Done.") c.write("|Done.")
if not options.quiet: if not options.quiet:
output = "\n[ Removed " + str( remove_file_count ) + singular_pulural( remove_file_count, " file, ", " files, " ) output = "\nChecked " + str( processed_file_count ) + singular_pulural( processed_file_count, " file, ", " files, " )
output += str( processed_directory_count ) + singular_pulural( processed_directory_count, " directory", " directories")
output += "\nRemoved " + str( remove_file_count ) + singular_pulural( remove_file_count, " file, ", " files, " )
output += str( remove_dir_count ) + singular_pulural( remove_dir_count, " directory", " directories") output += str( remove_dir_count ) + singular_pulural( remove_dir_count, " directory", " directories")
if warning_count > 0: if warning_count > 0:
@ -494,9 +505,9 @@ def main( args ):
end = time.clock() end = time.clock()
delta = end - start delta = end - start
output += ", and finished in " + str(delta) + "s" output += "\nFinished in " + str(delta) + "s"
c.write( output + " ]" ) c.write( output )
if __name__ == "__main__": if __name__ == "__main__":
try: try:

View File

@ -1,16 +0,0 @@
Stack trace:
Frame Function Args
000FD4FC6C0 0018006F733 (FFFFFFFFFFFFFFFF, 006002C2510, 005CCDD1850, 005CCDD1870)
00000000006 00180070C6A (000FD4FC8A0, 00000000000, 0000000035C, 00000000000)
000FD4FC8A0 00180118778 (00000000000, 00000000000, 000FD4FCA20, 00600000003)
00000000041 0018011587E (00180133B2D, 000000002CC, 00000000000, 00000000000)
00000000000 00180115D4B (001801362C0, 006002C2270, 000775D19A1, 00000000006)
00000000000 00180115F1C (00000000000, 0008FB10544, 7FEFD6464DA, 006002C2318)
00000000000 001801161DF (0018013B2FB, 00600000001, 001801CA2C0, 000FD4FD640)
00000000000 00180144816 (00180135C7F, 006002C2270, 006002C2270, 006002C2270)
00000000000 001800BFCE3 (0018013460D, 00000000000, 005CCDB7127, 006002C2318)
00000000000 001801629FC (00000000000, 00000000000, 00000000000, 006002C2270)
00000000000 00180136AEF (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00180136334 (000003A0000, 00000000000, 00000000000, 00000000000)
00000000000 001800C373B (000003A0000, 00000000000, 00000000000, 00000000000)
End of stack trace