Add LICENSE file to packages/flutter, add test to make sure it… (#53799)
This adds a LICENSE file to the packages/flutter directory so that it can be found when building, and a test to make sure it exists in produced binaries.
This commit is contained in:
parent
aad460b7f1
commit
e20080b5d1
71
dev/integration_tests/ui/lib/license_check.dart
Normal file
71
dev/integration_tests/ui/lib/license_check.dart
Normal file
@ -0,0 +1,71 @@
|
||||
// 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:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_driver/driver_extension.dart';
|
||||
|
||||
/// This application does nothing but show a screen with the flutter package
|
||||
/// license in it.
|
||||
void main() {
|
||||
enableFlutterDriverExtension();
|
||||
runApp(ShowLicenses());
|
||||
}
|
||||
|
||||
class ShowLicenses extends StatelessWidget {
|
||||
Widget _buildTestResultWidget(
|
||||
BuildContext context,
|
||||
AsyncSnapshot<List<LicenseEntry>> snapshot,
|
||||
) {
|
||||
final List<LicenseEntry> entries = snapshot.data;
|
||||
String flutterPackage = '';
|
||||
final List<String> flutterParagraphs = <String>[];
|
||||
String enginePackage = '';
|
||||
final List<String> engineParagraphs = <String>[];
|
||||
for (final LicenseEntry entry in entries) {
|
||||
if (entry.packages.contains('flutter')) {
|
||||
flutterPackage = 'flutter';
|
||||
flutterParagraphs.addAll(
|
||||
entry.paragraphs.map<String>((LicenseParagraph para) => para.text),
|
||||
);
|
||||
}
|
||||
if (entry.packages.contains('engine')) {
|
||||
enginePackage = 'engine';
|
||||
engineParagraphs.addAll(
|
||||
entry.paragraphs.map<String>((LicenseParagraph para) => para.text),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final List<Widget> result = <Widget>[];
|
||||
if (entries.isNotEmpty) {
|
||||
result.addAll(<Widget>[
|
||||
const Text('License Check Test', key: ValueKey<String>('Header')),
|
||||
Text(flutterPackage, key: const ValueKey<String>('FlutterPackage')),
|
||||
Text(flutterParagraphs.join(' '), key: const ValueKey<String>('FlutterLicense')),
|
||||
Text('${flutterParagraphs.length}', key: const ValueKey<String>('FlutterCount')),
|
||||
Text(enginePackage, key: const ValueKey<String>('EnginePackage')),
|
||||
Text(engineParagraphs.join(' '), key: const ValueKey<String>('EngineLicense')),
|
||||
Text('${engineParagraphs.length}', key: const ValueKey<String>('EngineCount')),
|
||||
]);
|
||||
}
|
||||
|
||||
return ListView(
|
||||
children: result,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: FutureBuilder<List<LicenseEntry>>(
|
||||
initialData: const <LicenseEntry>[],
|
||||
builder: _buildTestResultWidget,
|
||||
future: LicenseRegistry.licenses.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
96
dev/integration_tests/ui/test_driver/license_check_test.dart
Normal file
96
dev/integration_tests/ui/test_driver/license_check_test.dart
Normal file
@ -0,0 +1,96 @@
|
||||
// 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 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
import 'package:vm_service_client/vm_service_client.dart';
|
||||
|
||||
// Connect and disconnect from the empty app.
|
||||
void main() {
|
||||
// Load the license file from disk to compare it with the one in the app.
|
||||
final File licenseFile = File(path.join('..', '..', '..', 'packages', 'flutter', 'LICENSE'));
|
||||
if (!licenseFile.existsSync()) {
|
||||
print('Test failed. Unable to find LICENSE file at ${licenseFile.path}');
|
||||
exit(-1);
|
||||
}
|
||||
final RegExp newlineSplit = RegExp(r'\s+');
|
||||
final String license = licenseFile.readAsStringSync().split(newlineSplit).join(' ').trim();
|
||||
|
||||
group('License file check', () {
|
||||
FlutterDriver driver;
|
||||
IsolatesWorkaround workaround;
|
||||
|
||||
setUpAll(() async {
|
||||
driver = await FlutterDriver.connect();
|
||||
workaround = IsolatesWorkaround(driver);
|
||||
await workaround.resumeIsolates();
|
||||
await driver.waitUntilFirstFrameRasterized();
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
if (driver != null) {
|
||||
await driver.close();
|
||||
await workaround.tearDown();
|
||||
}
|
||||
});
|
||||
|
||||
test('flutter license', () async {
|
||||
await driver.waitFor(find.byValueKey('Header'));
|
||||
final String foundPackage = await driver.getText(find.byValueKey('FlutterPackage'));
|
||||
final String foundLicense = await driver.getText(find.byValueKey('FlutterLicense'));
|
||||
expect(foundPackage, equals('flutter'));
|
||||
expect(foundLicense, equals(license));
|
||||
});
|
||||
|
||||
test('engine license', () async {
|
||||
await driver.waitFor(find.byValueKey('Header'));
|
||||
final String foundPackage = await driver.getText(find.byValueKey('EnginePackage'));
|
||||
final String foundLicense = await driver.getText(find.byValueKey('EngineLicense'));
|
||||
expect(foundPackage, equals('engine'));
|
||||
// The engine has the same license, but with a different Copyright date.
|
||||
expect(foundLicense, contains(license.replaceFirst('2014', '2013')));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Workaround for isolates being paused by driver tests.
|
||||
/// https://github.com/flutter/flutter/issues/24703
|
||||
class IsolatesWorkaround {
|
||||
IsolatesWorkaround(this._driver);
|
||||
|
||||
final FlutterDriver _driver;
|
||||
StreamSubscription<VMIsolateRef> _streamSubscription;
|
||||
|
||||
Future<void> resumeIsolates() async {
|
||||
final VM vm = await _driver.serviceClient.getVM();
|
||||
// Resume any paused isolate
|
||||
for (final VMIsolateRef isolateRef in vm.isolates) {
|
||||
final VMIsolate isolate = await isolateRef.load();
|
||||
if (isolate.isPaused) {
|
||||
isolate.resume();
|
||||
}
|
||||
}
|
||||
if (_streamSubscription != null) {
|
||||
return;
|
||||
}
|
||||
_streamSubscription = _driver.serviceClient.onIsolateRunnable
|
||||
.asBroadcastStream()
|
||||
.listen((VMIsolateRef isolateRef) async {
|
||||
final VMIsolate isolate = await isolateRef.load();
|
||||
if (isolate.isPaused) {
|
||||
isolate.resume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> tearDown() async {
|
||||
if (_streamSubscription != null) {
|
||||
await _streamSubscription.cancel();
|
||||
}
|
||||
}
|
||||
}
|
25
packages/flutter/LICENSE
Normal file
25
packages/flutter/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Loading…
x
Reference in New Issue
Block a user