106 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
"""Uninstall a previously installed CMake installation.
 | 
						|
 | 
						|
Read the ``install_manifest.txt`` file from a CMake build directory
 | 
						|
which has been installed then delete the files, and optionally the empty
 | 
						|
subdirectories of the install prefix, specified within.
 | 
						|
"""
 | 
						|
 | 
						|
from argparse import ArgumentParser, RawDescriptionHelpFormatter
 | 
						|
from os import listdir, path, remove, rmdir
 | 
						|
from sys import stderr
 | 
						|
 | 
						|
 | 
						|
def uninstall(build_dir, recursive=False):
 | 
						|
    """Uninstall a previoulsy installed CMake installation.
 | 
						|
 | 
						|
    Arguments:
 | 
						|
        :build_dir: Path to the build directory containing the
 | 
						|
        ``install_manifest.txt`` of files to uninstall.
 | 
						|
        :recursive: Boolean flag to enable recursively uninstall empty
 | 
						|
        directories up to the install prefix specified in ``CMakeCache.txt``.
 | 
						|
    """
 | 
						|
    # Get the list of installed files from the install_manifest.txt
 | 
						|
    install_manifest_path = path.join(build_dir, 'install_manifest.txt')
 | 
						|
    with open(install_manifest_path, 'r') as install_manifest_file:
 | 
						|
        install_manifest = sorted(install_manifest_file.read().splitlines())
 | 
						|
    # Delete files from the filesystem
 | 
						|
    removed = []
 | 
						|
    directories = []
 | 
						|
    for entry in install_manifest:
 | 
						|
        directories.append(path.dirname(entry))
 | 
						|
        if path.isfile(entry):
 | 
						|
            remove(entry)
 | 
						|
            removed.append(entry)
 | 
						|
    if recursive:
 | 
						|
        # Get the install prefix from CMakeCache.txt
 | 
						|
        cmakecache_path = path.join(build_dir, 'CMakeCache.txt')
 | 
						|
        with open(cmakecache_path, 'r') as cmakecache_file:
 | 
						|
            for line in cmakecache_file.read().splitlines():
 | 
						|
                if line.startswith('CMAKE_INSTALL_PREFIX'):
 | 
						|
                    prefix = path.normpath(line.split('=')[1])
 | 
						|
                    break
 | 
						|
        while True:
 | 
						|
            # Remove duplicates from list
 | 
						|
            directories = list(dict.fromkeys(directories))
 | 
						|
            # Find directories in list which are not empty
 | 
						|
            not_empty = []
 | 
						|
            for index, entry in enumerate(directories):
 | 
						|
                if listdir(entry):
 | 
						|
                    not_empty.append(index)
 | 
						|
            # Remove directories which are not empty from list
 | 
						|
            for index in reversed(not_empty):
 | 
						|
                del directories[index]
 | 
						|
            # Delete directories from the filesystem
 | 
						|
            to_del = []
 | 
						|
            to_append = []
 | 
						|
            for index, entry in enumerate(directories):
 | 
						|
                rmdir(entry)
 | 
						|
                removed.append(entry)
 | 
						|
                to_del.append(index)
 | 
						|
                parent = path.dirname(entry)
 | 
						|
                # Add parent directory to the list when not the install prefix
 | 
						|
                if path.normpath(parent) != prefix:
 | 
						|
                    to_append.append(parent)
 | 
						|
            # Remove deleted directories from list
 | 
						|
            for index in reversed(to_del):
 | 
						|
                del directories[index]
 | 
						|
            directories += to_append
 | 
						|
            # Exit loop when no more directories in list
 | 
						|
            if not directories:
 | 
						|
                break
 | 
						|
    return removed
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    """Command line entry point."""
 | 
						|
    cli = ArgumentParser(description=__doc__,
 | 
						|
                         formatter_class=RawDescriptionHelpFormatter)
 | 
						|
    cli.add_argument('--version', action='version', version='%(prog)s 0.1.0')
 | 
						|
    cli.add_argument('-q',
 | 
						|
                     '--quiet',
 | 
						|
                     action='store_true',
 | 
						|
                     help="don't print removed entries to stdout")
 | 
						|
    cli.add_argument('-r',
 | 
						|
                     '--recursive',
 | 
						|
                     action='store_true',
 | 
						|
                     help='recursively remove empty directories')
 | 
						|
    cli.add_argument('build_dir',
 | 
						|
                     help='path to the installed CMake build directory')
 | 
						|
    args = cli.parse_args()
 | 
						|
    try:
 | 
						|
        removed = uninstall(args.build_dir, recursive=args.recursive)
 | 
						|
        if not args.quiet:
 | 
						|
            for entry in removed:
 | 
						|
                print(f'-- Uninstalling: {entry}')
 | 
						|
    except FileNotFoundError as error:
 | 
						|
        print(f'error: file not found: {error.filename}', file=stderr)
 | 
						|
        exit(1)
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    try:
 | 
						|
        main()
 | 
						|
    except KeyboardInterrupt:
 | 
						|
        exit(130)
 |