blob: 44f4a4f0a10e34d866dbc954e5b1b057269bbec8 [file] [log] [blame]
#!/usr/bin/python
#
# Copyright 2016-present the Material Components for iOS authors. All Rights Reserved.
#
# 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.
"""Manages all pods under a directory.
"""
from __future__ import print_function
import argparse
import re
import os
import shutil
import subprocess
import sys
COMMANDS = ['install', 'clean', 'update', 'list']
BLACKLIST_DIRS = {'external', 'third_party', '.git'}
def find_matching_dirs(root, target_name, blacklist):
"""Return a list of directories that contain an entry with a particular name.
Paths have a directory matching anything in blacklist are excluded.
Args:
directory: Path to the directory to recursively search.
target_name: Name of a file/dir that, if it exists, marks its parent for
inclusion.
blacklist: A set of directories that cannot appear in the paths.
Returns:
A list of file paths.
"""
paths = []
for dirpath, dirnames, filenames in os.walk(root, topdown=True):
if target_name in filenames or target_name in dirnames:
paths.append(dirpath)
# Remove directories that we never want to explore further.
# Note that we have to modify dirnames in place, not replace it.
for p in set(dirnames) & blacklist:
dirnames.remove(p)
return paths
def update_podfile_dir(directory):
"""Run `pod update` in a directory.
Args:
directory: The directory to use.
"""
cmd = ['pod', 'update', '--project-directory=%s' % directory]
subprocess.check_call(cmd)
def update_all_podfile_dirs(directory, blacklist):
"""Run `pod update` in all directories containing a Podfile.
Args:
directory: The directory to use.
blacklist: A set of directories that cannot appear in the paths of podfiles.
"""
dirs = find_matching_dirs(directory, 'Podfile', blacklist)
for d in dirs:
update_podfile_dir(d)
def install_podfile_dir(directory, fast_install):
"""Run `pod install` in a directory.
Args:
directory: The directory to use.
fast_install: If True, then skip updating the podspec repo.
"""
cmd = ['pod', 'install', '--project-directory=%s' % directory]
if not fast_install:
cmd.append("--repo-update")
subprocess.check_call(cmd)
def install_all_podfile_dirs(directory, fast_install, blacklist):
"""Run `pod install` in all directories containing a Podfile.
Args:
directory: The directory to use.
fast_install: If True, then skip updating the podspec repo.
blacklist: A set of directories that cannot appear in the paths of podfiles.
"""
dirs = find_matching_dirs(directory, 'Podfile', blacklist)
for d in dirs:
install_podfile_dir(d, fast_install)
# If `fast_install` is not specified, we will do `pod update` again and
# again, even though it is a global operation and not a per-Podfile
# operation. Disable it after the first invocation to save time.
if not fast_install:
fast_install = True
def list_all_podfile_dirs(directory, blacklist):
"""Print all directories containing a Podfile.
Args:
directory: The directory to use.
blacklist: A set of directories that cannot appear in the paths of podfiles.
"""
dirs = find_matching_dirs(directory, 'Podfile', blacklist)
for d in dirs:
print(d)
def clean_all_pods_dirs(directory, blacklist):
"""Remove all Pods directories.
Args:
directory: The directory to search.
blacklist: A set of directories that cannot appear in the paths of podfiles.
"""
paths = find_matching_dirs(directory, 'Pods', blacklist)
paths = [os.path.join(p, 'Pods') for p in paths]
for p in paths:
shutil.rmtree(p, ignore_errors=True)
def create_argument_parser(commands):
"""Create an ArgumentParser for this script.
Args:
commands: The list of possible commands the user can specify.
Returns:
An ArgumentParser object.
"""
epilog="""
possible commands are:
install: Run `pod install` in every directory with a Podfile.
update: Run `pod update` in every directory with a Podfile.
clean: Recursively remove all Pods directories.
list: Print a list of directories with Podfiles.
"""
parser = argparse.ArgumentParser(description=('Runs `pod` commands in all '
'directories containing a '
'Podfile file.'),
epilog=epilog,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('command', help='the command to run.',
choices=COMMANDS)
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true',
help='print more information about actions being taken.',
default=False)
parser.add_argument('--dir', dest='directory',
help='do all work in this directory.',
default='.')
parser.add_argument('--fast_pod_install', action='store_true',
help=('skip updating the pod repos when running `pod '
'install`.'),
default=False)
return parser
def print_nothing(unused_message):
"""Prints nothing.
Args:
unused_message: A message to not print.
"""
pass
def main():
parser = create_argument_parser(COMMANDS)
args = parser.parse_args()
# Set up print functions for messages to the user.
if args.verbose:
verbose_printer = lambda x: print(x, file=sys.stdout)
else:
verbose_printer = print_nothing
stderr_printer = lambda x: print(x, file=sys.stderr)
# TODO: Avoid this duplication of the COMMANDS strings.
if args.command == 'install':
install_all_podfile_dirs(args.directory, args.fast_pod_install, BLACKLIST_DIRS)
elif args.command == 'update':
update_all_podfile_dirs(args.directory, BLACKLIST_DIRS)
elif args.command == 'list':
list_all_podfile_dirs(args.directory, BLACKLIST_DIRS)
elif args.command == 'clean':
clean_all_pods_dirs(args.directory, BLACKLIST_DIRS)
else:
print('Internal mismatch in the list of possible commands, aborting.',
file=sys.stderr)
sys.exit(-1)
if __name__ == '__main__':
main()