Skip to content

Commit 6fd8233

Browse files
committed
Implement DartPluginRegistrant build target for Tizen
1 parent f7ea1cd commit 6fd8233

File tree

6 files changed

+194
-85
lines changed

6 files changed

+194
-85
lines changed

lib/build_targets/plugin.dart

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved.
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+
// @dart = 2.8
7+
8+
import 'package:package_config/package_config.dart';
9+
10+
import 'package:flutter_tools/src/base/file_system.dart';
11+
import 'package:flutter_tools/src/build_system/build_system.dart';
12+
import 'package:flutter_tools/src/build_system/targets/common.dart';
13+
import 'package:flutter_tools/src/dart/package_map.dart';
14+
import 'package:flutter_tools/src/project.dart';
15+
16+
import '../../tizen_plugins.dart';
17+
18+
/// Source: [DartPluginRegistrantTarget] in `dart_plugin_registrant.dart`
19+
class TizenDartPluginRegistrant extends Target {
20+
const TizenDartPluginRegistrant();
21+
22+
@override
23+
String get name => 'tizen_dart_plugin_registrant';
24+
25+
@override
26+
List<Source> get inputs => <Source>[
27+
const Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
28+
];
29+
30+
@override
31+
List<Source> get outputs => <Source>[
32+
const Source.pattern(
33+
'{PROJECT_DIR}/.dart_tool/flutter_build/generated_main.dart',
34+
optional: true,
35+
),
36+
];
37+
38+
@override
39+
List<Target> get dependencies => <Target>[];
40+
41+
@override
42+
Future<void> build(Environment environment) async {
43+
// TODO: assert(environment.generateDartPluginRegistry);
44+
final FlutterProject project =
45+
FlutterProject.fromDirectory(environment.projectDir);
46+
final List<TizenPlugin> dartPlugins =
47+
await findTizenPlugins(project, dartOnly: true);
48+
if (dartPlugins.isEmpty) {
49+
return;
50+
}
51+
52+
final File packagesFile = environment.projectDir
53+
.childDirectory('.dart_tool')
54+
.childFile('package_config.json');
55+
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
56+
packagesFile,
57+
logger: environment.logger,
58+
);
59+
final String targetFile = environment.defines[kTargetFile] ??
60+
environment.fileSystem.path.join('lib', 'main.dart');
61+
final File mainFile = environment.fileSystem.file(targetFile);
62+
final Uri mainFileUri = mainFile.absolute.uri;
63+
final Uri mainUri = packageConfig.toPackageUri(mainFileUri) ?? mainFileUri;
64+
final File newMainDart = environment.projectDir
65+
.childDirectory('.dart_tool')
66+
.childDirectory('flutter_build')
67+
.childFile('generated_main.dart');
68+
createEntrypointWithPluginRegistrant(
69+
dartPlugins,
70+
packageConfig,
71+
mainUri.toString(),
72+
newMainDart,
73+
mainFile,
74+
);
75+
}
76+
77+
@override
78+
bool canSkip(Environment environment) {
79+
// TODO: return !environment.generateDartPluginRegistry;
80+
return false;
81+
}
82+
}

