| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 #!/usr/bin/env python |  | 
| 2 # |  | 
| 3 # Copyright 2015 The Chromium Authors. All rights reserved. |  | 
| 4 # Use of this source code is governed by a BSD-style license that can be |  | 
| 5 # found in the LICENSE file. |  | 
| 6 |  | 
| 7 """Utility for dart_pkg and dart_pkg_app rules""" |  | 
| 8 |  | 
| 9 import argparse |  | 
| 10 import errno |  | 
| 11 import json |  | 
| 12 import os |  | 
| 13 import shutil |  | 
| 14 import subprocess |  | 
| 15 import sys |  | 
| 16 |  | 
| 17 USE_LINKS = sys.platform != "win32" |  | 
| 18 |  | 
| 19 DART_ANALYZE = os.path.join(os.path.dirname(os.path.abspath(__file__)), |  | 
| 20                             "dart_analyze.py") |  | 
| 21 |  | 
| 22 def dart_filter(path): |  | 
| 23   if os.path.isdir(path): |  | 
| 24     return True |  | 
| 25   _, ext = os.path.splitext(path) |  | 
| 26   # .dart includes '.mojom.dart' |  | 
| 27   return ext == '.dart' |  | 
| 28 |  | 
| 29 |  | 
| 30 def ensure_dir_exists(path): |  | 
| 31   abspath = os.path.abspath(path) |  | 
| 32   if not os.path.exists(abspath): |  | 
| 33     os.makedirs(abspath) |  | 
| 34 |  | 
| 35 |  | 
| 36 def has_pubspec_yaml(paths): |  | 
| 37   for path in paths: |  | 
| 38     _, filename = os.path.split(path) |  | 
| 39     if 'pubspec.yaml' == filename: |  | 
| 40       return True |  | 
| 41   return False |  | 
| 42 |  | 
| 43 |  | 
| 44 def link(from_root, to_root): |  | 
| 45   ensure_dir_exists(os.path.dirname(to_root)) |  | 
| 46   try: |  | 
| 47     os.unlink(to_root) |  | 
| 48   except OSError as e: |  | 
| 49     if e.errno == errno.ENOENT: |  | 
| 50       pass |  | 
| 51 |  | 
| 52   try: |  | 
| 53     os.symlink(from_root, to_root) |  | 
| 54   except OSError as e: |  | 
| 55     if e.errno == errno.EEXIST: |  | 
| 56       pass |  | 
| 57 |  | 
| 58 |  | 
| 59 def copy(from_root, to_root, filter_func=None): |  | 
| 60   if not os.path.exists(from_root): |  | 
| 61     return |  | 
| 62   if os.path.isfile(from_root): |  | 
| 63     ensure_dir_exists(os.path.dirname(to_root)) |  | 
| 64     shutil.copy(from_root, to_root) |  | 
| 65     return |  | 
| 66 |  | 
| 67   ensure_dir_exists(to_root) |  | 
| 68 |  | 
| 69   for root, dirs, files in os.walk(from_root): |  | 
| 70     # filter_func expects paths not names, so wrap it to make them absolute. |  | 
| 71     wrapped_filter = None |  | 
| 72     if filter_func: |  | 
| 73       wrapped_filter = lambda name: filter_func(os.path.join(root, name)) |  | 
| 74 |  | 
| 75     for name in filter(wrapped_filter, files): |  | 
| 76       from_path = os.path.join(root, name) |  | 
| 77       root_rel_path = os.path.relpath(from_path, from_root) |  | 
| 78       to_path = os.path.join(to_root, root_rel_path) |  | 
| 79       to_dir = os.path.dirname(to_path) |  | 
| 80       if not os.path.exists(to_dir): |  | 
| 81         os.makedirs(to_dir) |  | 
| 82       shutil.copy(from_path, to_path) |  | 
| 83 |  | 
| 84     dirs[:] = filter(wrapped_filter, dirs) |  | 
| 85 |  | 
| 86 |  | 
| 87 def copy_or_link(from_root, to_root, filter_func=None): |  | 
| 88   if USE_LINKS: |  | 
| 89     link(from_root, to_root) |  | 
| 90   else: |  | 
| 91     copy(from_root, to_root, filter_func) |  | 
| 92 |  | 
| 93 |  | 
| 94 def link_if_possible(from_root, to_root): |  | 
| 95   if USE_LINKS: |  | 
| 96     link(from_root, to_root) |  | 
| 97 |  | 
| 98 |  | 
| 99 def remove_if_exists(path): |  | 
| 100   try: |  | 
| 101     os.remove(path) |  | 
| 102   except OSError as e: |  | 
| 103     if e.errno != errno.ENOENT: |  | 
| 104       raise |  | 
| 105 |  | 
| 106 |  | 
| 107 def list_files(from_root, filter_func=None): |  | 
| 108   file_list = [] |  | 
| 109   for root, dirs, files in os.walk(from_root): |  | 
| 110     # filter_func expects paths not names, so wrap it to make them absolute. |  | 
| 111     wrapped_filter = None |  | 
| 112     if filter_func: |  | 
| 113       wrapped_filter = lambda name: filter_func(os.path.join(root, name)) |  | 
| 114     for name in filter(wrapped_filter, files): |  | 
| 115       path = os.path.join(root, name) |  | 
| 116       file_list.append(path) |  | 
| 117     dirs[:] = filter(wrapped_filter, dirs) |  | 
| 118   return file_list |  | 
| 119 |  | 
| 120 |  | 
| 121 def remove_broken_symlink(path): |  | 
| 122   try: |  | 
| 123     link_path = os.readlink(path) |  | 
| 124   except OSError as e: |  | 
| 125     # Path was not a symlink. |  | 
| 126     if e.errno == errno.EINVAL: |  | 
| 127       pass |  | 
| 128   else: |  | 
| 129     if not os.path.exists(link_path): |  | 
| 130       remove_if_exists(path) |  | 
| 131 |  | 
| 132 |  | 
| 133 def remove_broken_symlinks(root_dir): |  | 
| 134   for current_dir, _, child_files in os.walk(root_dir): |  | 
| 135     for filename in child_files: |  | 
| 136       path = os.path.join(current_dir, filename) |  | 
| 137       remove_broken_symlink(path) |  | 
| 138 |  | 
| 139 |  | 
| 140 def analyze_entrypoints(dart_sdk, package_root, entrypoints): |  | 
| 141   cmd = [ "python", DART_ANALYZE ] |  | 
| 142   cmd.append("--dart-sdk") |  | 
| 143   cmd.append(dart_sdk) |  | 
| 144   cmd.append("--entrypoints") |  | 
| 145   cmd.extend(entrypoints) |  | 
| 146   cmd.append("--package-root") |  | 
| 147   cmd.append(package_root) |  | 
| 148   cmd.append("--no-hints") |  | 
| 149   try: |  | 
| 150     subprocess.check_output(cmd, stderr=subprocess.STDOUT) |  | 
| 151   except subprocess.CalledProcessError as e: |  | 
| 152     print('Failed analyzing %s' % entrypoints) |  | 
| 153     print(e.output) |  | 
| 154     return e.returncode |  | 
| 155   return 0 |  | 
| 156 |  | 
| 157 |  | 
| 158 def main(): |  | 
| 159   parser = argparse.ArgumentParser(description='Generate a dart-pkg') |  | 
| 160   parser.add_argument('--dart-sdk', |  | 
| 161                       action='store', |  | 
| 162                       metavar='dart_sdk', |  | 
| 163                       help='Path to the Dart SDK.') |  | 
| 164   parser.add_argument('--package-name', |  | 
| 165                       action='store', |  | 
| 166                       metavar='package_name', |  | 
| 167                       help='Name of package', |  | 
| 168                       required=True) |  | 
| 169   parser.add_argument('--pkg-directory', |  | 
| 170                       metavar='pkg_directory', |  | 
| 171                       help='Directory where dart_pkg should go', |  | 
| 172                       required=True) |  | 
| 173   parser.add_argument('--package-root', |  | 
| 174                       metavar='package_root', |  | 
| 175                       help='packages/ directory', |  | 
| 176                       required=True) |  | 
| 177   parser.add_argument('--stamp-file', |  | 
| 178                       metavar='stamp_file', |  | 
| 179                       help='timestamp file', |  | 
| 180                       required=True) |  | 
| 181   parser.add_argument('--entries-file', |  | 
| 182                       metavar='entries_file', |  | 
| 183                       help='script entries file', |  | 
| 184                       required=True) |  | 
| 185   parser.add_argument('--package-sources', |  | 
| 186                       metavar='package_sources', |  | 
| 187                       help='Package sources', |  | 
| 188                       nargs='+') |  | 
| 189   parser.add_argument('--package-entrypoints', |  | 
| 190                       metavar='package_entrypoints', |  | 
| 191                       help='Package entry points for analyzer', |  | 
| 192                       nargs='*', |  | 
| 193                       default=[]) |  | 
| 194   parser.add_argument('--sdk-ext-directories', |  | 
| 195                       metavar='sdk_ext_directories', |  | 
| 196                       help='Directory containing .dart sources', |  | 
| 197                       nargs='*', |  | 
| 198                       default=[]) |  | 
| 199   parser.add_argument('--sdk-ext-files', |  | 
| 200                       metavar='sdk_ext_files', |  | 
| 201                       help='List of .dart files that are part of of sdk_ext.', |  | 
| 202                       nargs='*', |  | 
| 203                       default=[]) |  | 
| 204   parser.add_argument('--sdk-ext-mappings', |  | 
| 205                       metavar='sdk_ext_mappings', |  | 
| 206                       help='Mappings for SDK extension libraries.', |  | 
| 207                       nargs='*', |  | 
| 208                       default=[]) |  | 
| 209   parser.add_argument('--read_only', |  | 
| 210                       action='store_true', |  | 
| 211                       dest='read_only', |  | 
| 212                       help='Package is a read only package.', |  | 
| 213                       default=False) |  | 
| 214   args = parser.parse_args() |  | 
| 215 |  | 
| 216   # We must have a pubspec.yaml. |  | 
| 217   assert has_pubspec_yaml(args.package_sources) |  | 
| 218 |  | 
| 219   target_dir = os.path.join(args.pkg_directory, args.package_name) |  | 
| 220   target_packages_dir = os.path.join(target_dir, 'packages') |  | 
| 221   lib_path = os.path.join(target_dir, "lib") |  | 
| 222   ensure_dir_exists(lib_path) |  | 
| 223 |  | 
| 224   mappings = {} |  | 
| 225   for mapping in args.sdk_ext_mappings: |  | 
| 226     library, path = mapping.split(',', 1) |  | 
| 227     mappings[library] = '../sdk_ext/%s' % path |  | 
| 228 |  | 
| 229   sdkext_path = os.path.join(lib_path, '_sdkext') |  | 
| 230   if mappings: |  | 
| 231     with open(sdkext_path, 'w') as stream: |  | 
| 232       json.dump(mappings, stream, sort_keys=True, |  | 
| 233                 indent=2, separators=(',', ': ')) |  | 
| 234   else: |  | 
| 235     remove_if_exists(sdkext_path) |  | 
| 236 |  | 
| 237   # Copy or symlink package sources into pkg directory. |  | 
| 238   common_source_prefix = os.path.dirname(os.path.commonprefix( |  | 
| 239       args.package_sources)) |  | 
| 240   for source in args.package_sources: |  | 
| 241     relative_source = os.path.relpath(source, common_source_prefix) |  | 
| 242     target = os.path.join(target_dir, relative_source) |  | 
| 243     copy_or_link(source, target) |  | 
| 244 |  | 
| 245   entrypoint_targets = [] |  | 
| 246   for source in args.package_entrypoints: |  | 
| 247     relative_source = os.path.relpath(source, common_source_prefix) |  | 
| 248     target = os.path.join(target_dir, relative_source) |  | 
| 249     copy_or_link(source, target) |  | 
| 250     entrypoint_targets.append(target) |  | 
| 251 |  | 
| 252   # Copy sdk-ext sources into pkg directory |  | 
| 253   sdk_ext_dir = os.path.join(target_dir, 'sdk_ext') |  | 
| 254   for directory in args.sdk_ext_directories: |  | 
| 255     sdk_ext_sources = list_files(directory, dart_filter) |  | 
| 256     common_prefix = os.path.commonprefix(sdk_ext_sources) |  | 
| 257     for source in sdk_ext_sources: |  | 
| 258       relative_source = os.path.relpath(source, common_prefix) |  | 
| 259       target = os.path.join(sdk_ext_dir, relative_source) |  | 
| 260       copy_or_link(source, target) |  | 
| 261 |  | 
| 262   common_source_prefix = os.path.dirname(os.path.commonprefix( |  | 
| 263       args.sdk_ext_files)) |  | 
| 264   for source in args.sdk_ext_files: |  | 
| 265     relative_source = os.path.relpath(source, common_source_prefix) |  | 
| 266     target = os.path.join(sdk_ext_dir, relative_source) |  | 
| 267     copy_or_link(source, target) |  | 
| 268 |  | 
| 269   # Symlink packages/ |  | 
| 270   package_path = os.path.join(args.package_root, args.package_name) |  | 
| 271   link(lib_path, package_path) |  | 
| 272 |  | 
| 273   # Link dart-pkg/$package/packages to dart-pkg/packages |  | 
| 274   link_if_possible(args.package_root, target_packages_dir) |  | 
| 275 |  | 
| 276   # Remove any broken symlinks in target_dir and package root. |  | 
| 277   remove_broken_symlinks(target_dir) |  | 
| 278   remove_broken_symlinks(args.package_root) |  | 
| 279 |  | 
| 280   # If any entrypoints are defined, write them to disk so that the analyzer |  | 
| 281   # test can find them. |  | 
| 282   with open(args.entries_file, 'w') as f: |  | 
| 283     for entrypoint in entrypoint_targets: |  | 
| 284       f.write(entrypoint + '\n') |  | 
| 285 |  | 
| 286   # Write stamp file. |  | 
| 287   with open(args.stamp_file, 'w'): |  | 
| 288     pass |  | 
| 289 |  | 
| 290   return 0 |  | 
| 291 |  | 
| 292 if __name__ == '__main__': |  | 
| 293   sys.exit(main()) |  | 
| OLD | NEW | 
|---|