| // 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. |
| |
| import 'package:flutter_migrate/src/base/file_system.dart'; |
| import 'package:flutter_migrate/src/base/io.dart'; |
| import 'package:flutter_migrate/src/base/logger.dart'; |
| import 'package:flutter_migrate/src/base/project.dart'; |
| import 'package:flutter_migrate/src/base/signals.dart'; |
| import 'package:flutter_migrate/src/base/terminal.dart'; |
| import 'package:flutter_migrate/src/update_locks.dart'; |
| import 'package:flutter_migrate/src/utils.dart'; |
| import 'package:process/process.dart'; |
| import 'package:yaml/yaml.dart'; |
| |
| import 'src/common.dart'; |
| import 'src/test_utils.dart'; |
| |
| void main() { |
| late FileSystem fileSystem; |
| late BufferLogger logger; |
| late MigrateUtils utils; |
| late Directory currentDir; |
| late FlutterProject flutterProject; |
| late Terminal terminal; |
| late ProcessManager processManager; |
| |
| setUp(() async { |
| fileSystem = LocalFileSystem.test(signals: LocalSignals.instance); |
| currentDir = createResolvedTempDirectorySync('current_app.'); |
| logger = BufferLogger.test(); |
| terminal = Terminal.test(); |
| utils = MigrateUtils( |
| logger: logger, |
| fileSystem: fileSystem, |
| processManager: const LocalProcessManager(), |
| ); |
| final FlutterProjectFactory flutterFactory = FlutterProjectFactory(); |
| flutterProject = flutterFactory.fromDirectory(currentDir); |
| processManager = const LocalProcessManager(); |
| }); |
| |
| tearDown(() async { |
| tryToDelete(currentDir); |
| }); |
| |
| testWithoutContext('updates pubspec locks', () async { |
| final ProcessResult result = await processManager.run(<String>[ |
| 'flutter', |
| 'create', |
| currentDir.absolute.path, |
| '--project-name=testproject' |
| ]); |
| expect(result.exitCode, 0); |
| final File pubspec = currentDir.childFile('pubspec.yaml'); |
| pubspec.writeAsStringSync(''' |
| name: testproject |
| description: A test flutter project. |
| |
| environment: |
| sdk: ">=2.17.0-0 <3.0.0" |
| |
| dependencies: |
| flutter: |
| sdk: flutter |
| |
| characters: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| collection: 1.15.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| js: 0.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| material_color_utilities: 0.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| meta: 1.7.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| vector_math: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" |
| |
| flutter: |
| uses-material-design: true |
| |
| # PUBSPEC CHECKSUM: 1b91 |
| |
| ''', flush: true); |
| await updatePubspecDependencies(flutterProject, utils, logger, terminal, |
| force: true); |
| final YamlMap pubspecYaml = loadYaml(pubspec.readAsStringSync()) as YamlMap; |
| final YamlMap dependenciesMap = pubspecYaml['dependencies'] as YamlMap; |
| expect( |
| _VersionCode.fromString(dependenciesMap['characters'] as String) > |
| _VersionCode.fromString('1.2.0'), |
| true); |
| expect( |
| _VersionCode.fromString(dependenciesMap['collection'] as String) > |
| _VersionCode.fromString('1.15.0'), |
| true); |
| expect( |
| _VersionCode.fromString(dependenciesMap['js'] as String) > |
| _VersionCode.fromString('0.6.3'), |
| true); |
| expect( |
| _VersionCode.fromString( |
| dependenciesMap['material_color_utilities'] as String) > |
| _VersionCode.fromString('0.1.0'), |
| true); |
| expect( |
| _VersionCode.fromString(dependenciesMap['meta'] as String) > |
| _VersionCode.fromString('1.7.0'), |
| true); |
| }); |
| |
| testWithoutContext('updates gradle locks', () async { |
| final ProcessResult result = await processManager.run(<String>[ |
| 'flutter', |
| 'create', |
| currentDir.absolute.path, |
| '--project-name=testproject' |
| ]); |
| expect(result.exitCode, 0); |
| final File projectAppLock = |
| currentDir.childDirectory('android').childFile('project-app.lockfile'); |
| final File buildGradle = |
| currentDir.childDirectory('android').childFile('build.gradle'); |
| final File gradleProperties = |
| currentDir.childDirectory('android').childFile('gradle.properties'); |
| gradleProperties.writeAsStringSync(''' |
| org.gradle.daemon=false |
| org.gradle.jvmargs=-Xmx1536M |
| android.useAndroidX=true |
| android.enableJetifier=true |
| ''', flush: true); |
| final File projectAppLockBackup = currentDir |
| .childDirectory('android') |
| .childFile('project-app.lockfile_backup_0'); |
| expect(projectAppLockBackup.existsSync(), false); |
| projectAppLock.createSync(recursive: true); |
| projectAppLock.writeAsStringSync(''' |
| # This is a Gradle generated file for dependency locking. |
| # Manual edits can break the build and are not advised. |
| # This file is expected to be part of source control. |
| androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath |
| androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath |
| androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath |
| |
| ''', flush: true); |
| buildGradle.writeAsStringSync(r''' |
| buildscript { |
| ext.kotlin_version = '1.5.31' |
| repositories { |
| google() |
| mavenCentral() |
| } |
| |
| dependencies { |
| classpath 'com.android.tools.build:gradle:7.2.0' |
| classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |
| } |
| |
| configurations.classpath { |
| resolutionStrategy.activateDependencyLocking() |
| } |
| } |
| |
| allprojects { |
| repositories { |
| google() |
| mavenCentral() |
| } |
| } |
| |
| rootProject.buildDir = '../build' |
| |
| subprojects { |
| project.buildDir = "${rootProject.buildDir}/${project.name}" |
| } |
| subprojects { |
| project.evaluationDependsOn(':app') |
| dependencyLocking { |
| ignoredDependencies.add('io.flutter:*') |
| lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile") |
| if (!project.hasProperty('local-engine-repo')) { |
| lockAllConfigurations() |
| } |
| } |
| } |
| |
| ''', flush: true); |
| expect( |
| currentDir |
| .childDirectory('android') |
| .childFile('gradlew.bat') |
| .existsSync(), |
| true); |
| final Directory dotGradle = |
| currentDir.childDirectory('android').childDirectory('.gradle'); |
| tryToDelete(dotGradle); |
| await updateGradleDependencyLocking( |
| flutterProject, utils, logger, terminal, true, fileSystem, |
| force: true); |
| expect(projectAppLockBackup.existsSync(), true); |
| expect(projectAppLock.existsSync(), true); |
| expect(projectAppLock.readAsStringSync(), |
| contains('# This is a Gradle generated file for dependency locking.')); |
| expect(projectAppLock.readAsStringSync(), |
| contains('# Manual edits can break the build and are not advised.')); |
| expect(projectAppLock.readAsStringSync(), |
| contains('# This file is expected to be part of source control.')); |
| }, timeout: const Timeout(Duration(seconds: 500)), skip: true); |
| } |
| |
| class _VersionCode extends Comparable<_VersionCode> { |
| _VersionCode(this.first, this.second, this.third, this.caret); |
| _VersionCode.fromString(String str) |
| : first = 0, |
| second = 0, |
| third = 0, |
| caret = 0 { |
| caret = str.contains('^') ? 1 : 0; |
| str = str.replaceAll('^', ''); |
| final List<String> splits = str.split('.'); |
| assert(splits.length == 3); |
| |
| first = int.parse(splits[0]); |
| second = int.parse(splits[1]); |
| third = int.parse(splits[2]); |
| } |
| |
| int caret; |
| int first; |
| int second; |
| int third; |
| |
| bool operator >(_VersionCode other) { |
| return compareTo(other) > 0; |
| } |
| |
| bool operator <(_VersionCode other) { |
| return !(this > other); |
| } |
| |
| @override |
| int compareTo(_VersionCode other) { |
| final int value = first * 10000000 + second * 100000 + third + caret; |
| final int otherValue = |
| other.first * 10000000 + other.second * 100000 + other.third + caret; |
| return value - otherValue; |
| } |
| } |