Unverified Commit b92bb62d authored by stuartmorgan's avatar stuartmorgan Committed by GitHub

Fix Windows and Linux plugin template filenames (#66997)

parent 03190b8e
......@@ -166,6 +166,7 @@ class Template {
final String projectName = context['projectName'] as String;
final String androidIdentifier = context['androidIdentifier'] as String;
final String pluginClass = context['pluginClass'] as String;
final String pluginClassSnakeCase = context['pluginClassSnakeCase'] as String;
final String destinationDirPath = destination.absolute.path;
final String pathSeparator = _fileSystem.path.separator;
String finalDestinationPath = _fileSystem.path
......@@ -181,6 +182,10 @@ class Template {
if (projectName != null) {
finalDestinationPath = finalDestinationPath.replaceAll('projectName', projectName);
}
// This must be before the pluginClass replacement step.
if (pluginClassSnakeCase != null) {
finalDestinationPath = finalDestinationPath.replaceAll('pluginClassSnakeCase', pluginClassSnakeCase);
}
if (pluginClass != null) {
finalDestinationPath = finalDestinationPath.replaceAll('pluginClass', pluginClass);
}
......
......@@ -2,10 +2,12 @@ cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME "{{projectName}}")
project(${PROJECT_NAME} LANGUAGES CXX)
set(PLUGIN_NAME "${PROJECT_NAME}_plugin")
# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "{{projectName}}_plugin")
add_library(${PLUGIN_NAME} SHARED
"${PLUGIN_NAME}.cc"
"{{pluginClassSnakeCase}}.cc"
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
......
#include "include/{{projectName}}/{{projectName}}_plugin.h"
#include "include/{{projectName}}/{{pluginClassSnakeCase}}.h"
#include <flutter_linux/flutter_linux.h>
#include <gtk/gtk.h>
......
......@@ -2,10 +2,12 @@ cmake_minimum_required(VERSION 3.15)
set(PROJECT_NAME "{{projectName}}")
project(${PROJECT_NAME} LANGUAGES CXX)
set(PLUGIN_NAME "${PROJECT_NAME}_plugin")
# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "{{projectName}}_plugin")
add_library(${PLUGIN_NAME} SHARED
"${PLUGIN_NAME}.cpp"
"{{pluginClassSnakeCase}}.cpp"
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
......
#include "include/{{projectName}}/{{projectName}}_plugin.h"
#include "include/{{projectName}}/{{pluginClassSnakeCase}}.h"
// This must be included before many other Windows headers.
#include <windows.h>
......
......@@ -263,8 +263,8 @@
"templates/plugin/lib/projectName.dart.tmpl",
"templates/plugin/LICENSE.tmpl",
"templates/plugin/linux.tmpl/CMakeLists.txt.tmpl",
"templates/plugin/linux.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl",
"templates/plugin/linux.tmpl/projectName_plugin.cc.tmpl",
"templates/plugin/linux.tmpl/include/projectName.tmpl/pluginClassSnakeCase.h.tmpl",
"templates/plugin/linux.tmpl/pluginClassSnakeCase.cc.tmpl",
"templates/plugin/macos.tmpl/Classes/pluginClass.swift.tmpl",
"templates/plugin/macos.tmpl/projectName.podspec.tmpl",
"templates/plugin/projectName.iml.tmpl",
......@@ -273,8 +273,8 @@
"templates/plugin/test/projectName_test.dart.tmpl",
"templates/plugin/windows.tmpl/.gitignore",
"templates/plugin/windows.tmpl/CMakeLists.txt.tmpl",
"templates/plugin/windows.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl",
"templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl",
"templates/plugin/windows.tmpl/include/projectName.tmpl/pluginClassSnakeCase.h.tmpl",
"templates/plugin/windows.tmpl/pluginClassSnakeCase.cpp.tmpl",
"templates/plugin/lib/projectName_web.dart.tmpl"
]
}
......@@ -2044,6 +2044,148 @@ void main() {
expect(buildContent.contains('targetSdkVersion 29'), true);
});
testUsingContext('Linux plugins handle partially camel-case project names correctly', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
const String projectName = 'foo_BarBaz';
final Directory projectDir = tempDir.childDirectory(projectName);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=linux', projectDir.path]);
final Directory platformDir = projectDir.childDirectory('linux');
const String classFilenameBase = 'foo_bar_baz_plugin';
const String headerName = '$classFilenameBase.h';
final File headerFile = platformDir
.childDirectory('include')
.childDirectory(projectName)
.childFile(headerName);
final File implFile = platformDir.childFile('$classFilenameBase.cc');
// Ensure that the files have the right names.
expect(headerFile.existsSync(), true);
expect(implFile.existsSync(), true);
// Ensure that the include is correct.
expect(implFile.readAsStringSync(), contains(headerName));
// Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cc"'));
expect(cmakeContents, contains('set(PLUGIN_NAME "foo_BarBaz_plugin")'));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
testUsingContext('Windows plugins handle partially camel-case project names correctly', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
const String projectName = 'foo_BarBaz';
final Directory projectDir = tempDir.childDirectory(projectName);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=windows', projectDir.path]);
final Directory platformDir = projectDir.childDirectory('windows');
const String classFilenameBase = 'foo_bar_baz_plugin';
const String headerName = '$classFilenameBase.h';
final File headerFile = platformDir
.childDirectory('include')
.childDirectory(projectName)
.childFile(headerName);
final File implFile = platformDir.childFile('$classFilenameBase.cpp');
// Ensure that the files have the right names.
expect(headerFile.existsSync(), true);
expect(implFile.existsSync(), true);
// Ensure that the include is correct.
expect(implFile.readAsStringSync(), contains(headerName));
// Ensure that the plugin target name matches the post-processed version.
// Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cpp"'));
expect(cmakeContents, contains('set(PLUGIN_NAME "foo_BarBaz_plugin")'));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
testUsingContext('Linux plugins handle project names ending in _plugin correctly', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
const String projectName = 'foo_bar_plugin';
final Directory projectDir = tempDir.childDirectory(projectName);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=linux', projectDir.path]);
final Directory platformDir = projectDir.childDirectory('linux');
// If the project already ends in _plugin, it shouldn't be added again.
const String classFilenameBase = projectName;
const String headerName = '$classFilenameBase.h';
final File headerFile = platformDir
.childDirectory('include')
.childDirectory(projectName)
.childFile(headerName);
final File implFile = platformDir.childFile('$classFilenameBase.cc');
// Ensure that the files have the right names.
expect(headerFile.existsSync(), true);
expect(implFile.existsSync(), true);
// Ensure that the include is correct.
expect(implFile.readAsStringSync(), contains(headerName));
// Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cc"'));
// The "_plugin_plugin" suffix is intentional; because the target names must
// be unique across the ecosystem, no canonicalization can be done,
// otherwise plugins called "foo_bar" and "foo_bar_plugin" would collide in
// builds.
expect(cmakeContents, contains('set(PLUGIN_NAME "foo_bar_plugin_plugin")'));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
testUsingContext('Windows plugins handle project names ending in _plugin correctly', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
const String projectName = 'foo_bar_plugin';
final Directory projectDir = tempDir.childDirectory(projectName);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=windows', projectDir.path]);
final Directory platformDir = projectDir.childDirectory('windows');
// If the project already ends in _plugin, it shouldn't be added again.
const String classFilenameBase = projectName;
const String headerName = '$classFilenameBase.h';
final File headerFile = platformDir
.childDirectory('include')
.childDirectory(projectName)
.childFile(headerName);
final File implFile = platformDir.childFile('$classFilenameBase.cpp');
// Ensure that the files have the right names.
expect(headerFile.existsSync(), true);
expect(implFile.existsSync(), true);
// Ensure that the include is correct.
expect(implFile.readAsStringSync(), contains(headerName));
// Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cpp"'));
// The "_plugin_plugin" suffix is intentional; because the target names must
// be unique across the ecosystem, no canonicalization can be done,
// otherwise plugins called "foo_bar" and "foo_bar_plugin" would collide in
// builds.
expect(cmakeContents, contains('set(PLUGIN_NAME "foo_bar_plugin_plugin")'));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
}
Future<void> _createProject(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment