blob: d04118f377da4fbc85d4034d2592e72cc5aad65a [file] [log] [blame]
// 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;
}
}