diff --git a/packages/flutter_tools/lib/src/commands/migrate.dart b/packages/flutter_tools/lib/src/commands/migrate.dart deleted file mode 100644 index d2c71fb6c7..0000000000 --- a/packages/flutter_tools/lib/src/commands/migrate.dart +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2014 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:process/process.dart'; - -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/platform.dart'; -import '../base/terminal.dart'; -import '../migrate/migrate_utils.dart'; -import '../runner/flutter_command.dart'; -import 'migrate_abandon.dart'; -import 'migrate_apply.dart'; -import 'migrate_status.dart'; - -/// Base command for the migration tool. -class MigrateCommand extends FlutterCommand { - MigrateCommand({ - required bool verbose, - required this.logger, - required FileSystem fileSystem, - required Terminal terminal, - required Platform platform, - required ProcessManager processManager, - }) { - addSubcommand(MigrateStatusCommand( - verbose: verbose, - logger: logger, - fileSystem: fileSystem, - platform: platform, - processManager: processManager - )); - addSubcommand(MigrateAbandonCommand( - logger: logger, - fileSystem: fileSystem, - terminal: terminal, - platform: platform, - processManager: processManager - )); - addSubcommand(MigrateApplyCommand( - verbose: verbose, - logger: logger, - fileSystem: fileSystem, - terminal: terminal, - platform: platform, - processManager: processManager - )); - } - - final Logger logger; - - @override - final String name = 'migrate'; - - @override - final String description = 'Migrates flutter generated project files to the current flutter version'; - - @override - String get category => FlutterCommandCategory.project; - - @override - Future> get requiredArtifacts async => const {}; - - @override - Future runCommand() async { - return const FlutterCommandResult(ExitStatus.fail); - } -} - -Future gitRepoExists(String projectDirectory, Logger logger, MigrateUtils migrateUtils) async { - if (await migrateUtils.isGitRepo(projectDirectory)) { - return true; - } - logger.printStatus('Project is not a git repo. Please initialize a git repo and try again.'); - printCommandText('git init', logger); - return false; -} - -Future hasUncommittedChanges(String projectDirectory, Logger logger, MigrateUtils migrateUtils) async { - if (await migrateUtils.hasUncommittedChanges(projectDirectory)) { - logger.printStatus('There are uncommitted changes in your project. Please git commit, abandon, or stash your changes before trying again.'); - return true; - } - return false; -} - -/// Prints a command to logger with appropriate formatting. -void printCommandText(String command, Logger logger) { - logger.printStatus( - '\n\$ $command\n', - color: TerminalColor.grey, - indent: 4, - newline: false, - ); -} diff --git a/packages/flutter_tools/lib/src/commands/migrate_abandon.dart b/packages/flutter_tools/lib/src/commands/migrate_abandon.dart deleted file mode 100644 index 1a61810ef9..0000000000 --- a/packages/flutter_tools/lib/src/commands/migrate_abandon.dart +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2014 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:process/process.dart'; - -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/platform.dart'; -import '../base/terminal.dart'; -import '../migrate/migrate_utils.dart'; -import '../project.dart'; -import '../runner/flutter_command.dart'; -import 'migrate.dart'; - -/// Abandons the existing migration by deleting the migrate working directory. -class MigrateAbandonCommand extends FlutterCommand { - MigrateAbandonCommand({ - required this.logger, - required this.fileSystem, - required this.terminal, - required Platform platform, - required ProcessManager processManager, - }) : migrateUtils = MigrateUtils( - logger: logger, - fileSystem: fileSystem, - platform: platform, - processManager: processManager, - ) { - requiresPubspecYaml(); - argParser.addOption( - 'staging-directory', - help: 'Specifies the custom migration working directory used to stage ' - 'and edit proposed changes. This path can be absolute or relative ' - 'to the flutter project root. This defaults to ' - '`$kDefaultMigrateStagingDirectoryName`', - valueHelp: 'path', - ); - argParser.addOption( - 'project-directory', - help: 'The root directory of the flutter project. This defaults to the ' - 'current working directory if omitted.', - valueHelp: 'path', - ); - argParser.addFlag( - 'force', - abbr: 'f', - help: 'Delete the migrate working directory without asking for confirmation.', - ); - } - - final Logger logger; - - final FileSystem fileSystem; - - final Terminal terminal; - - final MigrateUtils migrateUtils; - - @override - final String name = 'abandon'; - - @override - final String description = 'Deletes the current active migration working directory.'; - - @override - String get category => FlutterCommandCategory.project; - - @override - Future> get requiredArtifacts async => const {}; - - @override - Future runCommand() async { - final String? projectDirectory = stringArg('project-directory'); - final FlutterProjectFactory flutterProjectFactory = FlutterProjectFactory(logger: logger, fileSystem: fileSystem); - final FlutterProject project = projectDirectory == null - ? FlutterProject.current() - : flutterProjectFactory.fromDirectory(fileSystem.directory(projectDirectory)); - Directory stagingDirectory = project.directory.childDirectory(kDefaultMigrateStagingDirectoryName); - final String? customStagingDirectoryPath = stringArg('staging-directory'); - if (customStagingDirectoryPath != null) { - if (fileSystem.path.isAbsolute(customStagingDirectoryPath)) { - stagingDirectory = fileSystem.directory(customStagingDirectoryPath); - } else { - stagingDirectory = project.directory.childDirectory(customStagingDirectoryPath); - } - if (!stagingDirectory.existsSync()) { - logger.printError('Provided staging directory `$customStagingDirectoryPath` ' - 'does not exist or is not valid.'); - return const FlutterCommandResult(ExitStatus.fail); - } - } - if (!stagingDirectory.existsSync()) { - logger.printStatus('No migration in progress. Start a new migration with:'); - printCommandText('flutter migrate start', logger); - return const FlutterCommandResult(ExitStatus.fail); - } - - logger.printStatus('\nAbandoning the existing migration will delete the ' - 'migration staging directory at ${stagingDirectory.path}'); - final bool force = boolArg('force') ?? false; - if (!force) { - String selection = 'y'; - terminal.usesTerminalUi = true; - try { - selection = await terminal.promptForCharInput( - ['y', 'n'], - logger: logger, - prompt: 'Are you sure you wish to continue with abandoning? (y)es, (N)o', - defaultChoiceIndex: 1, - ); - } on StateError catch(e) { - logger.printError( - e.message, - indent: 0, - ); - } - if (selection != 'y') { - return const FlutterCommandResult(ExitStatus.success); - } - } - - try { - stagingDirectory.deleteSync(recursive: true); - } on FileSystemException catch (e) { - logger.printError('Deletion failed with: $e'); - logger.printError('Please manually delete the staging directory at `${stagingDirectory.path}`'); - } - - logger.printStatus('\nAbandon complete. Start a new migration with:'); - printCommandText('flutter migrate start', logger); - return const FlutterCommandResult(ExitStatus.success); - } -} diff --git a/packages/flutter_tools/lib/src/commands/migrate_apply.dart b/packages/flutter_tools/lib/src/commands/migrate_apply.dart deleted file mode 100644 index f02736ed42..0000000000 --- a/packages/flutter_tools/lib/src/commands/migrate_apply.dart +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2014 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:process/process.dart'; - -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/platform.dart'; -import '../base/terminal.dart'; -import '../flutter_project_metadata.dart'; -import '../migrate/migrate_manifest.dart'; -import '../migrate/migrate_update_locks.dart'; -import '../migrate/migrate_utils.dart'; -import '../project.dart'; -import '../runner/flutter_command.dart'; -import '../version.dart'; -import 'migrate.dart'; - -/// Migrate subcommand that checks the migrate working directory for unresolved conflicts and -/// applies the staged changes to the project. -class MigrateApplyCommand extends FlutterCommand { - MigrateApplyCommand({ - bool verbose = false, - required this.logger, - required this.fileSystem, - required this.terminal, - required Platform platform, - required ProcessManager processManager, - }) : _verbose = verbose, - migrateUtils = MigrateUtils( - logger: logger, - fileSystem: fileSystem, - platform: platform, - processManager: processManager, - ) { - requiresPubspecYaml(); - argParser.addOption( - 'staging-directory', - help: 'Specifies the custom migration working directory used to stage ' - 'and edit proposed changes. This path can be absolute or relative ' - 'to the flutter project root. This defaults to ' - '`$kDefaultMigrateStagingDirectoryName`', - valueHelp: 'path', - ); - argParser.addOption( - 'project-directory', - help: 'The root directory of the flutter project. This defaults to the ' - 'current working directory if omitted.', - valueHelp: 'path', - ); - argParser.addFlag( - 'force', - abbr: 'f', - help: 'Ignore unresolved merge conflicts and uncommitted changes and ' - 'apply staged changes by force.', - ); - argParser.addFlag( - 'keep-working-directory', - help: 'Do not delete the working directory.', - ); - } - - final bool _verbose; - - final Logger logger; - - final FileSystem fileSystem; - - final Terminal terminal; - - final MigrateUtils migrateUtils; - - @override - final String name = 'apply'; - - @override - final String description = r'Accepts the changes produced by `$ flutter ' - 'migrate start` and copies the changed files into ' - 'your project files. All merge conflicts should ' - 'be resolved before apply will complete ' - 'successfully. If conflicts still exist, this ' - 'command will print the remaining conflicted files.'; - - @override - String get category => FlutterCommandCategory.project; - - @override - Future> get requiredArtifacts async => const {}; - - @override - Future runCommand() async { - final String? projectDirectory = stringArg('project-directory'); - final FlutterProjectFactory flutterProjectFactory = FlutterProjectFactory(logger: logger, fileSystem: fileSystem); - final FlutterProject project = projectDirectory == null - ? FlutterProject.current() - : flutterProjectFactory.fromDirectory(fileSystem.directory(projectDirectory)); - - if (!await gitRepoExists(project.directory.path, logger, migrateUtils)) { - logger.printStatus('No git repo found. Please run in a project with an ' - 'initialized git repo or initialize one with:'); - printCommandText('git init', logger); - return const FlutterCommandResult(ExitStatus.fail); - } - - final bool force = boolArg('force') ?? false; - - Directory stagingDirectory = project.directory.childDirectory(kDefaultMigrateStagingDirectoryName); - final String? customStagingDirectoryPath = stringArg('staging-directory'); - if (customStagingDirectoryPath != null) { - if (fileSystem.path.isAbsolute(customStagingDirectoryPath)) { - stagingDirectory = fileSystem.directory(customStagingDirectoryPath); - } else { - stagingDirectory = project.directory.childDirectory(customStagingDirectoryPath); - } - } - if (!stagingDirectory.existsSync()) { - logger.printStatus('No migration in progress at $stagingDirectory. Please run:'); - printCommandText('flutter migrate start', logger); - return const FlutterCommandResult(ExitStatus.fail); - } - - final File manifestFile = MigrateManifest.getManifestFileFromDirectory(stagingDirectory); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - if (!checkAndPrintMigrateStatus(manifest, stagingDirectory, warnConflict: true, logger: logger) && !force) { - logger.printStatus('Conflicting files found. Resolve these conflicts and try again.'); - logger.printStatus('Guided conflict resolution wizard:'); - printCommandText('flutter migrate resolve-conflicts', logger); - return const FlutterCommandResult(ExitStatus.fail); - } - - if (await hasUncommittedChanges(project.directory.path, logger, migrateUtils) && !force) { - return const FlutterCommandResult(ExitStatus.fail); - } - - logger.printStatus('Applying migration.'); - // Copy files from working directory to project root - final List allFilesToCopy = []; - allFilesToCopy.addAll(manifest.mergedFiles); - allFilesToCopy.addAll(manifest.conflictFiles); - allFilesToCopy.addAll(manifest.addedFiles); - if (allFilesToCopy.isNotEmpty && _verbose) { - logger.printStatus('Modifying ${allFilesToCopy.length} files.', indent: 2); - } - for (final String localPath in allFilesToCopy) { - if (_verbose) { - logger.printStatus('Writing $localPath'); - } - final File workingFile = stagingDirectory.childFile(localPath); - final File targetFile = project.directory.childFile(localPath); - if (!workingFile.existsSync()) { - continue; - } - - if (!targetFile.existsSync()) { - targetFile.createSync(recursive: true); - } - try { - targetFile.writeAsStringSync(workingFile.readAsStringSync(), flush: true); - } on FileSystemException { - targetFile.writeAsBytesSync(workingFile.readAsBytesSync(), flush: true); - } - } - // Delete files slated for deletion. - if (manifest.deletedFiles.isNotEmpty) { - logger.printStatus('Deleting ${manifest.deletedFiles.length} files.', indent: 2); - } - for (final String localPath in manifest.deletedFiles) { - final File targetFile = FlutterProject.current().directory.childFile(localPath); - targetFile.deleteSync(); - } - - // Update the migrate config files to reflect latest migration. - if (_verbose) { - logger.printStatus('Updating .migrate_configs'); - } - final FlutterProjectMetadata metadata = FlutterProjectMetadata(project.directory.childFile('.metadata'), logger); - final FlutterVersion version = FlutterVersion(workingDirectory: project.directory.absolute.path); - - final String currentGitHash = version.frameworkRevision; - metadata.migrateConfig.populate( - projectDirectory: project.directory, - currentRevision: currentGitHash, - logger: logger, - ); - - // Clean up the working directory - final bool keepWorkingDirectory = boolArg('keep-working-directory') ?? false; - if (!keepWorkingDirectory) { - stagingDirectory.deleteSync(recursive: true); - } - - // Detect pub dependency locking. Run flutter pub upgrade --major-versions - await updatePubspecDependencies(project, migrateUtils, logger, terminal); - - // Detect gradle lockfiles in android directory. Delete lockfiles and regenerate with ./gradlew tasks (any gradle task that requires a build). - await updateGradleDependencyLocking(project, migrateUtils, logger, terminal, _verbose, fileSystem); - - logger.printStatus('Migration complete. You may use commands like `git ' - 'status`, `git diff` and `git restore ` to continue ' - 'working with the migrated files.'); - return const FlutterCommandResult(ExitStatus.success); - } -} diff --git a/packages/flutter_tools/lib/src/commands/migrate_status.dart b/packages/flutter_tools/lib/src/commands/migrate_status.dart deleted file mode 100644 index 26dcc5d79c..0000000000 --- a/packages/flutter_tools/lib/src/commands/migrate_status.dart +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2014 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:process/process.dart'; - -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/platform.dart'; -import '../base/terminal.dart'; -import '../migrate/migrate_manifest.dart'; -import '../migrate/migrate_utils.dart'; -import '../project.dart'; -import '../runner/flutter_command.dart'; -import 'migrate.dart'; - -/// Flutter migrate subcommand to check the migration status of the project. -class MigrateStatusCommand extends FlutterCommand { - MigrateStatusCommand({ - bool verbose = false, - required this.logger, - required this.fileSystem, - required Platform platform, - required ProcessManager processManager, - }) : _verbose = verbose, - migrateUtils = MigrateUtils( - logger: logger, - fileSystem: fileSystem, - platform: platform, - processManager: processManager, - ) { - requiresPubspecYaml(); - argParser.addOption( - 'staging-directory', - help: 'Specifies the custom migration working directory used to stage ' - 'and edit proposed changes. This path can be absolute or relative ' - 'to the flutter project root. This defaults to ' - '`$kDefaultMigrateStagingDirectoryName`', - valueHelp: 'path', - ); - argParser.addOption( - 'project-directory', - help: 'The root directory of the flutter project. This defaults to the ' - 'current working directory if omitted.', - valueHelp: 'path', - ); - argParser.addFlag( - 'diff', - defaultsTo: true, - help: 'Shows the diff output when enabled. Enabled by default.', - ); - argParser.addFlag( - 'show-added-files', - help: 'Shows the contents of added files. Disabled by default.', - ); - } - - final bool _verbose; - - final Logger logger; - - final FileSystem fileSystem; - - final MigrateUtils migrateUtils; - - @override - final String name = 'status'; - - @override - final String description = 'Prints the current status of the in progress migration.'; - - @override - String get category => FlutterCommandCategory.project; - - @override - Future> get requiredArtifacts async => const {}; - - /// Manually marks the lines in a diff that should be printed unformatted for visbility. - /// - /// This is used to ensure the initial lines that display the files being diffed and the - /// git revisions are printed and never skipped. - final Set _initialDiffLines = {0, 1}; - - @override - Future runCommand() async { - final String? projectDirectory = stringArg('project-directory'); - final FlutterProjectFactory flutterProjectFactory = FlutterProjectFactory(logger: logger, fileSystem: fileSystem); - final FlutterProject project = projectDirectory == null - ? FlutterProject.current() - : flutterProjectFactory.fromDirectory(fileSystem.directory(projectDirectory)); - Directory stagingDirectory = project.directory.childDirectory(kDefaultMigrateStagingDirectoryName); - final String? customStagingDirectoryPath = stringArg('staging-directory'); - if (customStagingDirectoryPath != null) { - if (fileSystem.path.isAbsolute(customStagingDirectoryPath)) { - stagingDirectory = fileSystem.directory(customStagingDirectoryPath); - } else { - stagingDirectory = project.directory.childDirectory(customStagingDirectoryPath); - } - } - if (!stagingDirectory.existsSync()) { - logger.printStatus('No migration in progress in $stagingDirectory. Start a new migration with:'); - printCommandText('flutter migrate start', logger); - return const FlutterCommandResult(ExitStatus.fail); - } - - final File manifestFile = MigrateManifest.getManifestFileFromDirectory(stagingDirectory); - if (!manifestFile.existsSync()) { - logger.printError('No migrate manifest in the migrate working directory ' - 'at ${stagingDirectory.path}. Fix the working directory ' - 'or abandon and restart the migration.'); - return const FlutterCommandResult(ExitStatus.fail); - } - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - - final bool showDiff = boolArg('diff') ?? true; - final bool showAddedFiles = boolArg('show-added-files') ?? true; - if (showDiff || _verbose) { - if (showAddedFiles || _verbose) { - for (final String localPath in manifest.addedFiles) { - logger.printStatus('Newly added file at $localPath:\n'); - try { - logger.printStatus(stagingDirectory.childFile(localPath).readAsStringSync(), color: TerminalColor.green); - } on FileSystemException { - logger.printStatus('Contents are byte data\n', color: TerminalColor.grey); - } - } - } - final List files = []; - files.addAll(manifest.mergedFiles); - files.addAll(manifest.resolvedConflictFiles(stagingDirectory)); - files.addAll(manifest.remainingConflictFiles(stagingDirectory)); - for (final String localPath in files) { - final DiffResult result = await migrateUtils.diffFiles(project.directory.childFile(localPath), stagingDirectory.childFile(localPath)); - if (result.diff != '' && result.diff != null) { - // Print with different colors for better visibility. - int lineNumber = -1; - for (final String line in result.diff!.split('\n')) { - lineNumber++; - if (line.startsWith('---') || line.startsWith('+++') || line.startsWith('&&') || _initialDiffLines.contains(lineNumber)) { - logger.printStatus(line); - continue; - } - if (line.startsWith('-')) { - logger.printStatus(line, color: TerminalColor.red); - continue; - } - if (line.startsWith('+')) { - logger.printStatus(line, color: TerminalColor.green); - continue; - } - logger.printStatus(line, color: TerminalColor.grey); - } - } - } - } - - logger.printBox('Working directory at `${stagingDirectory.path}`'); - - checkAndPrintMigrateStatus(manifest, stagingDirectory, logger: logger); - - final bool readyToApply = manifest.remainingConflictFiles(stagingDirectory).isEmpty; - - if (!readyToApply) { - logger.printStatus('Guided conflict resolution wizard:'); - printCommandText('flutter migrate resolve-conflicts', logger); - logger.printStatus('Resolve conflicts and accept changes with:'); - } else { - logger.printStatus('All conflicts resolved. Review changes above and ' - 'apply the migration with:', - color: TerminalColor.green); - } - printCommandText('flutter migrate apply', logger); - - return const FlutterCommandResult(ExitStatus.success); - } -} diff --git a/packages/flutter_tools/lib/src/migrate/migrate_manifest.dart b/packages/flutter_tools/lib/src/migrate/migrate_manifest.dart deleted file mode 100644 index af7013bb2d..0000000000 --- a/packages/flutter_tools/lib/src/migrate/migrate_manifest.dart +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2014 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:yaml/yaml.dart'; - -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/terminal.dart'; -import 'migrate_result.dart'; -import 'migrate_utils.dart'; - -const String _kMergedFilesKey = 'merged_files'; -const String _kConflictFilesKey = 'conflict_files'; -const String _kAddedFilesKey = 'added_files'; -const String _kDeletedFilesKey = 'deleted_files'; - -/// Represents the manifest file that tracks the contents of the current -/// migration working directory. -/// -/// This manifest file is created with the MigrateResult of a computeMigration run. -class MigrateManifest { - /// Creates a new manifest from a MigrateResult. - MigrateManifest({ - required this.migrateRootDir, - required this.migrateResult, - }); - - /// Parses an existing migrate manifest. - MigrateManifest.fromFile(File manifestFile) : migrateResult = MigrateResult.empty(), migrateRootDir = manifestFile.parent { - final Object? yamlContents = loadYaml(manifestFile.readAsStringSync()); - if (yamlContents is! YamlMap) { - throw Exception('Invalid .migrate_manifest file in the migrate working directory. File is not a Yaml map.'); - } - final YamlMap map = yamlContents; - bool valid = map.containsKey(_kMergedFilesKey) && map.containsKey(_kConflictFilesKey) && map.containsKey(_kAddedFilesKey) && map.containsKey(_kDeletedFilesKey); - if (!valid) { - throw Exception('Invalid .migrate_manifest file in the migrate working directory. File is missing an entry.'); - } - final Object? mergedFilesYaml = map[_kMergedFilesKey]; - final Object? conflictFilesYaml = map[_kConflictFilesKey]; - final Object? addedFilesYaml = map[_kAddedFilesKey]; - final Object? deletedFilesYaml = map[_kDeletedFilesKey]; - valid = valid && (mergedFilesYaml is YamlList || mergedFilesYaml == null); - valid = valid && (conflictFilesYaml is YamlList || conflictFilesYaml == null); - valid = valid && (addedFilesYaml is YamlList || addedFilesYaml == null); - valid = valid && (deletedFilesYaml is YamlList || deletedFilesYaml == null); - if (!valid) { - throw Exception('Invalid .migrate_manifest file in the migrate working directory. Entry is not a Yaml list.'); - } - if (mergedFilesYaml != null) { - for (final Object? localPath in mergedFilesYaml as YamlList) { - if (localPath is String) { - // We can fill the maps with partially dummy data as not all properties are used by the manifest. - migrateResult.mergeResults.add(StringMergeResult.explicit(mergedString: '', hasConflict: false, exitCode: 0, localPath: localPath)); - } - } - } - if (conflictFilesYaml != null) { - for (final Object? localPath in conflictFilesYaml as YamlList) { - if (localPath is String) { - migrateResult.mergeResults.add(StringMergeResult.explicit(mergedString: '', hasConflict: true, exitCode: 1, localPath: localPath)); - } - } - } - if (addedFilesYaml != null) { - for (final Object? localPath in addedFilesYaml as YamlList) { - if (localPath is String) { - migrateResult.addedFiles.add(FilePendingMigration(localPath, migrateRootDir.childFile(localPath))); - } - } - } - if (deletedFilesYaml != null) { - for (final Object? localPath in deletedFilesYaml as YamlList) { - if (localPath is String) { - migrateResult.deletedFiles.add(FilePendingMigration(localPath, migrateRootDir.childFile(localPath))); - } - } - } - } - - final Directory migrateRootDir; - final MigrateResult migrateResult; - - /// A list of local paths of files that require conflict resolution. - List get conflictFiles { - final List output = []; - for (final MergeResult result in migrateResult.mergeResults) { - if (result.hasConflict) { - output.add(result.localPath); - } - } - return output; - } - - /// A list of local paths of files that require conflict resolution. - List remainingConflictFiles(Directory workingDir) { - final List output = []; - for (final String localPath in conflictFiles) { - if (!_conflictsResolved(workingDir.childFile(localPath).readAsStringSync())) { - output.add(localPath); - } - } - return output; - } - - // A list of local paths of files that had conflicts and are now fully resolved. - List resolvedConflictFiles(Directory workingDir) { - final List output = []; - for (final String localPath in conflictFiles) { - if (_conflictsResolved(workingDir.childFile(localPath).readAsStringSync())) { - output.add(localPath); - } - } - return output; - } - - /// A list of local paths of files that were automatically merged. - List get mergedFiles { - final List output = []; - for (final MergeResult result in migrateResult.mergeResults) { - if (!result.hasConflict) { - output.add(result.localPath); - } - } - return output; - } - - /// A list of local paths of files that were newly added. - List get addedFiles { - final List output = []; - for (final FilePendingMigration file in migrateResult.addedFiles) { - output.add(file.localPath); - } - return output; - } - - /// A list of local paths of files that are marked for deletion. - List get deletedFiles { - final List output = []; - for (final FilePendingMigration file in migrateResult.deletedFiles) { - output.add(file.localPath); - } - return output; - } - - /// Returns the manifest file given a migration workind directory. - static File getManifestFileFromDirectory(Directory workingDir) { - return workingDir.childFile('.migrate_manifest'); - } - - /// Writes the manifest yaml file in the working directory. - void writeFile() { - final StringBuffer mergedFileManifestContents = StringBuffer(); - final StringBuffer conflictFilesManifestContents = StringBuffer(); - for (final MergeResult result in migrateResult.mergeResults) { - if (result.hasConflict) { - conflictFilesManifestContents.write(' - ${result.localPath}\n'); - } else { - mergedFileManifestContents.write(' - ${result.localPath}\n'); - } - } - - final StringBuffer newFileManifestContents = StringBuffer(); - for (final String localPath in addedFiles) { - newFileManifestContents.write(' - $localPath\n)'); - } - - final StringBuffer deletedFileManifestContents = StringBuffer(); - for (final String localPath in deletedFiles) { - deletedFileManifestContents.write(' - $localPath\n'); - } - - final String migrateManifestContents = 'merged_files:\n${mergedFileManifestContents}conflict_files:\n${conflictFilesManifestContents}added_files:\n${newFileManifestContents}deleted_files:\n$deletedFileManifestContents'; - final File migrateManifest = getManifestFileFromDirectory(migrateRootDir); - migrateManifest.createSync(recursive: true); - migrateManifest.writeAsStringSync(migrateManifestContents, flush: true); - } -} - -/// Returns true if the file does not contain any git conflict markers. -bool _conflictsResolved(String contents) { - if (contents.contains('>>>>>>>') && contents.contains('=======') && contents.contains('<<<<<<<')) { - return false; - } - return true; -} - -/// Returns true if the migration working directory has all conflicts resolved and prints the migration status. -/// -/// The migration status printout lists all added, deleted, merged, and conflicted files. -bool checkAndPrintMigrateStatus(MigrateManifest manifest, Directory workingDir, {bool warnConflict = false, Logger? logger}) { - final StringBuffer printout = StringBuffer(); - final StringBuffer redPrintout = StringBuffer(); - bool result = true; - final List remainingConflicts = []; - final List mergedFiles = []; - for (final String localPath in manifest.conflictFiles) { - if (!_conflictsResolved(workingDir.childFile(localPath).readAsStringSync())) { - remainingConflicts.add(localPath); - } else { - mergedFiles.add(localPath); - } - } - - mergedFiles.addAll(manifest.mergedFiles); - if (manifest.addedFiles.isNotEmpty) { - printout.write('Added files:\n'); - for (final String localPath in manifest.addedFiles) { - printout.write(' - $localPath\n'); - } - } - if (manifest.deletedFiles.isNotEmpty) { - printout.write('Deleted files:\n'); - for (final String localPath in manifest.deletedFiles) { - printout.write(' - $localPath\n'); - } - } - if (mergedFiles.isNotEmpty) { - printout.write('Modified files:\n'); - for (final String localPath in mergedFiles) { - printout.write(' - $localPath\n'); - } - } - if (remainingConflicts.isNotEmpty) { - if (warnConflict) { - printout.write('Unable to apply migration. The following files in the migration working directory still have unresolved conflicts:'); - } else { - printout.write('Merge conflicted files:'); - } - for (final String localPath in remainingConflicts) { - redPrintout.write(' - $localPath\n'); - } - result = false; - } - if (logger != null) { - logger.printStatus(printout.toString()); - logger.printStatus(redPrintout.toString(), color: TerminalColor.red, newline: false); - } - return result; -} diff --git a/packages/flutter_tools/lib/src/migrate/migrate_result.dart b/packages/flutter_tools/lib/src/migrate/migrate_result.dart deleted file mode 100644 index ef930bcdda..0000000000 --- a/packages/flutter_tools/lib/src/migrate/migrate_result.dart +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2014 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 '../base/file_system.dart'; -import 'migrate_utils.dart'; - -/// Data class that holds all results and generated directories from a computeMigration run. -/// -/// mergeResults, addedFiles, and deletedFiles includes the sets of files to be migrated while -/// the other members track the temporary sdk and generated app directories created by the tool. -/// -/// The compute function does not clean up the temp directories, as the directories may be reused, -/// so this must be done manually afterwards. -class MigrateResult { - /// Explicitly initialize the MigrateResult. - MigrateResult({ - required this.mergeResults, - required this.addedFiles, - required this.deletedFiles, - required this.tempDirectories, - required this.sdkDirs, - required this.mergeTypeMap, - required this.diffMap, - this.generatedBaseTemplateDirectory, - this.generatedTargetTemplateDirectory}); - - /// Creates a MigrateResult with all empty members. - MigrateResult.empty() - : mergeResults = [], - addedFiles = [], - deletedFiles = [], - tempDirectories = [], - mergeTypeMap = {}, - diffMap = {}, - sdkDirs = {}; - - /// The results of merging existing files with the target files. - final List mergeResults; - - /// Tracks the files that are to be newly added to the project. - final List addedFiles; - - /// Tracks the files that are to be deleted from the project. - final List deletedFiles; - - /// Tracks the temporary directories created during the migrate compute process. - final List tempDirectories; - - /// Mapping between the local path of a file and the type of merge that should be used. - final Map mergeTypeMap; - - /// Mapping between the local path of a file and the diff between the base and target - /// versions of the file. - final Map diffMap; - - /// The root directory of the base app. - Directory? generatedBaseTemplateDirectory; - - /// The root directory of the target app. - Directory? generatedTargetTemplateDirectory; - - /// The root directories of the Flutter SDK for each revision. - Map sdkDirs; -} - -/// Defines available merge techniques. -enum MergeType { - /// A standard three-way merge. - threeWay, - /// A two way merge that ignores the base version of the file. - twoWay, - /// A `CustomMerge` manually handles the merge. - custom, -} - -/// Stores a file that has been marked for migration and metadata about the file. -class FilePendingMigration { - FilePendingMigration(this.localPath, this.file); - String localPath; - File file; -} diff --git a/packages/flutter_tools/lib/src/migrate/migrate_update_locks.dart b/packages/flutter_tools/lib/src/migrate/migrate_update_locks.dart deleted file mode 100644 index 665fc4f64b..0000000000 --- a/packages/flutter_tools/lib/src/migrate/migrate_update_locks.dart +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2014 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 '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/terminal.dart'; -import '../project.dart'; -import 'migrate_utils.dart'; - -/// Checks if the project uses pubspec dependency locking and prompts if -/// the pub upgrade should be run. -Future updatePubspecDependencies( - FlutterProject flutterProject, - MigrateUtils migrateUtils, - Logger logger, - Terminal terminal -) async { - final File pubspecFile = flutterProject.directory.childFile('pubspec.yaml'); - if (!pubspecFile.existsSync()) { - return; - } - if (!pubspecFile.readAsStringSync().contains('# THIS LINE IS AUTOGENERATED')) { - return; - } - logger.printStatus('\nDart dependency locking detected in pubspec.yaml.'); - terminal.usesTerminalUi = true; - String selection = 'y'; - selection = await terminal.promptForCharInput( - ['y', 'n'], - logger: logger, - prompt: 'Do you want the tool to run `flutter pub upgrade --major-versions`? (y)es, (n)o', - defaultChoiceIndex: 1, - ); - if (selection == 'y') { - // Runs `flutter pub upgrade --major-versions` - await migrateUtils.flutterPubUpgrade(flutterProject.directory.path); - } -} - -/// Checks if gradle dependency locking is used and prompts the developer to -/// remove and back up the gradle dependency lockfile. -Future updateGradleDependencyLocking( - FlutterProject flutterProject, - MigrateUtils migrateUtils, - Logger logger, - Terminal terminal, - bool verbose, - FileSystem fileSystem -) async { - final Directory androidDir = flutterProject.directory.childDirectory('android'); - if (!androidDir.existsSync()) { - return; - } - final List androidFiles = androidDir.listSync(); - final List lockfiles = []; - final List backedUpFilePaths = []; - for (final FileSystemEntity entity in androidFiles) { - if (entity is! File) { - continue; - } - final File file = entity.absolute; - // Don't re-handle backed up lockfiles. - if (file.path.contains('_backup_')) { - continue; - } - try { - // lockfiles generated by gradle start with this prefix. - if (file.readAsStringSync().startsWith( - '# This is a Gradle generated file for dependency locking.\n# ' - 'Manual edits can break the build and are not advised.\n# This ' - 'file is expected to be part of source control.')) { - lockfiles.add(file); - } - } on FileSystemException { - if (verbose) { - logger.printStatus('Unable to check ${file.path}'); - } - } - } - if (lockfiles.isNotEmpty) { - logger.printStatus('\nGradle dependency locking detected.'); - logger.printStatus('Flutter can backup the lockfiles and regenerate updated ' - 'lockfiles.'); - terminal.usesTerminalUi = true; - String selection = 'y'; - selection = await terminal.promptForCharInput( - ['y', 'n'], - logger: logger, - prompt: 'Do you want the tool to update locked dependencies? (y)es, (n)o', - defaultChoiceIndex: 1, - ); - if (selection == 'y') { - for (final File file in lockfiles) { - int counter = 0; - while (true) { - final String newPath = '${file.absolute.path}_backup_$counter'; - if (!fileSystem.file(newPath).existsSync()) { - file.renameSync(newPath); - backedUpFilePaths.add(newPath); - break; - } else { - counter++; - } - } - } - // Runs `./gradlew tasks`in the project's android directory. - await migrateUtils.gradlewTasks(flutterProject.directory.childDirectory('android').path); - logger.printStatus('Old lockfiles renamed to:'); - for (final String path in backedUpFilePaths) { - logger.printStatus(path, color: TerminalColor.grey, indent: 2); - } - } - } -} diff --git a/packages/flutter_tools/lib/src/migrate/migrate_utils.dart b/packages/flutter_tools/lib/src/migrate/migrate_utils.dart deleted file mode 100644 index 25891fe3c9..0000000000 --- a/packages/flutter_tools/lib/src/migrate/migrate_utils.dart +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2014 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 'dart:async'; -import 'dart:typed_data'; - -import 'package:process/process.dart'; - -import '../base/common.dart'; -import '../base/file_system.dart'; -import '../base/logger.dart'; -import '../base/platform.dart'; -import '../base/process.dart'; - -/// The default name of the migrate working directory used to stage proposed changes. -const String kDefaultMigrateStagingDirectoryName = 'migrate_staging_dir'; - -/// Utility class that contains methods that wrap git and other shell commands. -class MigrateUtils { - MigrateUtils({ - required Logger logger, - required FileSystem fileSystem, - required Platform platform, - required ProcessManager processManager, - }) : - _processUtils = ProcessUtils(processManager: processManager, logger: logger), - _logger = logger, - _fileSystem = fileSystem, - _platform = platform; - - final Logger _logger; - final FileSystem _fileSystem; - final Platform _platform; - final ProcessUtils _processUtils; - - /// Calls `git diff` on two files and returns the diff as a DiffResult. - Future diffFiles(File one, File two) async { - if (one.existsSync() && !two.existsSync()) { - return DiffResult(diffType: DiffType.deletion); - } - if (!one.existsSync() && two.existsSync()) { - return DiffResult(diffType: DiffType.addition); - } - final List cmdArgs = ['git', 'diff', '--no-index', one.absolute.path, two.absolute.path]; - final RunResult result = await _processUtils.run(cmdArgs); - - // diff exits with 1 if diffs are found. - checkForErrors(result, allowedExitCodes: [0, 1], commandDescription: 'git ${cmdArgs.join(' ')}'); - return DiffResult(diffType: DiffType.command, diff: result.stdout, exitCode: result.exitCode); - } - - /// Clones a copy of the flutter repo into the destination directory. Returns false if unsuccessful. - Future cloneFlutter(String revision, String destination) async { - // Use https url instead of ssh to avoid need to setup ssh on git. - List cmdArgs = ['git', 'clone', '--filter=blob:none', 'https://github.com/flutter/flutter.git', destination]; - RunResult result = await _processUtils.run(cmdArgs); - checkForErrors(result, commandDescription: cmdArgs.join(' ')); - - cmdArgs.clear(); - cmdArgs = ['git', 'reset', '--hard', revision]; - result = await _processUtils.run(cmdArgs, workingDirectory: destination); - if (!checkForErrors(result, commandDescription: cmdArgs.join(' '), exit: false)) { - return false; - } - return true; - } - - /// Calls `flutter create` as a re-entrant command. - Future createFromTemplates(String flutterBinPath, { - required String name, - bool legacyNameParameter = false, - required String androidLanguage, - required String iosLanguage, - required String outputDirectory, - String? createVersion, - List platforms = const [], - int iterationsAllowed = 5, - }) async { - // Limit the number of iterations this command is allowed to attempt to prevent infinite looping. - if (iterationsAllowed <= 0) { - _logger.printError('Unable to `flutter create` with the version of flutter at $flutterBinPath'); - return outputDirectory; - } - - final List cmdArgs = ['$flutterBinPath/flutter', 'create']; - if (!legacyNameParameter) { - cmdArgs.add('--project-name=$name'); - } - cmdArgs.add('--android-language=$androidLanguage'); - cmdArgs.add('--ios-language=$iosLanguage'); - if (platforms.isNotEmpty) { - String platformsArg = '--platforms='; - for (int i = 0; i < platforms.length; i++) { - if (i > 0) { - platformsArg += ','; - } - platformsArg += platforms[i]; - } - cmdArgs.add(platformsArg); - } - cmdArgs.add('--no-pub'); - if (legacyNameParameter) { - cmdArgs.add(name); - } else { - cmdArgs.add(outputDirectory); - } - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: outputDirectory, allowReentrantFlutter: true); - final String error = result.stderr; - - // Catch errors due to parameters not existing. - - // Old versions of the tool does not include the platforms option. - if (error.contains('Could not find an option named "platforms".')) { - return createFromTemplates( - flutterBinPath, - name: name, - legacyNameParameter: legacyNameParameter, - androidLanguage: androidLanguage, - iosLanguage: iosLanguage, - outputDirectory: outputDirectory, - iterationsAllowed: iterationsAllowed--, - ); - } - // Old versions of the tool does not include the project-name option. - if ((result.stderr).contains('Could not find an option named "project-name".')) { - return createFromTemplates( - flutterBinPath, - name: name, - legacyNameParameter: true, - androidLanguage: androidLanguage, - iosLanguage: iosLanguage, - outputDirectory: outputDirectory, - platforms: platforms, - iterationsAllowed: iterationsAllowed--, - ); - } - if (error.contains('Multiple output directories specified.')) { - if (error.contains('Try moving --platforms')) { - return createFromTemplates( - flutterBinPath, - name: name, - legacyNameParameter: legacyNameParameter, - androidLanguage: androidLanguage, - iosLanguage: iosLanguage, - outputDirectory: outputDirectory, - iterationsAllowed: iterationsAllowed--, - ); - } - } - checkForErrors(result, commandDescription: cmdArgs.join(' '), silent: true); - - if (legacyNameParameter) { - return _fileSystem.path.join(outputDirectory, name); - } - return outputDirectory; - } - - /// Runs the git 3-way merge on three files and returns the results as a MergeResult. - /// - /// Passing the same path for base and current will perform a two-way fast forward merge. - Future gitMergeFile({ - required String base, - required String current, - required String target, - required String localPath, - }) async { - final List cmdArgs = ['git', 'merge-file', '-p', current, base, target]; - final RunResult result = await _processUtils.run(cmdArgs); - checkForErrors(result, allowedExitCodes: [-1], commandDescription: cmdArgs.join(' ')); - return StringMergeResult(result, localPath); - } - - /// Calls `git init` on the workingDirectory. - Future gitInit(String workingDirectory) async { - final List cmdArgs = ['git', 'init']; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory); - checkForErrors(result, commandDescription: cmdArgs.join(' ')); - } - - /// Returns true if the workingDirectory git repo has any uncommited changes. - Future hasUncommittedChanges(String workingDirectory, {String? migrateStagingDir}) async { - final List cmdArgs = [ - 'git', - 'ls-files', - '--deleted', - '--modified', - '--others', - '--exclude=${migrateStagingDir ?? kDefaultMigrateStagingDirectoryName}' - ]; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory); - checkForErrors(result, allowedExitCodes: [-1], commandDescription: cmdArgs.join(' ')); - if (result.stdout.isEmpty) { - return false; - } - return true; - } - - /// Returns true if the workingDirectory is a git repo. - Future isGitRepo(String workingDirectory) async { - final List cmdArgs = ['git', 'rev-parse', '--is-inside-work-tree']; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory); - checkForErrors(result, allowedExitCodes: [-1], commandDescription: cmdArgs.join(' ')); - if (result.exitCode == 0) { - return true; - } - return false; - } - - /// Returns true if the file at `filePath` is covered by the `.gitignore` - Future isGitIgnored(String filePath, String workingDirectory) async { - final List cmdArgs = ['git', 'check-ignore', filePath]; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory); - checkForErrors(result, allowedExitCodes: [0, 1, 128], commandDescription: cmdArgs.join(' ')); - return result.exitCode == 0; - } - - /// Runs `flutter pub upgrade --major-revisions`. - Future flutterPubUpgrade(String workingDirectory) async { - final List cmdArgs = ['flutter', 'pub', 'upgrade', '--major-versions']; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory, allowReentrantFlutter: true); - checkForErrors(result, commandDescription: cmdArgs.join(' ')); - } - - /// Runs `./gradlew tasks` in the android directory of a flutter project. - Future gradlewTasks(String workingDirectory) async { - final String baseCommand = _platform.isWindows ? 'gradlew.bat' : './gradlew'; - final List cmdArgs = [baseCommand, 'tasks']; - final RunResult result = await _processUtils.run(cmdArgs, workingDirectory: workingDirectory); - checkForErrors(result, commandDescription: cmdArgs.join(' ')); - } - - /// Verifies that the RunResult does not contain an error. - /// - /// If an error is detected, the error can be optionally logged or exit the tool. - /// - /// Passing -1 in allowedExitCodes means all exit codes are valid. - bool checkForErrors( - RunResult result, { - List allowedExitCodes = const [0], - String? commandDescription, - bool exit = true, - bool silent = false - }) { - if (allowedExitCodes.contains(result.exitCode) || allowedExitCodes.contains(-1)) { - return true; - } - if (!silent) { - _logger.printError('Command encountered an error with exit code ${result.exitCode}.'); - if (commandDescription != null) { - _logger.printError('Command:'); - _logger.printError(commandDescription, indent: 2); - } - _logger.printError('Stdout:'); - _logger.printError(result.stdout, indent: 2); - _logger.printError('Stderr:'); - _logger.printError(result.stderr, indent: 2); - } - if (exit) { - throwToolExit('Command failed with exit code ${result.exitCode}', exitCode: result.exitCode); - } - return false; - } - - /// Returns true if the file does not contain any git conflit markers. - bool conflictsResolved(String contents) { - final bool hasMarker = contents.contains('>>>>>>>') || - contents.contains('=======') || - contents.contains('<<<<<<<'); - return !hasMarker; - } -} - -/// Defines the classification of difference between files. -enum DiffType { - command, - addition, - deletion, - ignored, - none, -} - -/// Tracks the output of a git diff command or any special cases such as addition of a new -/// file or deletion of an existing file. -class DiffResult { - DiffResult({ - required this.diffType, - this.diff, - this.exitCode, - }) : assert(diffType == DiffType.command && exitCode != null || diffType != DiffType.command && exitCode == null); - - /// The diff string output by git. - final String? diff; - - final DiffType diffType; - - /// The exit code of the command. This is zero when no diffs are found. - /// - /// The exitCode is null when the diffType is not `command`. - final int? exitCode; -} - -/// Data class to hold the results of a merge. -abstract class MergeResult { - /// Initializes a MergeResult based off of a RunResult. - MergeResult(RunResult result, this.localPath) : - hasConflict = result.exitCode != 0, - exitCode = result.exitCode; - - /// Manually initializes a MergeResult with explicit values. - MergeResult.explicit({ - required this.hasConflict, - required this.exitCode, - required this.localPath, - }); - - /// True when there is a merge conflict. - bool hasConflict; - - /// The exitcode of the merge command. - int exitCode; - - /// The local path relative to the project root of the file. - String localPath; -} - -/// The results of a string merge. -class StringMergeResult extends MergeResult { - /// Initializes a BinaryMergeResult based off of a RunResult. - StringMergeResult(super.result, super.localPath) : - mergedString = result.stdout; - - /// Manually initializes a StringMergeResult with explicit values. - StringMergeResult.explicit({ - required this.mergedString, - required super.hasConflict, - required super.exitCode, - required super.localPath, - }) : super.explicit(); - /// The final merged string. - String mergedString; -} - -/// The results of a binary merge. -class BinaryMergeResult extends MergeResult { - /// Initializes a BinaryMergeResult based off of a RunResult. - BinaryMergeResult(super.result, super.localPath) : - mergedBytes = result.stdout as Uint8List; - - /// Manually initializes a BinaryMergeResult with explicit values. - BinaryMergeResult.explicit({ - required this.mergedBytes, - required super.hasConflict, - required super.exitCode, - required super.localPath, - }) : super.explicit(); - /// The final merged bytes. - Uint8List mergedBytes; -} diff --git a/packages/flutter_tools/test/commands.shard/permeable/migrate_abandon_test.dart b/packages/flutter_tools/test/commands.shard/permeable/migrate_abandon_test.dart deleted file mode 100644 index b522f1d6b3..0000000000 --- a/packages/flutter_tools/test/commands.shard/permeable/migrate_abandon_test.dart +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2014 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_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/base/terminal.dart'; -import 'package:flutter_tools/src/cache.dart'; -import 'package:flutter_tools/src/commands/migrate.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../../src/common.dart'; -import '../../src/context.dart'; -import '../../src/test_flutter_command_runner.dart'; - -void main() { - late FileSystem fileSystem; - late BufferLogger logger; - late Platform platform; - late Terminal terminal; - late ProcessManager processManager; - late Directory appDir; - - setUp(() { - fileSystem = globals.localFileSystem; - appDir = fileSystem.systemTempDirectory.createTempSync('apptestdir'); - logger = BufferLogger.test(); - platform = FakePlatform(); - terminal = Terminal.test(); - processManager = globals.processManager; - }); - - setUpAll(() { - Cache.disableLocking(); - }); - - tearDown(() async { - tryToDelete(appDir); - }); - - testUsingContext('abandon deletes staging directory', () async { - final MigrateCommand command = MigrateCommand( - verbose: true, - logger: logger, - fileSystem: fileSystem, - terminal: terminal, - platform: platform, - processManager: processManager, - ); - final Directory stagingDir = appDir.childDirectory(kDefaultMigrateStagingDirectoryName); - appDir.childFile('lib/main.dart').createSync(recursive: true); - final File pubspecOriginal = appDir.childFile('pubspec.yaml'); - pubspecOriginal.createSync(); - pubspecOriginal.writeAsStringSync(''' -name: originalname -description: A new Flutter project. -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: true''', flush: true); - - expect(stagingDir.existsSync(), false); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'abandon', - '--staging-directory=${stagingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.errorText, contains('Provided staging directory')); - expect(logger.errorText, contains('migrate_staging_dir` does not exist or is not valid.')); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'abandon', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains('No migration in progress. Start a new migration with:')); - - final File pubspecModified = stagingDir.childFile('pubspec.yaml'); - pubspecModified.createSync(recursive: true); - pubspecModified.writeAsStringSync(''' -name: newname -description: new description of the test project -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: false - EXTRALINE''', flush: true); - - final File addedFile = stagingDir.childFile('added.file'); - addedFile.createSync(recursive: true); - addedFile.writeAsStringSync('new file contents'); - - final File manifestFile = stagingDir.childFile('.migrate_manifest'); - manifestFile.createSync(recursive: true); - manifestFile.writeAsStringSync(''' -merged_files: - - pubspec.yaml -conflict_files: -added_files: - - added.file -deleted_files: -'''); - - expect(appDir.childFile('lib/main.dart').existsSync(), true); - - expect(stagingDir.existsSync(), true); - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'abandon', - '--staging-directory=${stagingDir.path}', - '--project-directory=${appDir.path}', - '--force', - ] - ); - expect(logger.statusText, contains('Abandon complete. Start a new migration with:')); - expect(stagingDir.existsSync(), false); - }, overrides: { - FileSystem: () => fileSystem, - ProcessManager: () => processManager, - Platform: () => platform, - }); -} diff --git a/packages/flutter_tools/test/commands.shard/permeable/migrate_apply_test.dart b/packages/flutter_tools/test/commands.shard/permeable/migrate_apply_test.dart deleted file mode 100644 index 26b6b9233a..0000000000 --- a/packages/flutter_tools/test/commands.shard/permeable/migrate_apply_test.dart +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2014 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_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/base/terminal.dart'; -import 'package:flutter_tools/src/cache.dart'; -import 'package:flutter_tools/src/commands/migrate.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../../src/common.dart'; -import '../../src/context.dart'; -import '../../src/test_flutter_command_runner.dart'; - -void main() { - late FileSystem fileSystem; - late BufferLogger logger; - late Platform platform; - late Terminal terminal; - late ProcessManager processManager; - late Directory appDir; - - setUp(() { - fileSystem = globals.localFileSystem; - appDir = fileSystem.systemTempDirectory.createTempSync('apptestdir'); - logger = BufferLogger.test(); - platform = FakePlatform(); - terminal = Terminal.test(); - processManager = globals.processManager; - }); - - setUpAll(() { - Cache.disableLocking(); - }); - - tearDown(() async { - tryToDelete(appDir); - }); - - testUsingContext('Apply produces all outputs', () async { - final MigrateCommand command = MigrateCommand( - verbose: true, - logger: logger, - fileSystem: fileSystem, - terminal: terminal, - platform: platform, - processManager: processManager, - ); - final Directory workingDir = appDir.childDirectory(kDefaultMigrateStagingDirectoryName); - appDir.childFile('lib/main.dart').createSync(recursive: true); - final File pubspecOriginal = appDir.childFile('pubspec.yaml'); - pubspecOriginal.createSync(); - pubspecOriginal.writeAsStringSync(''' -name: originalname -description: A new Flutter project. -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: true''', flush: true); - - final File gitignore = appDir.childFile('.gitignore'); - gitignore.createSync(); - gitignore.writeAsStringSync(kDefaultMigrateStagingDirectoryName, flush: true); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'apply', - '--staging-directory=${workingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains('Project is not a git repo. Please initialize a git repo and try again.')); - - await processManager.run(['git', 'init'], workingDirectory: appDir.path); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'apply', - '--staging-directory=${workingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains('No migration in progress')); - - final File pubspecModified = workingDir.childFile('pubspec.yaml'); - pubspecModified.createSync(recursive: true); - pubspecModified.writeAsStringSync(''' -name: newname -description: new description of the test project -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: false - # EXTRALINE:''', flush: true); - - final File addedFile = workingDir.childFile('added.file'); - addedFile.createSync(recursive: true); - addedFile.writeAsStringSync('new file contents'); - - final File manifestFile = workingDir.childFile('.migrate_manifest'); - manifestFile.createSync(recursive: true); - manifestFile.writeAsStringSync(''' -merged_files: - - pubspec.yaml -conflict_files: - - conflict/conflict.file -added_files: - - added.file -deleted_files: -'''); - - // Add conflict file - final File conflictFile = workingDir.childDirectory('conflict').childFile('conflict.file'); - conflictFile.createSync(recursive: true); - conflictFile.writeAsStringSync(''' -line1 -<<<<<<< /conflcit/conflict.file -line2 -======= -linetwo ->>>>>>> /var/folders/md/gm0zgfcj07vcsj6jkh_mp_wh00ff02/T/flutter_tools.4Xdep8/generatedTargetTemplatetlN44S/conflict/conflict.file -line3 -''', flush: true); - - final File conflictFileOriginal = appDir.childDirectory('conflict').childFile('conflict.file'); - conflictFileOriginal.createSync(recursive: true); - conflictFileOriginal.writeAsStringSync(''' -line1 -line2 -line3 -''', flush: true); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'apply', - '--staging-directory=${workingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains(r''' -Added files: - - added.file -Modified files: - - pubspec.yaml -Unable to apply migration. The following files in the migration working directory still have unresolved conflicts: - - conflict/conflict.file -Conflicting files found. Resolve these conflicts and try again. -Guided conflict resolution wizard: - - $ flutter migrate resolve-conflicts''')); - - conflictFile.writeAsStringSync(''' -line1 -linetwo -line3 -''', flush: true); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'apply', - '--staging-directory=${workingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains('There are uncommitted changes in your project. Please git commit, abandon, or stash your changes before trying again.')); - - await processManager.run(['git', 'add', '.'], workingDirectory: appDir.path); - await processManager.run(['git', 'commit', '-m', 'Initial commit'], workingDirectory: appDir.path); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'apply', - '--staging-directory=${workingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - expect(logger.statusText, contains(r''' -Added files: - - added.file -Modified files: - - conflict/conflict.file - - pubspec.yaml - -Applying migration. - Modifying 3 files. -Writing pubspec.yaml -Writing conflict/conflict.file -Writing added.file -Updating .migrate_configs -Migration complete. You may use commands like `git status`, `git diff` and `git restore ` to continue working with the migrated files.''')); - - expect(pubspecOriginal.readAsStringSync(), contains('# EXTRALINE')); - expect(conflictFileOriginal.readAsStringSync(), contains('linetwo')); - expect(appDir.childFile('added.file').existsSync(), true); - expect(appDir.childFile('added.file').readAsStringSync(), contains('new file contents')); - - }, overrides: { - FileSystem: () => fileSystem, - ProcessManager: () => processManager, - Platform: () => platform, - }); -} diff --git a/packages/flutter_tools/test/commands.shard/permeable/migrate_status_test.dart b/packages/flutter_tools/test/commands.shard/permeable/migrate_status_test.dart deleted file mode 100644 index 3df997c78a..0000000000 --- a/packages/flutter_tools/test/commands.shard/permeable/migrate_status_test.dart +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2014 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_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/base/terminal.dart'; -import 'package:flutter_tools/src/cache.dart'; -import 'package:flutter_tools/src/commands/migrate.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../../src/common.dart'; -import '../../src/context.dart'; -import '../../src/test_flutter_command_runner.dart'; - -void main() { - late FileSystem fileSystem; - late BufferLogger logger; - late Platform platform; - late Terminal terminal; - late ProcessManager processManager; - late Directory appDir; - - setUp(() { - fileSystem = globals.localFileSystem; - appDir = fileSystem.systemTempDirectory.createTempSync('apptestdir'); - logger = BufferLogger.test(); - platform = FakePlatform(); - terminal = Terminal.test(); - processManager = globals.processManager; - }); - - setUpAll(() { - Cache.disableLocking(); - }); - - tearDown(() async { - tryToDelete(appDir); - }); - - testUsingContext('Status produces all outputs', () async { - final MigrateCommand command = MigrateCommand( - verbose: true, - logger: logger, - fileSystem: fileSystem, - terminal: terminal, - platform: platform, - processManager: processManager, - ); - final Directory stagingDir = appDir.childDirectory(kDefaultMigrateStagingDirectoryName); - final File pubspecOriginal = appDir.childFile('pubspec.yaml'); - pubspecOriginal.createSync(); - pubspecOriginal.writeAsStringSync(''' -name: originalname -description: A new Flutter project. -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: true''', flush: true); - - final File pubspecModified = stagingDir.childFile('pubspec.yaml'); - pubspecModified.createSync(recursive: true); - pubspecModified.writeAsStringSync(''' -name: newname -description: new description of the test project -version: 1.0.0+1 -environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -dependencies: - flutter: - sdk: flutter -dev_dependencies: - flutter_test: - sdk: flutter -flutter: - uses-material-design: false - EXTRALINE''', flush: true); - - final File addedFile = stagingDir.childFile('added.file'); - addedFile.createSync(recursive: true); - addedFile.writeAsStringSync('new file contents'); - - final File manifestFile = stagingDir.childFile('.migrate_manifest'); - manifestFile.createSync(recursive: true); - manifestFile.writeAsStringSync(''' -merged_files: - - pubspec.yaml -conflict_files: -added_files: - - added.file -deleted_files: -'''); - - await createTestCommandRunner(command).run( - [ - 'migrate', - 'status', - '--staging-directory=${stagingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - - expect(logger.statusText, contains(''' -Newly added file at added.file: - -new file contents''')); - expect(logger.statusText, contains(r''' -Added files: - - added.file -Modified files: - - pubspec.yaml - -All conflicts resolved. Review changes above and apply the migration with: - - $ flutter migrate apply -''')); - - expect(logger.statusText, contains(r''' -@@ -1,5 +1,5 @@ --name: originalname --description: A new Flutter project. -+name: newname -+description: new description of the test project - version: 1.0.0+1 - environment: - sdk: '>=2.18.0-58.0.dev <3.0.0' -@@ -10,4 +10,5 @@ dev_dependencies: - flutter_test: - sdk: flutter - flutter: -- uses-material-design: true -\ No newline at end of file -+ uses-material-design: false -+ EXTRALINE''')); - - // Add conflict file - final File conflictFile = stagingDir.childDirectory('conflict').childFile('conflict.file'); - conflictFile.createSync(recursive: true); - conflictFile.writeAsStringSync(''' -line1 -<<<<<<< /conflcit/conflict.file -line2 -======= -linetwo ->>>>>>> /var/folders/md/gm0zgfcj07vcsj6jkh_mp_wh00ff02/T/flutter_tools.4Xdep8/generatedTargetTemplatetlN44S/conflict/conflict.file -line3 -''', flush: true); - final File conflictFileOriginal = appDir.childDirectory('conflict').childFile('conflict.file'); - conflictFileOriginal.createSync(recursive: true); - conflictFileOriginal.writeAsStringSync(''' -line1 -line2 -line3 -''', flush: true); - - manifestFile.writeAsStringSync(''' -merged_files: - - pubspec.yaml -conflict_files: - - conflict/conflict.file -added_files: - - added.file -deleted_files: -'''); - - logger.clear(); - await createTestCommandRunner(command).run( - [ - 'migrate', - 'status', - '--staging-directory=${stagingDir.path}', - '--project-directory=${appDir.path}', - ] - ); - - expect(logger.statusText, contains(''' -@@ -1,3 +1,7 @@ - line1 -+<<<<<<< /conflcit/conflict.file - line2 -+======= -+linetwo -+>>>>>>>''')); - }, overrides: { - FileSystem: () => fileSystem, - ProcessManager: () => processManager, - Platform: () => platform, - }); -} diff --git a/packages/flutter_tools/test/general.shard/migrate/migrate_manifest_test.dart b/packages/flutter_tools/test/general.shard/migrate/migrate_manifest_test.dart deleted file mode 100644 index 6f6f0badc5..0000000000 --- a/packages/flutter_tools/test/general.shard/migrate/migrate_manifest_test.dart +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright 2014 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:file/memory.dart'; -import 'package:flutter_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/migrate/migrate_manifest.dart'; -import 'package:flutter_tools/src/migrate/migrate_result.dart'; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../../src/common.dart'; - -void main() { - late FileSystem fileSystem; - late File manifestFile; - late BufferLogger logger; - - setUpAll(() { - fileSystem = MemoryFileSystem.test(); - logger = BufferLogger.test(); - manifestFile = fileSystem.file('.migrate_manifest'); - }); - - group('checkAndPrintMigrateStatus', () { - testWithoutContext('empty MigrateResult produces empty output', () async { - final Directory workingDir = fileSystem.directory('migrate_working_dir'); - workingDir.createSync(recursive: true); - final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult( - mergeResults: [], - addedFiles: [], - deletedFiles: [], - mergeTypeMap: {}, - diffMap: {}, - tempDirectories: [], - sdkDirs: {}, - )); - - checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger); - - expect(logger.statusText, contains('\n')); - }); - - testWithoutContext('populated MigrateResult produces correct output', () async { - final Directory workingDir = fileSystem.directory('migrate_working_dir'); - workingDir.createSync(recursive: true); - final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult( - mergeResults: [ - StringMergeResult.explicit( - localPath: 'merged_file', - mergedString: 'str', - hasConflict: false, - exitCode: 0, - ), - StringMergeResult.explicit( - localPath: 'conflict_file', - mergedString: 'hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n', - hasConflict: true, - exitCode: 1, - ), - ], - addedFiles: [FilePendingMigration('added_file', fileSystem.file('added_file'))], - deletedFiles: [FilePendingMigration('deleted_file', fileSystem.file('deleted_file'))], - // The following are ignored by the manifest. - mergeTypeMap: {'test': MergeType.threeWay}, - diffMap: {}, - tempDirectories: [], - sdkDirs: {}, - )); - - final File conflictFile = workingDir.childFile('conflict_file'); - conflictFile.writeAsStringSync('hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n', flush: true); - - checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger); - - expect(logger.statusText, contains(''' -Added files: - - added_file -Deleted files: - - deleted_file -Modified files: - - conflict_file - - merged_file -''')); - }); - - testWithoutContext('populated MigrateResult detects fixed conflict', () async { - final Directory workingDir = fileSystem.directory('migrate_working_dir'); - workingDir.createSync(recursive: true); - final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult( - mergeResults: [ - StringMergeResult.explicit( - localPath: 'merged_file', - mergedString: 'str', - hasConflict: false, - exitCode: 0, - ), - StringMergeResult.explicit( - localPath: 'conflict_file', - mergedString: 'hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n', - hasConflict: true, - exitCode: 1, - ), - ], - addedFiles: [FilePendingMigration('added_file', fileSystem.file('added_file'))], - deletedFiles: [FilePendingMigration('deleted_file', fileSystem.file('deleted_file'))], - // The following are ignored by the manifest. - mergeTypeMap: {'test': MergeType.threeWay}, - diffMap: {}, - tempDirectories: [], - sdkDirs: {}, - )); - - final File conflictFile = workingDir.childFile('conflict_file'); - conflictFile.writeAsStringSync('hello\nwow a bunch of lines\nhi\n', flush: true); - - checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger); - expect(logger.statusText, contains(''' -Added files: - - added_file -Deleted files: - - deleted_file -Modified files: - - conflict_file - - merged_file -''')); - }); - }); - - group('manifest file parsing', () { - testWithoutContext('empty fails', () async { - manifestFile.writeAsStringSync(''); - bool exceptionFound = false; - try { - MigrateManifest.fromFile(manifestFile); - } on Exception catch (e) { - exceptionFound = true; - expect(e.toString(), 'Exception: Invalid .migrate_manifest file in the migrate working directory. File is not a Yaml map.'); - } - expect(exceptionFound, true); - }); - - testWithoutContext('invalid name fails', () async { - manifestFile.writeAsStringSync(''' - merged_files: - conflict_files: - added_filessssss: - deleted_files: - '''); - bool exceptionFound = false; - try { - MigrateManifest.fromFile(manifestFile); - } on Exception catch (e) { - exceptionFound = true; - expect(e.toString(), 'Exception: Invalid .migrate_manifest file in the migrate working directory. File is missing an entry.'); - } - expect(exceptionFound, true); - }); - - testWithoutContext('missing name fails', () async { - manifestFile.writeAsStringSync(''' - merged_files: - conflict_files: - deleted_files: - '''); - bool exceptionFound = false; - try { - MigrateManifest.fromFile(manifestFile); - } on Exception catch (e) { - exceptionFound = true; - expect(e.toString(), 'Exception: Invalid .migrate_manifest file in the migrate working directory. File is missing an entry.'); - } - expect(exceptionFound, true); - }); - - testWithoutContext('wrong entry type fails', () async { - manifestFile.writeAsStringSync(''' - merged_files: - conflict_files: - other_key: - added_files: - deleted_files: - '''); - bool exceptionFound = false; - try { - MigrateManifest.fromFile(manifestFile); - } on Exception catch (e) { - exceptionFound = true; - expect(e.toString(), 'Exception: Invalid .migrate_manifest file in the migrate working directory. Entry is not a Yaml list.'); - } - expect(exceptionFound, true); - }); - - testWithoutContext('unpopulated succeeds', () async { - manifestFile.writeAsStringSync(''' - merged_files: - conflict_files: - added_files: - deleted_files: - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, true); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, true); - }); - - testWithoutContext('order does not matter', () async { - manifestFile.writeAsStringSync(''' - added_files: - merged_files: - deleted_files: - conflict_files: - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, true); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, true); - }); - - testWithoutContext('basic succeeds', () async { - manifestFile.writeAsStringSync(''' - merged_files: - - file1 - conflict_files: - - file2 - added_files: - - file3 - deleted_files: - - file4 - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, false); - expect(manifest.conflictFiles.isEmpty, false); - expect(manifest.addedFiles.isEmpty, false); - expect(manifest.deletedFiles.isEmpty, false); - - expect(manifest.mergedFiles.length, 1); - expect(manifest.conflictFiles.length, 1); - expect(manifest.addedFiles.length, 1); - expect(manifest.deletedFiles.length, 1); - - expect(manifest.mergedFiles[0], 'file1'); - expect(manifest.conflictFiles[0], 'file2'); - expect(manifest.addedFiles[0], 'file3'); - expect(manifest.deletedFiles[0], 'file4'); - }); - - testWithoutContext('basic multi-list succeeds', () async { - manifestFile.writeAsStringSync(''' - merged_files: - - file1 - - file2 - conflict_files: - added_files: - deleted_files: - - file3 - - file4 - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, false); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, false); - - expect(manifest.mergedFiles.length, 2); - expect(manifest.conflictFiles.length, 0); - expect(manifest.addedFiles.length, 0); - expect(manifest.deletedFiles.length, 2); - - expect(manifest.mergedFiles[0], 'file1'); - expect(manifest.mergedFiles[1], 'file2'); - expect(manifest.deletedFiles[0], 'file3'); - expect(manifest.deletedFiles[1], 'file4'); - }); - }); - - group('manifest MigrateResult creation', () { - testWithoutContext('empty MigrateResult', () async { - final MigrateManifest manifest = MigrateManifest(migrateRootDir: fileSystem.directory('root'), migrateResult: MigrateResult( - mergeResults: [], - addedFiles: [], - deletedFiles: [], - mergeTypeMap: {}, - diffMap: {}, - tempDirectories: [], - sdkDirs: {}, - )); - expect(manifest.mergedFiles.isEmpty, true); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, true); - }); - - testWithoutContext('simple MigrateResult', () async { - final MigrateManifest manifest = MigrateManifest(migrateRootDir: fileSystem.directory('root'), migrateResult: MigrateResult( - mergeResults: [ - StringMergeResult.explicit( - localPath: 'merged_file', - mergedString: 'str', - hasConflict: false, - exitCode: 0, - ), - StringMergeResult.explicit( - localPath: 'conflict_file', - mergedString: '<<<<<<<<<<<', - hasConflict: true, - exitCode: 1, - ), - ], - addedFiles: [FilePendingMigration('added_file', fileSystem.file('added_file'))], - deletedFiles: [FilePendingMigration('deleted_file', fileSystem.file('deleted_file'))], - // The following are ignored by the manifest. - mergeTypeMap: {'test': MergeType.threeWay}, - diffMap: {}, - tempDirectories: [], - sdkDirs: {}, - )); - expect(manifest.mergedFiles.isEmpty, false); - expect(manifest.conflictFiles.isEmpty, false); - expect(manifest.addedFiles.isEmpty, false); - expect(manifest.deletedFiles.isEmpty, false); - - expect(manifest.mergedFiles.length, 1); - expect(manifest.conflictFiles.length, 1); - expect(manifest.addedFiles.length, 1); - expect(manifest.deletedFiles.length, 1); - - expect(manifest.mergedFiles[0], 'merged_file'); - expect(manifest.conflictFiles[0], 'conflict_file'); - expect(manifest.addedFiles[0], 'added_file'); - expect(manifest.deletedFiles[0], 'deleted_file'); - }); - }); - - group('manifest write', () { - testWithoutContext('empty', () async { - manifestFile.writeAsStringSync(''' - merged_files: - conflict_files: - added_files: - deleted_files: - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, true); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, true); - - manifest.writeFile(); - expect(manifestFile.readAsStringSync(), ''' -merged_files: -conflict_files: -added_files: -deleted_files: -'''); - }); - - testWithoutContext('basic multi-list', () async { - manifestFile.writeAsStringSync(''' - merged_files: - - file1 - - file2 - conflict_files: - added_files: - deleted_files: - - file3 - - file4 - '''); - final MigrateManifest manifest = MigrateManifest.fromFile(manifestFile); - expect(manifest.mergedFiles.isEmpty, false); - expect(manifest.conflictFiles.isEmpty, true); - expect(manifest.addedFiles.isEmpty, true); - expect(manifest.deletedFiles.isEmpty, false); - - expect(manifest.mergedFiles.length, 2); - expect(manifest.conflictFiles.length, 0); - expect(manifest.addedFiles.length, 0); - expect(manifest.deletedFiles.length, 2); - - expect(manifest.mergedFiles[0], 'file1'); - expect(manifest.mergedFiles[1], 'file2'); - expect(manifest.deletedFiles[0], 'file3'); - expect(manifest.deletedFiles[1], 'file4'); - - manifest.writeFile(); - expect(manifestFile.readAsStringSync(), ''' -merged_files: - - file1 - - file2 -conflict_files: -added_files: -deleted_files: - - file3 - - file4 -'''); - }); - }); -} diff --git a/packages/flutter_tools/test/integration.shard/migrate_command_test.dart b/packages/flutter_tools/test/integration.shard/migrate_command_test.dart deleted file mode 100644 index 65a160e004..0000000000 --- a/packages/flutter_tools/test/integration.shard/migrate_command_test.dart +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2014 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:file/file.dart'; -import 'package:flutter_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/process.dart'; -import 'package:flutter_tools/src/commands/migrate.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../src/common.dart'; - -void main() { - late BufferLogger logger; - late FileSystem fileSystem; - late Directory projectRoot; - late String projectRootPath; - late ProcessUtils processUtils; - late MigrateUtils utils; - - setUpAll(() async { - fileSystem = globals.localFileSystem; - logger = BufferLogger.test(); - utils = MigrateUtils( - logger: logger, - fileSystem: fileSystem, - platform: globals.platform, - processManager: globals.processManager, - ); - processUtils = ProcessUtils(processManager: globals.processManager, logger: logger); - }); - - group('git', () { - setUp(() async { - projectRoot = fileSystem.systemTempDirectory.createTempSync('flutter_migrate_command_test'); - projectRoot.createSync(recursive: true); - projectRootPath = projectRoot.path; - }); - - tearDown(() async { - tryToDelete(projectRoot); - }); - - testWithoutContext('isGitRepo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - - expect(await gitRepoExists(projectRootPath, logger, utils), false); - expect(logger.statusText, contains('Project is not a git repo. Please initialize a git repo and try again.')); - - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - expect(await gitRepoExists(projectRootPath, logger, utils), true); - }); - - testWithoutContext('printCommandText produces formatted output', () async { - printCommandText('some command --help', logger); - - expect(logger.statusText, contains(r' $ some command --help')); - }); - - testWithoutContext('hasUncommittedChanges false on clean repo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - projectRoot.childFile('.gitignore') - ..createSync() - ..writeAsStringSync('ignored_file.dart', flush: true); - - await processUtils.run(['git', 'add', '.'], workingDirectory: projectRootPath); - await processUtils.run(['git', 'commit', '-m', 'Initial commit'], workingDirectory: projectRootPath); - - expect(await hasUncommittedChanges(projectRootPath, logger, utils), false); - }); - - testWithoutContext('hasUncommittedChanges true on dirty repo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - projectRoot.childFile('some_file.dart') - ..createSync() - ..writeAsStringSync('void main() {}', flush: true); - - expect(await hasUncommittedChanges(projectRootPath, logger, utils), true); - }); - }); -} diff --git a/packages/flutter_tools/test/integration.shard/migrate_config_test.dart b/packages/flutter_tools/test/integration.shard/migrate_config_test.dart deleted file mode 100644 index 8d5a9f7418..0000000000 --- a/packages/flutter_tools/test/integration.shard/migrate_config_test.dart +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2014 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:file/file.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/flutter_project_metadata.dart'; -import 'package:flutter_tools/src/project.dart'; - -import '../src/common.dart'; -import '../src/context.dart'; -import 'test_data/migrate_project.dart'; -import 'test_driver.dart'; -import 'test_utils.dart'; - - -void main() { - late Directory tempDir; - late FlutterRunTestDriver flutter; - late Logger logger; - - setUp(() async { - tempDir = createResolvedTempDirectorySync('run_test.'); - flutter = FlutterRunTestDriver(tempDir); - logger = BufferLogger.test(); - }); - - tearDown(() async { - await flutter.stop(); - tryToDelete(tempDir); - }); - - testWithoutContext('parse simple config file', () async { - final File metadataFile = tempDir.childFile('.metadata'); - metadataFile.createSync(recursive: true); - metadataFile.writeAsStringSync(''' -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: fj19vkla9vnlka9vni3n808v3nch8cd - channel: stable - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: fj19vkla9vnlka9vni3n808v3nch8cd - base_revision: 93kf9v3njfa90vnidfjvn39nvi3vnie - - platform: android - create_revision: abfj19vkla9vnlka9vni3n808v3nch8cd - base_revision: ab93kf9v3njfa90vnidfjvn39nvi3vnie - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - lib/main.dart - - ios/Runner.xcodeproj/project.pbxproj - - lib/file1/etc.dart - - android/my_file.java -''', flush: true); - FlutterProjectMetadata metadata = FlutterProjectMetadata(metadataFile, logger); - - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.root]!.createRevision, equals('fj19vkla9vnlka9vni3n808v3nch8cd')); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.root]!.baseRevision, equals('93kf9v3njfa90vnidfjvn39nvi3vnie')); - - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.android]!.createRevision, equals('abfj19vkla9vnlka9vni3n808v3nch8cd')); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.android]!.baseRevision, equals('ab93kf9v3njfa90vnidfjvn39nvi3vnie')); - - expect(metadata.migrateConfig.unmanagedFiles[0], equals('lib/main.dart')); - expect(metadata.migrateConfig.unmanagedFiles[1], equals('ios/Runner.xcodeproj/project.pbxproj')); - expect(metadata.migrateConfig.unmanagedFiles[2], equals('lib/file1/etc.dart')); - expect(metadata.migrateConfig.unmanagedFiles[3], equals('android/my_file.java')); - - metadataFile.writeAsStringSync(''' -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: fj19vkla9vnlka9vni3n808v3nch8cd - channel: stable - -project_type: app -''', flush: true); - - metadata = FlutterProjectMetadata(metadataFile, logger); - - expect(metadata.migrateConfig.isEmpty, equals(true)); - expect(metadata.versionRevision, equals('fj19vkla9vnlka9vni3n808v3nch8cd')); - expect(metadata.versionChannel, equals('stable')); - }); - - testUsingContext('write simple config file', () async { - const String testCreateRevision = 'testmc9skl32nlnf23lnakcs9njr3'; - const String testBaseRevision = 'testanas9anlnq9ba7bjhavan3kma'; - MigrateConfig config = MigrateConfig( - platformConfigs: { - SupportedPlatform.android: MigratePlatformConfig(platform: SupportedPlatform.android, createRevision: testCreateRevision, baseRevision: testBaseRevision), - SupportedPlatform.ios: MigratePlatformConfig(platform: SupportedPlatform.ios, createRevision: testCreateRevision, baseRevision: testBaseRevision), - SupportedPlatform.root: MigratePlatformConfig(platform: SupportedPlatform.root, createRevision: testCreateRevision, baseRevision: testBaseRevision), - SupportedPlatform.windows: MigratePlatformConfig(platform: SupportedPlatform.windows, createRevision: testCreateRevision, baseRevision: testBaseRevision), - }, - unmanagedFiles: [ - 'lib/main.dart', - 'ios/Runner.xcodeproj/project.pbxproj', - 'lib/file1/etc.dart', - ], - ); - String outputString = config.getOutputFileString(); - expect(outputString, equals(''' - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: android - create_revision: $testCreateRevision - base_revision: $testBaseRevision - - platform: ios - create_revision: $testCreateRevision - base_revision: $testBaseRevision - - platform: root - create_revision: $testCreateRevision - base_revision: $testBaseRevision - - platform: windows - create_revision: $testCreateRevision - base_revision: $testBaseRevision - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' - - 'lib/file1/etc.dart' -''')); - - config = MigrateConfig(); - outputString = config.getOutputFileString(); - expect(outputString, equals('')); - }); - - testUsingContext('populate migrate config', () async { - // Flutter Stable 1.22.6 hash: 9b2d32b605630f28625709ebd9d78ab3016b2bf6 - final MigrateProject project = MigrateProject('version:1.22.6_stable'); - await project.setUpIn(tempDir); - - final File metadataFile = tempDir.childFile('.metadata'); - - const String currentRevision = 'test_base_revision'; - const String createRevision = 'test_create_revision'; - - final FlutterProjectMetadata metadata = FlutterProjectMetadata(metadataFile, logger); - metadata.migrateConfig.populate( - projectDirectory: tempDir, - currentRevision: currentRevision, - createRevision: createRevision, - logger: logger, - ); - - expect(metadata.migrateConfig.platformConfigs.length, equals(3)); - - final List keyList = List.from(metadata.migrateConfig.platformConfigs.keys); - - expect(keyList[0], equals(SupportedPlatform.root)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.root]!.baseRevision, equals(currentRevision)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.root]!.createRevision, equals(createRevision)); - - expect(keyList[1], equals(SupportedPlatform.android)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.android]!.baseRevision, equals(currentRevision)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.android]!.createRevision, equals(createRevision)); - - expect(keyList[2], equals(SupportedPlatform.ios)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.ios]!.baseRevision, equals(currentRevision)); - expect(metadata.migrateConfig.platformConfigs[SupportedPlatform.ios]!.createRevision, equals(createRevision)); - - final File metadataFileOutput = tempDir.childFile('.metadata_output'); - metadata.writeFile(outputFile: metadataFileOutput); - expect(metadataFileOutput.readAsStringSync(), equals(''' -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: 9b2d32b605630f28625709ebd9d78ab3016b2bf6 - channel: unknown - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: $createRevision - base_revision: $currentRevision - - platform: android - create_revision: $createRevision - base_revision: $currentRevision - - platform: ios - create_revision: $createRevision - base_revision: $currentRevision - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' -''')); - }); - - testUsingContext('equality compares platform', () async { - const String testCreateRevision = 'testmc9skl32nlnf23lnakcs9njr3'; - const String testBaseRevision = 'testanas9anlnq9ba7bjhavan3kma'; - final MigratePlatformConfig configAndroid = MigratePlatformConfig(platform: SupportedPlatform.android, createRevision: testCreateRevision, baseRevision: testBaseRevision); - final MigratePlatformConfig configIos = MigratePlatformConfig(platform: SupportedPlatform.ios, createRevision: testCreateRevision, baseRevision: testBaseRevision); - - expect(configAndroid.equals(configIos), false); - expect(configAndroid.equals(configAndroid), true); - expect(configIos.equals(configIos), true); - }); -} diff --git a/packages/flutter_tools/test/integration.shard/migrate_utils_test.dart b/packages/flutter_tools/test/integration.shard/migrate_utils_test.dart deleted file mode 100644 index c2d0e7325e..0000000000 --- a/packages/flutter_tools/test/integration.shard/migrate_utils_test.dart +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2014 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:file/file.dart'; -import 'package:flutter_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; -import 'package:flutter_tools/src/base/process.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; -import 'package:flutter_tools/src/migrate/migrate_utils.dart'; - -import '../src/common.dart'; - -void main() { - late BufferLogger logger; - late FileSystem fileSystem; - late Directory projectRoot; - late String projectRootPath; - late MigrateUtils utils; - late ProcessUtils processUtils; - - setUpAll(() async { - fileSystem = globals.localFileSystem; - logger = BufferLogger.test(); - utils = MigrateUtils( - logger: logger, - fileSystem: fileSystem, - platform: globals.platform, - processManager: globals.processManager, - ); - processUtils = ProcessUtils(processManager: globals.processManager, logger: logger); - }); - - group('git', () { - setUp(() async { - projectRoot = fileSystem.systemTempDirectory.createTempSync('flutter_migrate_utils_test'); - projectRoot.createSync(recursive: true); - projectRootPath = projectRoot.path; - }); - - tearDown(() async { - tryToDelete(projectRoot); - }); - - testWithoutContext('init', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - }); - - testWithoutContext('isGitIgnored', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - projectRoot.childFile('.gitignore') - ..createSync() - ..writeAsStringSync('ignored_file.dart', flush: true); - - expect(await utils.isGitIgnored('ignored_file.dart', projectRootPath), true); - expect(await utils.isGitIgnored('other_file.dart', projectRootPath), false); - }); - - testWithoutContext('isGitRepo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - expect(await utils.isGitRepo(projectRootPath), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - expect(await utils.isGitRepo(projectRootPath), true); - - expect(await utils.isGitRepo(projectRoot.parent.path), false); - }); - - testWithoutContext('hasUncommittedChanges false on clean repo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - projectRoot.childFile('.gitignore') - ..createSync() - ..writeAsStringSync('ignored_file.dart', flush: true); - - await processUtils.run(['git', 'add', '.'], workingDirectory: projectRootPath); - await processUtils.run(['git', 'commit', '-m', 'Initial commit'], workingDirectory: projectRootPath); - - expect(await utils.hasUncommittedChanges(projectRootPath), false); - }); - - testWithoutContext('hasUncommittedChanges true on dirty repo', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - projectRoot.childFile('some_file.dart') - ..createSync() - ..writeAsStringSync('void main() {}', flush: true); - - expect(await utils.hasUncommittedChanges(projectRootPath), true); - }); - - testWithoutContext('diffFiles', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - final File file1 = projectRoot.childFile('some_file.dart') - ..createSync() - ..writeAsStringSync('void main() {}\n', flush: true); - - final File file2 = projectRoot.childFile('some_other_file.dart'); - - DiffResult result = await utils.diffFiles(file1, file2); - expect(result.diff, null); - expect(result.diffType, DiffType.deletion); - expect(result.exitCode, null); - - result = await utils.diffFiles(file2, file1); - expect(result.diff, null); - expect(result.diffType, DiffType.addition); - expect(result.exitCode, null); - - file2.createSync(); - file2.writeAsStringSync('void main() {}\n', flush: true); - - result = await utils.diffFiles(file1, file2); - expect(result.diff, ''); - expect(result.diffType, DiffType.command); - expect(result.exitCode, 0); - - file2.writeAsStringSync('void main() {}\na second line\na third line\n', flush: true); - - result = await utils.diffFiles(file1, file2); - expect(result.diff, contains('@@ -1 +1,3 @@\n void main() {}\n+a second line\n+a third line')); - expect(result.diffType, DiffType.command); - expect(result.exitCode, 1); - }); - - testWithoutContext('merge', () async { - expect(projectRoot.existsSync(), true); - expect(projectRoot.childDirectory('.git').existsSync(), false); - await utils.gitInit(projectRootPath); - expect(projectRoot.childDirectory('.git').existsSync(), true); - - final File file1 = projectRoot.childFile('some_file.dart'); - file1.createSync(); - file1.writeAsStringSync('void main() {}\n\nline1\nline2\nline3\nline4\nline5\n', flush: true); - final File file2 = projectRoot.childFile('some_other_file.dart'); - file2.createSync(); - file2.writeAsStringSync('void main() {}\n\nline1\nline2\nline3.0\nline3.5\nline4\nline5\n', flush: true); - final File file3 = projectRoot.childFile('some_other_third_file.dart'); - file3.createSync(); - file3.writeAsStringSync('void main() {}\n\nline2\nline3\nline4\nline5\n', flush: true); - - StringMergeResult result = await utils.gitMergeFile( - base: file1.path, - current: file2.path, - target: file3.path, - localPath: 'some_file.dart', - ) as StringMergeResult; - - expect(result.mergedString, 'void main() {}\n\nline2\nline3.0\nline3.5\nline4\nline5\n'); - expect(result.hasConflict, false); - expect(result.exitCode, 0); - - file3.writeAsStringSync('void main() {}\n\nline1\nline2\nline3.1\nline3.5\nline4\nline5\n', flush: true); - - result = await utils.gitMergeFile( - base: file1.path, - current: file2.path, - target: file3.path, - localPath: 'some_file.dart', - ) as StringMergeResult; - - expect(result.mergedString, contains('line3.0\n=======\nline3.1\n>>>>>>>')); - expect(result.hasConflict, true); - expect(result.exitCode, 1); - - // Two way merge - result = await utils.gitMergeFile( - base: file1.path, - current: file1.path, - target: file3.path, - localPath: 'some_file.dart', - ) as StringMergeResult; - - expect(result.mergedString, 'void main() {}\n\nline1\nline2\nline3.1\nline3.5\nline4\nline5\n'); - expect(result.hasConflict, false); - expect(result.exitCode, 0); - }); - }); - - group('legacy app creation', () { - testWithoutContext('clone and create', () async { - projectRoot = fileSystem.systemTempDirectory.createTempSync('flutter_sdk_test'); - const String revision = '5391447fae6209bb21a89e6a5a6583cac1af9b4b'; - - expect(await utils.cloneFlutter(revision, projectRoot.path), true); - expect(projectRoot.childFile('README.md').existsSync(), true); - - final Directory appDir = fileSystem.systemTempDirectory.createTempSync('flutter_app'); - await utils.createFromTemplates( - projectRoot.childDirectory('bin').path, - name: 'testapp', - androidLanguage: 'java', - iosLanguage: 'objc', - outputDirectory: appDir.path, - ); - expect(appDir.childFile('pubspec.yaml').existsSync(), true); - expect(appDir.childFile('.metadata').existsSync(), true); - expect(appDir.childFile('.metadata').readAsStringSync(), contains(revision)); - expect(appDir.childDirectory('android').existsSync(), true); - expect(appDir.childDirectory('ios').existsSync(), true); - expect(appDir.childDirectory('web').existsSync(), false); - - projectRoot.deleteSync(recursive: true); - }); - }); - - testWithoutContext('conflictsResolved', () async { - expect(utils.conflictsResolved(''), true); - expect(utils.conflictsResolved('hello'), true); - expect(utils.conflictsResolved('hello\n'), true); - expect(utils.conflictsResolved('hello\nwow a bunch of lines\n\nhi\n'), true); - expect(utils.conflictsResolved('hello\nwow a bunch of lines\n>>>>>>>\nhi\n'), false); - expect(utils.conflictsResolved('hello\nwow a bunch of lines\n=======\nhi\n'), false); - expect(utils.conflictsResolved('hello\nwow a bunch of lines\n<<<<<<<\nhi\n'), false); - expect(utils.conflictsResolved('hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n'), false); - }); -}