| // Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| import 'dart:io'; |
| |
| /// This script creates monorepo's DEPS file, which is based on |
| /// flutter/engine/DEPS. Changes to Dart dependencies from |
| /// dart-lang/sdk/DEPS are merged into engine/DEPS, and the |
| /// paths of dependencies are changed, to put the engine checkout |
| /// at the path engine/src/flutter in the gclient solution. |
| /// |
| /// The script does not use any package dependencies, so it can |
| /// be run without running 'dart pub get' first. |
| |
| void main(List<String> args) async { |
| final root = Platform.script.resolve('../..'); |
| if (root != Directory.current.uri) { |
| print('create_monorepo_deps must be run from the root of ' |
| 'a monorepo gclient checkout.'); |
| exit(1); |
| } |
| |
| // Arguments are like --flutter=[40-character commit hash] |
| final hashArgument = RegExp(r'--(\w*)=(\w{40})'); |
| final matchedArguments = [ |
| for (final arg in args) hashArgument.matchAsPrefix(arg) |
| ]; |
| final hashes = { |
| for (final match in matchedArguments) |
| if (match != null) match[1]!: match[2]! |
| }; |
| |
| final engineDeps = File.fromUri(root.resolve('engine/src/flutter/DEPS')); |
| final monorepoDeps = File.fromUri(root.resolve('monorepo/DEPS')); |
| |
| await engineDeps.copy(monorepoDeps.path); |
| final result = await Process.run('python3', [ |
| root |
| .resolve('engine/src/tools/dart/create_updated_flutter_deps.py') |
| .toFilePath(), |
| '-f', |
| monorepoDeps.path |
| ]); |
| if (result.exitCode != 0) { |
| print('create_updated_flutter_deps.py -f ${monorepoDeps.path} failed'); |
| print(' exit code: ${result.exitCode}'); |
| print(result.stdout); |
| print(result.stderr); |
| exit(1); |
| } |
| |
| final deps = await monorepoDeps.readAsLines(); |
| commentDartRevision(deps); |
| removeDartDependency(deps); |
| stopSdkDownload(deps); |
| addPinnedRepositories(deps, hashes); |
| moveDepsToEngine(deps); |
| |
| await monorepoDeps.writeAsString(deps.join('\n') + '\n', flush: true); |
| } |
| |
| /// Add comment to the 'dart_revision' variable |
| /// that it is unused in the monorepo DEPS. |
| /// The download prebuild SDK steps still use it, but they are disabled. |
| void commentDartRevision(List<String> deps) { |
| final firstCommentStart = ' # When updating the Dart revision,'; |
| final dartRevisionLineStart = " 'dart_revision':"; |
| var index = deps.indexWhere((line) => line.startsWith(firstCommentStart)); |
| if (index != -1) { |
| deps.insert( |
| index, ' # The dart_revision variable is not used in monorepo.'); |
| } |
| index = deps.indexWhere((line) => line.startsWith(dartRevisionLineStart)); |
| if (index != -1) { |
| deps[index] = "$dartRevisionLineStart 'unused',"; |
| } |
| } |
| |
| void removeDartDependency(List<String> deps) { |
| final index = deps.indexOf(" 'src/third_party/dart':"); |
| if (index == -1 || !deps[index + 1].startsWith(" Var('dart_git')")) { |
| print('Could not remove the Dart dependency'); |
| exit(1); |
| } |
| deps.removeRange(index, index + 2); |
| } |
| |
| void stopSdkDownload(List<String> deps) { |
| final downloadLine = " 'download_dart_sdk': True,"; |
| final noDownloadLine = " 'download_dart_sdk': False,"; |
| |
| final index = deps.indexOf(downloadLine); |
| if (index == -1) { |
| print("Could not modify 'download_dart_sdk'"); |
| exit(1); |
| } |
| deps[index] = noDownloadLine; |
| } |
| |
| /// Adds pinned dependencies for flutter/flutter, flutter/engine, and Dart SDK. |
| void addPinnedRepositories(List<String> deps, Map<String, String> hashes) { |
| final depsIndex = deps.indexOf('deps = {'); |
| if (depsIndex == -1 || |
| depsIndex + 2 > deps.length || |
| !deps[depsIndex + 1] |
| .startsWith(" 'src': 'https://github.com/flutter/buildroot.git'") || |
| hashes['dart'] == null || |
| hashes['engine'] == null || |
| hashes['flutter'] == null) { |
| print('Could not add dart and flutter dependencies to DEPS'); |
| exit(1); |
| } |
| deps.insertAll(depsIndex + 2, [ |
| '', |
| " 'src/flutter': Var('flutter_git') + '/mirrors/engine' + " |
| "'@' + '${hashes['engine']!}',", |
| '', |
| " 'src/third_party/dart': Var('dart_git') + '/sdk' + '@' + " |
| "'${hashes['dart']!}',", |
| '', |
| " 'flutter': Var('flutter_git') + '/mirrors/flutter' + '@' + " |
| "'${hashes['flutter']}',", |
| ]); |
| } |
| |
| /// Move the dependencies that engine DEPS checks out into src/ |
| /// to the equivalent path in engine/src/. |
| void moveDepsToEngine(List<String> deps) { |
| final depsIndex = deps.indexOf('deps = {'); |
| var recursedepsIndex = deps.indexOf('recursedeps = ['); |
| final hooksIndex = deps.indexOf('hooks = ['); |
| if (depsIndex == -1) { |
| print("Could not relocate dependencies. Could not find deps section"); |
| exit(1); |
| } |
| if (recursedepsIndex == -1) { |
| // No recursedeps section. |
| recursedepsIndex = hooksIndex; |
| } |
| if (hooksIndex == -1) { |
| print("Could not relocate dependencies. Could not find hooks section"); |
| exit(1); |
| } |
| |
| final preDepsSrcLine = RegExp("^gclient_gn_args_file = 'src/third_part"); |
| for (var i = 0; i < depsIndex; i++) { |
| if (preDepsSrcLine.hasMatch(deps[i])) { |
| deps[i] = deps[i].replaceFirst('src', 'engine/src'); |
| } |
| } |
| |
| var count = 0; |
| final srcDependencySrcLine = RegExp(r"^\s+'src(/[\w-]+)*':"); |
| for (var i = depsIndex; i < recursedepsIndex; i++) { |
| if (srcDependencySrcLine.hasMatch(deps[i])) { |
| deps[i] = deps[i].replaceFirst('src', 'engine/src'); |
| count++; |
| } |
| } |
| print('Moved $count dependencies to engine/src'); |
| |
| final recursedepsSrcLine = RegExp("^ 'src/"); |
| for (var i = recursedepsIndex; i < hooksIndex; i++) { |
| if (recursedepsSrcLine.hasMatch(deps[i])) { |
| deps[i] = deps[i].replaceFirst(" 'src/", " 'engine/src/"); |
| } |
| } |
| final hooksSrcLine = RegExp(" 'src/"); |
| for (var i = hooksIndex; i < deps.length; i++) { |
| if (hooksSrcLine.hasMatch(deps[i])) { |
| deps[i] = deps[i].replaceAll(" 'src/", " 'engine/src/"); |
| } |
| } |
| } |