Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: setup_links.py

Issue 1414343008: DEPS: Sync Git subtree mirrors instead of symlinking into chromium/src (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromium/README ('k') | sync_chromium.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: setup_links.py
diff --git a/setup_links.py b/setup_links.py
deleted file mode 100755
index ac6865be4409d3c45019d585320fe083b58a1a9f..0000000000000000000000000000000000000000
--- a/setup_links.py
+++ /dev/null
@@ -1,517 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
-#
-# Use of this source code is governed by a BSD-style license
-# that can be found in the LICENSE file in the root of the source
-# tree. An additional intellectual property rights grant can be found
-# in the file PATENTS. All contributing project authors may
-# be found in the AUTHORS file in the root of the source tree.
-
-"""Setup links to a Chromium checkout for WebRTC.
-
-WebRTC standalone shares a lot of dependencies and build tools with Chromium.
-To do this, many of the paths of a Chromium checkout is emulated by creating
-symlinks to files and directories. This script handles the setup of symlinks to
-achieve this.
-"""
-
-
-import ctypes
-import errno
-import logging
-import optparse
-import os
-import shelve
-import shutil
-import subprocess
-import sys
-import textwrap
-
-
-DIRECTORIES = [
- 'base',
- 'build',
- 'buildtools',
- 'testing',
- 'third_party/afl',
- 'third_party/binutils',
- 'third_party/boringssl',
- 'third_party/catapult',
- 'third_party/closure_compiler',
- 'third_party/colorama',
- 'third_party/expat',
- 'third_party/ffmpeg',
- 'third_party/instrumented_libraries',
- 'third_party/jsoncpp',
- 'third_party/libFuzzer',
- 'third_party/libjpeg',
- 'third_party/libjpeg_turbo',
- 'third_party/libsrtp',
- 'third_party/libvpx',
- 'third_party/libyuv',
- 'third_party/lss',
- 'third_party/ocmock',
- 'third_party/openh264',
- 'third_party/openmax_dl',
- 'third_party/opus',
- 'third_party/proguard',
- 'third_party/protobuf',
- 'third_party/sqlite',
- 'third_party/usrsctp',
- 'third_party/yasm',
- 'third_party/zlib',
- 'tools/clang',
- 'tools/clang_format_merge_driver',
- 'tools/determinism',
- 'tools/generate_library_loader',
- 'tools/generate_stubs',
- 'tools/gn',
- 'tools/grit',
- 'tools/gyp',
- 'tools/luci-go',
- 'tools/memory',
- 'tools/protoc_wrapper',
- 'tools/python',
- 'tools/swarming_client',
- 'tools/valgrind',
- 'tools/vim',
- 'tools/win',
-]
-
-from sync_chromium import get_target_os_list
-target_os = get_target_os_list()
-if 'android' in target_os:
- DIRECTORIES += [
- 'third_party/accessibility_test_framework',
- 'third_party/android_platform',
- 'third_party/android_support_test_runner',
- 'third_party/android_tools',
- 'third_party/apache_velocity',
- 'third_party/ashmem',
- 'third_party/bouncycastle',
- 'third_party/byte_buddy',
- 'third_party/ced',
- 'third_party/espresso',
- 'third_party/guava',
- 'third_party/hamcrest',
- 'third_party/icu',
- 'third_party/icu4j',
- 'third_party/ijar',
- 'third_party/intellij',
- 'third_party/javax_inject',
- 'third_party/jsr-305',
- 'third_party/junit',
- 'third_party/libxml',
- 'third_party/mockito',
- 'third_party/modp_b64',
- 'third_party/objenesis',
- 'third_party/ow2_asm',
- 'third_party/requests',
- 'third_party/robolectric',
- 'third_party/sqlite4java',
- 'third_party/tcmalloc',
- 'tools/android',
- ]
-
-FILES = {
- 'third_party/BUILD.gn': None,
-}
-
-ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
-CHROMIUM_CHECKOUT = os.path.join('chromium', 'src')
-LINKS_DB = 'links'
-
-# Version management to make future upgrades/downgrades easier to support.
-SCHEMA_VERSION = 1
-
-
-def query_yes_no(question, default=False):
- """Ask a yes/no question via raw_input() and return their answer.
-
- Modified from http://stackoverflow.com/a/3041990.
- """
- prompt = " [%s/%%s]: "
- prompt = prompt % ('Y' if default is True else 'y')
- prompt = prompt % ('N' if default is False else 'n')
-
- if default is None:
- default = 'INVALID'
-
- while True:
- sys.stdout.write(question + prompt)
- choice = raw_input().lower()
- if choice == '' and default != 'INVALID':
- return default
-
- if 'yes'.startswith(choice):
- return True
- elif 'no'.startswith(choice):
- return False
-
- print "Please respond with 'yes' or 'no' (or 'y' or 'n')."
-
-
-# Actions
-class Action(object):
- def __init__(self, dangerous):
- self.dangerous = dangerous
-
- def announce(self, planning):
- """Log a description of this action.
-
- Args:
- planning - True iff we're in the planning stage, False if we're in the
- doit stage.
- """
- pass
-
- def doit(self, links_db):
- """Execute the action, recording what we did to links_db, if necessary."""
- pass
-
-
-class Remove(Action):
- def __init__(self, path, dangerous):
- super(Remove, self).__init__(dangerous)
- self._priority = 0
- self._path = path
-
- def announce(self, planning):
- log = logging.warn
- filesystem_type = 'file'
- if not self.dangerous:
- log = logging.info
- filesystem_type = 'link'
- if planning:
- log('Planning to remove %s: %s', filesystem_type, self._path)
- else:
- log('Removing %s: %s', filesystem_type, self._path)
-
- def doit(self, _):
- os.remove(self._path)
-
-
-class Rmtree(Action):
- def __init__(self, path):
- super(Rmtree, self).__init__(dangerous=True)
- self._priority = 0
- self._path = path
-
- def announce(self, planning):
- if planning:
- logging.warn('Planning to remove directory: %s', self._path)
- else:
- logging.warn('Removing directory: %s', self._path)
-
- def doit(self, _):
- if sys.platform.startswith('win'):
- # shutil.rmtree() doesn't work on Windows if any of the directories are
- # read-only, which svn repositories are.
- subprocess.check_call(['rd', '/q', '/s', self._path], shell=True)
- else:
- shutil.rmtree(self._path)
-
-
-class Makedirs(Action):
- def __init__(self, path):
- super(Makedirs, self).__init__(dangerous=False)
- self._priority = 1
- self._path = path
-
- def doit(self, _):
- try:
- os.makedirs(self._path)
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
-
-
-class Symlink(Action):
- def __init__(self, source_path, link_path):
- super(Symlink, self).__init__(dangerous=False)
- self._priority = 2
- self._source_path = source_path
- self._link_path = link_path
-
- def announce(self, planning):
- if planning:
- logging.info(
- 'Planning to create link from %s to %s', self._link_path,
- self._source_path)
- else:
- logging.debug(
- 'Linking from %s to %s', self._link_path, self._source_path)
-
- def doit(self, links_db):
- # Files not in the root directory need relative path calculation.
- # On Windows, use absolute paths instead since NTFS doesn't seem to support
- # relative paths for symlinks.
- if sys.platform.startswith('win'):
- source_path = os.path.abspath(self._source_path)
- else:
- if os.path.dirname(self._link_path) != self._link_path:
- source_path = os.path.relpath(self._source_path,
- os.path.dirname(self._link_path))
-
- os.symlink(source_path, os.path.abspath(self._link_path))
- links_db[self._source_path] = self._link_path
-
-
-class LinkError(IOError):
- """Failed to create a link."""
- pass
-
-
-# Use junctions instead of symlinks on the Windows platform.
-if sys.platform.startswith('win'):
- def symlink(source_path, link_path):
- if os.path.isdir(source_path):
- subprocess.check_call(['cmd.exe', '/c', 'mklink', '/J', link_path,
- source_path])
- else:
- # Don't create symlinks to files on Windows, just copy the file instead
- # (there's no way to create a link without administrator's privileges).
- shutil.copy(source_path, link_path)
- os.symlink = symlink
-
-
-class WebRTCLinkSetup(object):
- def __init__(self, links_db, force=False, dry_run=False, prompt=False):
- self._force = force
- self._dry_run = dry_run
- self._prompt = prompt
- self._links_db = links_db
-
- def CreateLinks(self, on_bot):
- logging.debug('CreateLinks')
- # First, make a plan of action
- actions = []
-
- for source_path, link_path in FILES.iteritems():
- actions += self._ActionForPath(
- source_path, link_path, check_fn=os.path.isfile, check_msg='files')
- for source_dir in DIRECTORIES:
- actions += self._ActionForPath(
- source_dir, None, check_fn=os.path.isdir,
- check_msg='directories')
-
- if not on_bot and self._force:
- # When making the manual switch from legacy SVN checkouts to the new
- # Git-based Chromium DEPS, the .gclient_entries file that contains cached
- # URLs for all DEPS entries must be removed to avoid future sync problems.
- entries_file = os.path.join(os.path.dirname(ROOT_DIR), '.gclient_entries')
- if os.path.exists(entries_file):
- actions.append(Remove(entries_file, dangerous=True))
-
- actions.sort()
-
- if self._dry_run:
- for action in actions:
- action.announce(planning=True)
- logging.info('Not doing anything because dry-run was specified.')
- sys.exit(0)
-
- if any(a.dangerous for a in actions):
- logging.warn('Dangerous actions:')
- for action in (a for a in actions if a.dangerous):
- action.announce(planning=True)
- print
-
- if not self._force:
- logging.error(textwrap.dedent("""\
- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- A C T I O N R E Q I R E D
- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-
- Setting up the checkout requires creating symlinks to directories in the
- Chromium checkout inside chromium/src.
- To avoid disrupting developers, we've chosen to not delete directories
- forcibly, in case you have some work in progress in one of them :)
-
- ACTION REQUIRED:
- Before running `gclient sync|runhooks` again, you must run:
- %s%s --force
-
- Which will replace all directories which now must be symlinks, after
- prompting with a summary of the work-to-be-done.
- """), 'python ' if sys.platform.startswith('win') else '', __file__)
- sys.exit(1)
- elif self._prompt:
- if not query_yes_no('Would you like to perform the above plan?'):
- sys.exit(1)
-
- for action in actions:
- action.announce(planning=False)
- action.doit(self._links_db)
-
- if not on_bot and self._force:
- logging.info('Completed!\n\nNow run `gclient sync|runhooks` again to '
- 'let the remaining hooks (that probably were interrupted) '
- 'execute.')
-
- def CleanupLinks(self):
- logging.debug('CleanupLinks')
- for source, link_path in self._links_db.iteritems():
- if source == 'SCHEMA_VERSION':
- continue
- if os.path.islink(link_path) or sys.platform.startswith('win'):
- # os.path.islink() always returns false on Windows
- # See http://bugs.python.org/issue13143.
- logging.debug('Removing link to %s at %s', source, link_path)
- if not self._dry_run:
- if os.path.exists(link_path):
- if sys.platform.startswith('win') and os.path.isdir(link_path):
- subprocess.check_call(['rmdir', '/q', '/s', link_path],
- shell=True)
- else:
- os.remove(link_path)
- del self._links_db[source]
-
- @staticmethod
- def _ActionForPath(source_path, link_path=None, check_fn=None,
- check_msg=None):
- """Create zero or more Actions to link to a file or directory.
-
- This will be a symlink on POSIX platforms. On Windows it will result in:
- * a junction for directories
- * a copied file for single files.
-
- Args:
- source_path: Path relative to the Chromium checkout root.
- For readability, the path may contain slashes, which will
- automatically be converted to the right path delimiter on Windows.
- link_path: The location for the link to create. If omitted it will be the
- same path as source_path.
- check_fn: A function returning true if the type of filesystem object is
- correct for the attempted call. Otherwise an error message with
- check_msg will be printed.
- check_msg: String used to inform the user of an invalid attempt to create
- a file.
- Returns:
- A list of Action objects.
- """
- def fix_separators(path):
- if sys.platform.startswith('win'):
- return path.replace(os.altsep, os.sep)
- else:
- return path
-
- assert check_fn
- assert check_msg
- link_path = link_path or source_path
- link_path = fix_separators(link_path)
-
- source_path = fix_separators(source_path)
- source_path = os.path.join(CHROMIUM_CHECKOUT, source_path)
- if os.path.exists(source_path) and not check_fn:
- raise LinkError('Can only to link to %s: tried to link to: %s' %
- (check_msg, source_path))
-
- if not os.path.exists(source_path):
- logging.debug('Silently ignoring missing source: %s. This is to avoid '
- 'errors on platform-specific dependencies.', source_path)
- return []
-
- actions = []
-
- if os.path.exists(link_path) or os.path.islink(link_path):
- if os.path.islink(link_path):
- actions.append(Remove(link_path, dangerous=False))
- elif os.path.isfile(link_path):
- actions.append(Remove(link_path, dangerous=True))
- elif os.path.isdir(link_path):
- actions.append(Rmtree(link_path))
- else:
- raise LinkError('Don\'t know how to plan: %s' % link_path)
-
- # Create parent directories to the target link if needed.
- target_parent_dirs = os.path.dirname(link_path)
- if (target_parent_dirs and
- target_parent_dirs != link_path and
- not os.path.exists(target_parent_dirs)):
- actions.append(Makedirs(target_parent_dirs))
-
- actions.append(Symlink(source_path, link_path))
-
- return actions
-
-def _initialize_database(filename):
- links_database = shelve.open(filename)
-
- # Wipe the database if this version of the script ends up looking at a
- # newer (future) version of the links db, just to be sure.
- version = links_database.get('SCHEMA_VERSION')
- if version and version != SCHEMA_VERSION:
- logging.info('Found database with schema version %s while this script only '
- 'supports %s. Wiping previous database contents.', version,
- SCHEMA_VERSION)
- links_database.clear()
- links_database['SCHEMA_VERSION'] = SCHEMA_VERSION
- return links_database
-
-
-def main():
- on_bot = os.environ.get('CHROME_HEADLESS') == '1'
-
- parser = optparse.OptionParser()
- parser.add_option('-d', '--dry-run', action='store_true', default=False,
- help='Print what would be done, but don\'t perform any '
- 'operations. This will automatically set logging to '
- 'verbose.')
- parser.add_option('-c', '--clean-only', action='store_true', default=False,
- help='Only clean previously created links, don\'t create '
- 'new ones. This will automatically set logging to '
- 'verbose.')
- parser.add_option('-f', '--force', action='store_true', default=on_bot,
- help='Force link creation. CAUTION: This deletes existing '
- 'folders and files in the locations where links are '
- 'about to be created.')
- parser.add_option('-n', '--no-prompt', action='store_false', dest='prompt',
- default=(not on_bot),
- help='Prompt if we\'re planning to do a dangerous action')
- parser.add_option('-v', '--verbose', action='store_const',
- const=logging.DEBUG, default=logging.INFO,
- help='Print verbose output for debugging.')
- options, _ = parser.parse_args()
-
- if options.dry_run or options.force or options.clean_only:
- options.verbose = logging.DEBUG
- logging.basicConfig(format='%(message)s', level=options.verbose)
-
- # Work from the root directory of the checkout.
- script_dir = os.path.dirname(os.path.abspath(__file__))
- os.chdir(script_dir)
-
- if sys.platform.startswith('win'):
- def is_admin():
- try:
- return os.getuid() == 0
- except AttributeError:
- return ctypes.windll.shell32.IsUserAnAdmin() != 0
- if is_admin():
- logging.warning('WARNING: On Windows, you no longer need run as '
- 'administrator. Please run with user account privileges.')
-
- if not os.path.exists(CHROMIUM_CHECKOUT):
- logging.warning('Cannot find a Chromium checkout at %s. Did you run '
- '"gclient sync" before running this script?',
- CHROMIUM_CHECKOUT)
- return 0
-
- links_database = _initialize_database(LINKS_DB)
- try:
- symlink_creator = WebRTCLinkSetup(links_database, options.force,
- options.dry_run, options.prompt)
- symlink_creator.CleanupLinks()
- if not options.clean_only:
- symlink_creator.CreateLinks(on_bot)
- except LinkError as e:
- print >> sys.stderr, e.message
- return 3
- finally:
- links_database.close()
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
« no previous file with comments | « chromium/README ('k') | sync_chromium.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698