1*635a8641SAndroid Build Coastguard Worker#!/usr/bin/env python 2*635a8641SAndroid Build Coastguard Worker# Copyright (c) 2013 The Chromium Authors. All rights reserved. 3*635a8641SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*635a8641SAndroid Build Coastguard Worker# found in the LICENSE file. 5*635a8641SAndroid Build Coastguard Worker 6*635a8641SAndroid Build Coastguard Worker"""Make a symlink and optionally touch a file (to handle dependencies). 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard WorkerUsage: 9*635a8641SAndroid Build Coastguard Worker symlink.py [options] sources... target 10*635a8641SAndroid Build Coastguard Worker 11*635a8641SAndroid Build Coastguard WorkerA sym link to source is created at target. If multiple sources are specfied, 12*635a8641SAndroid Build Coastguard Workerthen target is assumed to be a directory, and will contain all the links to 13*635a8641SAndroid Build Coastguard Workerthe sources (basenames identical to their source). 14*635a8641SAndroid Build Coastguard Worker""" 15*635a8641SAndroid Build Coastguard Worker 16*635a8641SAndroid Build Coastguard Workerimport errno 17*635a8641SAndroid Build Coastguard Workerimport optparse 18*635a8641SAndroid Build Coastguard Workerimport os.path 19*635a8641SAndroid Build Coastguard Workerimport shutil 20*635a8641SAndroid Build Coastguard Workerimport sys 21*635a8641SAndroid Build Coastguard Worker 22*635a8641SAndroid Build Coastguard Worker 23*635a8641SAndroid Build Coastguard Workerdef Main(argv): 24*635a8641SAndroid Build Coastguard Worker parser = optparse.OptionParser() 25*635a8641SAndroid Build Coastguard Worker parser.add_option('-f', '--force', action='store_true') 26*635a8641SAndroid Build Coastguard Worker parser.add_option('--touch') 27*635a8641SAndroid Build Coastguard Worker 28*635a8641SAndroid Build Coastguard Worker options, args = parser.parse_args(argv[1:]) 29*635a8641SAndroid Build Coastguard Worker if len(args) < 2: 30*635a8641SAndroid Build Coastguard Worker parser.error('at least two arguments required.') 31*635a8641SAndroid Build Coastguard Worker 32*635a8641SAndroid Build Coastguard Worker target = args[-1] 33*635a8641SAndroid Build Coastguard Worker sources = args[:-1] 34*635a8641SAndroid Build Coastguard Worker for s in sources: 35*635a8641SAndroid Build Coastguard Worker t = os.path.join(target, os.path.basename(s)) 36*635a8641SAndroid Build Coastguard Worker if len(sources) == 1 and not os.path.isdir(target): 37*635a8641SAndroid Build Coastguard Worker t = target 38*635a8641SAndroid Build Coastguard Worker t = os.path.expanduser(t) 39*635a8641SAndroid Build Coastguard Worker if os.path.realpath(t) == s: 40*635a8641SAndroid Build Coastguard Worker continue 41*635a8641SAndroid Build Coastguard Worker try: 42*635a8641SAndroid Build Coastguard Worker os.symlink(s, t) 43*635a8641SAndroid Build Coastguard Worker except OSError as e: 44*635a8641SAndroid Build Coastguard Worker if e.errno == errno.EEXIST and options.force: 45*635a8641SAndroid Build Coastguard Worker if os.path.isdir(t): 46*635a8641SAndroid Build Coastguard Worker shutil.rmtree(t, ignore_errors=True) 47*635a8641SAndroid Build Coastguard Worker else: 48*635a8641SAndroid Build Coastguard Worker os.remove(t) 49*635a8641SAndroid Build Coastguard Worker os.symlink(s, t) 50*635a8641SAndroid Build Coastguard Worker else: 51*635a8641SAndroid Build Coastguard Worker raise 52*635a8641SAndroid Build Coastguard Worker 53*635a8641SAndroid Build Coastguard Worker 54*635a8641SAndroid Build Coastguard Worker if options.touch: 55*635a8641SAndroid Build Coastguard Worker with open(options.touch, 'w') as f: 56*635a8641SAndroid Build Coastguard Worker pass 57*635a8641SAndroid Build Coastguard Worker 58*635a8641SAndroid Build Coastguard Worker 59*635a8641SAndroid Build Coastguard Workerif __name__ == '__main__': 60*635a8641SAndroid Build Coastguard Worker sys.exit(Main(sys.argv)) 61