# winrm.py - remove long path directories on Windows
#
# Copyright 2008 Adrian Buehlmann <adrian@cadifra.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

_helptext = '''python winrm.py [-q] C:\\path\\to\\element ... [-y]

Recursively delete directories or files at long paths (>260) on Windows.

options:

  -q  --quiet  run quiet
  -y           actually delete (runs dry if omitted) 

This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE'''

import sys, os, os.path, stat

_levels = {'quiet':0, 'normal':1, 'debug':2}
class ui:
    def __init__(self, verbosity):
        self.level = _levels[verbosity]
    def _out(self, verbosity, str):
        if self.level >= _levels[verbosity]:
            print str
    def debug(self, str):
        self._out('debug', str)
    def status(self, str):
        self._out('normal', str)

def _rmele(ui, path, dryrun):
    ui.debug("_rmele('%s')" % path)
    mode = os.stat(path)[stat.ST_MODE]
    if stat.S_ISDIR(mode):   # directory
        _rmdir(ui, path, dryrun)
    elif stat.S_ISREG(mode): # file
        if not dryrun:
           os.unlink(path)
        ui.status("deleted file '%s'" % path)

def _rmdir(ui, path, dryrun):
    ui.debug("_rmdir('%s')" % path)
    for name in os.listdir(path): 
        _rmele(ui, unicode(path + '\\' + name), dryrun)
    if not dryrun:
        os.rmdir(path)
    ui.status("deleted directory '%s'" % path)

_prefix = '\\\\?\\'
def rmdir(ui, path, dryrun):
    # delete long path directory tree or file
    if not path.startswith(_prefix):
        if not os.path.isabs(path):
            path = os.path.abspath(path)
        path = _prefix + path
    _rmele(ui, unicode(path), dryrun)

def main():
    verbosity = 'normal'
    dryrun = True
    dirs = []
    for arg in sys.argv[1:]:
        if (arg == '-q' or arg == '--quiet'):
           verbosity = 'quiet'
        elif (arg == '--debug'):
           verbosity = 'debug'
        elif (arg == '-y'):
           dryrun = False
        elif (arg[0] == '-'):
           print "error: unknown option %s" % arg
           return
        else:
           dirs.append(arg)
    if dirs == []:
        print _helptext
    else:
        u = ui(verbosity)
        if dryrun:
            print "(running dry, showing output only, nothing will be deleted)"
        for dir in dirs:
            rmdir(u, dir, dryrun)
        if dryrun:
            print "(this was a dry run only, repeat with -y to actually delete)"

if __name__ == '__main__':
    main()