lib/executable.dart

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/application_package.dart';
1313
import 'package:flutter_tools/src/base/context.dart';
1414
import 'package:flutter_tools/src/base/logger.dart';
1515
import 'package:flutter_tools/src/base/template.dart';
16+
import 'package:flutter_tools/src/build_system/build_system.dart';
1617
import 'package:flutter_tools/src/cache.dart';
1718
import 'package:flutter_tools/src/commands/config.dart';
1819
import 'package:flutter_tools/src/commands/devices.dart';
@@ -43,6 +44,7 @@ import 'commands/packages.dart';
4344
import 'commands/precache.dart';
4445
import 'commands/run.dart';
4546
import 'commands/test.dart';
47+
import 'tizen_build_system.dart';
4648
import 'tizen_cache.dart';
4749
import 'tizen_device_discovery.dart';
4850
import 'tizen_doctor.dart';
@@ -169,6 +171,11 @@ Future<void> main(List<String> args) async {
169171
logger: globals.logger,
170172
fileSystem: globals.fs,
171173
),
174+
BuildSystem: () => TizenBuildSystem(
175+
fileSystem: globals.fs,
176+
logger: globals.logger,
177+
platform: globals.platform,
178+
),
172179
if (verbose && !muteCommandLogging)
173180
Logger: () => VerboseLogger(StdoutLogger(
174181
stdio: globals.stdio,

lib/tizen_build_system.dart

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2021 Samsung Electronics Co., Ltd. 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.8
6+
7+
import 'package:file/file.dart';
8+
import 'package:flutter_tools/src/base/logger.dart';
9+
import 'package:flutter_tools/src/base/platform.dart';
10+
import 'package:flutter_tools/src/build_system/build_system.dart';
11+
import 'package:flutter_tools/src/build_system/targets/localizations.dart';
12+
import 'package:flutter_tools/src/resident_runner.dart';
13+
import 'package:meta/meta.dart';
14+
15+
import 'build_targets/plugin.dart';
16+
17+
class TizenBuildSystem extends FlutterBuildSystem {
18+
const TizenBuildSystem({
19+
@required FileSystem fileSystem,
20+
@required Platform platform,
21+
@required Logger logger,
22+
}) : super(
23+
fileSystem: fileSystem,
24+
platform: platform,
25+
logger: logger,
26+
);
27+
28+
/// See: [ResidentRunner.runSourceGenerators] in `resident_runner.dart`
29+
@override
30+
Future<BuildResult> buildIncremental(
31+
Target target,
32+
Environment environment,
33+
BuildResult previousBuild,
34+
) {
35+
// TODO: Check if the incremental build works on hot restart.
36+
// TODO: Update this later (replace DartPluginRegistrantTarget with TizenDartPluginRegistrant).
37+
if (target is GenerateLocalizationsTarget) {
38+
target = CompositeTarget(<Target>[
39+
target,
40+
const TizenDartPluginRegistrant(),
41+
]);
42+
}
43+
return super.buildIncremental(target, environment, previousBuild);
44+
}
45+
}

lib/tizen_build_target.dart

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import 'package:flutter_tools/src/cache.dart';
2626
import 'package:flutter_tools/src/globals.dart' as globals;
2727
import 'package:flutter_tools/src/project.dart';
2828

29+
import 'build_targets/plugin.dart';
2930
import 'tizen_builder.dart';
3031
import 'tizen_plugins.dart';
3132
import 'tizen_project.dart';
@@ -58,6 +59,7 @@ abstract class TizenAssetBundle extends Target {
5859
@override
5960
List<Target> get dependencies => const <Target>[
6061
KernelSnapshot(),
62+
TizenDartPluginRegistrant(),
6163
];
6264

6365
@override
@@ -561,6 +563,7 @@ class TizenAotElf extends AotElfBase {
561563
@override
562564
List<Target> get dependencies => const <Target>[
563565
KernelSnapshot(),
566+
TizenDartPluginRegistrant(),
564567
];
565568
}
566569

lib/tizen_builder.dart

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class TizenBuilder {
122122
logger: globals.logger,
123123
processManager: globals.processManager,
124124
platform: globals.platform,
125+
// TODO: generateDartPluginRegistry: true,
125126
);
126127

127128
final Target target = buildInfo.isDebug

lib/tizen_plugins.dart

+56-85
Original file line numberDiff line numberDiff line change
@@ -119,81 +119,88 @@ class TizenPlugin extends PluginPlatform implements NativeOrDartPlugin {
119119
}
120120
}
121121

122+
// TODO: Rename this mixin.
122123
/// Any [FlutterCommand] that invokes [usesPubOption] or [targetFile] should
123124
/// depend on this mixin to ensure plugins are correctly configured for Tizen.
124125
///
125126
/// See: [FlutterCommand.verifyThenRunCommand] in `flutter_command.dart`
126127
mixin DartPluginRegistry on FlutterCommand {
127-
String _entrypoint;
128-
129-
bool get _usesTargetOption => argParser.options.containsKey('target');
130-
131128
@override
132129
Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
133130
if (super.shouldRunPub) {
134131
// TODO(swift-kim): Should run pub get first before injecting plugins.
135132
await ensureReadyForTizenTooling(FlutterProject.current());
136133
}
137-
if (_usesTargetOption) {
138-
_entrypoint =
139-
await _createEntrypoint(FlutterProject.current(), super.targetFile);
140-
}
141134
return super.verifyThenRunCommand(commandPath);
142135
}
143-
144-
@override
145-
String get targetFile => _entrypoint ?? super.targetFile;
146136
}
147137

148-
/// Creates an entrypoint wrapper of [targetFile] and returns its path.
149-
/// This effectively adds support for Dart plugins.
150-
///
151-
/// Source: [WebEntrypointTarget.build] in `web.dart`
152-
Future<String> _createEntrypoint(
153-
FlutterProject project, String targetFile) async {
154-
final List<TizenPlugin> dartPlugins =
155-
await findTizenPlugins(project, dartOnly: true);
156-
if (dartPlugins.isEmpty) {
157-
return targetFile;
158-
}
159-
160-
final TizenProject tizenProject = TizenProject.fromFlutter(project);
161-
if (!tizenProject.existsSync()) {
162-
return targetFile;
138+
/// Source: [generateMainDartWithPluginRegistrant] in `flutter_plugins.dart`
139+
void createEntrypointWithPluginRegistrant(
140+
List<TizenPlugin> plugins,
141+
PackageConfig packageConfig,
142+
String currentMainUri,
143+
File newMainDart,
144+
File mainFile,
145+
) {
146+
if (plugins.isEmpty) {
147+
try {
148+
if (newMainDart.existsSync()) {
149+
newMainDart.deleteSync();
150+
}
151+
} on FileSystemException catch (error) {
152+
globals.printError(
153+
'Unable to remove ${newMainDart.path}, received error: $error.\n'
154+
'You might need to run flutter-tizen clean.');
155+
rethrow;
156+
}
157+
return;
163158
}
164-
165-
final File entrypoint = tizenProject.managedDirectory.childFile('main.dart')
166-
..createSync(recursive: true);
167-
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
168-
project.directory.childFile('.packages'),
169-
logger: globals.logger,
170-
);
171-
final FlutterProject flutterProject = FlutterProject.current();
172-
final LanguageVersion languageVersion = determineLanguageVersion(
173-
globals.fs.file(targetFile),
174-
packageConfig[flutterProject.manifest.appName],
159+
final LanguageVersion entrypointVersion = determineLanguageVersion(
160+
mainFile,
161+
packageConfig.packageOf(mainFile.absolute.uri),
175162
Cache.flutterRoot,
176163
);
177-
178-
final Uri mainUri = globals.fs.file(targetFile).absolute.uri;
179-
final String mainImport =
180-
packageConfig.toPackageUri(mainUri)?.toString() ?? mainUri.toString();
181-
182-
entrypoint.writeAsStringSync('''
164+
final List<Map<String, dynamic>> pluginConfigs =
165+
plugins.map((TizenPlugin plugin) => plugin.toMap()).toList();
166+
// TODO: Consider using PluginInterfaceResolution and implementing resolvePlatformImplementation().
167+
final Map<String, dynamic> templateContext = <String, dynamic>{
168+
'mainEntrypoint': currentMainUri,
169+
'dartLanguageVersion': entrypointVersion.toString(),
170+
'plugins': pluginConfigs,
171+
};
172+
try {
173+
_renderTemplateToFile(
174+
'''
183175
//
184176
// Generated file. Do not edit.
185177
//
186-
// @dart=${languageVersion.major}.${languageVersion.minor}
178+
// @dart = {{dartLanguageVersion}}
187179
188-
import '$mainImport' as entrypoint;
189-
import 'generated_plugin_registrant.dart';
180+
import '{{mainEntrypoint}}' as entrypoint;
181+
{{#plugins}}
182+
import 'package:{{name}}/{{name}}.dart';
183+
{{/plugins}}
184+
185+
void registerPlugins() {
186+
{{#plugins}}
187+
{{dartPluginClass}}.register();
188+
{{/plugins}}
189+
}
190190
191191
Future<void> main() async {
192192
registerPlugins();
193193
entrypoint.main();
194194
}
195-
''');
196-
return entrypoint.path;
195+
''',
196+
templateContext,
197+
newMainDart.path,
198+
);
199+
} on FileSystemException catch (error) {
200+
globals.printError(
201+
'Unable to write ${newMainDart.path}, received error: $error');
202+
rethrow;
203+
}
197204
}
198205

199206
/// https://github.com/flutter-tizen/plugins
@@ -239,18 +246,16 @@ Future<void> ensureReadyForTizenTooling(FlutterProject project) async {
239246
final TizenProject tizenProject = TizenProject.fromFlutter(project);
240247
await tizenProject.ensureReadyForPlatformSpecificTooling();
241248

249+
// TODO(swift-kim): Consider renaming the function.
242250
await injectTizenPlugins(project);
243251
}
244252

245253
/// See: [injectPlugins] in `plugins.dart`
246254
Future<void> injectTizenPlugins(FlutterProject project) async {
247255
final TizenProject tizenProject = TizenProject.fromFlutter(project);
248256
if (tizenProject.existsSync()) {
249-
final List<TizenPlugin> dartPlugins =
250-
await findTizenPlugins(project, dartOnly: true);
251257
final List<TizenPlugin> nativePlugins =
252258
await findTizenPlugins(project, nativeOnly: true);
253-
_writeDartPluginRegistrant(tizenProject.managedDirectory, dartPlugins);
254259
_writeCppPluginRegistrant(tizenProject.managedDirectory, nativePlugins);
255260
_writeCsharpPluginRegistrant(tizenProject.managedDirectory, nativePlugins);
256261
}
@@ -337,40 +342,6 @@ TizenPlugin _pluginFromPackage(String name, Uri packageRoot) {
337342
);
338343
}
339344

340-
/// See: [_writeWebPluginRegistrant] in `plugins.dart`
341-
void _writeDartPluginRegistrant(
342-
Directory registryDirectory,
343-
List<TizenPlugin> plugins,
344-
) {
345-
final List<Map<String, dynamic>> pluginConfigs =
346-
plugins.map((TizenPlugin plugin) => plugin.toMap()).toList();
347-
final Map<String, dynamic> context = <String, dynamic>{
348-
'plugins': pluginConfigs,
349-
};
350-
_renderTemplateToFile(
351-
'''
352-
//
353-
// Generated file. Do not edit.
354-
//
355-
356-
// ignore_for_file: lines_longer_than_80_chars
357-
358-
{{#plugins}}
359-
import 'package:{{name}}/{{name}}.dart';
360-
{{/plugins}}
361-
362-
// ignore: public_member_api_docs
363-
void registerPlugins() {
364-
{{#plugins}}
365-
{{dartPluginClass}}.register();
366-
{{/plugins}}
367-
}
368-
''',
369-
context,
370-
registryDirectory.childFile('generated_plugin_registrant.dart').path,
371-
);
372-
}
373-
374345
/// See: [_writeWindowsPluginFiles] in `plugins.dart`
375346
void _writeCppPluginRegistrant(
376347
Directory registryDirectory,

0 commit comments

Comments
 (0)