| # Copyright 2013 The Flutter Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # This python script uses `pub get --offline` to fill in |
| # .dart_tool/package_config.json files for Dart packages in the tree whose |
| # dependencies should be entirely resolved without requesting data from pub.dev. |
| # This allows us to be certain that the Dart code we are pulling for these |
| # packages is explicitly fetched by `gclient sync` rather than implicitly |
| # fetched by pub version solving, and pub fetching transitive dependencies. |
| |
| import json |
| import os |
| import subprocess |
| import sys |
| |
| SRC_ROOT = os.path.dirname( |
| os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| ) |
| ENGINE_DIR = os.path.join(SRC_ROOT, 'flutter') |
| |
| ALL_PACKAGES = [ |
| os.path.join(ENGINE_DIR, 'ci'), |
| os.path.join(ENGINE_DIR, 'flutter_frontend_server'), |
| os.path.join(ENGINE_DIR, 'impeller', 'golden_tests_harvester'), |
| os.path.join(ENGINE_DIR, 'impeller', 'tessellator', 'dart'), |
| os.path.join(ENGINE_DIR, 'shell', 'vmservice'), |
| os.path.join(ENGINE_DIR, 'testing', 'android_background_image'), |
| os.path.join(ENGINE_DIR, 'testing', 'benchmark'), |
| os.path.join(ENGINE_DIR, 'testing', 'dart'), |
| os.path.join(ENGINE_DIR, 'testing', 'litetest'), |
| os.path.join(ENGINE_DIR, 'testing', 'scenario_app'), |
| os.path.join(ENGINE_DIR, 'testing', 'skia_gold_client'), |
| os.path.join(ENGINE_DIR, 'testing', 'smoke_test_failure'), |
| os.path.join(ENGINE_DIR, 'testing', 'symbols'), |
| os.path.join(ENGINE_DIR, 'tools', 'android_lint'), |
| os.path.join(ENGINE_DIR, 'tools', 'api_check'), |
| os.path.join(ENGINE_DIR, 'tools', 'build_bucket_golden_scraper'), |
| os.path.join(ENGINE_DIR, 'tools', 'clang_tidy'), |
| os.path.join(ENGINE_DIR, 'tools', 'const_finder'), |
| os.path.join(ENGINE_DIR, 'tools', 'gen_web_locale_keymap'), |
| os.path.join(ENGINE_DIR, 'tools', 'githooks'), |
| os.path.join(ENGINE_DIR, 'tools', 'licenses'), |
| os.path.join(ENGINE_DIR, 'tools', 'path_ops', 'dart'), |
| os.path.join(ENGINE_DIR, 'tools', 'pkg', 'engine_repo_tools'), |
| ] |
| |
| |
| def fetch_package(pub, package): |
| try: |
| subprocess.check_output(pub, cwd=package, stderr=subprocess.STDOUT) |
| except subprocess.CalledProcessError as err: |
| print( |
| '"%s" failed in "%s" with status %d:\n%s' % |
| (' '.join(pub), package, err.returncode, err.output) |
| ) |
| return 1 |
| return 0 |
| |
| |
| def check_package(package): |
| package_config = os.path.join(package, '.dart_tool', 'package_config.json') |
| pub_count = 0 |
| with open(package_config) as config_file: |
| data_dict = json.load(config_file) |
| packages_data = data_dict['packages'] |
| for package_data in packages_data: |
| package_uri = package_data['rootUri'] |
| package_name = package_data['name'] |
| if '.pub-cache' in package_uri and 'pub.dartlang.org' in package_uri: |
| print('Error: package "%s" was fetched from pub' % package_name) |
| pub_count = pub_count + 1 |
| if pub_count > 0: |
| print( |
| 'Error: %d packages were fetched from pub for %s' % |
| (pub_count, package) |
| ) |
| print( |
| 'Please fix the pubspec.yaml for %s ' |
| 'so that all dependencies are path dependencies' % package |
| ) |
| return pub_count |
| |
| |
| EXCLUDED_DIRS = [ |
| os.path.join(ENGINE_DIR, 'lib'), |
| os.path.join(ENGINE_DIR, 'prebuilts'), |
| os.path.join(ENGINE_DIR, 'shell', 'platform', 'fuchsia'), |
| os.path.join(ENGINE_DIR, 'shell', 'vmservice'), |
| os.path.join(ENGINE_DIR, 'sky', 'packages'), |
| os.path.join(ENGINE_DIR, 'third_party'), |
| os.path.join(ENGINE_DIR, 'web_sdk'), |
| ] |
| |
| |
| # Returns a list of paths to directories containing pubspec.yaml files that |
| # are not listed in ALL_PACKAGES. Directory trees under the paths in |
| # EXCLUDED_DIRS are skipped. |
| def find_unlisted_packages(): |
| unlisted = [] |
| for root, dirs, files in os.walk(ENGINE_DIR): |
| excluded = [] |
| for dirname in dirs: |
| full_dirname = os.path.join(root, dirname) |
| if full_dirname in EXCLUDED_DIRS: |
| excluded.append(dirname) |
| for exclude in excluded: |
| dirs.remove(exclude) |
| for filename in files: |
| if filename == 'pubspec.yaml': |
| if root not in ALL_PACKAGES: |
| unlisted.append(root) |
| return unlisted |
| |
| |
| def main(): |
| dart_sdk_bin = os.path.join( |
| SRC_ROOT, 'third_party', 'dart', 'tools', 'sdks', 'dart-sdk', 'bin' |
| ) |
| |
| # Ensure all relevant packages are listed in ALL_PACKAGES. |
| unlisted = find_unlisted_packages() |
| if len(unlisted) > 0: |
| for pkg in unlisted: |
| print( |
| 'The Dart package "%s" must be checked in flutter/tools/pub_get_offline.py' |
| % pkg |
| ) |
| return 1 |
| |
| dart = 'dart' |
| if os.name == 'nt': |
| dart = 'dart.exe' |
| pubcmd = [os.path.join(dart_sdk_bin, dart), 'pub', 'get', '--offline'] |
| |
| pub_count = 0 |
| for package in ALL_PACKAGES: |
| if fetch_package(pubcmd, package) != 0: |
| return 1 |
| pub_count = pub_count + check_package(package) |
| |
| if pub_count > 0: |
| return 1 |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |