1#!/usr/bin/python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import os
7import sys
8
9def Main(argv):
10  """This is like 'env -i', but it uses a whitelist of env variables to allow
11  through to the command being run.  It attempts to strip off Xcode-added
12  values from PATH.
13  """
14  # Note: An attempt was made to do something like: env -i bash -lc '[command]'
15  # but that fails to set the things set by login (USER, etc.), so instead
16  # the only approach that seems to work is to have a whitelist.
17  env_key_whitelist = (
18    'HOME',
19    'LOGNAME',
20    # 'PATH' added below (but filtered).
21    'PWD',
22    'SHELL',
23    'TEMP',
24    'TMPDIR',
25    'USER'
26  )
27
28  # Need something to run.
29  # TODO(lliabraa): Make this output a usage string and exit (here and below).
30  assert(len(argv) > 0)
31
32  add_to_path = [];
33  first_entry = argv[0];
34  if first_entry.startswith('ADD_TO_PATH='):
35    argv = argv[1:];
36    add_to_path = first_entry.replace('ADD_TO_PATH=', '', 1).split(':')
37
38  # Still need something to run.
39  assert(len(argv) > 0)
40
41  clean_env = {}
42
43  # Pull over the whitelisted keys.
44  for key in env_key_whitelist:
45    val = os.environ.get(key, None)
46    if not val is None:
47      clean_env[key] = val
48
49  # Collect the developer dir as set via Xcode, defaulting it.
50  dev_prefix = os.environ.get('DEVELOPER_DIR', '/Developer/')
51  if dev_prefix[-1:] != '/':
52    dev_prefix += '/'
53
54  # Now pull in PATH, but remove anything Xcode might have added.
55  initial_path = os.environ.get('PATH', '')
56  filtered_chunks = \
57      [x for x in initial_path.split(':') if not x.startswith(dev_prefix)]
58  if filtered_chunks:
59    clean_env['PATH'] = ':'.join(add_to_path + filtered_chunks)
60
61  # Add any KEY=VALUE args before the command to the cleaned environment.
62  args = argv[:]
63  while '=' in args[0]:
64    (key, val) = args[0].split('=', 1)
65    clean_env[key] = val
66    args = args[1:]
67
68  # Still need something to run.
69  assert(len(args) > 0)
70
71  # Off it goes...
72  os.execvpe(args[0], args, clean_env)
73  # Should never get here, so return a distinctive, non-zero status code.
74  return 66
75
76if __name__ == '__main__':
77  sys.exit(Main(sys.argv[1:]))
78