License script improvements (flutter/engine#38148)

This commit is contained in:
Ian Hickson 2022-12-14 20:48:22 -08:00 committed by GitHub
parent a35e55cf9a
commit 1d61a2cde1
25 changed files with 33643 additions and 11582 deletions

2
DEPS
View File

@ -51,7 +51,7 @@ vars = {
'dart_revision': '358d0d1aa3e7ebe550ebc343aa795c7f4c136342',
# WARNING: DO NOT EDIT MANUALLY
# The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py
# The lines between blank lines above and below are generated by a script. See ../tools/dart/create_updated_flutter_deps.py
'dart_binaryen_rev': '7769139efbe818c7ba36d1a382db5114ebee9df8',
'dart_boringssl_gen_rev': 'ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f',
'dart_boringssl_rev': '87f316d7748268eb56f2dc147bd593254ae93198',

View File

@ -35,14 +35,18 @@ PATH="$DART_BIN:$PATH"
# Use:
# env VERBOSE=1 ./ci/licenses.sh
# to turn on verbose progress report printing.
# to turn on verbose progress report printing. Set it to 2 to also output
# information about which patterns are taking the most time.
QUIET="--quiet"
if [[ "${VERBOSE}" == "1" ]]; then
QUIET=""
fi
if [[ "${VERBOSE}" == "2" ]]; then
QUIET="--verbose"
fi
echo "Verifying license script is still happy..."
echo "Using pub from $(command -v pub), dart from $(command -v dart)"
echo "Using dart from: $(command -v dart)"
untracked_files="$(cd "$SRC_DIR/flutter"; git status --ignored --short | grep -E "^!" | awk "{print\$2}")"
untracked_count="$(echo "$untracked_files" | wc -l)"
@ -58,6 +62,12 @@ fi
dart --version
# Runs the tests for the license script.
function run_tests() (
cd "$SRC_DIR/flutter/tools/licenses"
find -name "*_test.dart" | xargs -n 1 dart --enable-asserts
)
# Collects the license information from the repo.
# Runs in a subshell.
function collect_licenses() (
@ -117,11 +127,29 @@ function verify_licenses() (
exitStatus=1
fi
echo "Verifying excluded files list..."
if ! cmp -s "flutter/ci/licenses_golden/excluded_files" "out/license_script_output/excluded_files"; then
echo "============================= ERROR ============================="
echo "The license is excluding a different number of files than previously."
echo "This is only expected when new non-source files have been introduced."
echo "Verify that all the newly ignored files are definitely not shipped with"
echo "any binaries that we compile (including impellerc and Wasm)."
echo "If the changes look correct, update this file:"
echo " ci/licenses_golden/excluded_files"
echo "For more information, see the script in:"
echo " https://github.com/flutter/engine/tree/main/tools/licenses"
echo ""
diff -U 6 "flutter/ci/licenses_golden/excluded_files" "out/license_script_output/excluded_files"
echo "================================================================="
echo ""
exitStatus=1
fi
echo "Checking license count in licenses_flutter..."
local actualLicenseCount
actualLicenseCount="$(tail -n 1 flutter/ci/licenses_golden/licenses_flutter | tr -dc '0-9')"
local expectedLicenseCount=19 # When changing this number: Update the error message below as well describing all expected license types.
local expectedLicenseCount=19 # When changing this number: Update the error message below as well describing the newly expected license types.
if [[ $actualLicenseCount -ne $expectedLicenseCount ]]; then
echo "=============================== ERROR ==============================="
@ -145,4 +173,5 @@ function verify_licenses() (
return $exitStatus
)
run_tests
verify_licenses

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,9 @@
Signature: ffe64a3daaf0ad982854594ad155dd56
UNUSED LICENSES:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
USED LICENSES:
====================================================================================================
LIBRARY: gpu
ORIGIN: ../../../flutter/LICENSE
LIBRARY: engine
ORIGIN: ../../../gpu/GLES2/gl2chromium.h + ../../../gpu/LICENSE
ORIGIN: ../../../gpu/command_buffer/client/gles2_c_lib_export.h + ../../../gpu/LICENSE
TYPE: LicenseType.bsd
FILE: ../../../gpu/GLES2/gl2chromium.h
FILE: ../../../gpu/command_buffer/client/gles2_c_lib_export.h
@ -39,4 +34,5 @@ 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.
====================================================================================================
Total license count: 1

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
Signature: 9d0f7a4c4f53b80e33da848062bef937
Signature: 2aaa7d1662adb75aac43db23f4bd5d97

View File

@ -61,8 +61,7 @@ impeller_component("compiler_lib") {
"../runtime_stage",
"//flutter/fml",
# All third_party deps must be reflected below in the impellerc_license
# target.
# All third_party deps must be included by the global license script.
"//third_party/inja",
"//third_party/shaderc_flutter",
"//third_party/spirv_cross_flutter",
@ -86,23 +85,6 @@ generated_file("impellerc_license") {
"",
read_file("//flutter/sky/packages/sky_engine/LICENSE", "string"),
"",
# These licenses are ignored by the main license checker, since they are not
# shipped to end-application binaries and only shipped as part of developer
# tooling in impellerc. Add them here.
"## Additional open source licenses",
"",
"### inja",
"",
read_file("//third_party/inja/LICENSE", "string"),
"",
"### shaderc",
"",
read_file("//third_party/shaderc/LICENSE", "string"),
"",
"### spirv_cross",
"",
read_file("//third_party/vulkan-deps/spirv-cross/src/LICENSE", "string"),
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
Copyright 2015 The Chromium 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.

View File

@ -0,0 +1,25 @@
Copyright 2013 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.

View File

@ -30,7 +30,7 @@ latest upstream main and then run the following in this directory:
dart pub get
gclient sync -D
rm -rf ../../../out/licenses
dart lib/main.dart --src ../../.. --out ../../../out/licenses --golden ../../ci/licenses_golden
dart --enable-asserts lib/main.dart --src ../../.. --out ../../../out/licenses --golden ../../ci/licenses_golden
```
In order for the license script to work correctly, you need to remove
@ -59,11 +59,20 @@ anything other than the `FILE` lines. To update this file, run:
```
dart pub get
gclient sync
dart lib/main.dart --release --src ../../.. --out ../../../out/licenses > ../../sky/packages/sky_engine/LICENSE
gclient sync -D
dart --enable-asserts lib/main.dart --release --src ../../.. > ../../sky/packages/sky_engine/LICENSE
```
The bots do not verify that you did this step, it's important that you
do it! When reviewing patches, if you see a change to the golden
files, check to see if there's a corresponding change to the LICENSE
file!
## Testing
To run the tests:
```
dart pub get
find -name "*_test.dart" | xargs -n 1 dart --enable-asserts
```

View File

@ -0,0 +1,25 @@
Copyright (C) The Internet Society (2002). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -35,7 +35,8 @@ licenses than strictly necessary), it tries to avoid including
material that isn't actually used. To do this, RepositoryDirectory
objects only crawl directories and files for which shouldRecurse
returns true. For example, shouldRecurse returns false for ".git"
files.
files. To simplify the configuration of such rules, the default is to
apply the rules in the paths.dart file.
Some directories and files require special handling, and have specific
subclasses of the above classes. To create the appropriate objects,
@ -71,10 +72,23 @@ the Free Software Foundation is off by one, for no clear reason,
leading to the pattern ending with "MA 0211[01]-1307, USA".
The license.dart file also contains the License object, the currently
simplistic normalizer (_reformat) for license text (which mostly just
removes comment syntax), the code that attempts to determine what
copyrights apply to which licenses, and the code that attempts to
identify the licenses themselves (at a high level), to make sure that
appropriate clauses are followed (e.g. including the copyright with a
BSD notice).
The license.dart file also contains the License object, the code that
attempts to determine what copyrights apply to which licenses, and the
code that attempts to identify the licenses themselves (at a high
level), to make sure that appropriate clauses are followed (e.g.
including the copyright with a BSD notice).
In formatter.dart you will find the only part of this codebase that is
actually tested at this time; this is the code that reformats blobs of
text to remove comments and decorations and the like.
The biggest problem with this script right now is that it is absurdly
slow, largely because of the many, many applications of regular
expressions in pattern.dart (especially the ones that use _linebreak).
In regexp_debug.dart we have a wrapper around RegExp that attempts to
quantify this cost, you can see the results if you run the script with
`--verbose`. Long term, the right solution is to change from these
all-in-one patterns to a world where we first tokenize each file, then
apply word-by-word pattern matching to the tokenized input.

View File

@ -11,6 +11,7 @@ import 'package:path/path.dart' as path;
import 'cache.dart';
import 'limits.dart';
import 'patterns.dart';
enum FileType {
binary, // won't have its own license block
@ -20,14 +21,14 @@ enum FileType {
tar, // should be parsed as an archive and drilled into
gz, // should be parsed as a single compressed file and exposed
bzip2, // should be parsed as a single compressed file and exposed
metadata, // can be skipped entirely (e.g. Mac OS X ._foo files)
notPartOfBuild, // can be skipped entirely (e.g. Mac OS X ._foo files, bash scripts)
}
typedef Reader = List<int> Function();
class BytesOf extends Key { BytesOf(dynamic value) : super(value); }
class UTF8Of extends Key { UTF8Of(dynamic value) : super(value); }
class Latin1Of extends Key { Latin1Of(dynamic value) : super(value); }
class BytesOf extends Key { BytesOf(super.value); }
class UTF8Of extends Key { UTF8Of(super.value); }
class Latin1Of extends Key { Latin1Of(super.value); }
bool matchesSignature(List<int> bytes, List<int> signature) {
if (bytes.length < signature.length) {
@ -76,15 +77,20 @@ FileType identifyFile(String name, Reader reader) {
(path.split(name).reversed.take(3).toList().reversed.join('/') == 'third_party/cares/cares.rc')) {
return FileType.latin1Text;
}
if (path.split(name).reversed.take(6).toList().reversed.join('/') == 'dart/runtime/tests/vm/dart/bad_snapshot' || // Not any particular format
path.split(name).reversed.take(8).toList().reversed.join('/') == 'third_party/android_tools/ndk/sources/cxx-stl/stlport/src/stlport.rc') {
if (path.split(name).reversed.take(6).toList().reversed.join('/') == 'dart/runtime/tests/vm/dart/bad_snapshot') { // Not any particular format
return FileType.binary;
}
if (path.split(name).reversed.take(9).toList().reversed.join('/') == 'fuchsia/sdk/linux/dart/zircon/lib/src/fakes/handle_disposition.dart' || // has bogus but benign "authors" reference, reported to jamesr@
path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/angle/src/common/fuchsia_egl/fuchsia_egl.c' || // has bogus but benign "authors" reference, reported to author and legal team
path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/angle/src/common/fuchsia_egl/fuchsia_egl.h' || // has bogus but benign "authors" reference, reported to author and legal team
path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/angle/src/common/fuchsia_egl/fuchsia_egl_backend.h') { // has bogus but benign "authors" reference, reported to author and legal team
return FileType.binary;
}
final String base = path.basename(name);
if (base.startsWith('._')) {
bytes ??= reader();
if (matchesSignature(bytes, <int>[0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58])) {
return FileType.metadata;
return FileType.notPartOfBuild;
} // The ._* files in Mac OS X archives that gives icons and stuff
}
if (path.split(name).contains('cairo')) {
@ -150,21 +156,22 @@ FileType identifyFile(String name, Reader reader) {
case '.cc': return FileType.text;
case '.cpp': return FileType.text;
case '.inc': return FileType.text;
// Go code
case '.go': return FileType.text;
// ObjectiveC code
case '.m': return FileType.text;
// Assembler
case '.asm': return FileType.text;
// Shell
case '.sh': return FileType.text;
case '.bat': return FileType.text;
case '.sh': return FileType.notPartOfBuild;
case '.bat': return FileType.notPartOfBuild;
// Build files
case '.in': return FileType.text;
case '.ac': return FileType.text;
case '.am': return FileType.text;
case '.gn': return FileType.text;
case '.gni': return FileType.text;
case '.gyp': return FileType.text;
case '.gypi': return FileType.text;
case '.ac': return FileType.notPartOfBuild;
case '.am': return FileType.notPartOfBuild;
case '.gn': return FileType.notPartOfBuild;
case '.gni': return FileType.notPartOfBuild;
case '.gyp': return FileType.notPartOfBuild;
case '.gypi': return FileType.notPartOfBuild;
// Java code
case '.java': return FileType.text;
case '.jar': return FileType.zip; // Java package
@ -218,6 +225,7 @@ FileType identifyFile(String name, Reader reader) {
case '.emf': return FileType.binary; // Windows enhanced metafile format
case '.skp': return FileType.binary; // Skia picture format
case '.mskp': return FileType.binary; // Skia picture format
case '.spv': return FileType.binary; // SPIR-V
// Videos
case '.ogg': return FileType.binary; // Ogg media
case '.mp4': return FileType.binary; // MPEG media
@ -332,9 +340,19 @@ FileType identifyFile(String name, Reader reader) {
if (matchesSignature(bytes, <int>[0x58, 0x50, 0x43, 0x4f, 0x4d, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x69, 0x62, 0x0d, 0x0a, 0x1a])) {
return FileType.binary;
} // XPCOM Type Library
if (matchesSignature(bytes, <int>[0x23, 0x21])) {
// #! indicates a shell script, those are not part of the build
return FileType.notPartOfBuild;
}
return FileType.text;
}
String _normalize(String fileContents) {
fileContents = fileContents.replaceAll(newlinePattern, '\n');
fileContents = fileContents.replaceAll('\t', ' ' * 4);
return fileContents;
}
// INTERFACE
@ -363,7 +381,7 @@ mixin UTF8TextFile implements TextFile {
@override
String readString() {
try {
return cache(UTF8Of(this), () => utf8.decode(readBytes()!));
return cache(UTF8Of(this), () => _normalize(utf8.decode(readBytes()!)));
} on FormatException {
print(fullName);
rethrow;
@ -390,13 +408,14 @@ mixin Latin1TextFile implements TextFile {
if (isUTF8) {
throw '$fullName contains valid UTF-8 and is probably not actually encoded as Win1252';
}
return latin1.decode(bytes);
return _normalize(latin1.decode(bytes));
});
}
}
// interface
abstract class Directory extends IoNode {
// lists children (shallow walk, not deep walk)
Iterable<IoNode> get walk;
}
@ -488,7 +507,7 @@ class FileSystemDirectory extends IoNode implements Directory {
String get fullName => _directory.path;
List<int> _readBytes(io.File file) {
return cache/*List<int>*/(BytesOf(file), () => file.readAsBytesSync());
return cache(BytesOf(file), () => file.readAsBytesSync());
}
@override
@ -512,7 +531,7 @@ class FileSystemDirectory extends IoNode implements Directory {
case FileType.bzip2: yield FileSystemBZip2File(fileEntity); break;
case FileType.text: yield FileSystemUTF8TextFile(fileEntity); break;
case FileType.latin1Text: yield FileSystemLatin1TextFile(fileEntity); break;
case FileType.metadata: break; // ignore this file
case FileType.notPartOfBuild: break; // ignore this file
}
}
}
@ -550,27 +569,27 @@ class FileSystemFile extends IoNode implements File {
}
class FileSystemUTF8TextFile extends FileSystemFile with UTF8TextFile {
FileSystemUTF8TextFile(io.File file) : super(file);
FileSystemUTF8TextFile(super.file);
}
class FileSystemLatin1TextFile extends FileSystemFile with Latin1TextFile {
FileSystemLatin1TextFile(io.File file) : super(file);
FileSystemLatin1TextFile(super.file);
}
class FileSystemZipFile extends FileSystemFile with ZipFile {
FileSystemZipFile(io.File file) : super(file);
FileSystemZipFile(super.file);
}
class FileSystemTarFile extends FileSystemFile with TarFile {
FileSystemTarFile(io.File file) : super(file);
FileSystemTarFile(super.file);
}
class FileSystemGZipFile extends FileSystemFile with GZipFile {
FileSystemGZipFile(io.File file) : super(file);
FileSystemGZipFile(super.file);
}
class FileSystemBZip2File extends FileSystemFile with BZip2File {
FileSystemBZip2File(io.File file) : super(file);
FileSystemBZip2File(super.file);
}
@ -606,7 +625,7 @@ class ArchiveDirectory extends IoNode implements Directory {
case FileType.bzip2: _files.add(ArchiveBZip2File(entryFullName, entry)); break;
case FileType.text: _files.add(ArchiveUTF8TextFile(entryFullName, entry)); break;
case FileType.latin1Text: _files.add(ArchiveLatin1TextFile(entryFullName, entry)); break;
case FileType.metadata: break; // ignore this file
case FileType.notPartOfBuild: break; // ignore this file
}
}
}
@ -647,27 +666,27 @@ class ArchiveFile extends IoNode implements File {
}
class ArchiveUTF8TextFile extends ArchiveFile with UTF8TextFile {
ArchiveUTF8TextFile(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveUTF8TextFile(super.fullName, super.file);
}
class ArchiveLatin1TextFile extends ArchiveFile with Latin1TextFile {
ArchiveLatin1TextFile(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveLatin1TextFile(super.fullName, super.file);
}
class ArchiveZipFile extends ArchiveFile with ZipFile {
ArchiveZipFile(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveZipFile(super.fullName, super.file);
}
class ArchiveTarFile extends ArchiveFile with TarFile {
ArchiveTarFile(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveTarFile(super.fullName, super.file);
}
class ArchiveGZipFile extends ArchiveFile with GZipFile {
ArchiveGZipFile(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveGZipFile(super.fullName, super.file);
}
class ArchiveBZip2File extends ArchiveFile with BZip2File {
ArchiveBZip2File(String fullName, a.ArchiveFile file) : super(fullName, file);
ArchiveBZip2File(super.fullName, super.file);
}
@ -688,7 +707,7 @@ class InMemoryFile extends IoNode implements File {
case FileType.bzip2: return InMemoryBZip2File(fullName, bytes);
case FileType.text: return InMemoryUTF8TextFile(fullName, bytes);
case FileType.latin1Text: return InMemoryLatin1TextFile(fullName, bytes);
case FileType.metadata: break; // ignore this file
case FileType.notPartOfBuild: break; // ignore this file
}
assert(false);
return null;
@ -707,25 +726,25 @@ class InMemoryFile extends IoNode implements File {
}
class InMemoryUTF8TextFile extends InMemoryFile with UTF8TextFile {
InMemoryUTF8TextFile(String fullName, List<int> file) : super(fullName, file);
InMemoryUTF8TextFile(super.fullName, super.file);
}
class InMemoryLatin1TextFile extends InMemoryFile with Latin1TextFile {
InMemoryLatin1TextFile(String fullName, List<int> file) : super(fullName, file);
InMemoryLatin1TextFile(super.fullName, super.file);
}
class InMemoryZipFile extends InMemoryFile with ZipFile {
InMemoryZipFile(String fullName, List<int> file) : super(fullName, file);
InMemoryZipFile(super.fullName, super.file);
}
class InMemoryTarFile extends InMemoryFile with TarFile {
InMemoryTarFile(String fullName, List<int> file) : super(fullName, file);
InMemoryTarFile(super.fullName, super.file);
}
class InMemoryGZipFile extends InMemoryFile with GZipFile {
InMemoryGZipFile(String fullName, List<int> file) : super(fullName, file);
InMemoryGZipFile(super.fullName, super.file);
}
class InMemoryBZip2File extends InMemoryFile with BZip2File {
InMemoryBZip2File(String fullName, List<int> file) : super(fullName, file);
InMemoryBZip2File(super.fullName, super.file);
}

View File

@ -0,0 +1,198 @@
// Copyright 2013 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:core' hide RegExp;
import 'patterns.dart';
void _stripFullLines(List<String> lines) {
// Strip full-line decorations, e.g. horizontal lines, and trailing whitespace.
for (int index = 0; index < lines.length; index += 1) {
lines[index] = lines[index].trimRight();
if (fullDecorations.matchAsPrefix(lines[index]) != null) {
if (index == 0 || lines[index].length != lines[index - 1].length) {
// (we leave the decorations if it's just underlining the previous line)
lines[index] = '';
}
}
}
// Remove leading and trailing blank lines
while (lines.isNotEmpty && lines.first == '') {
lines.removeAt(0);
}
while (lines.isNotEmpty && lines.last == '') {
lines.removeLast();
}
}
bool _stripIndentation(List<String> lines) {
// Try stripping leading indentation.
String? prefix;
bool removeTrailingBlockEnd = false;
if (lines.first.startsWith('/*') && lines.last.startsWith(' *')) {
// In addition to the leadingDecorations, we also support one specific
// kind of multiline decoration, the /*...*/ block comment.
prefix = ' *';
removeTrailingBlockEnd = true;
} else {
prefix = leadingDecorations.matchAsPrefix(lines.first)?.group(0);
}
if (prefix != null && lines.skip(1).every((String line) => line.startsWith(prefix!) || prefix.startsWith(line))) {
final int prefixLength = prefix.length;
for (int index = 0; index < lines.length; index += 1) {
final String line = lines[index];
if (line.length > prefixLength) {
lines[index] = line.substring(prefixLength);
} else {
lines[index] = '';
}
}
if (removeTrailingBlockEnd) {
if (lines.last == '/') {
// This removes the line with the trailing "*/" when we had a "/*" at the top.
lines.removeLast();
}
}
return true;
}
return false;
}
bool _unindentLeadingParagraphs(List<String> lines) {
// Try removing leading spaces
// (we know that this loop terminates before the end of the block because
// otherwise the previous section would have stripped a common prefix across
// the entire block)
//
// For example, this will change:
//
// foo
// bar
//
// ...into:
//
// foo
// bar
//
assert(' '.startsWith(leadingDecorations));
if (lines.first.startsWith(' ')) {
int lineCount = 0;
String line = lines.first;
int leadingBlockIndent = line.length; // arbitrarily big number
do {
int indentWidth = 1;
while (indentWidth < line.length && line[indentWidth] == ' ') {
indentWidth += 1;
}
if (indentWidth < leadingBlockIndent) {
leadingBlockIndent = indentWidth;
}
lineCount += 1;
assert(lineCount < lines.length);
line = lines[lineCount];
} while (line.startsWith(' '));
assert(leadingBlockIndent > 0);
for (int index = 0; index < lineCount; index += 1) {
lines[index] = lines[index].substring(leadingBlockIndent, lines[index].length);
}
return true;
}
return false;
}
bool _minorRemovals(List<String> lines) {
bool didEdits = false;
// Try removing stray leading spaces (but only one space).
for (int index = 0; index < lines.length; index += 1) {
if (lines[index].startsWith(' ') && !lines[index].startsWith(' ')) {
lines[index] = lines[index].substring(1, lines[index].length);
didEdits = true;
}
}
// Try stripping HTML leading and trailing block (<!--/-->) comment markers.
if (lines.first.contains('<!--') || lines.last.contains('-->')) {
lines.first = lines[0].replaceFirst('<!--', '');
lines.last = lines[0].replaceFirst('-->', '');
didEdits = true;
}
// Try stripping C-style leading block comment markers.
// We don't do this earlier because if it's a multiline block comment
// we want to be careful about stripping the trailing aligned "*/".
if (lines.first.startsWith('/*')) {
lines.first = lines.first.substring(2, lines.first.length);
didEdits = true;
}
// Try stripping trailing decorations (specifically, stray "*/"s).
for (int index = 0; index < lines.length; index += 1) {
if (lines[index].endsWith('*/')) {
lines[index] = lines[index].substring(0, lines[index].length - 2);
didEdits = true;
}
}
return didEdits;
}
/// This function takes a block of text potentially decorated with leading
/// prefix indents, horizontal lines, C-style comment blocks, blank lines, etc,
/// and removes all such incidental material leaving only the significant text.
String reformat(String body) {
final List<String> lines = body.split('\n');
while (true) {
// The order of the following checks is important. If any test changes
// something that could affect an earlier test, then we should "continue" back
// to the top of the loop.
_stripFullLines(lines);
if (lines.isEmpty) {
// We've stripped everything, give up.
return '';
}
if (_stripIndentation(lines)) {
continue; // Go back to top since we may have more blank lines to strip now.
}
if (_unindentLeadingParagraphs(lines)) {
continue; // Go back to the top since we may have more indentation to strip now.
}
if (_minorRemovals(lines)) {
continue; // Go back to the top since we may have new stuff to strip.
}
// If we get here, we could not find anything else to do to the text to clean it up.
break;
}
return lines.join('\n');
}
String stripAsciiArt(String input) {
// Look for images so that we can remove them.
final List<String> lines = input.split('\n');
for (final List<String> image in asciiArtImages) {
assert(image.isNotEmpty);
// Look for the image starting on each line.
search: for (int index = 0; index < lines.length - image.length; index += 1) {
final int x = lines[index].indexOf(image[0]);
if (x >= 0) {
int width = image[0].length;
// Found the first line, check to see if we have a complete image.
for (int imageLine = 1; imageLine < image.length; imageLine += 1) {
if (lines[index + imageLine].indexOf(image[imageLine]) != x) {
continue search; // Not a complete image.
}
if (image[imageLine].length > width) {
width = image[imageLine].length;
}
}
// Now remove the image.
for (int imageLine = 0; imageLine < image.length; imageLine += 1) {
final String text = lines[index + imageLine];
assert(text.length > x);
if (text.length >= x + width) {
lines[index + imageLine] = text.substring(0, x) + text.substring(x + width, text.length);
} else {
lines[index + imageLine] = text.substring(0, x);
}
}
}
}
}
return lines.join('\n');
}

File diff suppressed because it is too large Load Diff

View File

@ -5,4 +5,8 @@
// Only look for copyrights and licenses at the top of the file.
// This can be increased as necessary, but the larger the value, the slower the
// script will be, so be judicious.
const int kMaxSize = 6 * 1024;
//
// FWIW, png.h's license statements end near the 7KB mark.
// third_party/boringssl/src/include/openssl/ssl.h has licenses for 7285 bytes
// third_party/boringssl/src/include/openssl/tls1.h has licenses for 7530 bytes
const int kMaxSize = 7530;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,451 @@
// Copyright 2013 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 'regexp_debug.dart';
// Directories or files that are not included in the final binaries.
//
// These are absolute paths relative to the root of the buildroot repository
// as checked out after gclient imports all the dependencies.
//
// Do not provide trailing slashes for directories.
//
// Including a directory in this list excludes the entire subtree rooted at
// that directory.
//
// Keep this list in lexical order.
final Set<String> skippedPaths = <String>{
r'README.md',
r'build', // only used by build
r'build_overrides', // only used by build
r'buildtools', // only used by build
r'flutter/build',
r'flutter/ci',
r'flutter/docs',
r'flutter/flutter_frontend_server',
r'flutter/impeller/docs',
r'flutter/lib/web_ui/build', // this is compiler-generated output
r'flutter/lib/web_ui/dev', // these are build tools; they do not end up in Engine artifacts
r'flutter/prebuilts',
r'flutter/sky/packages/sky_engine/LICENSE',
r'flutter/third_party/gn',
r'flutter/third_party/ninja', // build system
r'flutter/third_party/test_shaders', // for tests only
r'flutter/third_party/txt/third_party/fonts',
r'flutter/tools',
r'flutter/web_sdk', // this code is not linked into Flutter apps; it's only used by engine tests and tools
r'fuchsia/sdk/linux/docs',
r'fuchsia/sdk/linux/meta',
r'fuchsia/sdk/linux/tools',
r'fuchsia/sdk/mac/docs',
r'fuchsia/sdk/mac/meta',
r'fuchsia/sdk/mac/tools',
r'out', // output of build
r'third_party/android_embedding_dependencies', // testing framework for android
r'third_party/android_tools', // excluded on advice
r'third_party/angle/android',
r'third_party/angle/doc',
r'third_party/angle/extensions',
r'third_party/angle/infra',
r'third_party/angle/scripts',
r'third_party/angle/src/libANGLE/renderer/metal/doc',
r'third_party/angle/src/libANGLE/renderer/vulkan/doc',
r'third_party/angle/src/third_party/volk', // We don't use Vulkan in our ANGLE build.
r'third_party/angle/third_party', // Unused by Flutter: BUILD files with forwarding targets (but no code).
r'third_party/angle/tools', // These are build-time tools, and aren't shipped.
r'third_party/angle/util',
r'third_party/benchmark', // only used by tests
r'third_party/boringssl/src/crypto/err/err_data_generate.go',
r'third_party/boringssl/src/fuzz', // testing tools, not shipped
r'third_party/boringssl/src/util', // code generators, not shipped
r'third_party/colorama/src/demos',
r'third_party/colorama/src/screenshots',
r'third_party/dart/benchmarks', // not shipped in binary
r'third_party/dart/build', // not shipped in binary
r'third_party/dart/docs', // not shipped in binary
r'third_party/dart/pkg', // packages that don't become part of the binary (e.g. the analyzer)
r'third_party/dart/runtime/bin/ffi_test',
r'third_party/dart/runtime/docs',
r'third_party/dart/runtime/third_party/binary_size', // not linked in either
r'third_party/dart/runtime/third_party/d3', // Siva says "that is the charting library used by the binary size tool"
r'third_party/dart/runtime/vm/service',
r'third_party/dart/sdk/lib/html/doc',
r'third_party/dart/third_party/binaryen', // not linked in
r'third_party/dart/third_party/d8', // testing tool for dart2js
r'third_party/dart/third_party/devtools', // not linked in
r'third_party/dart/third_party/firefox_jsshell', // testing tool for dart2js
r'third_party/dart/third_party/pkg',
r'third_party/dart/third_party/pkg_tested',
r'third_party/dart/third_party/requirejs', // only used by DDC
r'third_party/dart/tools', // not shipped in binary
r'third_party/expat/expat/doc',
r'third_party/expat/expat/win32/expat.iss',
r'third_party/flatbuffers/android',
r'third_party/flatbuffers/benchmarks',
r'third_party/flatbuffers/docs',
r'third_party/flatbuffers/go',
r'third_party/flatbuffers/net',
r'third_party/flatbuffers/php',
r'third_party/flatbuffers/python',
r'third_party/flatbuffers/rust',
r'third_party/flatbuffers/ts',
r'third_party/fontconfig', // not used in standard configurations
r'third_party/freetype2/builds',
r'third_party/freetype2/src/tools',
r'third_party/glfw/deps', // Only used by examples and tests; not linked in build.
r'third_party/glfw/docs',
r'third_party/gradle',
r'third_party/harfbuzz/docs',
r'third_party/harfbuzz/util', // utils are command line tools that do not end up in the binary
r'third_party/icu/filters',
r'third_party/icu/fuzzers',
r'third_party/icu/scripts',
r'third_party/icu/source/common/unicode/uvernum.h', // this file contains strings that confuse the analysis
r'third_party/icu/source/config',
r'third_party/icu/source/data/brkitr/dictionaries/burmesedict.txt', // explicitly handled by ICU license
r'third_party/icu/source/data/brkitr/dictionaries/cjdict.txt', // explicitly handled by ICU license
r'third_party/icu/source/data/brkitr/dictionaries/laodict.txt', // explicitly handled by ICU license
r'third_party/icu/source/data/dtd',
r'third_party/imgui',
r'third_party/inja/doc', // documentation
r'third_party/inja/third_party/amalgamate', // only used at build time
r'third_party/inja/third_party/include/doctest', // seems to be a unit test library
r'third_party/java', // only used for Android builds
r'third_party/json/docs',
r'third_party/libcxx/benchmarks',
r'third_party/libcxx/docs',
r'third_party/libcxx/src/support/solaris',
r'third_party/libcxx/utils',
r'third_party/libcxxabi/www',
r'third_party/libpng/contrib', // not linked in
r'third_party/libpng/mips', // not linked in
r'third_party/libpng/powerpc', // not linked in
r'third_party/libpng/projects', // not linked in
r'third_party/libpng/scripts', // not linked in
r'third_party/libtess2/Contrib/nanosvg.c', // only used by the ../Example
r'third_party/libtess2/Contrib/nanosvg.h', // only used by the ../Example
r'third_party/libtess2/Example',
r'third_party/libwebp/doc',
r'third_party/libwebp/gradle', // not included in our build
r'third_party/libwebp/swig', // not included in our build
r'third_party/libwebp/webp_js',
r'third_party/libxml', // dependency of the testing system that we don't actually use
r'third_party/ocmock', // only used for tests
r'third_party/pkg/archive', // contains nothing that ends up in the binary executable
r'third_party/pkg/equatable',
r'third_party/pkg/file',
r'third_party/pkg/flutter_packages',
r'third_party/pkg/gcloud',
r'third_party/pkg/googleapis',
r'third_party/pkg/platform',
r'third_party/pkg/process',
r'third_party/pkg/process_runner',
r'third_party/pkg/vector_math',
r'third_party/pyyaml', // build-time dependency only
r'third_party/rapidjson/contrib', // contains nothing that ends up in the binary executable
r'third_party/rapidjson/doc', // documentation
r'third_party/root_certificates/certdata.pem',
r'third_party/root_certificates/certdata.txt',
r'third_party/shaderc/third_party/LICENSE.glslang', // unclear what the purpose of this file is
r'third_party/shaderc/third_party/LICENSE.spirv-tools', // unclear what the purpose of this file is
r'third_party/skia/bazel', // contains nothing that ends up in the binary executable
r'third_party/skia/bench',
r'third_party/skia/demos.skia.org',
r'third_party/skia/docs',
r'third_party/skia/experimental',
r'third_party/skia/infra', // contains nothing that ends up in the binary executable
r'third_party/skia/modules/canvaskit/go/gold_test_env',
r'third_party/skia/platform_tools', // contains nothing that ends up in the binary executable
r'third_party/skia/resources', // contains nothing that ends up in the binary executable
r'third_party/skia/samplecode',
r'third_party/skia/site',
r'third_party/skia/specs',
r'third_party/skia/third_party/freetype2', // we use our own version
r'third_party/skia/third_party/icu', // we use our own version
r'third_party/skia/third_party/libjpeg-turbo', // we use our own version
r'third_party/skia/third_party/libpng', // we use our own version
r'third_party/skia/third_party/lua', // not linked in
r'third_party/skia/tools', // contains nothing that ends up in the binary executable
r'third_party/swiftshader', // only used on hosts for tests
r'third_party/tinygltf',
r'third_party/vulkan-deps/glslang/LICENSE', // excluded to make sure we don't accidentally apply it as a default license
r'third_party/vulkan-deps/glslang/src/LICENSE.txt', // redundant with licenses inside files
r'third_party/vulkan-deps/glslang/src/glslang/OSDependent/Web', // we only use glslang in impellerc, not in web apps
r'third_party/vulkan-deps/glslang/src/kokoro', // only build files
r'third_party/vulkan-deps/spirv-cross/src/LICENSES', // directory with license templates
r'third_party/vulkan-deps/spirv-cross/src/shaders', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-hlsl', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-hlsl-no-opt', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-msl', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-msl-no-opt', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-no-opt', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-other', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-reflection', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-ue4', // used by regression tests
r'third_party/vulkan-deps/spirv-cross/src/shaders-ue4-no-opt', // used by regression tests
r'third_party/vulkan-deps/spirv-headers', // only used on hosts for tests
r'third_party/vulkan-deps/spirv-tools', // only used on hosts for tests
r'third_party/vulkan-deps/vulkan-headers/src/registry',
r'third_party/vulkan-deps/vulkan-loader', // on hosts for tests
r'third_party/vulkan-deps/vulkan-tools', // on hosts for tests
r'third_party/vulkan-deps/vulkan-validation-layers/src/docs',
r'third_party/vulkan_memory_allocator/bin',
r'third_party/vulkan_memory_allocator/docs',
r'third_party/vulkan_memory_allocator/media',
r'third_party/vulkan_memory_allocator/src',
r'third_party/vulkan_memory_allocator/tools',
r'third_party/web_dependencies/canvaskit', // redundant; covered by Skia dependencies
r'third_party/wuffs/docs',
r'third_party/wuffs/script',
r'third_party/yapf', // only used for code formatting
r'third_party/zlib/contrib/minizip/miniunz.c', // sample file
r'third_party/zlib/contrib/minizip/minizip.c', // sample file
r'tools', // not distributed in binary
};
// Directories that should be skipped anywhere we find them.
//
// Any directory whose name matches one of these strings is skipped, including
// its entire subtree.
//
// Keep this list in lexical order.
final Set<String> skippedCommonDirectories = <String>{
r'.bazelci',
r'.build-id',
r'.ccls-cache',
r'.cipd',
r'.dart_tool',
r'.git',
r'.github',
r'.reuse',
r'.versions',
r'.vscode',
r'CMake',
r'Test',
r'cmake',
r'example',
r'examples',
r'fixtures',
r'googletest',
r'javatests',
r'jvmTest',
r'playground',
r'samples',
r'test',
r'test.disabled',
r'test_runner',
r'test_support',
r'testdata',
r'testing',
r'tests',
r'unit_tests',
};
// Filenames of files we never look at.
//
// Any file with a name in this list is skipped.
//
// Be careful about adding files like "LICENSE" or "README" (and such
// variants) to this list as many packages put important license text in those
// files and we don't want to skip them. Only include files here whose names
// we would want to skip in ANY package.
//
// Keep this list in lexical order.
final Set<String> skippedCommonFiles = <String>{
r'.DS_Store',
r'.appveyor.yml',
r'.bazelrc',
r'.bazelversion',
r'.clang-format',
r'.clang-tidy',
r'.editorconfig',
r'.eslintrc.js',
r'.gitattributes',
r'.gitconfig',
r'.gitignore',
r'.gitlab-ci.yml',
r'.gitmodules',
r'.gn',
r'.lgtm.yml',
r'.mailmap',
r'.packages',
r'.project',
r'.style.yapf',
r'.travis.yml',
r'.vpython',
r'.vpython3',
r'.yapfignore',
r'ABSEIL_ISSUE_TEMPLATE.md',
r'ANNOUNCE',
r'API-CONVENTIONS.md',
r'AUTHORS',
r'BREAKING-CHANGES.md',
r'BUILD.bazel',
r'BUILD.md',
r'BUILDING.md',
r'Brewfile',
r'CHANGES',
r'CHANGES.md',
r'CITATION.cff',
r'CMake.README',
r'CMakeLists.txt',
r'CODEOWNERS',
r'CODE_CONVENTIONS.md',
r'CODE_OF_CONDUCT.adoc',
r'CODE_OF_CONDUCT.md',
r'CONFIG.md',
r'CONTRIBUTORS',
r'CONTRIBUTORS.md',
r'CPPLINT.cfg',
r'CQ_COMMITTERS',
r'CREDITS.TXT',
r'Changes',
r'CodingStandard.md',
r'DEPS',
r'DIR_METADATA',
r'Dockerfile',
r'Doxyfile',
r'FAQ.md',
r'FIPS.md',
r'FUZZING.md',
r'FeatureSupportGL.md',
r'FormatTables.md',
r'Formatters.md',
r'GIT_REVISION',
r'HACKING.md',
r'INCORPORATING.md',
r'LAYER_CONFIGURATION.md',
r'LOCALE_DEPS.json',
r'MANIFEST.in',
r'MANIFEST.txt',
r'METADATA',
r'NEWS',
r'OWNERS',
r'OWNERS.android',
r'PATENT_GRANT',
r'PORTING.md',
r'README.asciidoc',
r'RELEASE_NOTES.TXT',
r'RELEASING.md',
r'RapidJSON.pc.in',
r'RapidJSONConfig.cmake.in',
r'RapidJSONConfigVersion.cmake.in',
r'SANDBOXING.md',
r'SECURITY.md',
r'STYLE.md',
r'TESTING.md',
r'THANKS',
r'TODO',
r'TODO.TXT',
r'TRADEMARK',
r'UPGRADES.md',
r'UniformBlockToStructuredBufferTranslation.md',
r'WATCHLISTS',
r'WORKSPACE',
r'WORKSPACE.bazel',
r'_config.yml',
r'additional_readme_paths.json',
r'alg_outline.md',
r'allowed_experiments.json',
r'amalgamate_config.json',
r'api_readme.md',
r'appveyor-reqs-install.cmd',
r'appveyor.yml',
r'build.xml',
r'codereview.settings',
r'coderules.txt',
r'configure-ac-style.md',
r'doxygen.config',
r'example.html',
r'gerrit.md',
r'gradle.properties',
r'include_dirs.js',
r'known_good.json',
r'known_good_khr.json',
r'libraries.json',
r'library.json',
r'license-checker.cfg',
r'license.html',
r'memory-sanitizer-blacklist.txt',
r'meson.build',
r'meta.json',
r'minizip.md',
r'package.json',
r'pkgdataMakefile.in',
r'pom.xml',
r'pubspec.lock',
r'requirements-dev.txt',
r'requirements.txt',
r'sources.txt',
r'structure.txt',
r'swift.swiftformat',
r'sync.txt',
r'unit_tests.md',
r'version',
r'version_history.json',
r'vms_make.com',
r'vmservice_libraries.json',
};
// Extensions that we just never look at.
//
// We explicitly do not exclude .txt, .md, .TXT, and .MD files because it is common
// for licenses to be in such files.
//
// This list only works for extensions with a single dot.
//
// Keep this list in lexical order.
final Set<String> skippedCommonExtensions = <String>{
r'.1',
r'.5',
r'.autopkg',
r'.build',
r'.bzl',
r'.cmake',
r'.css',
r'.gn',
r'.gni',
r'.gradle',
r'.log',
r'.m4',
r'.mk',
r'.pl',
r'.py',
r'.pyc',
r'.pylintrc',
r'.sha1',
r'.yaml',
r'.~',
};
// Patterns for files and directories we should skip.
//
// Keep this list to a minimum, preferring all the other lists
// in this file. Testing patterns is more expensive.
//
// Keep this list in lexical order.
final List<Pattern> skippedFilePatterns = <Pattern>[
RegExp(r'\.[1-8]\.in$'), // man page source files (e.g. foo.1.in)
RegExp(r'/(?:_|\b)CONTRIBUTING(?:_|\b)[^/]*$'),
RegExp(r'/(?:_|\b)LAST_UPDATE(?:_|\b)[^/]*$'),
RegExp(r'/(?:_|\b)PATENTS(?:_|\b)[^/]*$'),
RegExp(r'/(?:_|\b)README(?!\.IJG)(?:_|\b)[^/]*$', caseSensitive: false),
RegExp(r'/(?:_|\b)VERSION(?:_|\b)[^/]*$'),
RegExp(r'/CHANGELOG(?:\.[.A-Z0-9]+)?$', caseSensitive: false),
RegExp(r'/INSTALL(?:\.[a-zA-Z0-9]+)?$'),
RegExp(r'/Makefile(?:\.[.A-Z0-9]+)?$', caseSensitive: false),
RegExp(r'\.~[0-9]+~$', expectNoMatch: true), // files that end in ".~1~", a backup convention of some IDEs
RegExp(r'\bmanual\.txt$'),
RegExp(r'^flutter/(?:.+/)*[^/]+_unittests?\.[^/]+$'),
RegExp(r'^flutter/lib/web_ui/lib/assets/ahem\.ttf$', expectNoMatch: true), // this gitignored file exists only for testing purposes
RegExp(r'^flutter/sky/packages/sky_engine/LICENSE$'), // that is the output of this script
RegExp(r'^third_party/abseil-cpp/(?:.+/)*[^/]+_test\.[^/]+$'),
RegExp(r'^third_party/angle/(?:.+/)*[^/]+_unittest\.[^/]+$'),
RegExp(r'^third_party/boringssl/(?:.+/)*[^/]+_test\.[^/]+$'),
RegExp(r'^third_party/boringssl/src/crypto/fipsmodule/bn/[^/]+.go$'),
RegExp(r'^third_party/boringssl/src/crypto/fipsmodule/ec/[^/]+.go$'),
RegExp(r'^third_party/dart/(?:.+/)*[^/]+_test\.[^/]+$'),
RegExp(r'^third_party/freetype2/docs/(?!FTL\.TXT$).+'), // ignore all documentation except the license
RegExp(r'^third_party/zlib/(?:.+/)*[^/]+_unittest\.[^/]+$'),
];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
// Copyright 2013 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:core' as core show RegExp;
import 'dart:core' hide RegExp;
import 'dart:io';
class RegExp implements core.RegExp {
RegExp(
String source, {
bool multiLine = false,
bool caseSensitive = true,
bool unicode = false,
bool dotAll = false,
this.expectNoMatch = false,
}) : _pattern = core.RegExp(source, multiLine: multiLine, caseSensitive: caseSensitive, unicode: unicode, dotAll: dotAll),
source = _stripFrameNumber(StackTrace.current.toString().split('\n').skip(1).take(1).single) {
_allPatterns.add(this);
}
static String _stripFrameNumber(String frame) {
return frame.substring(frame.indexOf(' ')).trim();
}
final core.RegExp _pattern;
final String source;
static final List<RegExp> _allPatterns = <RegExp>[];
final bool expectNoMatch;
int _matchCount = 0;
int get matchCount => _matchCount;
int _testCount = 0;
int get testCount => _testCount;
final Stopwatch _stopwatch = Stopwatch();
static void printDiagnostics() {
final List<RegExp> patterns = _allPatterns.toList();
stderr.writeln('Top ten patterns:');
patterns.sort((RegExp a, RegExp b) => b._stopwatch.elapsed.compareTo(a._stopwatch.elapsed));
for (final RegExp pattern in patterns.take(10)) {
stderr.writeln('${pattern._stopwatch.elapsedMicroseconds.toString().padLeft(10)}μs tests -- /${pattern.pattern}/ (${pattern.testCount} tests, ${pattern.matchCount} matches, ${pattern.source})');
}
stderr.writeln();
stderr.writeln('Unmatched patterns:');
patterns.sort((RegExp a, RegExp b) => a.pattern.compareTo(b.pattern));
for (final RegExp pattern in patterns) {
if (pattern.matchCount == 0 && !pattern.expectNoMatch && pattern.testCount > 0) {
stderr.writeln('/${pattern.pattern}/ (${pattern.testCount} tests, ${pattern.matchCount} matches, ${pattern.source})');
}
}
stderr.writeln();
stderr.writeln('Unexpectedly matched patterns:');
for (final RegExp pattern in patterns) {
if (pattern.matchCount > 0 && pattern.expectNoMatch) {
stderr.writeln('/${pattern.pattern}/ (${pattern.testCount} tests, ${pattern.matchCount} matches, ${pattern.source})');
}
}
stderr.writeln();
stderr.writeln('Unused patterns:');
for (final RegExp pattern in patterns) {
if (pattern.testCount == 0) {
stderr.writeln('/${pattern.pattern}/ (${pattern.testCount} tests, ${pattern.matchCount} matches, ${pattern.source})');
}
}
}
@override
bool get isCaseSensitive => _pattern.isCaseSensitive;
@override
bool get isDotAll => _pattern.isDotAll;
@override
bool get isMultiLine => _pattern.isMultiLine;
@override
bool get isUnicode => _pattern.isUnicode;
@override
String get pattern => _pattern.pattern;
@override
Iterable<RegExpMatch> allMatches(String input, [int start = 0]) {
_stopwatch.start();
final List<RegExpMatch> result = _pattern.allMatches(input, start).toList();
_stopwatch.stop();
_testCount += 1;
if (result.isNotEmpty) {
_matchCount += 1;
}
return result;
}
@override
RegExpMatch? firstMatch(String input) {
_stopwatch.start();
final RegExpMatch? result = _pattern.firstMatch(input);
_stopwatch.stop();
_testCount += 1;
if (result != null) {
_matchCount += 1;
}
return result;
}
@override
bool hasMatch(String input) {
_stopwatch.start();
final bool result = _pattern.hasMatch(input);
_stopwatch.stop();
_stopwatch.stop();
_testCount += 1;
if (result) {
_matchCount += 1;
}
return result;
}
@override
Match? matchAsPrefix(String string, [int start = 0]) {
_stopwatch.start();
final Match? result = _pattern.matchAsPrefix(string, start);
_stopwatch.stop();
_testCount += 1;
if (result != null) {
_matchCount += 1;
}
return result;
}
@override
String? stringMatch(String input) {
_stopwatch.start();
final String? result = _pattern.stringMatch(input);
_stopwatch.stop();
_testCount += 1;
if (result != null) {
_matchCount += 1;
}
return result;
}
@override
String toString() => _pattern.toString();
}

View File

@ -5,37 +5,49 @@
name: licenses
publish_to: none
environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=2.18.0 <3.0.0'
# Do not add any dependencies that require more than what is provided in
# //third_party.pkg, //third_party/dart/pkg, or
# //third_party/dart/third_party/pkg. In particular, package:test is not usable
# here.
# Do not add any dependencies that require more than what is provided
# in //third_party.pkg, //third_party/dart/pkg, or
# //third_party/dart/third_party/pkg.
# If you do add packages here, make sure you can run `pub get --offline`, and
# check the .packages and .package_config to make sure all the paths are
# relative to this directory into //third_party/dart
# In particular, package:test is not usable here.
# If you do add packages here, make sure you can run `pub get
# --offline`, and check the .packages and .package_config to make sure
# all the paths are relative to this directory into //third_party/dart
dependencies:
archive: any
args: any
collection: ^1.16.0
crypto: any
meta: any
path: any
collection: ^1.16.0
dev_dependencies:
litetest: any
dependency_overrides:
archive:
path: ../../../third_party/pkg/archive
args:
path: ../../../third_party/dart/third_party/pkg/args
async_helper:
path: ../../../third_party/dart/pkg/async_helper
collection:
path: ../../../third_party/dart/third_party/pkg/collection
crypto:
path: ../../../third_party/dart/third_party/pkg/crypto
expect:
path: ../../../third_party/dart/pkg/expect
litetest:
path: ../../testing/litetest
meta:
path: ../../../third_party/dart/pkg/meta
path:
path: ../../../third_party/dart/third_party/pkg/path
smith:
path: ../../../third_party/dart/pkg/smith
typed_data:
path: ../../../third_party/dart/third_party/pkg/typed_data

View File

@ -0,0 +1,87 @@
// Copyright 2013 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:licenses/formatter.dart';
import 'package:litetest/litetest.dart';
void main() {
test('Block comments', () {
expect(reformat('/* test */'), 'test');
expect(reformat('/*\ntest\n*/'), 'test');
expect(reformat('/*\ntest\n */'), 'test');
expect(reformat('/*\n * test\n*/'), 'test');
expect(reformat('/*\n * test\n */'), 'test');
expect(reformat('/*\n * test\n * test\n */'), 'test\ntest');
expect(reformat('/*\n * test\n + test\n */'), '* test\n+ test');
expect(reformat('test */'), 'test');
});
test('Indenting blocks', () {
expect(reformat(' a\nb\n c'), 'a\nb\n c'); // strips leading indents
expect(reformat(' a\n b\n c'), 'a\nb\nc'); // strips common one-space indent, then strips stray one-space indents
expect(reformat(' a\n b\n c'), 'a\nb\nc'); // strips common two-space indent
expect(reformat(' a\n b\n c'), 'a\nb\nc'); // strips common two-space indent, then strips stray one-space indent
expect(reformat(' a\n b\n c'), 'a\n b\nc'); // streps common two-space indent
expect(reformat(' a\n b\n c'), 'a\n b\nc'); // streps common two-space indent
});
test('Leading blocks', () {
expect(reformat('#; a\n#; b\n#; c'), 'a\nb\nc');
expect(reformat('#; a\nb\nc'), '#; a\nb\nc');
expect(reformat('#; a\n b\n c'), '#; a\n b\n c');
});
test('Leading indented lines', () {
expect(reformat(' a\nb\nc'), 'a\nb\nc');
expect(reformat(' a\n b\nc'), 'a\nb\nc');
expect(reformat(' a\n b\nc'), 'a\nb\nc');
expect(reformat(' a\n b\nc'), 'a\nb\nc');
expect(reformat(' a\n b\nc'), 'a\n b\nc');
expect(reformat(' a\n b\nc'), 'a\n b\nc');
});
test('Leading indented blocks', () {
expect(reformat(' a\n a\nb\nc'), 'a\na\nb\nc');
expect(reformat(' a\n a\n b\nc'), 'a\na\nb\nc');
expect(reformat(' a\n a\n b\nc'), 'a\na\nb\nc');
expect(reformat(' a\n a\n b\nc'), 'a\na\nb\nc');
expect(reformat(' a\n a\n b\nc'), 'a\na\n b\nc');
expect(reformat(' a\n a\n b\nc'), 'a\na\n b\nc');
});
test('Specific cases', () {
expect(reformat(' Apache\n Version\n Bla bla\n\nBla bla bla'), 'Apache\nVersion\nBla bla\n\nBla bla bla');
expect(
reformat(
'/* Copyright (c) IBM Corporation, 2000-2012. All rights reserved. */\n'
'/* */\n'
'/* This software is made available under the terms of the */\n'
'/* ICU License -- ICU 1.8.1 and later. */\n'
),
'Copyright (c) IBM Corporation, 2000-2012. All rights reserved.\n'
'\n'
'This software is made available under the terms of the\n'
'ICU License -- ICU 1.8.1 and later.'
);
expect(
reformat(
'/* Copyright (c) IBM Corporation, 2000-2012. All rights reserved. */\n'
'/* */\n'
'/* This software is made available under the terms of the */\n'
'/* ICU License -- ICU 1.8.1 and later. */'
),
'Copyright (c) IBM Corporation, 2000-2012. All rights reserved.\n'
'\n'
'This software is made available under the terms of the\n'
'ICU License -- ICU 1.8.1 and later.'
);
expect(
reformat(
'/* Copyright (c) IBM Corporation, 2000-2012. All rights reserved. */\n'
'/* */\n'
'/* This software is made available under the terms of the */\n'
'/* ICU License -- ICU 1.8.1 and later.'
),
'Copyright (c) IBM Corporation, 2000-2012. All rights reserved.\n'
'\n'
'This software is made available under the terms of the\n'
'ICU License -- ICU 1.8.1 and later.'
);
});
}