mirror of
https://github.com/flutter/flutter
synced 2024-08-25 02:46:31 +00:00
Reverts: flutter/flutter#143166
Initiated by: guidezpl
Reason for reverting: breaks devicelab windows tests
Original PR Author: guidezpl
Reviewed By: {loic-sharma}
This change reverts the following previous change:
Reland #128236, reverted in https://github.com/flutter/flutter/pull/143125.
This PR contains [one additional commit](199baea9a9
), fixing the 2 failed tests.
## Original description
Improves the build output:
1. Gives confirmation that the build succeeded, in green
1. Gives the path to the built executable, without a trailing period to make it slightly easier to cmd/ctrl+open
1. Gives the size of the built executable (when the built executable is self contained)
### `apk`, `appbundle`
<img width="607" alt="image" src="https://github.com/flutter/flutter/assets/6655696/ecc52abe-cd2e-4116-b22a-8385ae3e980d">
<img width="634" alt="image" src="https://github.com/flutter/flutter/assets/6655696/8af8bd33-c0bd-4215-9a06-9652ee019436">
### `macos`, `ios`, `ipa`
Build executables are self-contained and use a newly introduced `OperatingSystemUtils.getDirectorySize`.
<img width="514" alt="image" src="https://github.com/flutter/flutter/assets/6655696/b5918a69-3959-4417-9205-4f501d185257">
<img width="581" alt="image" src="https://github.com/flutter/flutter/assets/6655696/d72fd420-18cf-4470-9e4b-b6ac10fbcd50">
<img width="616" alt="image" src="https://github.com/flutter/flutter/assets/6655696/5f235ce1-252a-4c13-898f-139f6c7bc698">
### `windows`, `linux`, and `web`
Build executables aren't self-contained, and folder size can sometimes overestimate distribution size, therefore their size isn't mentioned (see discussion below).
<img width="647" alt="image" src="https://github.com/flutter/flutter/assets/6655696/7179e771-1eb7-48f6-b770-975bc073437b">
<img width="658" alt="image" src="https://github.com/flutter/flutter/assets/6655696/a6801cab-7b5a-4975-a406-f4c9fa44d7a2">
<img width="608" alt="image" src="https://github.com/flutter/flutter/assets/6655696/ee7c4125-a273-4a65-95d7-ab441edf8ac5">
### Size reporting
When applicable, the printed size matches the OS reported size.
- macOS
<img width="391" alt="image" src="https://github.com/flutter/flutter/assets/6655696/881cbfb1-d355-444b-ab44-c1a6343190ce">
- Windows
<img width="338" alt="image" src="https://github.com/flutter/flutter/assets/6655696/3b806def-3d15-48a9-8a25-df200d6feef7">
- Linux
<img width="320" alt="image" src="https://github.com/flutter/flutter/assets/6655696/89a4aa3d-2148-4f3b-b231-f93a057fee2b">
## Related issues
Part of #120127
Fixes https://github.com/flutter/flutter/issues/121401
This commit is contained in:
parent
2fc76c7896
commit
48c1c2313a
|
@ -135,7 +135,7 @@ class AndroidRunOutputTest extends RunOutputTask {
|
||||||
_findNextMatcherInList(
|
_findNextMatcherInList(
|
||||||
stdout,
|
stdout,
|
||||||
(String line) => line.contains('Built build/app/outputs/flutter-apk/$apk') &&
|
(String line) => line.contains('Built build/app/outputs/flutter-apk/$apk') &&
|
||||||
(!release || line.contains('MB)')),
|
(!release || line.contains('MB).')),
|
||||||
'Built build/app/outputs/flutter-apk/$apk',
|
'Built build/app/outputs/flutter-apk/$apk',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -549,15 +549,14 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
||||||
final File bundleFile = findBundleFile(project, buildInfo, _logger, _usage, _analytics);
|
final File bundleFile = findBundleFile(project, buildInfo, _logger, _usage, _analytics);
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug)
|
final String appSize = (buildInfo.mode == BuildMode.debug)
|
||||||
? '' // Don't display the size when building a debug variant.
|
? '' // Don't display the size when building a debug variant.
|
||||||
: ' (${getSizeAsPlatformMB(bundleFile.lengthSync())})';
|
: ' (${getSizeAsMB(bundleFile.lengthSync())})';
|
||||||
|
|
||||||
if (buildInfo.codeSizeDirectory != null) {
|
if (buildInfo.codeSizeDirectory != null) {
|
||||||
await _performCodeSizeAnalysis('aab', bundleFile, androidBuildInfo);
|
await _performCodeSizeAnalysis('aab', bundleFile, androidBuildInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.printStatus(
|
_logger.printStatus(
|
||||||
'${_logger.terminal.successMark} '
|
'${_logger.terminal.successMark} Built ${_fileSystem.path.relative(bundleFile.path)}$appSize.',
|
||||||
'Built ${_fileSystem.path.relative(bundleFile.path)}$appSize',
|
|
||||||
color: TerminalColor.green,
|
color: TerminalColor.green,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -587,10 +586,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
||||||
|
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug)
|
final String appSize = (buildInfo.mode == BuildMode.debug)
|
||||||
? '' // Don't display the size when building a debug variant.
|
? '' // Don't display the size when building a debug variant.
|
||||||
: ' (${getSizeAsPlatformMB(apkFile.lengthSync())})';
|
: ' (${getSizeAsMB(apkFile.lengthSync())})';
|
||||||
_logger.printStatus(
|
_logger.printStatus(
|
||||||
'${_logger.terminal.successMark} '
|
'${_logger.terminal.successMark} Built ${_fileSystem.path.relative(apkFile.path)}$appSize.',
|
||||||
'Built ${_fileSystem.path.relative(apkFile.path)}$appSize',
|
|
||||||
color: TerminalColor.green,
|
color: TerminalColor.green,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -782,8 +780,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_logger.printStatus(
|
_logger.printStatus(
|
||||||
'${_logger.terminal.successMark} '
|
'${_logger.terminal.successMark} Built ${_fileSystem.path.relative(repoDirectory.path)}.',
|
||||||
'Built ${_fileSystem.path.relative(repoDirectory.path)}',
|
|
||||||
color: TerminalColor.green,
|
color: TerminalColor.green,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,18 +105,6 @@ abstract class OperatingSystemUtils {
|
||||||
/// Return the File representing a new pipe.
|
/// Return the File representing a new pipe.
|
||||||
File makePipe(String path);
|
File makePipe(String path);
|
||||||
|
|
||||||
/// Return a directory's total size in bytes.
|
|
||||||
int? getDirectorySize(Directory directory) {
|
|
||||||
int? size;
|
|
||||||
for (final FileSystemEntity entity in directory.listSync(recursive: true, followLinks: false)) {
|
|
||||||
if (entity is File) {
|
|
||||||
size ??= 0;
|
|
||||||
size += entity.lengthSync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unzip(File file, Directory targetDirectory);
|
void unzip(File file, Directory targetDirectory);
|
||||||
|
|
||||||
void unpack(File gzippedTarFile, Directory targetDirectory);
|
void unpack(File gzippedTarFile, Directory targetDirectory);
|
||||||
|
|
|
@ -7,11 +7,9 @@ import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
import 'package:path/path.dart' as path; // flutter_ignore: package_path_import
|
import 'package:path/path.dart' as path; // flutter_ignore: package_path_import
|
||||||
|
|
||||||
import '../convert.dart';
|
import '../convert.dart';
|
||||||
import 'platform.dart';
|
|
||||||
|
|
||||||
/// A path jointer for URL paths.
|
/// A path jointer for URL paths.
|
||||||
final path.Context urlContext = path.url;
|
final path.Context urlContext = path.url;
|
||||||
|
@ -90,14 +88,9 @@ String getElapsedAsMilliseconds(Duration duration) {
|
||||||
return '${kMillisecondsFormat.format(duration.inMilliseconds)}ms';
|
return '${kMillisecondsFormat.format(duration.inMilliseconds)}ms';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a platform-appropriate [String] representing the size of the given number of bytes.
|
/// Return a String - with units - for the size in MB of the given number of bytes.
|
||||||
String getSizeAsPlatformMB(int bytesLength, {
|
String getSizeAsMB(int bytesLength) {
|
||||||
@visibleForTesting Platform platform = const LocalPlatform()
|
return '${(bytesLength / (1024 * 1024)).toStringAsFixed(1)}MB';
|
||||||
}) {
|
|
||||||
// Because Windows displays 'MB' but actually reports MiB, we calculate MiB
|
|
||||||
// accordingly on Windows.
|
|
||||||
final int bytesInPlatformMB = platform.isWindows ? 1024 * 1024 : 1000 * 1000;
|
|
||||||
return '${(bytesLength / bytesInPlatformMB).toStringAsFixed(1)}MB';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class to maintain a list of items, fire events when items are added or
|
/// A class to maintain a list of items, fire events when items are added or
|
||||||
|
|
|
@ -5,16 +5,15 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:file/file.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:unified_analytics/unified_analytics.dart';
|
import 'package:unified_analytics/unified_analytics.dart';
|
||||||
|
|
||||||
import '../base/analyze_size.dart';
|
import '../base/analyze_size.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
import '../base/error_handling_io.dart';
|
import '../base/error_handling_io.dart';
|
||||||
import '../base/file_system.dart';
|
|
||||||
import '../base/logger.dart';
|
import '../base/logger.dart';
|
||||||
import '../base/process.dart';
|
import '../base/process.dart';
|
||||||
import '../base/terminal.dart';
|
|
||||||
import '../base/utils.dart';
|
import '../base/utils.dart';
|
||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../convert.dart';
|
import '../convert.dart';
|
||||||
|
@ -524,17 +523,7 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
|
||||||
return FlutterCommandResult.success();
|
return FlutterCommandResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Directory outputDirectory = globals.fs.directory(absoluteOutputPath);
|
globals.printStatus('Built IPA to $absoluteOutputPath.');
|
||||||
final int? directorySize = globals.os.getDirectorySize(outputDirectory);
|
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug || directorySize == null)
|
|
||||||
? '' // Don't display the size when building a debug variant.
|
|
||||||
: ' (${getSizeAsPlatformMB(directorySize)})';
|
|
||||||
|
|
||||||
globals.printStatus(
|
|
||||||
'${globals.terminal.successMark} '
|
|
||||||
'Built IPA to ${globals.fs.path.relative(outputDirectory.path)}$appSize',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isAppStoreUpload) {
|
if (isAppStoreUpload) {
|
||||||
globals.printStatus('To upload to the App Store either:');
|
globals.printStatus('To upload to the App Store either:');
|
||||||
|
@ -748,17 +737,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.output != null) {
|
if (result.output != null) {
|
||||||
final Directory outputDirectory = globals.fs.directory(result.output);
|
globals.printStatus('Built ${result.output}.');
|
||||||
final int? directorySize = globals.os.getDirectorySize(outputDirectory);
|
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug || directorySize == null)
|
|
||||||
? '' // Don't display the size when building a debug variant.
|
|
||||||
: ' (${getSizeAsPlatformMB(directorySize)})';
|
|
||||||
|
|
||||||
globals.printStatus(
|
|
||||||
'${globals.terminal.successMark} '
|
|
||||||
'Built ${globals.fs.path.relative(outputDirectory.path)}$appSize',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
|
|
||||||
// When an app is successfully built, record to analytics whether Impeller
|
// When an app is successfully built, record to analytics whether Impeller
|
||||||
// is enabled or disabled.
|
// is enabled or disabled.
|
||||||
|
|
|
@ -577,7 +577,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
|
||||||
shaderCompiler: device!.developmentShaderCompiler,
|
shaderCompiler: device!.developmentShaderCompiler,
|
||||||
);
|
);
|
||||||
devFSStatus.stop();
|
devFSStatus.stop();
|
||||||
_logger.printTrace('Synced ${getSizeAsPlatformMB(report.syncedBytes)}.');
|
_logger.printTrace('Synced ${getSizeAsMB(report.syncedBytes)}.');
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import '../base/common.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
import '../base/logger.dart';
|
import '../base/logger.dart';
|
||||||
import '../base/project_migrator.dart';
|
import '../base/project_migrator.dart';
|
||||||
import '../base/terminal.dart';
|
|
||||||
import '../base/utils.dart';
|
import '../base/utils.dart';
|
||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
|
@ -74,31 +73,16 @@ Future<void> buildLinux(
|
||||||
final Status status = logger.startProgress(
|
final Status status = logger.startProgress(
|
||||||
'Building Linux application...',
|
'Building Linux application...',
|
||||||
);
|
);
|
||||||
final String buildModeName = buildInfo.mode.cliName;
|
|
||||||
final Directory platformBuildDirectory = globals.fs.directory(getLinuxBuildDirectory(targetPlatform));
|
|
||||||
final Directory buildDirectory = platformBuildDirectory.childDirectory(buildModeName);
|
|
||||||
try {
|
try {
|
||||||
|
final String buildModeName = buildInfo.mode.cliName;
|
||||||
|
final Directory buildDirectory =
|
||||||
|
globals.fs.directory(getLinuxBuildDirectory(targetPlatform)).childDirectory(buildModeName);
|
||||||
await _runCmake(buildModeName, linuxProject.cmakeFile.parent, buildDirectory,
|
await _runCmake(buildModeName, linuxProject.cmakeFile.parent, buildDirectory,
|
||||||
needCrossBuild, targetPlatform, targetSysroot);
|
needCrossBuild, targetPlatform, targetSysroot);
|
||||||
await _runBuild(buildDirectory);
|
await _runBuild(buildDirectory);
|
||||||
} finally {
|
} finally {
|
||||||
status.cancel();
|
status.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String? binaryName = getCmakeExecutableName(linuxProject);
|
|
||||||
final File binaryFile = buildDirectory
|
|
||||||
.childDirectory('bundle')
|
|
||||||
.childFile('$binaryName');
|
|
||||||
final FileSystemEntity buildOutput = binaryFile.existsSync() ? binaryFile : binaryFile.parent;
|
|
||||||
// We don't print a size because the output directory can contain
|
|
||||||
// optional files not needed by the user and because the binary is not
|
|
||||||
// self-contained.
|
|
||||||
globals.printStatus(
|
|
||||||
'${globals.terminal.successMark} '
|
|
||||||
'Built ${globals.fs.path.relative(buildOutput.path)}',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (buildInfo.codeSizeDirectory != null && sizeAnalyzer != null) {
|
if (buildInfo.codeSizeDirectory != null && sizeAnalyzer != null) {
|
||||||
final String arch = getNameForTargetPlatform(targetPlatform);
|
final String arch = getNameForTargetPlatform(targetPlatform);
|
||||||
final File codeSizeFile = globals.fs.directory(buildInfo.codeSizeDirectory)
|
final File codeSizeFile = globals.fs.directory(buildInfo.codeSizeDirectory)
|
||||||
|
|
|
@ -9,8 +9,6 @@ import '../base/common.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
import '../base/logger.dart';
|
import '../base/logger.dart';
|
||||||
import '../base/project_migrator.dart';
|
import '../base/project_migrator.dart';
|
||||||
import '../base/terminal.dart';
|
|
||||||
import '../base/utils.dart';
|
|
||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../convert.dart';
|
import '../convert.dart';
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
|
@ -20,7 +18,6 @@ import '../migrations/xcode_project_object_version_migration.dart';
|
||||||
import '../migrations/xcode_script_build_phase_migration.dart';
|
import '../migrations/xcode_script_build_phase_migration.dart';
|
||||||
import '../migrations/xcode_thin_binary_build_phase_input_paths_migration.dart';
|
import '../migrations/xcode_thin_binary_build_phase_input_paths_migration.dart';
|
||||||
import '../project.dart';
|
import '../project.dart';
|
||||||
import 'application_package.dart';
|
|
||||||
import 'cocoapod_utils.dart';
|
import 'cocoapod_utils.dart';
|
||||||
import 'migrations/flutter_application_migration.dart';
|
import 'migrations/flutter_application_migration.dart';
|
||||||
import 'migrations/macos_deployment_target_migration.dart';
|
import 'migrations/macos_deployment_target_migration.dart';
|
||||||
|
@ -161,24 +158,9 @@ Future<void> buildMacOS({
|
||||||
} finally {
|
} finally {
|
||||||
status.cancel();
|
status.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
throwToolExit('Build process failed');
|
throwToolExit('Build process failed');
|
||||||
}
|
}
|
||||||
final String? applicationBundle = MacOSApp.fromMacOSProject(flutterProject.macos).applicationBundle(buildInfo);
|
|
||||||
if (applicationBundle != null) {
|
|
||||||
final Directory outputDirectory = globals.fs.directory(applicationBundle);
|
|
||||||
// This output directory is the .app folder itself.
|
|
||||||
final int? directorySize = globals.os.getDirectorySize(outputDirectory);
|
|
||||||
final String appSize = (buildInfo.mode == BuildMode.debug || directorySize == null)
|
|
||||||
? '' // Don't display the size when building a debug variant.
|
|
||||||
: ' (${getSizeAsPlatformMB(directorySize)})';
|
|
||||||
globals.printStatus(
|
|
||||||
'${globals.terminal.successMark} '
|
|
||||||
'Built ${globals.fs.path.relative(outputDirectory.path)}$appSize',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await _writeCodeSizeAnalysis(buildInfo, sizeAnalyzer);
|
await _writeCodeSizeAnalysis(buildInfo, sizeAnalyzer);
|
||||||
final Duration elapsedDuration = sw.elapsed;
|
final Duration elapsedDuration = sw.elapsed;
|
||||||
globals.flutterUsage.sendTiming('build', 'xcode-macos', elapsedDuration);
|
globals.flutterUsage.sendTiming('build', 'xcode-macos', elapsedDuration);
|
||||||
|
|
|
@ -597,7 +597,7 @@ class FlutterDevice {
|
||||||
return UpdateFSReport();
|
return UpdateFSReport();
|
||||||
}
|
}
|
||||||
devFSStatus.stop();
|
devFSStatus.stop();
|
||||||
globals.printTrace('Synced ${getSizeAsPlatformMB(report.syncedBytes)}.');
|
globals.printTrace('Synced ${getSizeAsMB(report.syncedBytes)}.');
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import '../base/common.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
import '../base/logger.dart';
|
import '../base/logger.dart';
|
||||||
import '../base/project_migrator.dart';
|
import '../base/project_migrator.dart';
|
||||||
import '../base/terminal.dart';
|
|
||||||
import '../base/utils.dart';
|
import '../base/utils.dart';
|
||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../build_system/build_system.dart';
|
import '../build_system/build_system.dart';
|
||||||
|
@ -131,14 +130,6 @@ class WebBuilder {
|
||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't print a size because the output directory can contain
|
|
||||||
// optional files not needed by the user.
|
|
||||||
globals.printStatus(
|
|
||||||
'${globals.terminal.successMark} '
|
|
||||||
'Built ${globals.fs.path.relative(outputDirectory.path)}',
|
|
||||||
color: TerminalColor.green,
|
|
||||||
);
|
|
||||||
|
|
||||||
final String buildSettingsString = _buildEventAnalyticsSettings(
|
final String buildSettingsString = _buildEventAnalyticsSettings(
|
||||||
configs: compilerConfigs,
|
configs: compilerConfigs,
|
||||||
);
|
);
|
||||||
|
|
|
@ -114,19 +114,20 @@ Future<void> buildWindows(
|
||||||
}
|
}
|
||||||
|
|
||||||
final String? binaryName = getCmakeExecutableName(windowsProject);
|
final String? binaryName = getCmakeExecutableName(windowsProject);
|
||||||
final File binaryFile = buildDirectory
|
final File appFile = buildDirectory
|
||||||
.childDirectory('runner')
|
.childDirectory('runner')
|
||||||
.childDirectory(sentenceCase(buildModeName))
|
.childDirectory(sentenceCase(buildModeName))
|
||||||
.childFile('$binaryName.exe');
|
.childFile('$binaryName.exe');
|
||||||
final FileSystemEntity buildOutput = binaryFile.existsSync() ? binaryFile : binaryFile.parent;
|
if (appFile.existsSync()) {
|
||||||
// We don't print a size because the output directory can contain
|
final String appSize = (buildInfo.mode == BuildMode.debug)
|
||||||
// optional files not needed by the user and because the binary is not
|
? '' // Don't display the size when building a debug variant.
|
||||||
// self-contained.
|
: ' (${getSizeAsMB(appFile.lengthSync())})';
|
||||||
globals.logger.printStatus(
|
globals.logger.printStatus(
|
||||||
'${globals.logger.terminal.successMark} '
|
'${globals.logger.terminal.successMark} '
|
||||||
'Built ${globals.fs.path.relative(buildOutput.path)}',
|
'Built ${globals.fs.path.relative(appFile.path)}$appSize.',
|
||||||
color: TerminalColor.green,
|
color: TerminalColor.green,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (buildInfo.codeSizeDirectory != null && sizeAnalyzer != null) {
|
if (buildInfo.codeSizeDirectory != null && sizeAnalyzer != null) {
|
||||||
final String arch = getNameForTargetPlatform(targetPlatform);
|
final String arch = getNameForTargetPlatform(targetPlatform);
|
||||||
|
|
|
@ -282,36 +282,6 @@ void main() {
|
||||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
testUsingContext('ios build outputs path and size when successful', () async {
|
|
||||||
final BuildCommand command = BuildCommand(
|
|
||||||
artifacts: artifacts,
|
|
||||||
androidSdk: FakeAndroidSdk(),
|
|
||||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
|
||||||
fileSystem: MemoryFileSystem.test(),
|
|
||||||
logger: BufferLogger.test(),
|
|
||||||
processUtils: processUtils,
|
|
||||||
osUtils: FakeOperatingSystemUtils(),
|
|
||||||
);
|
|
||||||
createMinimalMockProjectFiles();
|
|
||||||
|
|
||||||
await createTestCommandRunner(command).run(
|
|
||||||
const <String>['build', 'ios', '--no-pub']
|
|
||||||
);
|
|
||||||
expect(testLogger.statusText, contains(RegExp(r'✓ Built build/ios/iphoneos/Runner\.app \(\d+\.\d+MB\)')));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
|
||||||
xattrCommand,
|
|
||||||
setUpFakeXcodeBuildHandler(onRun: (_) {
|
|
||||||
fileSystem.directory('build/ios/Release-iphoneos/Runner.app').createSync(recursive: true);
|
|
||||||
}),
|
|
||||||
setUpRsyncCommand(),
|
|
||||||
]),
|
|
||||||
Platform: () => macosPlatform,
|
|
||||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('ios build invokes xcode build', () async {
|
testUsingContext('ios build invokes xcode build', () async {
|
||||||
final BuildCommand command = BuildCommand(
|
final BuildCommand command = BuildCommand(
|
||||||
artifacts: artifacts,
|
artifacts: artifacts,
|
||||||
|
|
|
@ -576,7 +576,7 @@ void main() {
|
||||||
|
|
||||||
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
||||||
expect(logger.statusText, contains('Building App Store IPA'));
|
expect(logger.statusText, contains('Building App Store IPA'));
|
||||||
expect(logger.statusText, contains(RegExp(r'Built IPA to build/ios/ipa \(\d+\.\d+MB\)')));
|
expect(logger.statusText, contains('Built IPA to /build/ios/ipa'));
|
||||||
expect(logger.statusText, contains('To upload to the App Store'));
|
expect(logger.statusText, contains('To upload to the App Store'));
|
||||||
expect(logger.statusText, contains('Apple Transporter macOS app'));
|
expect(logger.statusText, contains('Apple Transporter macOS app'));
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
@ -628,7 +628,7 @@ void main() {
|
||||||
|
|
||||||
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
||||||
expect(logger.statusText, contains('Building ad-hoc IPA'));
|
expect(logger.statusText, contains('Building ad-hoc IPA'));
|
||||||
expect(logger.statusText, contains(RegExp(r'Built IPA to build/ios/ipa \(\d+\.\d+MB\)')));
|
expect(logger.statusText, contains('Built IPA to /build/ios/ipa'));
|
||||||
// Don'ltruct how to upload to the App Store.
|
// Don'ltruct how to upload to the App Store.
|
||||||
expect(logger.statusText, isNot(contains('To upload')));
|
expect(logger.statusText, isNot(contains('To upload')));
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
@ -680,7 +680,7 @@ void main() {
|
||||||
|
|
||||||
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
expect(logger.statusText, contains('build/ios/archive/Runner.xcarchive'));
|
||||||
expect(logger.statusText, contains('Building enterprise IPA'));
|
expect(logger.statusText, contains('Building enterprise IPA'));
|
||||||
expect(logger.statusText, contains(RegExp(r'Built IPA to build/ios/ipa \(\d+\.\d+MB\)')));
|
expect(logger.statusText, contains('Built IPA to /build/ios/ipa'));
|
||||||
// Don'ltruct how to upload to the App Store.
|
// Don'ltruct how to upload to the App Store.
|
||||||
expect(logger.statusText, isNot(contains('To upload')));
|
expect(logger.statusText, isNot(contains('To upload')));
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
@ -889,7 +889,7 @@ void main() {
|
||||||
|
|
||||||
testUsingContext('ipa build invokes xcode build export archive when passed plist', () async {
|
testUsingContext('ipa build invokes xcode build export archive when passed plist', () async {
|
||||||
final String outputPath =
|
final String outputPath =
|
||||||
fileSystem.path.relative(fileSystem.path.join('build', 'ios', 'ipa'));
|
fileSystem.path.absolute(fileSystem.path.join('build', 'ios', 'ipa'));
|
||||||
final File exportOptions = fileSystem.file('ExportOptions.plist')
|
final File exportOptions = fileSystem.file('ExportOptions.plist')
|
||||||
..createSync();
|
..createSync();
|
||||||
final BuildCommand command = BuildCommand(
|
final BuildCommand command = BuildCommand(
|
||||||
|
@ -918,7 +918,7 @@ void main() {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(logger.statusText, contains(RegExp('Built IPA to $outputPath ' r'\(\d+\.\d+MB\)')));
|
expect(logger.statusText, contains('Built IPA to $outputPath.'));
|
||||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
|
|
|
@ -194,35 +194,6 @@ void main() {
|
||||||
FeatureFlags: () => TestFeatureFlags(),
|
FeatureFlags: () => TestFeatureFlags(),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Linux build outputs path when successful', () async {
|
|
||||||
final BuildCommand command = BuildCommand(
|
|
||||||
artifacts: artifacts,
|
|
||||||
androidSdk: FakeAndroidSdk(),
|
|
||||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
|
||||||
fileSystem: MemoryFileSystem.test(),
|
|
||||||
logger: BufferLogger.test(),
|
|
||||||
processUtils: processUtils,
|
|
||||||
osUtils: FakeOperatingSystemUtils(),
|
|
||||||
);
|
|
||||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
|
||||||
cmakeCommand('release'),
|
|
||||||
ninjaCommand('release'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
setUpMockProjectFilesForBuild();
|
|
||||||
|
|
||||||
await createTestCommandRunner(command).run(
|
|
||||||
const <String>['build', 'linux', '--no-pub']
|
|
||||||
);
|
|
||||||
expect(testLogger.statusText, contains('✓ Built build/linux/x64/release/bundle'));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => processManager,
|
|
||||||
Platform: () => linuxPlatform,
|
|
||||||
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
|
|
||||||
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('Linux build invokes CMake and ninja, and writes temporary files', () async {
|
testUsingContext('Linux build invokes CMake and ninja, and writes temporary files', () async {
|
||||||
final BuildCommand command = BuildCommand(
|
final BuildCommand command = BuildCommand(
|
||||||
artifacts: artifacts,
|
artifacts: artifacts,
|
||||||
|
|
|
@ -301,31 +301,6 @@ STDERR STUFF
|
||||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('macOS build outputs path and size when successful', () async {
|
|
||||||
final BuildCommand command = BuildCommand(
|
|
||||||
artifacts: artifacts,
|
|
||||||
androidSdk: FakeAndroidSdk(),
|
|
||||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
|
||||||
fileSystem: MemoryFileSystem.test(),
|
|
||||||
processUtils: processUtils,
|
|
||||||
logger: BufferLogger.test(),
|
|
||||||
osUtils: FakeOperatingSystemUtils(),
|
|
||||||
);
|
|
||||||
createMinimalMockProjectFiles();
|
|
||||||
|
|
||||||
await createTestCommandRunner(command).run(
|
|
||||||
const <String>['build', 'macos', '--no-pub']
|
|
||||||
);
|
|
||||||
expect(testLogger.statusText, contains(RegExp(r'✓ Built build/macos/Build/Products/Release/example.app \(\d+\.\d+MB\)')));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
|
||||||
setUpFakeXcodeBuildHandler('Release'),
|
|
||||||
]),
|
|
||||||
Platform: () => macosPlatform,
|
|
||||||
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('macOS build invokes xcode build (debug)', () async {
|
testUsingContext('macOS build invokes xcode build (debug)', () async {
|
||||||
final BuildCommand command = BuildCommand(
|
final BuildCommand command = BuildCommand(
|
||||||
artifacts: artifacts,
|
artifacts: artifacts,
|
||||||
|
@ -664,7 +639,7 @@ STDERR STUFF
|
||||||
);
|
);
|
||||||
createMinimalMockProjectFiles();
|
createMinimalMockProjectFiles();
|
||||||
|
|
||||||
fileSystem.file('build/macos/Build/Products/Release/example.app/App')
|
fileSystem.file('build/macos/Build/Products/Release/Runner.app/App')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
|
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0));
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,6 @@ void main() {
|
||||||
final Directory buildDir = fileSystem.directory(fileSystem.path.join('build', 'web'));
|
final Directory buildDir = fileSystem.directory(fileSystem.path.join('build', 'web'));
|
||||||
|
|
||||||
expect(buildDir.existsSync(), true);
|
expect(buildDir.existsSync(), true);
|
||||||
expect(testLogger.statusText, contains('✓ Built ${buildDir.path}'));
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => fakePlatform,
|
Platform: () => fakePlatform,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
|
@ -237,7 +236,6 @@ void main() {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(buildDir.existsSync(), true);
|
expect(buildDir.existsSync(), true);
|
||||||
expect(testLogger.statusText, contains('✓ Built $newBuildDir'));
|
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => fakePlatform,
|
Platform: () => fakePlatform,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
|
|
|
@ -570,28 +570,6 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
|
||||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('Windows build outputs path when successful', () async {
|
|
||||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
|
||||||
final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test(), operatingSystemUtils: FakeOperatingSystemUtils())
|
|
||||||
..visualStudioOverride = fakeVisualStudio;
|
|
||||||
setUpMockProjectFilesForBuild();
|
|
||||||
|
|
||||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
|
||||||
cmakeGenerationCommand(),
|
|
||||||
buildCommand('Release'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await createTestCommandRunner(command).run(
|
|
||||||
const <String>['windows', '--release', '--no-pub']
|
|
||||||
);
|
|
||||||
expect(testLogger.statusText, contains(r'✓ Built build\windows\x64\runner\Release'));
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fileSystem,
|
|
||||||
ProcessManager: () => processManager,
|
|
||||||
Platform: () => windowsPlatform,
|
|
||||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('Windows build passes correct generator', () async {
|
testUsingContext('Windows build passes correct generator', () async {
|
||||||
const String generator = 'A different generator';
|
const String generator = 'A different generator';
|
||||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(
|
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(
|
||||||
|
|
|
@ -751,7 +751,7 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => unknownOsUtils.unzip(fileSystem.file('foo.zip'), fileSystem.currentDirectory),
|
() => unknownOsUtils.unzip(fileSystem.file('foo.zip'), fileSystem.currentDirectory),
|
||||||
throwsToolExit
|
throwsToolExit
|
||||||
(message: 'Missing "unzip" tool. Unable to extract foo.zip.\n'
|
(message: 'Missing "unzip" tool. Unable to extract foo.zip.\n'
|
||||||
'Please install unzip.'),
|
'Please install unzip.'),
|
||||||
|
@ -759,26 +759,6 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('directory size', () {
|
|
||||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
||||||
final OperatingSystemUtils osUtils = OperatingSystemUtils(
|
|
||||||
fileSystem: fileSystem,
|
|
||||||
logger: BufferLogger.test(),
|
|
||||||
platform: FakePlatform(operatingSystem: 'fuchsia'),
|
|
||||||
processManager: fakeProcessManager,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Directory directory = fileSystem.systemTempDirectory.childDirectory('test_directory');
|
|
||||||
directory.createSync();
|
|
||||||
directory.childFile('file1.txt').writeAsBytesSync(List<int>.filled(10, 0));
|
|
||||||
directory.childFile('file2.txt').writeAsBytesSync(List<int>.filled(20, 0));
|
|
||||||
final Directory subDirectory = directory.childDirectory('sub_directory');
|
|
||||||
subDirectory.createSync();
|
|
||||||
subDirectory.childFile('file3.txt').writeAsBytesSync(List<int>.filled(15, 0));
|
|
||||||
|
|
||||||
expect(osUtils.getDirectorySize(directory), equals(10 + 20 + 15));
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('stream compression level', () {
|
testWithoutContext('stream compression level', () {
|
||||||
expect(OperatingSystemUtils.gzipLevel1.level, equals(1));
|
expect(OperatingSystemUtils.gzipLevel1.level, equals(1));
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter_tools/src/base/platform.dart';
|
|
||||||
import 'package:flutter_tools/src/base/terminal.dart';
|
import 'package:flutter_tools/src/base/terminal.dart';
|
||||||
import 'package:flutter_tools/src/base/utils.dart';
|
import 'package:flutter_tools/src/base/utils.dart';
|
||||||
import 'package:flutter_tools/src/base/version.dart';
|
import 'package:flutter_tools/src/base/version.dart';
|
||||||
|
@ -407,14 +406,4 @@ needs to be wrapped.
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('getSizeAsMB', () async {
|
|
||||||
// ignore: avoid_redundant_argument_values
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'linux')), '10.0MB');
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'macos')), '10.0MB');
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'windows')), '9.5MB');
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'android')), '10.0MB');
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'ios')), '10.0MB');
|
|
||||||
expect(getSizeAsPlatformMB(10 * 1000 * 1000, platform: FakePlatform(operatingSystem: 'web')), '10.0MB');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,9 +550,6 @@ class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {
|
||||||
@override
|
@override
|
||||||
List<File> whichAll(String execName) => <File>[];
|
List<File> whichAll(String execName) => <File>[];
|
||||||
|
|
||||||
@override
|
|
||||||
int? getDirectorySize(Directory directory) => 10000000; // 10 MB / 9.5 MiB
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void unzip(File file, Directory targetDirectory) { }
|
void unzip(File file, Directory targetDirectory) { }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue