Skip to content

Commit 5f34b5b

Browse files
committed
Hard copy of tools edition of migrate
More code Passing compute custom_merge and utils tests More code Running commands Additional tests, resolve-conflicts More tests, cleanup Passing more tests and cleanup Refactoring Standalone command work Analyzer, cleanup, changelog, misc Passes analyzer Cleanup of comments Lean analysisoptions Part 1 of boilerplate retrofit Primary files no longer depend on Flutter tools Cleanup of unused base files Clean up extraneous dead code Fully remove dependency on flutter_tools Add base tests More base tests Add tests, cleanup, validations Analyze Fix tests Merge with upstream Merge tests with main
1 parent 42094d1 commit 5f34b5b

20 files changed

+4947
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2014 The Flutter Authors. All rights reserved.
3+
# Use of this source code is governed by a BSD-style license that can be
4+
# found in the LICENSE file.
5+
6+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
7+
8+
dart run $SCRIPT_DIR/flutter_migrate.dart "$@"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@ECHO off
2+
REM Copyright 2014 The Flutter Authors. All rights reserved.
3+
REM Use of this source code is governed by a BSD-style license that can be
4+
REM found in the LICENSE file.
5+
6+
REM If available, add location of bundled mingit to PATH
7+
SET mingit_path=%FLUTTER_ROOT%\bin\mingit\cmd
8+
IF EXIST "%mingit_path%" SET PATH=%PATH%;%mingit_path%
9+
10+
REM Test if Git is available on the Host
11+
where /q git || ECHO Error: Unable to find git in your PATH. && EXIT /B 1
12+
13+
rem SET flutter_tools_dir=%FLUTTER_ROOT%\packages\flutter_tools
14+
SET cache_dir=%FLUTTER_ROOT%\bin\cache
15+
rem SET snapshot_path=%cache_dir%\flutter_tools.snapshot
16+
SET dart_sdk_path=%cache_dir%\dart-sdk
17+
SET dart=%dart_sdk_path%\bin\dart.exe
18+
19+
SET exit_with_errorlevel=%FLUTTER_ROOT%/bin/internal/exit_with_errorlevel.bat
20+
21+
REM Chaining the call to 'dart' and 'exit' with an ampersand ensures that
22+
REM Windows reads both commands into memory once before executing them. This
23+
REM avoids nasty errors that may otherwise occur when the dart command (e.g. as
24+
REM part of 'flutter upgrade') modifies this batch script while it is executing.
25+
REM
26+
REM Do not use the CALL command in the next line to execute Dart. CALL causes
27+
REM Windows to re-read the line from disk after the CALL command has finished
28+
REM regardless of the ampersand chain.
29+
"%dart%" --disable-dart-dev --packages="%flutter_tools_dir%\.dart_tool\package_config.json" %FLUTTER_TOOL_ARGS% "%snapshot_path%" %* & "%exit_with_errorlevel%"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// @dart = 2.9
6+
7+
import 'package:flutter_migrate/executable.dart' as executable;
8+
9+
void main(List<String> args) {
10+
executable.main(args);
11+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:io';
7+
8+
import 'package:process/process.dart';
9+
10+
import 'src/base/command.dart';
11+
import 'src/base/common.dart';
12+
import 'src/base/file_system.dart';
13+
import 'src/base/io.dart';
14+
import 'src/base/logger.dart';
15+
import 'src/base/signals.dart';
16+
import 'src/base/terminal.dart';
17+
18+
import 'src/commands/abandon.dart';
19+
import 'src/commands/apply.dart';
20+
import 'src/commands/resolve_conflicts.dart';
21+
import 'src/commands/start.dart';
22+
import 'src/commands/status.dart';
23+
24+
Future<void> main(List<String> args) async {
25+
final bool veryVerbose = args.contains('-vv');
26+
final bool verbose = args.contains('-v') || args.contains('--verbose') || veryVerbose;
27+
28+
const ProcessManager localProcessManager = LocalProcessManager();
29+
final FileSystem fileSystem = LocalFileSystem(LocalSignals.instance, Signals.defaultExitSignals, ShutdownHooks());
30+
31+
// flutterRoot must be set early because other features use it (e.g.
32+
// enginePath's initializer uses it). This can only work with the real
33+
// instances of the platform or filesystem, so just use those.
34+
flutterRoot = defaultFlutterRoot(fileSystem: fileSystem);
35+
36+
final Stdio stdio = Stdio();
37+
final Terminal terminal = AnsiTerminal(stdio: stdio);
38+
39+
final LoggerFactory loggerFactory = LoggerFactory(
40+
outputPreferences: OutputPreferences(
41+
wrapText: stdio.hasTerminal,
42+
showColor: stdout.supportsAnsiEscapes,
43+
stdio: stdio,
44+
),
45+
terminal: terminal,
46+
stdio: stdio,
47+
);
48+
final Logger logger = loggerFactory.createLogger(
49+
windows: isWindows,
50+
);
51+
52+
final List<MigrateCommand> commands = <MigrateCommand>[
53+
MigrateStartCommand(
54+
verbose: verbose,
55+
logger: logger,
56+
fileSystem: fileSystem,
57+
processManager: localProcessManager,
58+
),
59+
MigrateStatusCommand(
60+
verbose: verbose,
61+
logger: logger,
62+
fileSystem: fileSystem,
63+
processManager: localProcessManager,
64+
),
65+
MigrateResolveConflictsCommand(
66+
logger: logger,
67+
fileSystem: fileSystem,
68+
terminal: terminal,
69+
),
70+
MigrateAbandonCommand(
71+
logger: logger,
72+
fileSystem: fileSystem,
73+
terminal: terminal,
74+
processManager: localProcessManager
75+
),
76+
MigrateApplyCommand(
77+
verbose: verbose,
78+
logger: logger,
79+
fileSystem: fileSystem,
80+
terminal: terminal,
81+
processManager: localProcessManager
82+
),
83+
];
84+
85+
for (final MigrateCommand command in commands) {
86+
if (command.name == args[0]) {
87+
command.run();
88+
break;
89+
}
90+
}
91+
}
92+
93+
94+
95+
/// An abstraction for instantiation of the correct logger type.
96+
///
97+
/// Our logger class hierarchy and runtime requirements are overly complicated.
98+
class LoggerFactory {
99+
LoggerFactory({
100+
required Terminal terminal,
101+
required Stdio stdio,
102+
required OutputPreferences outputPreferences,
103+
StopwatchFactory stopwatchFactory = const StopwatchFactory(),
104+
}) : _terminal = terminal,
105+
_stdio = stdio,
106+
_stopwatchFactory = stopwatchFactory,
107+
_outputPreferences = outputPreferences;
108+
109+
final Terminal _terminal;
110+
final Stdio _stdio;
111+
final StopwatchFactory _stopwatchFactory;
112+
final OutputPreferences _outputPreferences;
113+
114+
/// Create the appropriate logger for the current platform and configuration.
115+
Logger createLogger({
116+
required bool windows,
117+
}) {
118+
Logger logger;
119+
if (windows) {
120+
logger = WindowsStdoutLogger(
121+
terminal: _terminal,
122+
stdio: _stdio,
123+
outputPreferences: _outputPreferences,
124+
stopwatchFactory: _stopwatchFactory,
125+
);
126+
} else {
127+
logger = StdoutLogger(
128+
terminal: _terminal,
129+
stdio: _stdio,
130+
outputPreferences: _outputPreferences,
131+
stopwatchFactory: _stopwatchFactory
132+
);
133+
}
134+
return logger;
135+
}
136+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
library flutter_migrate;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:process/process.dart';
6+
7+
import '../base/command.dart';
8+
import '../base/file_system.dart';
9+
import '../base/logger.dart';
10+
import '../base/project.dart';
11+
import '../base/terminal.dart';
12+
13+
import '../utils.dart';
14+
15+
/// Abandons the existing migration by deleting the migrate working directory.
16+
class MigrateAbandonCommand extends MigrateCommand {
17+
MigrateAbandonCommand({
18+
required this.logger,
19+
required this.fileSystem,
20+
required this.terminal,
21+
required ProcessManager processManager,
22+
}) : migrateUtils = MigrateUtils(
23+
logger: logger,
24+
fileSystem: fileSystem,
25+
processManager: processManager,
26+
) {
27+
argParser.addOption(
28+
'staging-directory',
29+
help: 'Specifies the custom migration working directory used to stage '
30+
'and edit proposed changes. This path can be absolute or relative '
31+
'to the flutter project root. This defaults to '
32+
'`$kDefaultMigrateStagingDirectoryName`',
33+
valueHelp: 'path',
34+
);
35+
argParser.addOption(
36+
'project-directory',
37+
help: 'The root directory of the flutter project. This defaults to the '
38+
'current working directory if omitted.',
39+
valueHelp: 'path',
40+
);
41+
argParser.addFlag(
42+
'force',
43+
abbr: 'f',
44+
help: 'Delete the migrate working directory without asking for confirmation.',
45+
);
46+
argParser.addFlag(
47+
'flutter-subcommand',
48+
help: 'Enable when using the flutter tool as a subcommand. This changes the '
49+
'wording of log messages to indicate the correct suggested commands to use.',
50+
);
51+
}
52+
53+
final Logger logger;
54+
55+
final FileSystem fileSystem;
56+
57+
final Terminal terminal;
58+
59+
final MigrateUtils migrateUtils;
60+
61+
@override
62+
final String name = 'abandon';
63+
64+
@override
65+
final String description = 'Deletes the current active migration working directory.';
66+
67+
@override
68+
Future<CommandResult> runCommand() async {
69+
final String? projectDirectory = stringArg('project-directory');
70+
final FlutterProjectFactory flutterProjectFactory = FlutterProjectFactory();
71+
final FlutterProject project = projectDirectory == null
72+
? FlutterProject.current(fileSystem)
73+
: flutterProjectFactory.fromDirectory(fileSystem.directory(projectDirectory));
74+
final bool isSubcommand = boolArg('flutter-subcommand') ?? false;
75+
Directory stagingDirectory = project.directory.childDirectory(kDefaultMigrateStagingDirectoryName);
76+
final String? customStagingDirectoryPath = stringArg('staging-directory');
77+
if (customStagingDirectoryPath != null) {
78+
if (fileSystem.path.isAbsolute(customStagingDirectoryPath)) {
79+
stagingDirectory = fileSystem.directory(customStagingDirectoryPath);
80+
} else {
81+
stagingDirectory = project.directory.childDirectory(customStagingDirectoryPath);
82+
}
83+
if (!stagingDirectory.existsSync()) {
84+
logger.printError('Provided staging directory `$customStagingDirectoryPath` '
85+
'does not exist or is not valid.');
86+
return const CommandResult(ExitStatus.fail);
87+
}
88+
}
89+
if (!stagingDirectory.existsSync()) {
90+
logger.printStatus('No migration in progress. Start a new migration with:');
91+
printCommandText('start', logger, standalone: !isSubcommand);
92+
return const CommandResult(ExitStatus.fail);
93+
}
94+
95+
logger.printStatus('\nAbandoning the existing migration will delete the '
96+
'migration staging directory at ${stagingDirectory.path}');
97+
final bool force = boolArg('force') ?? false;
98+
if (!force) {
99+
String selection = 'y';
100+
terminal.usesTerminalUi = true;
101+
try {
102+
selection = await terminal.promptForCharInput(
103+
<String>['y', 'n'],
104+
logger: logger,
105+
prompt: 'Are you sure you wish to continue with abandoning? (y)es, (N)o',
106+
defaultChoiceIndex: 1,
107+
);
108+
} on StateError catch(e) {
109+
logger.printError(
110+
e.message,
111+
indent: 0,
112+
);
113+
}
114+
if (selection != 'y') {
115+
return const CommandResult(ExitStatus.success);
116+
}
117+
}
118+
119+
try {
120+
stagingDirectory.deleteSync(recursive: true);
121+
} on FileSystemException catch (e) {
122+
logger.printError('Deletion failed with: $e');
123+
logger.printError('Please manually delete the staging directory at `${stagingDirectory.path}`');
124+
}
125+
126+
logger.printStatus('\nAbandon complete. Start a new migration with:');
127+
printCommandText('start', logger, standalone: !isSubcommand);
128+
return const CommandResult(ExitStatus.success);
129+
}
130+
}

0 commit comments

Comments
 (0)