| #!/usr/bin/python |
| |
| # |
| # Copyright (C) 2016 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| """Cleans up any orphaned .pyc files in the tree.""" |
| |
| |
| from __future__ import print_function |
| import argparse |
| import fnmatch |
| import os |
| import sys |
| |
| |
| def get_user_input(prompt): |
| """Prompt a user for input and return the result.""" |
| print(prompt) |
| sys.stdout.flush() |
| result = sys.stdin.readline() |
| return result |
| |
| |
| def parse_args(argv): |
| """Parse the command line arguments. |
| |
| Args: |
| argv: The list of command line arguments to parse. |
| |
| Returns: |
| The populated namespace object returned from argparse.parse_args(..). |
| """ |
| parser = argparse.ArgumentParser(description=__doc__) |
| parser.add_argument('--quiet', action='store_true', |
| help='Do not print any output.') |
| parser.add_argument('--yes', action='store_true', |
| help='Do not prompt for confirmation.') |
| parser.add_argument('directory', nargs='?', |
| default=os.path.dirname( |
| os.path.dirname(os.path.realpath(__file__))), |
| help='The base directory to search.') |
| args = parser.parse_args(argv) |
| |
| if args.quiet and not args.yes: |
| parser.error( |
| 'Using the --quiet flag requires also using the --yes flag.') |
| |
| return args |
| |
| |
| def main(argv): |
| args = parse_args(argv) |
| |
| if args.quiet: |
| sys.stdout = open('/dev/null', 'w') |
| |
| matches = [] |
| failures = [] |
| for dirpath, _, filenames in os.walk(args.directory): |
| for filename in fnmatch.filter(filenames, '*.pyc'): |
| filepath = os.path.join(dirpath, filename) |
| # If a .pyc file does not have a corresponding .py file, add it |
| # to the list of matches. |
| if not os.path.isfile(filepath[:-1]): |
| matches.append(filepath) |
| |
| if not matches: |
| print('No orphaned .pyc files found.') |
| else: |
| print('Found the following orphaned .pyc files:') |
| print('\n'.join(' ' + f for f in matches)) |
| |
| if args.yes: |
| choice = 'Y' |
| else: |
| choice = get_user_input('Remove these files? (y/N)').strip().upper() |
| if choice == 'Y': |
| # Remove the matched files. Under certain circumstances, an |
| # OSError may be raised, so keep track of how many files have been |
| # successfully deleted. |
| count = 0 |
| for f in matches: |
| try: |
| os.remove(f) |
| count += 1 |
| except OSError: |
| failures.append(f) |
| if failures: |
| print('Could not remove:') |
| print('\n'.join(' ' + f for f in failures)) |
| print('{} files removed.'.format(count)) |
| |
| else: |
| print('Files not removed.') |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |