OLD | NEW |
1 # coding=utf-8 | 1 # coding=utf-8 |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Common code to manage .isolate format. | 6 """Common code to manage .isolate format. |
7 """ | 7 """ |
8 | 8 |
9 import logging | 9 import logging |
10 import os | 10 import os |
11 import posixpath | 11 import posixpath |
| 12 import re |
12 import sys | 13 import sys |
13 | 14 |
| 15 import trace_inputs |
| 16 |
| 17 |
| 18 PATH_VARIABLES = ('DEPTH', 'PRODUCT_DIR') |
14 | 19 |
15 KEY_TRACKED = 'isolate_dependency_tracked' | 20 KEY_TRACKED = 'isolate_dependency_tracked' |
16 KEY_UNTRACKED = 'isolate_dependency_untracked' | 21 KEY_UNTRACKED = 'isolate_dependency_untracked' |
17 | 22 |
18 _GIT_PATH = os.path.sep + '.git' + os.path.sep | 23 _GIT_PATH = os.path.sep + '.git' + os.path.sep |
19 _SVN_PATH = os.path.sep + '.svn' + os.path.sep | 24 _SVN_PATH = os.path.sep + '.svn' + os.path.sep |
20 | 25 |
21 | 26 |
22 def posix_relpath(path, root): | 27 def posix_relpath(path, root): |
23 """posix.relpath() that keeps trailing slash.""" | 28 """posix.relpath() that keeps trailing slash.""" |
(...skipping 23 matching lines...) Expand all Loading... |
47 'sunos5': 'solaris', | 52 'sunos5': 'solaris', |
48 'freebsd7': 'freebsd', | 53 'freebsd7': 'freebsd', |
49 'freebsd8': 'freebsd', | 54 'freebsd8': 'freebsd', |
50 } | 55 } |
51 return flavors.get(sys.platform, 'linux') | 56 return flavors.get(sys.platform, 'linux') |
52 | 57 |
53 | 58 |
54 def default_blacklist(f): | 59 def default_blacklist(f): |
55 """Filters unimportant files normally ignored.""" | 60 """Filters unimportant files normally ignored.""" |
56 return ( | 61 return ( |
57 f.endswith('.pyc') or | 62 f.endswith(('.pyc', 'testserver.log')) or |
58 _GIT_PATH in f or | 63 _GIT_PATH in f or |
59 _SVN_PATH in f) | 64 _SVN_PATH in f) |
60 | 65 |
61 | 66 |
62 def generate_dict(files, cwd_dir, product_dir): | 67 def classify_files(files): |
63 """Converts the list of files into a .isolate dictionary. | 68 """Converts the list of files into a .isolate 'variables' dictionary. |
64 | 69 |
65 Arguments: | 70 Arguments: |
66 - files: list of files to generate a dictionary out of. | 71 - files: list of files names to generate a dictionary out of. |
67 - cwd_dir: directory to base all the files from, relative to root_dir. | |
68 - product_dir: directory to replace with <(PRODUCT_DIR), relative to root_dir. | |
69 """ | 72 """ |
70 cwd_dir = cleanup_path(cwd_dir) | 73 files = list(files) |
71 product_dir = cleanup_path(product_dir) | 74 tracked = sorted(f for f in files if not f.endswith('/') and ' ' not in f) |
72 | 75 untracked = sorted(f for f in files if f.endswith('/') or ' ' in f) |
73 def fix(f): | |
74 """Bases the file on the most restrictive variable.""" | |
75 logging.debug('fix(%s)' % f) | |
76 # Important, GYP stores the files with / and not \. | |
77 f = f.replace(os.path.sep, '/') | |
78 if product_dir and f.startswith(product_dir): | |
79 return '<(PRODUCT_DIR)/%s' % f[len(product_dir):] | |
80 else: | |
81 # cwd_dir is usually the directory containing the gyp file. It may be | |
82 # empty if the whole directory containing the gyp file is needed. | |
83 return posix_relpath(f, cwd_dir) or './' | |
84 | |
85 corrected = [fix(f) for f in files] | |
86 tracked = [f for f in corrected if not f.endswith('/') and ' ' not in f] | |
87 untracked = [f for f in corrected if f.endswith('/') or ' ' in f] | |
88 variables = {} | 76 variables = {} |
89 if tracked: | 77 if tracked: |
90 variables[KEY_TRACKED] = tracked | 78 variables[KEY_TRACKED] = tracked |
91 if untracked: | 79 if untracked: |
92 variables[KEY_UNTRACKED] = untracked | 80 variables[KEY_UNTRACKED] = untracked |
93 return variables | 81 return variables |
94 | 82 |
95 | 83 |
| 84 def generate_simplified(files, root_dir, variables, relative_cwd): |
| 85 """Generates a clean and complete .isolate 'variables' dictionary. |
| 86 |
| 87 Cleans up and extracts only files from within root_dir then processes |
| 88 variables and relative_cwd. |
| 89 """ |
| 90 # Constants. |
| 91 # Skip log in PRODUCT_DIR. |
| 92 LOG_FILE = re.compile(r'^\<\(PRODUCT_DIR\)\/[^/]+\.log$') |
| 93 EXECUTABLE = re.compile( |
| 94 r'^(\<\(PRODUCT_DIR\)\/[^/\.]+)' + |
| 95 re.escape(variables.get('EXECUTABLE_SUFFIX', '')) + |
| 96 r'$') |
| 97 |
| 98 # Preparation work. |
| 99 relative_cwd = cleanup_path(relative_cwd) |
| 100 # Creates the right set of variables here. We only care about |
| 101 # PATH_VARIABLES. |
| 102 variables = dict( |
| 103 ('<(%s)' % k, variables[k]) for k in PATH_VARIABLES if k in variables) |
| 104 |
| 105 # Actual work: Process the files. |
| 106 files = trace_inputs.extract_directories(root_dir, files) |
| 107 files = (f.replace_variables(variables) for f in files) |
| 108 |
| 109 def fix(f): |
| 110 """Bases the file on the most restrictive variable.""" |
| 111 logging.debug('fix(%s)' % f) |
| 112 # Important, GYP stores the files with / and not \. |
| 113 f = f.replace(os.path.sep, '/') |
| 114 # If it's not already a variable. |
| 115 if not f.startswith('<'): |
| 116 # relative_cwd is usually the directory containing the gyp file. It may be |
| 117 # empty if the whole directory containing the gyp file is needed. |
| 118 f = posix_relpath(f, relative_cwd) or './' |
| 119 |
| 120 # Now strips off known files we want to ignore and to any specific mangling |
| 121 # as necessary. It's easier to do it here than generate a blacklist. |
| 122 match = EXECUTABLE.match(f) |
| 123 if match: |
| 124 return match.group(1) + '<(EXECUTABLE_SUFFIX)' |
| 125 if LOG_FILE.match(f): |
| 126 return None |
| 127 return f |
| 128 |
| 129 return classify_files(filter(None, (fix(f.path) for f in files))) |
| 130 |
| 131 |
| 132 def generate_isolate(files, root_dir, variables, relative_cwd): |
| 133 """Generates a clean and complete .isolate file.""" |
| 134 result = generate_simplified(files, root_dir, variables, relative_cwd) |
| 135 return { |
| 136 'conditions': [ |
| 137 ['OS=="%s"' % get_flavor(), { |
| 138 'variables': result, |
| 139 }], |
| 140 ], |
| 141 } |
| 142 |
| 143 |
96 def pretty_print(variables, stdout): | 144 def pretty_print(variables, stdout): |
97 """Outputs a gyp compatible list from the decoded variables. | 145 """Outputs a gyp compatible list from the decoded variables. |
98 | 146 |
99 Similar to pprint.print() but with NIH syndrome. | 147 Similar to pprint.print() but with NIH syndrome. |
100 """ | 148 """ |
101 # Order the dictionary keys by these keys in priority. | 149 # Order the dictionary keys by these keys in priority. |
102 ORDER = ( | 150 ORDER = ( |
103 'variables', 'condition', 'command', 'relative_cwd', 'read_only', | 151 'variables', 'condition', 'command', 'relative_cwd', 'read_only', |
104 KEY_TRACKED, KEY_UNTRACKED) | 152 KEY_TRACKED, KEY_UNTRACKED) |
105 | 153 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 stdout.write( | 202 stdout.write( |
155 '\'%s\',\n' % item.replace('\\', '\\\\').replace('\'', '\\\'')) | 203 '\'%s\',\n' % item.replace('\\', '\\\\').replace('\'', '\\\'')) |
156 elif item in (True, False, None): | 204 elif item in (True, False, None): |
157 stdout.write('%s\n' % item) | 205 stdout.write('%s\n' % item) |
158 else: | 206 else: |
159 assert False, item | 207 assert False, item |
160 | 208 |
161 stdout.write('{\n') | 209 stdout.write('{\n') |
162 loop_dict(' ', variables) | 210 loop_dict(' ', variables) |
163 stdout.write('}\n') | 211 stdout.write('}\n') |
OLD | NEW |