blob: 1933977fe83bf0eb5943939d479a00722b81b24d [file] [log] [blame]
// 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:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/cmake_project.dart';
import 'package:flutter_tools/src/migrations/cmake_custom_command_migration.dart';
import 'package:flutter_tools/src/migrations/cmake_native_assets_migration.dart';
import 'package:test/fake.dart';
import '../../src/common.dart';
void main () {
group('CMake project migration', () {
group('migrate add_custom_command() to use VERBATIM', () {
late MemoryFileSystem memoryFileSystem;
late BufferLogger testLogger;
late FakeCmakeProject mockCmakeProject;
late File managedCmakeFile;
setUp(() {
memoryFileSystem = MemoryFileSystem.test();
managedCmakeFile = memoryFileSystem.file('CMakeLists.txtx');
testLogger = BufferLogger(
terminal: Terminal.test(),
outputPreferences: OutputPreferences.test(),
);
mockCmakeProject = FakeCmakeProject(managedCmakeFile);
});
testWithoutContext('skipped if files are missing', () async {
final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
mockCmakeProject,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.existsSync(), isFalse);
expect(testLogger.traceText, contains('CMake project not found, skipping add_custom_command() VERBATIM migration'));
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if nothing to migrate', () async {
const String contents = 'Nothing to migrate';
managedCmakeFile.writeAsStringSync(contents);
final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
mockCmakeProject,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
expect(managedCmakeFile.readAsStringSync(), contents);
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if already migrated', () async {
const String contents = r'''
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
''';
managedCmakeFile.writeAsStringSync(contents);
final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
mockCmakeProject,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
expect(managedCmakeFile.readAsStringSync(), contents);
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('is migrated to use VERBATIM', () async {
managedCmakeFile.writeAsStringSync(r'''
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
)
''');
final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
mockCmakeProject,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.readAsStringSync(), r'''
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
''');
expect(testLogger.statusText, contains('add_custom_command() missing VERBATIM or FLUTTER_TARGET_PLATFORM, updating.'));
});
testWithoutContext('is migrated to use FLUTTER_TARGET_PLATFORM', () async {
managedCmakeFile.writeAsStringSync(r'''
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
linux-x64 ${CMAKE_BUILD_TYPE}
VERBATIM
)
''');
final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
mockCmakeProject,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.readAsStringSync(), r'''
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
''');
expect(testLogger.statusText, contains('add_custom_command() missing VERBATIM or FLUTTER_TARGET_PLATFORM, updating.'));
});
});
group('migrate add install() NATIVE_ASSETS_DIR command', () {
late MemoryFileSystem memoryFileSystem;
late BufferLogger testLogger;
late FakeCmakeProject mockCmakeProject;
late File managedCmakeFile;
setUp(() {
memoryFileSystem = MemoryFileSystem.test();
managedCmakeFile = memoryFileSystem.file('CMakeLists.txtx');
testLogger = BufferLogger(
terminal: Terminal.test(),
outputPreferences: OutputPreferences.test(),
);
mockCmakeProject = FakeCmakeProject(managedCmakeFile);
});
testWithoutContext('skipped if files are missing', () async {
final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration(
mockCmakeProject,
'linux',
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.existsSync(), isFalse);
expect(testLogger.traceText, contains('CMake project not found, skipping install() NATIVE_ASSETS_DIR migration.'));
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if nothing to migrate', () async {
const String contents = 'Nothing to migrate';
managedCmakeFile.writeAsStringSync(contents);
final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration(
mockCmakeProject,
'linux',
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
expect(managedCmakeFile.readAsStringSync(), contents);
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if already migrated', () async {
const String contents = r'''
# Copy the native assets provided by the build.dart from all packages.
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
''';
managedCmakeFile.writeAsStringSync(contents);
final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration(
mockCmakeProject,
'linux',
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
expect(managedCmakeFile.readAsStringSync(), contents);
expect(testLogger.statusText, isEmpty);
});
for (final String os in <String>['linux', 'windows']) {
testWithoutContext('is migrated to copy native assets', () async {
managedCmakeFile.writeAsStringSync(r'''
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
''');
final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration(
mockCmakeProject,
os,
testLogger,
);
await cmakeProjectMigration.migrate();
expect(managedCmakeFile.readAsStringSync(), '''
foreach(bundled_library \${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "\${bundled_library}"
DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Copy the native assets provided by the build.dart from all packages.
set(NATIVE_ASSETS_DIR "\${PROJECT_BUILD_DIR}native_assets/$os/")
install(DIRECTORY "\${NATIVE_ASSETS_DIR}"
DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \\"\${INSTALL_BUNDLE_DATA_DIR}/\${FLUTTER_ASSET_DIR_NAME}\\")
" COMPONENT Runtime)
install(DIRECTORY "\${PROJECT_BUILD_DIR}/\${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "\${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
''');
expect(testLogger.statusText,
contains('CMake missing install() NATIVE_ASSETS_DIR command, updating.'));
});
}
});
});
}
class FakeCmakeProject extends Fake implements CmakeBasedProject {
FakeCmakeProject(this.managedCmakeFile);
@override
final File managedCmakeFile;
}