From d00bfbb87a56e71ee0dccd3e10c20e66730eace7 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Mon, 16 Dec 2024 16:19:17 -0800 Subject: [PATCH] Pre-format licenses script (flutter/engine#57219) The license script has load-baring formatting: Changing its format makes signature checks fail. To ensure the formatting change goes in smoothly later this week I am taking it off the critical path by pre-formatting it. The script itself is fairly stable, so I am not expecting any changes to it between now and when we actually enforce formatting. Edit: The issue that surfaced with `ci/licenses_golden/licenses_dart` is another reason to take this off the critical path of enforcing formatting. --- .../flutter/ci/licenses_golden/tool_signature | 2 +- .../tools/licenses/lib/filesystem.dart | 491 +++-- .../flutter/tools/licenses/lib/formatter.dart | 9 +- .../flutter/tools/licenses/lib/licenses.dart | 647 +++++-- .../src/flutter/tools/licenses/lib/main.dart | 401 ++-- .../src/flutter/tools/licenses/lib/paths.dart | 14 +- .../flutter/tools/licenses/lib/patterns.dart | 1641 ++++++++--------- .../tools/licenses/lib/regexp_debug.dart | 28 +- .../tools/licenses/test/formatter_test.dart | 43 +- 9 files changed, 1954 insertions(+), 1322 deletions(-) diff --git a/engine/src/flutter/ci/licenses_golden/tool_signature b/engine/src/flutter/ci/licenses_golden/tool_signature index 1e8b05bf95..11c3e48d3b 100644 --- a/engine/src/flutter/ci/licenses_golden/tool_signature +++ b/engine/src/flutter/ci/licenses_golden/tool_signature @@ -1,2 +1,2 @@ -Signature: 08cd2e281007e92182d3d540ff50e0ad +Signature: ddf9867e4034dc9bd94a9e107c31752e diff --git a/engine/src/flutter/tools/licenses/lib/filesystem.dart b/engine/src/flutter/tools/licenses/lib/filesystem.dart index 3136523056..a720829cd3 100644 --- a/engine/src/flutter/tools/licenses/lib/filesystem.dart +++ b/engine/src/flutter/tools/licenses/lib/filesystem.dart @@ -26,9 +26,17 @@ enum FileType { typedef Reader = List Function(); -class BytesOf extends Key { BytesOf(super.value); } -class UTF8Of extends Key { UTF8Of(super.value); } -class Latin1Of extends Key { Latin1Of(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 bytes, List signature) { if (bytes.length < signature.length) { @@ -66,71 +74,136 @@ const String kMultiLicenseFileHeader = 'Notices for files contained in'; bool isMultiLicenseNotice(Reader reader) { final List bytes = reader(); - return ascii.decode(bytes.take(kMultiLicenseFileHeader.length).toList(), allowInvalid: true) == kMultiLicenseFileHeader; + return ascii.decode(bytes.take(kMultiLicenseFileHeader.length).toList(), allowInvalid: true) == + kMultiLicenseFileHeader; } FileType identifyFile(String name, Reader reader) { List? bytes; - if ((path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/icu/source/extra/uconv/README') || // This specific ICU README isn't in UTF-8. - (path.split(name).reversed.take(6).toList().reversed.join('/') == 'third_party/icu/source/samples/uresb/sr.txt') || // This specific sample contains non-UTF-8 data (unlike other sr.txt files). - (path.split(name).reversed.take(2).toList().reversed.join('/') == 'builds/detect.mk') || // This specific freetype sample contains non-UTF-8 data (unlike other .mk files). + if ((path.split(name).reversed.take(6).toList().reversed.join('/') == + 'third_party/icu/source/extra/uconv/README') || // This specific ICU README isn't in UTF-8. + (path.split(name).reversed.take(6).toList().reversed.join('/') == + 'third_party/icu/source/samples/uresb/sr.txt') || // This specific sample contains non-UTF-8 data (unlike other sr.txt files). + (path.split(name).reversed.take(2).toList().reversed.join('/') == + 'builds/detect.mk') || // This specific freetype sample contains non-UTF-8 data (unlike other .mk files). (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 + 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 + 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; } - if (path.split(name).reversed.take(6).toList().reversed.join('/') == 'flutter/third_party/brotli/c/common/dictionary.bin.br') { // Brotli-compressed Brotli dictionary + if (path.split(name).reversed.take(6).toList().reversed.join('/') == + 'flutter/third_party/brotli/c/common/dictionary.bin.br') { + // Brotli-compressed Brotli dictionary return FileType.binary; } final String base = path.basename(name); if (base.startsWith('._')) { bytes ??= reader(); - if (matchesSignature(bytes, [0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58])) { + if (matchesSignature(bytes, [ + 0x00, + 0x05, + 0x16, + 0x07, + 0x00, + 0x02, + 0x00, + 0x00, + 0x4d, + 0x61, + 0x63, + 0x20, + 0x4f, + 0x53, + 0x20, + 0x58, + ])) { return FileType.notPartOfBuild; } // The ._* files in Mac OS X archives that gives icons and stuff } if (path.split(name).contains('cairo')) { bytes ??= reader(); // "Copyright " - if (hasSubsequence(bytes, [0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0xA9, 0x20], kMaxSize)) { + if (hasSubsequence(bytes, [ + 0x43, + 0x6f, + 0x70, + 0x79, + 0x72, + 0x69, + 0x67, + 0x68, + 0x74, + 0x20, + 0xA9, + 0x20, + ], kMaxSize)) { return FileType.latin1Text; } } switch (base) { // Build files - case 'DEPS': return FileType.text; - case 'MANIFEST': return FileType.text; + case 'DEPS': + return FileType.text; + case 'MANIFEST': + return FileType.text; // Licenses - case 'COPYING': return FileType.text; - case 'LICENSE': return FileType.text; - case 'NOTICE.txt': return isMultiLicenseNotice(reader) ? FileType.binary : FileType.text; - case 'NOTICE': return FileType.text; + case 'COPYING': + return FileType.text; + case 'LICENSE': + return FileType.text; + case 'NOTICE.txt': + return isMultiLicenseNotice(reader) ? FileType.binary : FileType.text; + case 'NOTICE': + return FileType.text; // Documentation - case 'Changes': return FileType.text; - case 'change.log': return FileType.text; - case 'ChangeLog': return FileType.text; - case 'CHANGES.0': return FileType.latin1Text; - case 'README': return FileType.text; - case 'TODO': return FileType.text; - case 'NEWS': return FileType.text; - case 'README.chromium': return FileType.text; - case 'README.flutter': return FileType.text; - case 'README.tests': return FileType.text; - case 'OWNERS': return FileType.text; - case 'AUTHORS': return FileType.text; + case 'Changes': + return FileType.text; + case 'change.log': + return FileType.text; + case 'ChangeLog': + return FileType.text; + case 'CHANGES.0': + return FileType.latin1Text; + case 'README': + return FileType.text; + case 'TODO': + return FileType.text; + case 'NEWS': + return FileType.text; + case 'README.chromium': + return FileType.text; + case 'README.flutter': + return FileType.text; + case 'README.tests': + return FileType.text; + case 'OWNERS': + return FileType.text; + case 'AUTHORS': + return FileType.text; // Signatures (found in .jar files typically) - case 'CERT.RSA': return FileType.binary; - case 'ECLIPSE_.RSA': return FileType.binary; + case 'CERT.RSA': + return FileType.binary; + case 'ECLIPSE_.RSA': + return FileType.binary; // Binary data files - case 'tzdata': return FileType.binary; - case 'compressed_atrace_data.txt': return FileType.binary; + case 'tzdata': + return FileType.binary; + case 'compressed_atrace_data.txt': + return FileType.binary; // Source files that don't use UTF-8 case 'Messages_de_DE.properties': // has a few non-ASCII characters they forgot to escape (from gnu-libstdc++) case 'mmx_blendtmp.h': // author name in comment contains latin1 (mesa) @@ -154,101 +227,192 @@ FileType identifyFile(String name, Reader reader) { } switch (path.extension(name)) { // C/C++ code - case '.h': return FileType.text; - case '.c': return FileType.text; - case '.cc': return FileType.text; - case '.cpp': return FileType.text; - case '.inc': return FileType.text; + case '.h': + return FileType.text; + case '.c': + return FileType.text; + case '.cc': + return FileType.text; + case '.cpp': + return FileType.text; + case '.inc': + return FileType.text; // Go code - case '.go': return FileType.text; + case '.go': + return FileType.text; // ObjectiveC code - case '.m': return FileType.text; + case '.m': + return FileType.text; // Assembler - case '.asm': return FileType.text; + case '.asm': + return FileType.text; // Shell - case '.sh': return FileType.notPartOfBuild; - case '.bat': return FileType.notPartOfBuild; + case '.sh': + return FileType.notPartOfBuild; + case '.bat': + return FileType.notPartOfBuild; // Build files - 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; + 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 - case '.class': return FileType.binary; // compiled Java bytecode (usually found inside .jar archives) - case '.dex': return FileType.binary; // Dalvik Executable (usually found inside .jar archives) + case '.java': + return FileType.text; + case '.jar': + return FileType.zip; // Java package + case '.class': + return FileType.binary; // compiled Java bytecode (usually found inside .jar archives) + case '.dex': + return FileType.binary; // Dalvik Executable (usually found inside .jar archives) // Dart code - case '.dart': return FileType.text; - case '.dill': return FileType.binary; // Compiled Dart code + case '.dart': + return FileType.text; + case '.dill': + return FileType.binary; // Compiled Dart code // LLVM bitcode - case '.bc': return FileType.binary; + case '.bc': + return FileType.binary; // Python code case '.py': bytes ??= reader(); // # -*- coding: Latin-1 -*- - if (matchesSignature(bytes, [0x23, 0x20, 0x2d, 0x2a, 0x2d, 0x20, 0x63, 0x6f, 0x64, - 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x4c, 0x61, 0x74, 0x69, - 0x6e, 0x2d, 0x31, 0x20, 0x2d, 0x2a, 0x2d])) { + if (matchesSignature(bytes, [ + 0x23, + 0x20, + 0x2d, + 0x2a, + 0x2d, + 0x20, + 0x63, + 0x6f, + 0x64, + 0x69, + 0x6e, + 0x67, + 0x3a, + 0x20, + 0x4c, + 0x61, + 0x74, + 0x69, + 0x6e, + 0x2d, + 0x31, + 0x20, + 0x2d, + 0x2a, + 0x2d, + ])) { return FileType.latin1Text; } return FileType.text; - case '.pyc': return FileType.binary; // compiled Python bytecode + case '.pyc': + return FileType.binary; // compiled Python bytecode // Machine code - case '.so': return FileType.binary; // ELF shared object - case '.xpt': return FileType.binary; // XPCOM Type Library + case '.so': + return FileType.binary; // ELF shared object + case '.xpt': + return FileType.binary; // XPCOM Type Library // Graphics code - case '.glsl': return FileType.text; - case '.spvasm': return FileType.text; + case '.glsl': + return FileType.text; + case '.spvasm': + return FileType.text; // Documentation - case '.md': return FileType.text; - case '.txt': return FileType.text; - case '.html': return FileType.text; + case '.md': + return FileType.text; + case '.txt': + return FileType.text; + case '.html': + return FileType.text; // Fonts - case '.ttf': return FileType.binary; // TrueType Font + case '.ttf': + return FileType.binary; // TrueType Font case '.ttcf': // (mac) - case '.ttc': return FileType.binary; // TrueType Collection (windows) - case '.woff': return FileType.binary; // Web Open Font Format - case '.otf': return FileType.binary; // OpenType Font + case '.ttc': + return FileType.binary; // TrueType Collection (windows) + case '.woff': + return FileType.binary; // Web Open Font Format + case '.otf': + return FileType.binary; // OpenType Font // Graphics formats - case '.gif': return FileType.binary; // GIF - case '.png': return FileType.binary; // PNG - case '.tga': return FileType.binary; // Truevision TGA (TARGA) - case '.dng': return FileType.binary; // Digial Negative (Adobe RAW format) + case '.gif': + return FileType.binary; // GIF + case '.png': + return FileType.binary; // PNG + case '.tga': + return FileType.binary; // Truevision TGA (TARGA) + case '.dng': + return FileType.binary; // Digial Negative (Adobe RAW format) case '.jpg': - case '.jpeg': return FileType.binary; // JPEG - case '.ico': return FileType.binary; // Windows icon format - case '.icns': return FileType.binary; // macOS icon format - case '.bmp': return FileType.binary; // Windows bitmap format - case '.wbmp': return FileType.binary; // Wireless bitmap format - case '.webp': return FileType.binary; // WEBP - case '.pdf': return FileType.binary; // PDF - 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 + case '.jpeg': + return FileType.binary; // JPEG + case '.ico': + return FileType.binary; // Windows icon format + case '.icns': + return FileType.binary; // macOS icon format + case '.bmp': + return FileType.binary; // Windows bitmap format + case '.wbmp': + return FileType.binary; // Wireless bitmap format + case '.webp': + return FileType.binary; // WEBP + case '.pdf': + return FileType.binary; // PDF + 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 - case '.ts': return FileType.binary; // MPEG2 transport stream + case '.ogg': + return FileType.binary; // Ogg media + case '.mp4': + return FileType.binary; // MPEG media + case '.ts': + return FileType.binary; // MPEG2 transport stream // Other binary files - case '.raw': return FileType.binary; // raw audio or graphical data - case '.bin': return FileType.binary; // some sort of binary data - case '.rsc': return FileType.binary; // some sort of resource data - case '.arsc': return FileType.binary; // Android compiled resources - case '.apk': return FileType.zip; // Android Package - case '.crx': return FileType.binary; // Chrome extension - case '.keystore': return FileType.binary; - case '.icc': return FileType.binary; // Color profile - case '.swp': return FileType.binary; // Vim swap file - case '.bfbs': return FileType.binary; // Flatbuffers Binary Schema + case '.raw': + return FileType.binary; // raw audio or graphical data + case '.bin': + return FileType.binary; // some sort of binary data + case '.rsc': + return FileType.binary; // some sort of resource data + case '.arsc': + return FileType.binary; // Android compiled resources + case '.apk': + return FileType.zip; // Android Package + case '.crx': + return FileType.binary; // Chrome extension + case '.keystore': + return FileType.binary; + case '.icc': + return FileType.binary; // Color profile + case '.swp': + return FileType.binary; // Vim swap file + case '.bfbs': + return FileType.binary; // Flatbuffers Binary Schema // Archives - case '.zip': return FileType.zip; // ZIP - case '.tar': return FileType.tar; // Tar - case '.gz': return FileType.gz; // GZip - case '.bzip2': return FileType.bzip2; // BZip2 + case '.zip': + return FileType.zip; // ZIP + case '.tar': + return FileType.tar; // Tar + case '.gz': + return FileType.gz; // GZip + case '.bzip2': + return FileType.bzip2; // BZip2 // Image file types from the Fuchsia SDK. case '.blk': case '.vboot': @@ -340,7 +504,24 @@ FileType identifyFile(String name, Reader reader) { if (matchesSignature(bytes, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0a])) { return FileType.binary; } // PNG - if (matchesSignature(bytes, [0x58, 0x50, 0x43, 0x4f, 0x4d, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x69, 0x62, 0x0d, 0x0a, 0x1a])) { + if (matchesSignature(bytes, [ + 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, [0x23, 0x21])) { @@ -356,7 +537,6 @@ String _normalize(String fileContents) { return fileContents; } - // INTERFACE // base class @@ -423,7 +603,7 @@ abstract class Directory extends IoNode { } // interface -abstract class Link extends IoNode { } +abstract class Link extends IoNode {} mixin ZipFile on File implements Directory { ArchiveDirectory? _root; @@ -462,7 +642,8 @@ mixin GZipFile on File implements Directory { Iterable get walk sync* { try { final String innerName = path.basenameWithoutExtension(fullName); - _data ??= InMemoryFile.parse('$fullName!$innerName', a.GZipDecoder().decodeBytes(readBytes()!))!; + _data ??= + InMemoryFile.parse('$fullName!$innerName', a.GZipDecoder().decodeBytes(readBytes()!))!; if (_data != null) { yield _data!; } @@ -480,7 +661,8 @@ mixin BZip2File on File implements Directory { Iterable get walk sync* { try { final String innerName = path.basenameWithoutExtension(fullName); - _data ??= InMemoryFile.parse('$fullName!$innerName', a.BZip2Decoder().decodeBytes(readBytes()!))!; + _data ??= + InMemoryFile.parse('$fullName!$innerName', a.BZip2Decoder().decodeBytes(readBytes()!))!; if (_data != null) { yield _data!; } @@ -491,7 +673,6 @@ mixin BZip2File on File implements Directory { } } - // FILESYSTEM IMPLEMENTATIoN class FileSystemDirectory extends IoNode implements Directory { @@ -527,14 +708,22 @@ class FileSystemDirectory extends IoNode implements Directory { final io.File fileEntity = entity as io.File; if (fileEntity.lengthSync() > 0) { switch (identifyFile(fileEntity.path, () => _readBytes(fileEntity))) { - case FileType.binary: yield FileSystemFile(fileEntity); - case FileType.zip: yield FileSystemZipFile(fileEntity); - case FileType.tar: yield FileSystemTarFile(fileEntity); - case FileType.gz: yield FileSystemGZipFile(fileEntity); - case FileType.bzip2: yield FileSystemBZip2File(fileEntity); - case FileType.text: yield FileSystemUTF8TextFile(fileEntity); - case FileType.latin1Text: yield FileSystemLatin1TextFile(fileEntity); - case FileType.notPartOfBuild: break; // ignore this file + case FileType.binary: + yield FileSystemFile(fileEntity); + case FileType.zip: + yield FileSystemZipFile(fileEntity); + case FileType.tar: + yield FileSystemTarFile(fileEntity); + case FileType.gz: + yield FileSystemGZipFile(fileEntity); + case FileType.bzip2: + yield FileSystemBZip2File(fileEntity); + case FileType.text: + yield FileSystemUTF8TextFile(fileEntity); + case FileType.latin1Text: + yield FileSystemLatin1TextFile(fileEntity); + case FileType.notPartOfBuild: + break; // ignore this file } } } @@ -595,7 +784,6 @@ class FileSystemBZip2File extends FileSystemFile with BZip2File { FileSystemBZip2File(super.file); } - // ARCHIVES class ArchiveDirectory extends IoNode implements Directory { @@ -613,22 +801,32 @@ class ArchiveDirectory extends IoNode implements Directory { void _add(a.ArchiveFile entry, List remainingPath) { if (remainingPath.length > 1) { final String subdirectoryName = remainingPath.removeAt(0); - _subdirectories.putIfAbsent( - subdirectoryName, - () => ArchiveDirectory('$fullName/$subdirectoryName', subdirectoryName) - )._add(entry, remainingPath); + _subdirectories + .putIfAbsent( + subdirectoryName, + () => ArchiveDirectory('$fullName/$subdirectoryName', subdirectoryName), + ) + ._add(entry, remainingPath); } else { if (entry.size > 0) { final String entryFullName = '$fullName/${path.basename(entry.name)}'; switch (identifyFile(entry.name, () => entry.content as List)) { - case FileType.binary: _files.add(ArchiveFile(entryFullName, entry)); - case FileType.zip: _files.add(ArchiveZipFile(entryFullName, entry)); - case FileType.tar: _files.add(ArchiveTarFile(entryFullName, entry)); - case FileType.gz: _files.add(ArchiveGZipFile(entryFullName, entry)); - case FileType.bzip2: _files.add(ArchiveBZip2File(entryFullName, entry)); - case FileType.text: _files.add(ArchiveUTF8TextFile(entryFullName, entry)); - case FileType.latin1Text: _files.add(ArchiveLatin1TextFile(entryFullName, entry)); - case FileType.notPartOfBuild: break; // ignore this file + case FileType.binary: + _files.add(ArchiveFile(entryFullName, entry)); + case FileType.zip: + _files.add(ArchiveZipFile(entryFullName, entry)); + case FileType.tar: + _files.add(ArchiveTarFile(entryFullName, entry)); + case FileType.gz: + _files.add(ArchiveGZipFile(entryFullName, entry)); + case FileType.bzip2: + _files.add(ArchiveBZip2File(entryFullName, entry)); + case FileType.text: + _files.add(ArchiveUTF8TextFile(entryFullName, entry)); + case FileType.latin1Text: + _files.add(ArchiveLatin1TextFile(entryFullName, entry)); + case FileType.notPartOfBuild: + break; // ignore this file } } } @@ -692,7 +890,6 @@ class ArchiveBZip2File extends ArchiveFile with BZip2File { ArchiveBZip2File(super.fullName, super.file); } - // IN-MEMORY FILES (e.g. contents of GZipped files) class InMemoryFile extends IoNode implements File { @@ -703,14 +900,22 @@ class InMemoryFile extends IoNode implements File { return null; } switch (identifyFile(fullName, () => bytes)) { - case FileType.binary: return InMemoryFile(fullName, bytes); - case FileType.zip: return InMemoryZipFile(fullName, bytes); - case FileType.tar: return InMemoryTarFile(fullName, bytes); - case FileType.gz: return InMemoryGZipFile(fullName, bytes); - case FileType.bzip2: return InMemoryBZip2File(fullName, bytes); - case FileType.text: return InMemoryUTF8TextFile(fullName, bytes); - case FileType.latin1Text: return InMemoryLatin1TextFile(fullName, bytes); - case FileType.notPartOfBuild: break; // ignore this file + case FileType.binary: + return InMemoryFile(fullName, bytes); + case FileType.zip: + return InMemoryZipFile(fullName, bytes); + case FileType.tar: + return InMemoryTarFile(fullName, bytes); + case FileType.gz: + return InMemoryGZipFile(fullName, bytes); + case FileType.bzip2: + return InMemoryBZip2File(fullName, bytes); + case FileType.text: + return InMemoryUTF8TextFile(fullName, bytes); + case FileType.latin1Text: + return InMemoryLatin1TextFile(fullName, bytes); + case FileType.notPartOfBuild: + break; // ignore this file } assert(false); return null; diff --git a/engine/src/flutter/tools/licenses/lib/formatter.dart b/engine/src/flutter/tools/licenses/lib/formatter.dart index 152755b450..418d2326fa 100644 --- a/engine/src/flutter/tools/licenses/lib/formatter.dart +++ b/engine/src/flutter/tools/licenses/lib/formatter.dart @@ -38,7 +38,8 @@ bool _stripIndentation(List lines) { } else { prefix = leadingDecorations.matchAsPrefix(lines.first)?.group(0); } - if (prefix != null && lines.skip(1).every((String line) => line.startsWith(prefix!) || prefix.startsWith(line))) { + 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]; @@ -168,7 +169,8 @@ String stripAsciiArt(String input) { for (final List 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) { + 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; @@ -186,7 +188,8 @@ String stripAsciiArt(String input) { 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); + lines[index + imageLine] = + text.substring(0, x) + text.substring(x + width, text.length); } else { lines[index + imageLine] = text.substring(0, x); } diff --git a/engine/src/flutter/tools/licenses/lib/licenses.dart b/engine/src/flutter/tools/licenses/lib/licenses.dart index 5092b1a7e5..c55879ad72 100644 --- a/engine/src/flutter/tools/licenses/lib/licenses.dart +++ b/engine/src/flutter/tools/licenses/lib/licenses.dart @@ -12,7 +12,9 @@ import 'limits.dart'; import 'patterns.dart'; import 'regexp_debug.dart'; -class FetchedContentsOf extends Key { FetchedContentsOf(super.value); } +class FetchedContentsOf extends Key { + FetchedContentsOf(super.value); +} enum LicenseType { afl, @@ -159,7 +161,7 @@ abstract class LicenseSource { String get officialSourceLocation; List? nearestLicensesFor(String name); License? nearestLicenseOfType(LicenseType type); - License? nearestLicenseWithName(String name, { String? authors }); + License? nearestLicenseWithName(String name, {String? authors}); } // Represents a license/file pairing, with metadata saying where the license came from. @@ -217,7 +219,10 @@ List groupLicenses(Iterable assignments) { final Map groups = {}; for (final Assignment assignment in assignments) { final String body = assignment.license.toStringBody(assignment.source); - final GroupedLicense entry = groups.putIfAbsent(body, () => GroupedLicense(assignment.license.type, body)); + final GroupedLicense entry = groups.putIfAbsent( + body, + () => GroupedLicense(assignment.license.type, body), + ); entry.targets.add(assignment.target); entry.libraries.add(assignment.source.libraryName); entry.origins.add(assignment.license.origin); @@ -228,16 +233,24 @@ List groupLicenses(Iterable assignments) { } abstract class License { - factory License.unique(String body, LicenseType type, { + factory License.unique( + String body, + LicenseType type, { bool reformatted = false, required String origin, String? authors, - bool yesWeKnowWhatItLooksLikeButItIsNot = false + bool yesWeKnowWhatItLooksLikeButItIsNot = false, }) { if (!reformatted) { body = reformat(body); } - final License result = UniqueLicense._(body, type, origin: origin, yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, authors: authors); + final License result = UniqueLicense._( + body, + type, + origin: origin, + yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, + authors: authors, + ); assert(() { if (result is! UniqueLicense || result.type != type) { throw 'tried to add a UniqueLicense $type, but it was a duplicate of a ${result.runtimeType} ${result.type}'; @@ -247,7 +260,9 @@ abstract class License { return result; } - factory License.template(String body, LicenseType type, { + factory License.template( + String body, + LicenseType type, { bool reformatted = false, required String origin, String? authors, @@ -265,10 +280,12 @@ abstract class License { return result; } - factory License.multiLicense(String body, LicenseType type, { + factory License.multiLicense( + String body, + LicenseType type, { bool reformatted = false, String? authors, - required String origin + required String origin, }) { if (!reformatted) { body = reformat(body); @@ -283,9 +300,11 @@ abstract class License { return result; } - factory License.message(String body, LicenseType type, { + factory License.message( + String body, + LicenseType type, { bool reformatted = false, - required String origin + required String origin, }) { if (!reformatted) { body = reformat(body); @@ -300,7 +319,7 @@ abstract class License { return result; } - factory License.blank(String body, LicenseType type, { required String origin }) { + factory License.blank(String body, LicenseType type, {required String origin}) { final License result = BlankLicense._(reformat(body), type, origin: origin); assert(() { if (result is! BlankLicense || result.type != type) { @@ -311,7 +330,7 @@ abstract class License { return result; } - factory License.mozilla(String body, { required String origin }) { + factory License.mozilla(String body, {required String origin}) { body = reformat(body); final License result = MozillaLicense._(body, LicenseType.mpl, origin: origin); assert(() { @@ -323,18 +342,28 @@ abstract class License { return result; } - factory License.fromMultipleBlocks(List bodies, LicenseType type, { + factory License.fromMultipleBlocks( + List bodies, + LicenseType type, { String? authors, required String origin, bool yesWeKnowWhatItLooksLikeButItIsNot = false, }) { final String body = bodies.map((String s) => reformat(s)).join('\n\n'); - return MultiLicense._(body, type, authors: authors, origin: origin, yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot); + return MultiLicense._( + body, + type, + authors: authors, + origin: origin, + yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, + ); } - factory License.fromBodyAndType(String body, LicenseType type, { + factory License.fromBodyAndType( + String body, + LicenseType type, { bool reformatted = false, - required String origin + required String origin, }) { if (!reformatted) { body = reformat(body); @@ -380,7 +409,7 @@ abstract class License { return result; } - factory License.fromBodyAndName(String body, String name, { required String origin }) { + factory License.fromBodyAndName(String body, String name, {required String origin}) { body = reformat(body); LicenseType type = convertLicenseNameToType(name); if (type == LicenseType.unknown) { @@ -389,7 +418,7 @@ abstract class License { return License.fromBodyAndType(body, type, reformatted: true, origin: origin); } - factory License.fromBody(String body, { required String origin, bool reformatted = false }) { + factory License.fromBody(String body, {required String origin, bool reformatted = false}) { if (!reformatted) { body = reformat(body); } @@ -397,18 +426,26 @@ abstract class License { return License.fromBodyAndType(body, type, reformatted: true, origin: origin); } - factory License.fromCopyrightAndLicense(String copyright, String template, LicenseType type, { required String origin }) { + factory License.fromCopyrightAndLicense( + String copyright, + String template, + LicenseType type, { + required String origin, + }) { copyright = reformat(copyright); template = reformat(template); return TemplateLicense._(copyright, template, type, origin: origin); } - factory License.fromIdentifyingReference(String identifyingReference, { required String referencer }) { + factory License.fromIdentifyingReference( + String identifyingReference, { + required String referencer, + }) { String body; LicenseType type = LicenseType.unknown; switch (identifyingReference) { - case 'Apache-2.0 OR MIT': // SPDX ID - case 'Apache-2.0': // SPDX ID + case 'Apache-2.0 OR MIT': // SPDX ID + case 'Apache-2.0': // SPDX ID case 'Apache:2.0': case 'http://www.apache.org/licenses/LICENSE-2.0': case 'https://www.apache.org/licenses/LICENSE-2.0': @@ -417,7 +454,7 @@ abstract class License { // https://github.com/abseil/abseil-cpp/pull/270/files#r793181143 body = system.File('data/apache-license-2.0').readAsStringSync(); type = LicenseType.apache; - case 'Apache-2.0 WITH LLVM-exception': // SPDX ID + case 'Apache-2.0 WITH LLVM-exception': // SPDX ID case 'https://llvm.org/LICENSE.txt': body = system.File('data/apache-license-2.0-with-llvm-exception').readAsStringSync(); type = LicenseType.llvm; @@ -438,7 +475,7 @@ abstract class License { body = system.File('data/library-gpl-2.0').readAsStringSync(); type = LicenseType.lgpl; case 'GNU Lesser:2': - // there has never been such a license, but the authors said they meant the LGPL2.1 + // there has never been such a license, but the authors said they meant the LGPL2.1 case 'GNU Lesser:2.1': body = system.File('data/lesser-gpl-2.1').readAsStringSync(); type = LicenseType.lgpl; @@ -454,7 +491,7 @@ abstract class License { case 'http://mozilla.org/MPL/2.0/:2.0': body = system.File('data/mozilla-2.0').readAsStringSync(); type = LicenseType.mpl; - case 'MIT': // SPDX ID + case 'MIT': // SPDX ID case 'http://opensource->org/licenses/MIT': // i don't even case 'http://opensource.org/licenses/MIT': case 'https://opensource.org/licenses/MIT': @@ -472,15 +509,22 @@ abstract class License { case 'http://www.ietf.org/rfc/rfc3454.txt': body = system.File('data/ietf').readAsStringSync(); type = LicenseType.ietf; - default: throw 'unknown identifyingReference $identifyingReference'; + default: + throw 'unknown identifyingReference $identifyingReference'; } - return License.fromBodyAndType(body, type, origin: '$identifyingReference referenced by $referencer'); + return License.fromBodyAndType( + body, + type, + origin: '$identifyingReference referenced by $referencer', + ); } - License._(String body, this.type, { + License._( + String body, + this.type, { required this.origin, String? authors, - bool yesWeKnowWhatItLooksLikeButItIsNot = false + bool yesWeKnowWhatItLooksLikeButItIsNot = false, }) : authors = authors ?? _readAuthors(body) { assert(() { try { @@ -525,13 +569,21 @@ abstract class License { return true; }()); final LicenseType detectedType = convertBodyToType(body); - if (detectedType != LicenseType.unknown && detectedType != type && !yesWeKnowWhatItLooksLikeButItIsNot) { + if (detectedType != LicenseType.unknown && + detectedType != type && + !yesWeKnowWhatItLooksLikeButItIsNot) { throw 'Created a license of type $type but it looks like $detectedType:\n---------\n$body\n-----------'; } - if (type != LicenseType.apache && type != LicenseType.llvm && type != LicenseType.vulkan && type != LicenseType.apacheNotice && body.contains('Apache')) { + if (type != LicenseType.apache && + type != LicenseType.llvm && + type != LicenseType.vulkan && + type != LicenseType.apacheNotice && + body.contains('Apache')) { throw 'Non-Apache license (type=$type, detectedType=$detectedType) contains the word "Apache"; maybe it\'s a notice?:\n---\n$body\n---'; } - if (detectedType != LicenseType.unknown && detectedType != type && !yesWeKnowWhatItLooksLikeButItIsNot) { + if (detectedType != LicenseType.unknown && + detectedType != type && + !yesWeKnowWhatItLooksLikeButItIsNot) { throw 'Created a license of type $type but it looks like $detectedType.'; } if (body.contains(trailingColon)) { @@ -542,20 +594,26 @@ abstract class License { try { latin1Encoded = latin1.encode(body); isUTF8 = false; - } on ArgumentError { /* Fall through to next encoding check. */ } + } on ArgumentError { + /* Fall through to next encoding check. */ + } if (!isUTF8) { bool isAscii = false; try { ascii.decode(latin1Encoded); isAscii = true; - } on FormatException { /* Fall through to next encoding check */ } + } on FormatException { + /* Fall through to next encoding check */ + } if (isAscii) { return; } try { utf8.decode(latin1Encoded); isUTF8 = true; - } on FormatException { /* We check isUTF8 below and throw if necessary */ } + } on FormatException { + /* We check isUTF8 below and throw if necessary */ + } if (isUTF8) { throw 'tried to create a License object with text that appears to have been misdecoded as Latin1 instead of as UTF-8:\n$body'; } @@ -577,13 +635,13 @@ abstract class License { // here in those cases is usually a reference to that license); some other // licenses turn into two, one for the original license and one for this // copyright/body pair. - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }); + Iterable _expandTemplate(String copyright, String licenseBody, {required String origin}); String toStringBody(LicenseSource source); static final RegExp _copyrightForAuthors = RegExp( r'Copyright [-0-9 ,(cC)©]+\b(The .+ Authors)\.', - caseSensitive: false + caseSensitive: false, ); static String? _readAuthors(String body) { @@ -629,8 +687,8 @@ Iterable<_LineRange> _walkLinesBackwards(String body, int start) sync* { } } -Iterable<_LineRange> _walkLinesForwards(String body, { int start = 0, int? end }) sync* { - int? startIndex = start == 0 || body[start-1] == '\n' ? start : null; +Iterable<_LineRange> _walkLinesForwards(String body, {int start = 0, int? end}) sync* { + int? startIndex = start == 0 || body[start - 1] == '\n' ? start : null; int endIndex = startIndex ?? start; end ??= body.length; while (endIndex < end) { @@ -648,15 +706,17 @@ Iterable<_LineRange> _walkLinesForwards(String body, { int start = 0, int? end } } class _SplitLicense { - _SplitLicense(this._body, this._split) : assert(_split == 0 || _split == _body.length || _body[_split] == '\n'); + _SplitLicense(this._body, this._split) + : assert(_split == 0 || _split == _body.length || _body[_split] == '\n'); final String _body; final int _split; String getCopyright() => _body.substring(0, _split); - String getConditions() => _split >= _body.length ? '' : _body.substring(_split == 0 ? 0 : _split + 1); + String getConditions() => + _split >= _body.length ? '' : _body.substring(_split == 0 ? 0 : _split + 1); } -_SplitLicense _splitLicense(String body, { bool verifyResults = true }) { +_SplitLicense _splitLicense(String body, {bool verifyResults = true}) { final Iterator<_LineRange> lines = _walkLinesForwards(body).iterator; if (!lines.moveNext()) { throw 'tried to split empty license'; @@ -734,15 +794,24 @@ _SplitLicense _splitLicense(String body, { bool verifyResults = true }) { break; } } - if (verifyResults && 'Copyright ('.allMatches(body, end).isNotEmpty && !body.startsWith('If you modify libpng')) { + if (verifyResults && + 'Copyright ('.allMatches(body, end).isNotEmpty && + !body.startsWith('If you modify libpng')) { throw 'the license seems to contain a copyright:\n===copyright===\n${body.substring(0, end)}\n===license===\n${body.substring(end)}\n=========\ntermination reason: $endReason'; } return _SplitLicense(body, end); } class _PartialLicenseMatch { - _PartialLicenseMatch(this._body, this.start, this.split, this.end, this._match, { required this.hasCopyrights }) : assert(split >= start), - assert(split == start || _body[split] == '\n'); + _PartialLicenseMatch( + this._body, + this.start, + this.split, + this.end, + this._match, { + required this.hasCopyrights, + }) : assert(split >= start), + assert(split == start || _body[split] == '\n'); final String _body; final int start; @@ -757,6 +826,7 @@ class _PartialLicenseMatch { } return null; } + String getCopyrights() => _body.substring(start, split); String getConditions() => _body.substring(split + 1, end); String getEntireLicense() => _body.substring(start, end); @@ -764,7 +834,13 @@ class _PartialLicenseMatch { } // Look for all matches of `pattern` in `body` and return them along with associated copyrights. -Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, int firstPrefixIndex, int indentPrefixIndex, { bool needsCopyright = true }) sync* { +Iterable<_PartialLicenseMatch> _findLicenseBlocks( + String body, + RegExp pattern, + int firstPrefixIndex, + int indentPrefixIndex, { + bool needsCopyright = true, +}) sync* { // I tried doing this with one big RegExp initially, but that way lay madness. for (final Match match in pattern.allMatches(body)) { assert(match.groupCount >= firstPrefixIndex); @@ -818,7 +894,8 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i // we think might be part of a copyright statement bool foundAny = false; RegExp? debugFirstPattern; - copyrightSearch: for (final _LineRange range in _walkLinesForwards(body, start: start, end: match.start)) { + copyrightSearch: + for (final _LineRange range in _walkLinesForwards(body, start: start, end: match.start)) { String line = range.value; if (firstLineOffset > 0) { line = line.substring(firstLineOffset); @@ -826,7 +903,10 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i } else if (line.startsWith(fullPrefix)) { line = line.substring(fullPrefix.length); } else { - assert(line.isEmpty || fullPrefix.startsWith(line), 'invariant violated: expected this to be a blank line but it was "$line" (prefix is "$fullPrefix").'); + assert( + line.isEmpty || fullPrefix.startsWith(line), + 'invariant violated: expected this to be a blank line but it was "$line" (prefix is "$fullPrefix").', + ); continue copyrightSearch; } for (final RegExp pattern in copyrightStatementLeadingPatterns) { @@ -842,7 +922,7 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i int split; if (!foundAny) { if (needsCopyright) { - throw 'could not find copyright before license\nlicense body was:\n---\n${body.substring(match.start, match.end)}\n---\nfile was:\n---\n$body\n---'; + throw 'could not find copyright before license\nlicense body was:\n---\n${body.substring(match.start, match.end)}\n---\nfile was:\n---\n$body\n---'; } start = match.start; split = match.start; @@ -853,7 +933,10 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i // This will tell us if we collected something in the copyright block // that was more license than copyright and that therefore should be // examined closer. - final _SplitLicense consistencyCheck = _splitLicense(undecoratedCopyrights, verifyResults: false); + final _SplitLicense consistencyCheck = _splitLicense( + undecoratedCopyrights, + verifyResults: false, + ); final String conditions = consistencyCheck.getConditions(); if (conditions != '') { // Copyright lines long enough to spill to a second line can create @@ -870,7 +953,10 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i if (!copyrights.contains(anySlightSignOfCopyrights)) { throw 'could not find copyright before license block:\n---\ncopyrights was:\n---\n$copyrights\n---\nblock was:\n---\n${body.substring(start, match.end)}\n---'; } - assert(body[match.start - 1] == '\n', 'match did not start at a newline; match.start = ${match.start}, match.end = ${match.end}, split at: "${body[match.start - 1]}"'); + assert( + body[match.start - 1] == '\n', + 'match did not start at a newline; match.start = ${match.start}, match.end = ${match.end}, split at: "${body[match.start - 1]}"', + ); split = match.start - 1; } yield _PartialLicenseMatch(body, start, split, match.end, match, hasCopyrights: foundAny); @@ -878,10 +964,13 @@ Iterable<_PartialLicenseMatch> _findLicenseBlocks(String body, RegExp pattern, i } class _LicenseMatch { - _LicenseMatch(this.license, this.start, this.end, { + _LicenseMatch( + this.license, + this.start, + this.end, { this.debug = '', this.ignoreWhenCheckingOverlappingRegions = false, - this.missingCopyrights = false + this.missingCopyrights = false, }); final License license; final int start; @@ -896,22 +985,47 @@ class _LicenseMatch { } } -Iterable<_LicenseMatch> _expand(License template, String copyright, String body, int start, int end, { String debug = '', required String origin }) sync* { - final List results = template._expandTemplate(reformat(copyright), body, origin: origin).toList(); +Iterable<_LicenseMatch> _expand( + License template, + String copyright, + String body, + int start, + int end, { + String debug = '', + required String origin, +}) sync* { + final List results = + template._expandTemplate(reformat(copyright), body, origin: origin).toList(); if (results.isEmpty) { throw 'license could not be expanded'; } yield _LicenseMatch(results.first, start, end, debug: 'expanding template for $debug'); if (results.length > 1) { - yield* results.skip(1).map((License license) => _LicenseMatch(license, start, end, ignoreWhenCheckingOverlappingRegions: true, debug: 'expanding subsequent template for $debug')); + yield* results + .skip(1) + .map( + (License license) => _LicenseMatch( + license, + start, + end, + ignoreWhenCheckingOverlappingRegions: true, + debug: 'expanding subsequent template for $debug', + ), + ); } } -Iterable<_LicenseMatch> _tryReferenceByFilename(String body, LicenseFileReferencePattern pattern, LicenseSource parentDirectory, { required String origin }) sync* { +Iterable<_LicenseMatch> _tryReferenceByFilename( + String body, + LicenseFileReferencePattern pattern, + LicenseSource parentDirectory, { + required String origin, +}) sync* { if (pattern.copyrightIndex != null) { for (final Match match in pattern.pattern.allMatches(body)) { final String copyright = match.group(pattern.copyrightIndex!)!; - final String? authors = pattern.authorIndex != null ? match.group(pattern.authorIndex!) : null; + final String? authors = + pattern.authorIndex != null ? match.group(pattern.authorIndex!) : null; final String filename = match.group(pattern.fileIndex)!; final License? template = parentDirectory.nearestLicenseWithName(filename, authors: authors); if (template == null) { @@ -919,10 +1033,24 @@ Iterable<_LicenseMatch> _tryReferenceByFilename(String body, LicenseFileReferenc } assert(reformat(copyright) != ''); final String entireLicense = body.substring(match.start, match.end); - yield* _expand(template, copyright, entireLicense, match.start, match.end, debug: '_tryReferenceByFilename (with explicit copyright) looking for $filename', origin: origin); + yield* _expand( + template, + copyright, + entireLicense, + match.start, + match.end, + debug: '_tryReferenceByFilename (with explicit copyright) looking for $filename', + origin: origin, + ); } } else { - for (final _PartialLicenseMatch match in _findLicenseBlocks(body, pattern.pattern, pattern.firstPrefixIndex, pattern.indentPrefixIndex, needsCopyright: pattern.needsCopyright)) { + for (final _PartialLicenseMatch match in _findLicenseBlocks( + body, + pattern.pattern, + pattern.firstPrefixIndex, + pattern.indentPrefixIndex, + needsCopyright: pattern.needsCopyright, + )) { final String? authors = match.getAuthors(); String? filename = match.group(pattern.fileIndex); if (filename == 'modp_b64.c') { @@ -934,42 +1062,96 @@ Iterable<_LicenseMatch> _tryReferenceByFilename(String body, LicenseFileReferenc // files never reach here because they're marked as binary files in filesystem.dart. final License? template = parentDirectory.nearestLicenseWithName(filename!, authors: authors); if (template == null) { - throw - 'failed to find accompanying "$filename" in $parentDirectory\n' - 'block:\n---\n${match.getEntireLicense()}\n---'; + throw 'failed to find accompanying "$filename" in $parentDirectory\n' + 'block:\n---\n${match.getEntireLicense()}\n---'; } if (match.getCopyrights() == '') { - yield _LicenseMatch(template, match.start, match.end, debug: '_tryReferenceByFilename (with failed copyright search) looking for $filename'); + yield _LicenseMatch( + template, + match.start, + match.end, + debug: '_tryReferenceByFilename (with failed copyright search) looking for $filename', + ); } else { - yield* _expand(template, match.getCopyrights(), match.getEntireLicense(), match.start, match.end, debug: '_tryReferenceByFilename (with successful copyright search) looking for $filename', origin: origin); + yield* _expand( + template, + match.getCopyrights(), + match.getEntireLicense(), + match.start, + match.end, + debug: '_tryReferenceByFilename (with successful copyright search) looking for $filename', + origin: origin, + ); } } } } -Iterable<_LicenseMatch> _tryReferenceByType(String body, RegExp pattern, LicenseSource parentDirectory, { required String origin }) sync* { - for (final _PartialLicenseMatch match in _findLicenseBlocks(body, pattern, 1, 2, needsCopyright: false)) { +Iterable<_LicenseMatch> _tryReferenceByType( + String body, + RegExp pattern, + LicenseSource parentDirectory, { + required String origin, +}) sync* { + for (final _PartialLicenseMatch match in _findLicenseBlocks( + body, + pattern, + 1, + 2, + needsCopyright: false, + )) { final LicenseType type = convertLicenseNameToType(match.group(3)); final License? template = parentDirectory.nearestLicenseOfType(type); if (template == null) { throw 'failed to find accompanying $type license in $parentDirectory'; } if (match.getCopyrights() == '') { - yield _LicenseMatch(template, match.start, match.end, debug: '_tryReferenceByType (without copyrights) for type $type'); + yield _LicenseMatch( + template, + match.start, + match.end, + debug: '_tryReferenceByType (without copyrights) for type $type', + ); } else { - yield* _expand(template, match.getCopyrights(), match.getEntireLicense(), match.start, match.end, debug: '_tryReferenceByType (with successful copyright search) for type $type', origin: origin); + yield* _expand( + template, + match.getCopyrights(), + match.getEntireLicense(), + match.start, + match.end, + debug: '_tryReferenceByType (with successful copyright search) for type $type', + origin: origin, + ); } } } -License _dereferenceLicense(int groupIndex, String? Function(int index) group, LicenseReferencePattern pattern, LicenseSource parentDirectory, { required String origin }) { - License? result = pattern.checkLocalFirst ? parentDirectory.nearestLicenseWithName(group(groupIndex)!) : null; +License _dereferenceLicense( + int groupIndex, + String? Function(int index) group, + LicenseReferencePattern pattern, + LicenseSource parentDirectory, { + required String origin, +}) { + License? result = + pattern.checkLocalFirst ? parentDirectory.nearestLicenseWithName(group(groupIndex)!) : null; result ??= License.fromIdentifyingReference(group(groupIndex)!, referencer: origin); return result; } -Iterable<_LicenseMatch> _tryReferenceByIdentifyingReference(String body, LicenseReferencePattern pattern, LicenseSource parentDirectory, { required String origin }) sync* { - for (final _PartialLicenseMatch match in _findLicenseBlocks(body, pattern.pattern!, 1, 2, needsCopyright: false)) { +Iterable<_LicenseMatch> _tryReferenceByIdentifyingReference( + String body, + LicenseReferencePattern pattern, + LicenseSource parentDirectory, { + required String origin, +}) sync* { + for (final _PartialLicenseMatch match in _findLicenseBlocks( + body, + pattern.pattern!, + 1, + 2, + needsCopyright: false, + )) { if (pattern.spdx) { // Per legal advice, we allowlist the use of SPDX headers. Currently, we // recognize SPDX headers in code from Khronos. To identify such code, we @@ -991,26 +1173,67 @@ Iterable<_LicenseMatch> _tryReferenceByIdentifyingReference(String body, License continue; } } - assert(match.group(3) != null, 'pattern ${pattern.pattern!} did not have three groups when matched against:\n---\n$body\n---\nmatch: $match'); - final License template = _dereferenceLicense(3, match.group, pattern, parentDirectory, origin: origin); + assert( + match.group(3) != null, + 'pattern ${pattern.pattern!} did not have three groups when matched against:\n---\n$body\n---\nmatch: $match', + ); + final License template = _dereferenceLicense( + 3, + match.group, + pattern, + parentDirectory, + origin: origin, + ); if (match.getCopyrights() == '') { - yield _LicenseMatch(template, match.start, match.end, debug: '_tryReferenceByIdentifyingReference (without copyrights)'); + yield _LicenseMatch( + template, + match.start, + match.end, + debug: '_tryReferenceByIdentifyingReference (without copyrights)', + ); } else { - yield* _expand(template, match.getCopyrights(), match.getEntireLicense(), match.start, match.end, debug: '_tryReferenceByIdentifyingReference (with copyright)', origin: origin); + yield* _expand( + template, + match.getCopyrights(), + match.getEntireLicense(), + match.start, + match.end, + debug: '_tryReferenceByIdentifyingReference (with copyright)', + origin: origin, + ); } } } -Iterable<_LicenseMatch> _tryInline(String body, RegExp pattern, { +Iterable<_LicenseMatch> _tryInline( + String body, + RegExp pattern, { required bool needsCopyright, required String origin, }) sync* { - for (final _PartialLicenseMatch match in _findLicenseBlocks(body, pattern, 1, 2, needsCopyright: needsCopyright)) { - yield _LicenseMatch(License.fromBody(match.getEntireLicense(), origin: origin), match.start, match.end, debug: '_tryInline', missingCopyrights: needsCopyright && !match.hasCopyrights); + for (final _PartialLicenseMatch match in _findLicenseBlocks( + body, + pattern, + 1, + 2, + needsCopyright: needsCopyright, + )) { + yield _LicenseMatch( + License.fromBody(match.getEntireLicense(), origin: origin), + match.start, + match.end, + debug: '_tryInline', + missingCopyrights: needsCopyright && !match.hasCopyrights, + ); } } -Iterable<_LicenseMatch> _tryStray(String body, RegExp pattern, LicenseSource parentDirectory, { required String origin }) sync* { +Iterable<_LicenseMatch> _tryStray( + String body, + RegExp pattern, + LicenseSource parentDirectory, { + required String origin, +}) sync* { // this one doesn't look for copyrights (that's the point, the patterns _are_ the copyrights) bool gotTemplate = false; License? template; @@ -1020,27 +1243,63 @@ Iterable<_LicenseMatch> _tryStray(String body, RegExp pattern, LicenseSource par gotTemplate = true; } if (template != null) { - yield* _expand(template, match.group(0)!, match.group(0)!, match.start, match.end, debug: '_tryStray (with template)', origin: origin); + yield* _expand( + template, + match.group(0)!, + match.group(0)!, + match.start, + match.end, + debug: '_tryStray (with template)', + origin: origin, + ); } else { - yield _LicenseMatch(License.fromBody(match.group(0)!, origin: origin), match.start, match.end, debug: '_tryStray'); + yield _LicenseMatch( + License.fromBody(match.group(0)!, origin: origin), + match.start, + match.end, + debug: '_tryStray', + ); } } } -Iterable<_LicenseMatch> _tryForwardReferencePattern(String fileContents, ForwardReferencePattern pattern, License template, LicenseSource source, { required String origin }) sync* { +Iterable<_LicenseMatch> _tryForwardReferencePattern( + String fileContents, + ForwardReferencePattern pattern, + License template, + LicenseSource source, { + required String origin, +}) sync* { String? body; - for (final _PartialLicenseMatch match in _findLicenseBlocks(fileContents, pattern.pattern, pattern.firstPrefixIndex, pattern.indentPrefixIndex)) { + for (final _PartialLicenseMatch match in _findLicenseBlocks( + fileContents, + pattern.pattern, + pattern.firstPrefixIndex, + pattern.indentPrefixIndex, + )) { body ??= template.toStringBody(source); if (!body.contains(pattern.targetPattern)) { - throw - 'forward license reference to unexpected license\n' - 'license:\n---\n$body\n---\nexpected pattern:\n---\n${pattern.targetPattern}\n---'; + throw 'forward license reference to unexpected license\n' + 'license:\n---\n$body\n---\nexpected pattern:\n---\n${pattern.targetPattern}\n---'; } - yield* _expand(template, match.getCopyrights(), match.getEntireLicense(), match.start, match.end, debug: '_tryForwardReferencePattern', origin: origin); + yield* _expand( + template, + match.getCopyrights(), + match.getEntireLicense(), + match.start, + match.end, + debug: '_tryForwardReferencePattern', + origin: origin, + ); } } -List determineLicensesFor(String fileContents, String filename, LicenseSource? parentDirectory, { required String origin }) { +List determineLicensesFor( + String fileContents, + String filename, + LicenseSource? parentDirectory, { + required String origin, +}) { if (parentDirectory == null) { throw 'Fatal error: determineLicensesFor was called with parentDirectory=null!'; } @@ -1049,24 +1308,65 @@ List determineLicensesFor(String fileContents, String filename, License } final List<_LicenseMatch> results = <_LicenseMatch>[]; fileContents = stripAsciiArt(fileContents); - results.addAll(csReferencesByFilename.expand((LicenseFileReferencePattern pattern) => _tryReferenceByFilename(fileContents, pattern, parentDirectory, origin: origin))); - results.addAll(csReferencesByType.expand((RegExp pattern) => _tryReferenceByType(fileContents, pattern, parentDirectory, origin: origin))); - results.addAll(csReferencesByIdentifyingReference.expand((LicenseReferencePattern pattern) => _tryReferenceByIdentifyingReference(fileContents, pattern, parentDirectory, origin: origin))); - results.addAll(csTemplateLicenses.expand((RegExp pattern) => _tryInline(fileContents, pattern, needsCopyright: true, origin: origin))); - results.addAll(csNoticeLicenses.expand((RegExp pattern) => _tryInline(fileContents, pattern, needsCopyright: false, origin: origin))); + results.addAll( + csReferencesByFilename.expand( + (LicenseFileReferencePattern pattern) => + _tryReferenceByFilename(fileContents, pattern, parentDirectory, origin: origin), + ), + ); + results.addAll( + csReferencesByType.expand( + (RegExp pattern) => + _tryReferenceByType(fileContents, pattern, parentDirectory, origin: origin), + ), + ); + results.addAll( + csReferencesByIdentifyingReference.expand( + (LicenseReferencePattern pattern) => _tryReferenceByIdentifyingReference( + fileContents, + pattern, + parentDirectory, + origin: origin, + ), + ), + ); + results.addAll( + csTemplateLicenses.expand( + (RegExp pattern) => _tryInline(fileContents, pattern, needsCopyright: true, origin: origin), + ), + ); + results.addAll( + csNoticeLicenses.expand( + (RegExp pattern) => _tryInline(fileContents, pattern, needsCopyright: false, origin: origin), + ), + ); _LicenseMatch? usedTemplate; if (results.length == 1) { final _LicenseMatch target = results.single; - results.addAll(csForwardReferenceLicenses.expand((ForwardReferencePattern pattern) => _tryForwardReferencePattern(fileContents, pattern, target.license, parentDirectory, origin: origin))); + results.addAll( + csForwardReferenceLicenses.expand( + (ForwardReferencePattern pattern) => _tryForwardReferencePattern( + fileContents, + pattern, + target.license, + parentDirectory, + origin: origin, + ), + ), + ); if (results.length > 1) { usedTemplate = target; } } - for (final _LicenseMatch match in results.where((_LicenseMatch match) => match.missingCopyrights)) { + for (final _LicenseMatch match in results.where( + (_LicenseMatch match) => match.missingCopyrights, + )) { throw 'found a license for $filename but could not match its copyright:\n----8<----\n${match.license}\n----8<----'; } if (results.isEmpty) { - if ((fileContents.contains(copyrightMentionPattern) && fileContents.contains(licenseMentionPattern)) && !fileContents.contains(copyrightMentionOkPattern)) { + if ((fileContents.contains(copyrightMentionPattern) && + fileContents.contains(licenseMentionPattern)) && + !fileContents.contains(copyrightMentionOkPattern)) { throw 'failed to find any license but saw unmatched potential copyright and license statements; first twenty lines:\n----8<----\n${fileContents.split("\n").take(20).join("\n")}\n----8<----'; } } @@ -1075,7 +1375,10 @@ List determineLicensesFor(String fileContents, String filename, License // allowlisted in csStrayCopyrights are handled this way, though. For each of // these, we have to make sure they don't overlap any of the actual licenses // matched earlier, so we check for overlaps on each one first. - strays: for (final _LicenseMatch stray in csStrayCopyrights.expand((RegExp pattern) => _tryStray(fileContents, pattern, parentDirectory, origin: origin))) { + strays: + for (final _LicenseMatch stray in csStrayCopyrights.expand( + (RegExp pattern) => _tryStray(fileContents, pattern, parentDirectory, origin: origin), + )) { for (final _LicenseMatch full in results) { if (stray.start >= full.start && stray.end <= full.end) { continue strays; @@ -1105,14 +1408,15 @@ List determineLicensesFor(String fileContents, String filename, License system.stderr.writeln( 'license match: ${n.start}..${n.end}, ${n.license.runtimeType}, ${n.debug}\n' ' first line: ${n.license.toStringBody(parentDirectory).split("\n").first}\n' - ' last line: ${n.license.toStringBody(parentDirectory).split("\n").last}' + ' last line: ${n.license.toStringBody(parentDirectory).split("\n").last}', ); } throw 'overlapping licenses in $filename (one ends at $position, another starts at ${m.start})'; } if (position < m.start) { final String substring = fileContents.substring(position, m.start); - if (substring.contains(copyrightMentionPattern) && !substring.contains(copyrightMentionOkPattern)) { + if (substring.contains(copyrightMentionPattern) && + !substring.contains(copyrightMentionOkPattern)) { throw 'there is another unmatched potential copyright statement in $filename:\n $position..${m.start}: "$substring"\nmatched licenses: $results'; } if (substring.contains(licenseMentionPattern)) { @@ -1122,7 +1426,8 @@ List determineLicensesFor(String fileContents, String filename, License position = m.end; } final String substring = fileContents.substring(position); - if (substring.contains(copyrightMentionPattern) && !substring.contains(copyrightMentionOkPattern)) { + if (substring.contains(copyrightMentionPattern) && + !substring.contains(copyrightMentionOkPattern)) { throw 'there is an unmatched potential copyright statement in $filename:\n $position..end: "$substring"\nmatched licenses: $results'; } if (substring.contains(licenseMentionPattern)) { @@ -1131,7 +1436,11 @@ List determineLicensesFor(String fileContents, String filename, License return results.map((_LicenseMatch entry) => entry.license).toSet().toList(); } -License? interpretAsRedirectLicense(String fileContents, LicenseSource parentDirectory, { required String origin }) { +License? interpretAsRedirectLicense( + String fileContents, + LicenseSource parentDirectory, { + required String origin, +}) { _SplitLicense split; try { split = _splitLicense(fileContents); @@ -1148,7 +1457,13 @@ License? interpretAsRedirectLicense(String fileContents, LicenseSource parentDir } final Match? match = pattern.pattern!.matchAsPrefix(body); if (match != null && match.start == 0 && match.end == body.length) { - final License candidate = _dereferenceLicense(3, match.group as String? Function(int?), pattern, parentDirectory, origin: origin); + final License candidate = _dereferenceLicense( + 3, + match.group as String? Function(int?), + pattern, + parentDirectory, + origin: origin, + ); if (result != null) { throw 'Multiple potential matches in interpretAsRedirectLicense in $parentDirectory; body was:\n------8<------\n$fileContents\n------8<------'; } @@ -1160,7 +1475,8 @@ License? interpretAsRedirectLicense(String fileContents, LicenseSource parentDir // the kind of license that just wants to show a message (e.g. the JPEG one) class MessageLicense extends License { - MessageLicense._(this.body, LicenseType type, { required String origin }) : super._(body, type, origin: origin); + MessageLicense._(this.body, LicenseType type, {required String origin}) + : super._(body, type, origin: origin); final String body; @@ -1168,22 +1484,41 @@ class MessageLicense extends License { String toStringBody(LicenseSource source) => body; @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) => [this]; + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) => [this]; } // the kind of license that says to include the copyright and the license text (e.g. BSD) class TemplateLicense extends License { - TemplateLicense._(this.defaultCopyright, this.terms, LicenseType type, { String? authors, required String origin }) - : assert(!defaultCopyright.endsWith('\n')), - assert(!terms.startsWith('\n')), - assert(terms.isNotEmpty), - super._('$defaultCopyright\n\n$terms', type, origin: origin, authors: authors); + TemplateLicense._( + this.defaultCopyright, + this.terms, + LicenseType type, { + String? authors, + required String origin, + }) : assert(!defaultCopyright.endsWith('\n')), + assert(!terms.startsWith('\n')), + assert(terms.isNotEmpty), + super._('$defaultCopyright\n\n$terms', type, origin: origin, authors: authors); - factory TemplateLicense._autosplit(String body, LicenseType type, { String? authors, required String origin }) { + factory TemplateLicense._autosplit( + String body, + LicenseType type, { + String? authors, + required String origin, + }) { final _SplitLicense bits = _splitLicense(body); final String copyright = bits.getCopyright(); final String terms = bits.getConditions(); - assert((copyright.isEmpty && terms == body) || ('$copyright\n$terms' == body) || (copyright == body && terms.isEmpty), '_splitLicense contract violation.\nCOPYRIGHT:\n===\n$copyright\n===\nTERMS:\n===\n$terms\n===\nBODY:\n===\n$body\n===\n'); + assert( + (copyright.isEmpty && terms == body) || + ('$copyright\n$terms' == body) || + (copyright == body && terms.isEmpty), + '_splitLicense contract violation.\nCOPYRIGHT:\n===\n$copyright\n===\nTERMS:\n===\n$terms\n===\nBODY:\n===\n$body\n===\n', + ); int copyrightLength = copyright.length; while (copyrightLength > 0 && copyright[copyrightLength - 1] == '\n') { copyrightLength -= 1; @@ -1213,8 +1548,14 @@ class TemplateLicense extends License { } @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { - return [ License.fromCopyrightAndLicense(copyright, terms, type, origin: '$origin + ${this.origin}') ]; + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { + return [ + License.fromCopyrightAndLicense(copyright, terms, type, origin: '$origin + ${this.origin}'), + ]; } } @@ -1227,11 +1568,19 @@ class TemplateLicense extends License { // copyright, plus there's a copyright in the file that (probably) doesn't exactly match any of the // copyrights in the file, plus some text saying that that license applies to the file. class MultiLicense extends License { - MultiLicense._(this.body, LicenseType type, { + MultiLicense._( + this.body, + LicenseType type, { String? authors, required String origin, bool yesWeKnowWhatItLooksLikeButItIsNot = false, - }) : super._(body, type, origin: origin, authors: authors, yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot); + }) : super._( + body, + type, + origin: origin, + authors: authors, + yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, + ); final String body; @@ -1239,13 +1588,20 @@ class MultiLicense extends License { String toStringBody(LicenseSource source) => body; @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { // Sometimes a license (e.g. the OpenSSL license in the BoringSSL package) is referenced // from a file that has its own copyright header. When that happens we just print the referenced // license and the reference to that license separately because it's not at all clear how we're // supposed to merge them otherwise. licenseBody = reformat(licenseBody); - assert(licenseBody.startsWith(copyright), 'copyright:\n---\n$copyright\n---\nlicenseBody:\n---\n$licenseBody\n---'); + assert( + licenseBody.startsWith(copyright), + 'copyright:\n---\n$copyright\n---\nlicenseBody:\n---\n$licenseBody\n---', + ); return [ this, License.fromBody(licenseBody, origin: '$origin (with ${this.origin})', reformatted: true), @@ -1255,11 +1611,19 @@ class MultiLicense extends License { // the kind of license that should not be combined with separate copyright notices class UniqueLicense extends License { - UniqueLicense._(this.body, LicenseType type, { + UniqueLicense._( + this.body, + LicenseType type, { required String origin, String? authors, - bool yesWeKnowWhatItLooksLikeButItIsNot = false - }) : super._(body, type, origin: origin, yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, authors: authors); + bool yesWeKnowWhatItLooksLikeButItIsNot = false, + }) : super._( + body, + type, + origin: origin, + yesWeKnowWhatItLooksLikeButItIsNot: yesWeKnowWhatItLooksLikeButItIsNot, + authors: authors, + ); final String body; @@ -1267,17 +1631,25 @@ class UniqueLicense extends License { String toStringBody(LicenseSource source) => body; @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { throw 'attempted to expand non-template license with "$copyright"\ntemplate was: $this'; } } // the kind of license that doesn't need to be reported anywhere class BlankLicense extends License { - BlankLicense._(super.body, super.type, { required super.origin }) : super._(); + BlankLicense._(super.body, super.type, {required super.origin}) : super._(); @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { // We don't care what copyrights this kind of license has, we don't need // to report them. Just report |this| (which is always blank, see below). return [this]; @@ -1289,7 +1661,9 @@ class BlankLicense extends License { // MPL class MozillaLicense extends License { - MozillaLicense._(this.body, LicenseType type, { required String origin }) : assert(type == LicenseType.mpl), super._(body, type, origin: origin); + MozillaLicense._(this.body, LicenseType type, {required String origin}) + : assert(type == LicenseType.mpl), + super._(body, type, origin: origin); final String body; @@ -1302,7 +1676,11 @@ class MozillaLicense extends License { } @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { throw 'attempted to expand non-template license with "$copyright"\ntemplate was: $this'; } @@ -1311,13 +1689,16 @@ class MozillaLicense extends License { final StringBuffer result = StringBuffer(); result.writeln(body); result.writeln(); - result.writeln("You may obtain a copy of this library's Source Code Form from: ${source.officialSourceLocation}"); + result.writeln( + "You may obtain a copy of this library's Source Code Form from: ${source.officialSourceLocation}", + ); return result.toString(); } } class DisallowedLicense extends License { - DisallowedLicense._(this.body, LicenseType type, { required String origin }) : super._(body, type, origin: origin); + DisallowedLicense._(this.body, LicenseType type, {required String origin}) + : super._(body, type, origin: origin); final String body; @@ -1327,7 +1708,11 @@ class DisallowedLicense extends License { } @override - Iterable _expandTemplate(String copyright, String licenseBody, { required String origin }) { + Iterable _expandTemplate( + String copyright, + String licenseBody, { + required String origin, + }) { throw 'attempted to use $origin which is a disallowed license type ($type)'; } diff --git a/engine/src/flutter/tools/licenses/lib/main.dart b/engine/src/flutter/tools/licenses/lib/main.dart index ef4af8b13c..6457bbbbf6 100644 --- a/engine/src/flutter/tools/licenses/lib/main.dart +++ b/engine/src/flutter/tools/licenses/lib/main.dart @@ -187,7 +187,16 @@ class _RepositoryGeneralSingleLicenseFile extends _RepositorySingleLicenseFile { // (e.g. having the copyright for one above the terms for the other and so on). class _RepositoryOpaqueLicenseFile extends _RepositorySingleLicenseFile { _RepositoryOpaqueLicenseFile(_RepositoryDirectory parent, fs.TextFile io) - : super(parent, io, License.unique(io.readString(), LicenseType.unknown, origin: io.fullName, yesWeKnowWhatItLooksLikeButItIsNot: true)); + : super( + parent, + io, + License.unique( + io.readString(), + LicenseType.unknown, + origin: io.fullName, + yesWeKnowWhatItLooksLikeButItIsNot: true, + ), + ); } class _RepositoryReadmeIjgFile extends _RepositorySingleLicenseFile { @@ -197,7 +206,8 @@ class _RepositoryReadmeIjgFile extends _RepositorySingleLicenseFile { // The message we are required to include in our output. // // We include it by just including the whole license. - static const String _message = 'this software is based in part on the work of the Independent JPEG Group'; + static const String _message = + 'this software is based in part on the work of the Independent JPEG Group'; // The license text that says we should output _message. // @@ -212,7 +222,9 @@ class _RepositoryReadmeIjgFile extends _RepositorySingleLicenseFile { r'unaltered; and any additions, deletions, or changes to the original files\n' r'must be clearly indicated in accompanying documentation\.\n' r'\(2\) If only executable code is distributed, then the accompanying\n' - r'documentation must state that "' '${_message.replaceAll(" ", "[ \n]+")}' r'"\.\n' + r'documentation must state that "' + '${_message.replaceAll(" ", "[ \n]+")}' + r'"\.\n' r'\(3\) Permission for use of this software is granted only if the user accepts\n' r'full responsibility for any undesirable consequences; the authors accept\n' r'NO LIABILITY for damages of any kind\.\n', @@ -239,9 +251,7 @@ class _RepositoryDartLicenseFile extends _RepositorySingleLicenseFile { _RepositoryDartLicenseFile(_RepositoryDirectory parent, fs.TextFile io) : super(parent, io, _parseLicense(io)); - static final RegExp _pattern = RegExp( - r'(Copyright (?:.|\n)+)$', - ); + static final RegExp _pattern = RegExp(r'(Copyright (?:.|\n)+)$'); static License _parseLicense(fs.TextFile io) { final Match? match = _pattern.firstMatch(io.readString()); @@ -290,7 +300,7 @@ class _RepositoryLibJpegTurboLicenseFile extends _RepositoryLicenseFile { r'- The zlib License, which is listed in \[simd/jsimdext\.inc\]\(simd/jsimdext\.inc\)\n' r'\n' r' This license is a subset of the other two, and it covers the libjpeg-turbo\n' - r' SIMD extensions\.\n' + r' SIMD extensions\.\n', ); static void _parseLicense(fs.TextFile io) { @@ -318,10 +328,13 @@ class _RepositoryLibJpegTurboLicenseFile extends _RepositoryLicenseFile { @override List get licenses { if (_licenses == null) { - final _RepositoryLicenseFile readme = parent!.getChildByName('README.ijg') as _RepositoryReadmeIjgFile; - final _RepositorySourceFile main = parent!.getChildByName('turbojpeg.c') as _RepositorySourceFile; + final _RepositoryLicenseFile readme = + parent!.getChildByName('README.ijg') as _RepositoryReadmeIjgFile; + final _RepositorySourceFile main = + parent!.getChildByName('turbojpeg.c') as _RepositorySourceFile; final _RepositoryDirectory simd = parent!.getChildByName('simd') as _RepositoryDirectory; - final _RepositorySourceFile zlib = simd.getChildByName('jsimdext.inc') as _RepositorySourceFile; + final _RepositorySourceFile zlib = + simd.getChildByName('jsimdext.inc') as _RepositorySourceFile; _licenses = []; _licenses!.addAll(readme.licenses); _licenses!.add(main.extractInternalLicense()); @@ -332,8 +345,7 @@ class _RepositoryLibJpegTurboLicenseFile extends _RepositoryLicenseFile { } class _RepositoryFreetypeLicenseFile extends _RepositoryLicenseFile { - _RepositoryFreetypeLicenseFile(super.parent, super.io) - : _target = _parseLicense(io); + _RepositoryFreetypeLicenseFile(super.parent, super.io) : _target = _parseLicense(io); static final RegExp _pattern = RegExp( r'FREETYPE LICENSES\n' @@ -376,7 +388,7 @@ class _RepositoryFreetypeLicenseFile extends _RepositoryLicenseFile { r'The MD5 checksum support \(only used for debugging in development\n' r'builds\) is in the public domain\.\n' r'\n*' - r'--- end of LICENSE\.TXT ---\n*$' + r'--- end of LICENSE\.TXT ---\n*$', ); static String _parseLicense(fs.TextFile io) { @@ -426,7 +438,10 @@ class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile { throw 'could not parse ICU license file'; } const int groupCount = 22; - assert(match.groupCount == groupCount, 'ICU: expected $groupCount groups, but got ${match.groupCount}'); + assert( + match.groupCount == groupCount, + 'ICU: expected $groupCount groups, but got ${match.groupCount}', + ); const int timeZoneGroup = 18; if (match.group(timeZoneGroup)!.contains(copyrightMentionPattern)) { throw 'ICU: unexpected copyright in time zone database group\n:${match.group(timeZoneGroup)}'; @@ -436,21 +451,24 @@ class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile { } const int gplGroup1 = 20; const int gplGroup2 = 21; - if (!match.group(gplGroup1)!.contains(gplExceptionExplanation1) || !match.group(gplGroup2)!.contains(gplExceptionExplanation2)) { + if (!match.group(gplGroup1)!.contains(gplExceptionExplanation1) || + !match.group(gplGroup2)!.contains(gplExceptionExplanation2)) { throw 'ICU: did not find GPL exception in GPL-licensed files'; } - const Set skippedGroups = { timeZoneGroup, gplGroup1, gplGroup2 }; + const Set skippedGroups = {timeZoneGroup, gplGroup1, gplGroup2}; return _RepositoryIcuLicenseFile._( parent, io, License.template(match.group(2)!, LicenseType.bsd, origin: io.fullName), License.fromMultipleBlocks( - match.groups( - Iterable - .generate(groupCount, (int index) => index + 1) - .where((int index) => !skippedGroups.contains(index)) - .toList() - ).cast(), + match + .groups( + Iterable.generate( + groupCount, + (int index) => index + 1, + ).where((int index) => !skippedGroups.contains(index)).toList(), + ) + .cast(), LicenseType.icu, origin: io.fullName, yesWeKnowWhatItLooksLikeButItIsNot: true, @@ -458,8 +476,12 @@ class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile { ); } - _RepositoryIcuLicenseFile._(_RepositoryDirectory parent, fs.TextFile io, this.template, License license) - : super(parent, io, license); + _RepositoryIcuLicenseFile._( + _RepositoryDirectory parent, + fs.TextFile io, + this.template, + License license, + ) : super(parent, io, license); // Every paragraph of the license is mentioned. All newlines are disregarded [\n+]. static final RegExp _pattern = RegExp( @@ -563,29 +585,29 @@ class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile { ); static const String gplExceptionExplanation1 = - 'As a special exception to the GNU General Public License, if you\n' - 'distribute this file as part of a program that contains a\n' - 'configuration script generated by Autoconf, you may include it under\n' - 'the same distribution terms that you use for the rest of that\n' - 'program.\n' - '\n' - '\n' - '(The condition for the exception is fulfilled because\n' - 'ICU4C includes a configuration script generated by Autoconf,\n' - 'namely the `configure` script.)'; + 'As a special exception to the GNU General Public License, if you\n' + 'distribute this file as part of a program that contains a\n' + 'configuration script generated by Autoconf, you may include it under\n' + 'the same distribution terms that you use for the rest of that\n' + 'program.\n' + '\n' + '\n' + '(The condition for the exception is fulfilled because\n' + 'ICU4C includes a configuration script generated by Autoconf,\n' + 'namely the `configure` script.)'; static const String gplExceptionExplanation2 = - 'As a special exception to the GNU General Public License, if you\n' - 'distribute this file as part of a program that contains a\n' - 'configuration script generated by Autoconf, you may include it under\n' - 'the same distribution terms that you use for the rest of that\n' - 'program. This Exception is an additional permission under section 7\n' - 'of the GNU General Public License, version 3 ("GPLv3").\n' - '\n' - '\n' - '(The condition for the exception is fulfilled because\n' - 'ICU4C includes a configuration script generated by Autoconf,\n' - 'namely the `configure` script.)'; + 'As a special exception to the GNU General Public License, if you\n' + 'distribute this file as part of a program that contains a\n' + 'configuration script generated by Autoconf, you may include it under\n' + 'the same distribution terms that you use for the rest of that\n' + 'program. This Exception is an additional permission under section 7\n' + 'of the GNU General Public License, version 3 ("GPLv3").\n' + '\n' + '\n' + '(The condition for the exception is fulfilled because\n' + 'ICU4C includes a configuration script generated by Autoconf,\n' + 'namely the `configure` script.)'; // Fixes an error in the license's formatting that our reformatter wouldn't be // able to figure out on its own and which would otherwise completely mess up @@ -609,8 +631,7 @@ class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile { } class _RepositoryCxxStlDualLicenseFile extends _RepositoryLicenseFile { - _RepositoryCxxStlDualLicenseFile(super.parent, super.io) - : _licenses = _parseLicenses(io); + _RepositoryCxxStlDualLicenseFile(super.parent, super.io) : _licenses = _parseLicenses(io); static final RegExp _pattern = RegExp( r'^' @@ -750,8 +771,7 @@ class _RepositoryCxxStlDualLicenseFile extends _RepositoryLicenseFile { } class _RepositoryKhronosLicenseFile extends _RepositoryLicenseFile { - _RepositoryKhronosLicenseFile(super.parent, super.io) - : _licenses = _parseLicenses(io); + _RepositoryKhronosLicenseFile(super.parent, super.io) : _licenses = _parseLicenses(io); static final RegExp _pattern = RegExp( r'^(Copyright .+?)\n' @@ -852,16 +872,21 @@ class _RepositoryFuchsiaSdkLinuxLicenseFile extends _RepositorySingleLicenseFile _RepositoryFuchsiaSdkLinuxLicenseFile(_RepositoryDirectory parent, fs.TextFile io) : super(parent, io, _parseLicense(io)); - static const String _pattern = 'The majority of files in this project use the Apache 2.0 License.\n' - 'There are a few exceptions and their license can be found in the source.\n' - 'Any license deviations from Apache 2.0 are "more permissive" licenses.\n'; + static const String _pattern = + 'The majority of files in this project use the Apache 2.0 License.\n' + 'There are a few exceptions and their license can be found in the source.\n' + 'Any license deviations from Apache 2.0 are "more permissive" licenses.\n'; static License _parseLicense(fs.TextFile io) { final String body = io.readString(); if (!body.startsWith(_pattern)) { throw 'unexpected Fuchsia license file contents'; } - return License.fromBodyAndType(body.substring(_pattern.length), LicenseType.apache, origin: io.fullName); + return License.fromBodyAndType( + body.substring(_pattern.length), + LicenseType.apache, + origin: io.fullName, + ); } } @@ -875,13 +900,13 @@ class _RepositoryVulkanApacheLicenseFile extends _RepositorySingleLicenseFile { : super(parent, io, _parseLicense(io)); static const String _prefix = - 'The majority of files in this project use the Apache 2.0 License.\n' - 'There are a few exceptions and their license can be found in the source.\n' - 'Any license deviations from Apache 2.0 are "more permissive" licenses.\n' - "Any file without a license in it's source defaults to the repository Apache 2.0 License.\n" - '\n' - '===========================================================================================\n' - '\n'; + 'The majority of files in this project use the Apache 2.0 License.\n' + 'There are a few exceptions and their license can be found in the source.\n' + 'Any license deviations from Apache 2.0 are "more permissive" licenses.\n' + "Any file without a license in it's source defaults to the repository Apache 2.0 License.\n" + '\n' + '===========================================================================================\n' + '\n'; static License _parseLicense(fs.TextFile io) { final String body = io.readString(); @@ -892,7 +917,6 @@ class _RepositoryVulkanApacheLicenseFile extends _RepositorySingleLicenseFile { } } - // DIRECTORIES typedef _Constructor = _RepositoryFile Function(_RepositoryDirectory parent, fs.TextFile); @@ -912,7 +936,7 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { List<_RepositoryDirectory> get subdirectories => _subdirectories; - final Map _childrenByName = {}; + final Map _childrenByName = {}; void crawl() { for (final fs.IoNode entry in ioDirectory.walk) { @@ -987,7 +1011,10 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { } // the bit at the beginning excludes files like "license.py". - static final RegExp _licenseNamePattern = RegExp(r'^(?!.*\.py$)(?!.*(?:no|update)-copyright)(?!.*mh-bsd-gcc).*\b_*(?:license(?!\.html)|copying|copyright|notice|l?gpl|GPLv2|bsd|mit|mpl?|ftl|Apache)_*\b', caseSensitive: false); + static final RegExp _licenseNamePattern = RegExp( + r'^(?!.*\.py$)(?!.*(?:no|update)-copyright)(?!.*mh-bsd-gcc).*\b_*(?:license(?!\.html)|copying|copyright|notice|l?gpl|GPLv2|bsd|mit|mpl?|ftl|Apache)_*\b', + caseSensitive: false, + ); static const Map _specialCaseFiles = { '/flutter/third_party/boringssl/src/LICENSE': _RepositoryOpenSSLLicenseFile.new, @@ -1002,7 +1029,8 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { '/flutter/third_party/libpng/LICENSE': _RepositoryLibPngLicenseFile.new, '/flutter/third_party/rapidjson/LICENSE': _RepositoryOpaqueLicenseFile.new, '/flutter/third_party/rapidjson/license.txt': _RepositoryOpaqueLicenseFile.new, - '/flutter/third_party/vulkan-deps/vulkan-validation-layers/src/LICENSE.txt': _RepositoryVulkanApacheLicenseFile.new, + '/flutter/third_party/vulkan-deps/vulkan-validation-layers/src/LICENSE.txt': + _RepositoryVulkanApacheLicenseFile.new, '/fuchsia/sdk/linux/LICENSE.vulkan': _RepositoryFuchsiaSdkLinuxLicenseFile.new, '/fuchsia/sdk/mac/LICENSE.vulkan': _RepositoryFuchsiaSdkLinuxLicenseFile.new, '/third_party/khronos/LICENSE': _RepositoryKhronosLicenseFile.new, @@ -1023,7 +1051,9 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { return _RepositoryBinaryFile(this, entry as fs.File); } - int get count => _files.length + _subdirectories.fold(0, (int count, _RepositoryDirectory child) => count + child.count); + int get count => + _files.length + + _subdirectories.fold(0, (int count, _RepositoryDirectory child) => count + child.count); bool _canGoUp() { assert(parent != null || isLicenseRoot); @@ -1063,13 +1093,14 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { /// Searches the current directory for licenses of the specified type. License? _localLicenseWithType(LicenseType type) { - final List licenses = _licenses.expand((_RepositoryLicenseFile license) { - final License? result = license.licenseOfType(type); - if (result != null) { - return [result]; - } - return const []; - }).toList(); + final List licenses = + _licenses.expand((_RepositoryLicenseFile license) { + final License? result = license.licenseOfType(type); + if (result != null) { + return [result]; + } + return const []; + }).toList(); if (licenses.length > 1) { print('unexpectedly found multiple matching licenses in $name of type $type'); return null; @@ -1083,8 +1114,11 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { /// Searches all subdirectories (depth-first) for a license of the specified type. License? _fullWalkDownForLicenseWithType(LicenseType type) { for (final _RepositoryDirectory directory in _subdirectories) { - if (directory._canGoUp()) { // avoid crawling into other license scopes - final License? result = directory._localLicenseWithType(type) ?? directory._fullWalkDownForLicenseWithType(type); + if (directory._canGoUp()) { + // avoid crawling into other license scopes + final License? result = + directory._localLicenseWithType(type) ?? + directory._fullWalkDownForLicenseWithType(type); if (result != null) { return result; } @@ -1108,13 +1142,13 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { if (_canGoUp()) { return parent!.nearestLicenseWithName(name, authors: authors); } - return _fullWalkDownForLicenseWithName(name, authors: authors) - ?? (authors != null ? parent?._fullWalkUpForLicenseWithName(name, authors: authors) : null); + return _fullWalkDownForLicenseWithName(name, authors: authors) ?? + (authors != null ? parent?._fullWalkUpForLicenseWithName(name, authors: authors) : null); }); return result; } - License? _localLicenseWithName(String name, { String? authors }) { + License? _localLicenseWithName(String name, {String? authors}) { final _RepositoryEntry? entry = _childrenByName[name]; License? license; if (entry is _RepositoryLicensedFile) { @@ -1132,7 +1166,7 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { return license; } - License? _fullWalkUpForLicenseWithName(String name, { required String authors }) { + License? _fullWalkUpForLicenseWithName(String name, {required String authors}) { // When looking for a license specific to certain authors, we want to walk // to the top of the local license root, then from there check all the // ancestors and all the descendants. @@ -1143,14 +1177,16 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { // Authors license is at the root, and is sometimes mentioned in various // files deep inside third party directories). return _localLicenseWithName(name, authors: authors) ?? - parent?._fullWalkUpForLicenseWithName(name, authors: authors); + parent?._fullWalkUpForLicenseWithName(name, authors: authors); } - License? _fullWalkDownForLicenseWithName(String name, { String? authors }) { + License? _fullWalkDownForLicenseWithName(String name, {String? authors}) { for (final _RepositoryDirectory directory in _subdirectories) { - if (directory._canGoUp()) { // avoid crawling into other license scopes - final License? result = directory._localLicenseWithName(name, authors: authors) - ?? directory._fullWalkDownForLicenseWithName(name, authors: authors); + if (directory._canGoUp()) { + // avoid crawling into other license scopes + final License? result = + directory._localLicenseWithName(name, authors: authors) ?? + directory._fullWalkDownForLicenseWithName(name, authors: authors); if (result != null) { return result; } @@ -1246,8 +1282,10 @@ class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource { /// this directory tree. Future get signature async { final List<_RepositoryLicensedFile> allFiles = _signatureFiles.toList(); - allFiles.sort((_RepositoryLicensedFile a, _RepositoryLicensedFile b) => - a.io.fullName.compareTo(b.io.fullName)); + allFiles.sort( + (_RepositoryLicensedFile a, _RepositoryLicensedFile b) => + a.io.fullName.compareTo(b.io.fullName), + ); final crypto.Digest digest = await crypto.md5.bind(_signatureStream(allFiles)).single; return digest.bytes.map((int e) => e.toRadixString(16).padLeft(2, '0')).join(); } @@ -1277,12 +1315,19 @@ class _RepositoryReachOutFile extends _RepositoryLicensedFile { directory = directory.parent; index -= 1; } - return directory!.nearestLicensesFor(name).map((License license) => license.assignLicenses(io.fullName, parent!)); + return directory! + .nearestLicensesFor(name) + .map((License license) => license.assignLicenses(io.fullName, parent!)); } } class _RepositoryReachOutDirectory extends _RepositoryDirectory { - _RepositoryReachOutDirectory(_RepositoryDirectory super.parent, super.io, this.reachOutFilenames, this.offset); + _RepositoryReachOutDirectory( + _RepositoryDirectory super.parent, + super.io, + this.reachOutFilenames, + this.offset, + ); final Set reachOutFilenames; final int offset; @@ -1356,13 +1401,25 @@ class _RepositoryInjaJsonFile extends _RepositorySourceFile { throw '${io.fullName} has changed contents.'; } final String license = match.group(3)!; - _internalLicenses = match.groups(const [ 2, 6, 8 ]).map((String? copyright) { - assert(copyright!.contains('Copyright')); - return License.fromCopyrightAndLicense(copyright!, license, LicenseType.mit, origin: io.fullName); - }).toList(); - assert(!match.groups(const [ 1, 4, 5, 7, 9, 10, 11]).any((String? text) => text!.contains(copyrightMentionPattern))); + _internalLicenses = + match.groups(const [2, 6, 8]).map((String? copyright) { + assert(copyright!.contains('Copyright')); + return License.fromCopyrightAndLicense( + copyright!, + license, + LicenseType.mit, + origin: io.fullName, + ); + }).toList(); + assert( + !match + .groups(const [1, 4, 5, 7, 9, 10, 11]) + .any((String? text) => text!.contains(copyrightMentionPattern)), + ); } - return _internalLicenses!.map((License license) => license.assignLicenses(io.fullName, parent!)); + return _internalLicenses!.map( + (License license) => license.assignLicenses(io.fullName, parent!), + ); } } @@ -1390,8 +1447,10 @@ class _EngineSrcDirectory extends _RepositoryDirectory { @override bool shouldRecurse(fs.IoNode entry) { - return entry.name != 'third_party' // all third_party components have been moved to flutter/third_party - && super.shouldRecurse(entry); + return entry.name != + 'third_party' // all third_party components have been moved to flutter/third_party + && + super.shouldRecurse(entry); } @override @@ -1520,7 +1579,10 @@ class _RepositoryFallbackRootCertificatesDirectory extends _RepositoryDirectory @override String get officialSourceLocation { - final system.ProcessResult result = system.Process.runSync('git', ['rev-parse', 'HEAD'], workingDirectory: '$this'); + final system.ProcessResult result = system.Process.runSync('git', [ + 'rev-parse', + 'HEAD', + ], workingDirectory: '$this'); if (result.exitCode != 0) { throw 'Failed to run "git rev-parse HEAD"; got non-zero exit code ${result.exitCode}\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}'; } @@ -1538,7 +1600,7 @@ class _RepositoryZLibDirectory extends _RepositoryDirectory { // exact same license text as in LICENSE. @override - License? nearestLicenseWithName(String name, { String? authors }) { + License? nearestLicenseWithName(String name, {String? authors}) { if (name == 'MiniZip_info.txt') { return super.nearestLicenseWithName('LICENSE', authors: authors)!; } @@ -1663,7 +1725,9 @@ class _RepositoryBoringSSLDirectory extends _RepositoryDirectory { @override License? nearestLicenseWithName(String name, {String? authors}) { assert(!src._canGoUp()); - final License? result = super.nearestLicenseWithName(name, authors: authors) ?? src.nearestLicenseWithName(name, authors: authors); + final License? result = + super.nearestLicenseWithName(name, authors: authors) ?? + src.nearestLicenseWithName(name, authors: authors); return result; } @@ -1713,9 +1777,13 @@ class _RepositoryFlutterThirdPartyDirectory extends _RepositoryGenericThirdParty @override bool shouldRecurse(fs.IoNode entry) { - return entry.name != 'skia' // handled as a virtual directory of the root - && entry.name != 'dart' // handled as a virtual directory of the root - && super.shouldRecurse(entry); + return entry.name != + 'skia' // handled as a virtual directory of the root + && + entry.name != + 'dart' // handled as a virtual directory of the root + && + super.shouldRecurse(entry); } @override @@ -1756,7 +1824,6 @@ class _RepositoryGpuShimDirectory extends _RepositoryDirectory { String get libraryName => 'engine'; } - /// The license tool directory. /// /// This is a special-case root node that is not used for license aggregation, @@ -1772,13 +1839,14 @@ class _RepositoryFlutterLicenseToolDirectory extends _RepositoryDirectory { } } - // BOOTSTRAPPING LOGIC fs.Directory? findChildDirectory(fs.Directory parent, String name) { - return parent.walk.firstWhereOrNull( // from IterableExtension in package:collection - (fs.IoNode child) => child.name == name, - ) as fs.Directory?; + return parent.walk.firstWhereOrNull( + // from IterableExtension in package:collection + (fs.IoNode child) => child.name == name, + ) + as fs.Directory?; } class _Progress { @@ -1821,7 +1889,9 @@ class _Progress { Stopwatch? _lastUpdate; void update({bool flush = false}) { - if (_lastUpdate == null || _lastUpdate!.elapsedMilliseconds >= millisecondsBetweenUpdates || flush) { + if (_lastUpdate == null || + _lastUpdate!.elapsedMilliseconds >= millisecondsBetweenUpdates || + flush) { _lastUpdate ??= Stopwatch(); if (!quiet) { final String line = toString(); @@ -1842,13 +1912,17 @@ class _Progress { String toString() { final int percent = (100.0 * (_withLicense + _withoutLicense) / max).round(); return '${(_withLicense + _withoutLicense).toString().padLeft(10)} of ${max.toString().padRight(6)} ' - '${'█' * (percent ~/ 10)}${'░' * (10 - (percent ~/ 10))} $percent% ' - '${ _withoutLicense > 0 ? "($_withoutLicense missing licenses) " : ""}' - '$label'; + '${'█' * (percent ~/ 10)}${'░' * (10 - (percent ~/ 10))} $percent% ' + '${_withoutLicense > 0 ? "($_withoutLicense missing licenses) " : ""}' + '$label'; } } -final RegExp _signaturePattern = RegExp(r'^Signature: (\w+)$', multiLine: true, expectNoMatch: true); +final RegExp _signaturePattern = RegExp( + r'^Signature: (\w+)$', + multiLine: true, + expectNoMatch: true, +); /// Reads the signature from a golden file. String? _readSignature(String goldenPath) { @@ -1879,11 +1953,17 @@ void _writeSignature(String signature, system.IOSink sink) { // Checks for changes to the license tool itself. // // Returns true if changes are detected. -Future _computeLicenseToolChanges(_RepositoryDirectory root, { required String goldenSignaturePath, required String outputSignaturePath }) async { +Future _computeLicenseToolChanges( + _RepositoryDirectory root, { + required String goldenSignaturePath, + required String outputSignaturePath, +}) async { final fs.Directory flutterNode = findChildDirectory(root.ioDirectory, 'flutter')!; final fs.Directory toolsNode = findChildDirectory(flutterNode, 'tools')!; final fs.Directory licenseNode = findChildDirectory(toolsNode, 'licenses')!; - final _RepositoryDirectory licenseToolDirectory = _RepositoryFlutterLicenseToolDirectory(licenseNode); + final _RepositoryDirectory licenseToolDirectory = _RepositoryFlutterLicenseToolDirectory( + licenseNode, + ); final String toolSignature = await licenseToolDirectory.signature; final system.IOSink sink = system.File(outputSignaturePath).openWrite(); _writeSignature(toolSignature, sink); @@ -1896,7 +1976,8 @@ Future _computeLicenseToolChanges(_RepositoryDirectory root, { required St /// /// If [writeSignature] is set, the signature is written to the output file. /// If [force] is set, collection is run regardless of whether or not the signature matches. -Future _collectLicensesForComponent(_RepositoryDirectory componentRoot, { +Future _collectLicensesForComponent( + _RepositoryDirectory componentRoot, { required String inputGoldenPath, String? outputGoldenPath, required bool writeSignature, @@ -1929,7 +2010,8 @@ Future _collectLicensesForComponent(_RepositoryDirectory componentRoot, { } progress.label = 'Dumping results...'; progress.flush(); - final List output = licenses.map((GroupedLicense license) => license.toStringDebug()).toList(); + final List output = + licenses.map((GroupedLicense license) => license.toStringDebug()).toList(); for (int index = 0; index < output.length; index += 1) { // The strings we look for here are strings which we do not expect to see in // any of the licenses we use. They either represent examples of misparsing @@ -1943,7 +2025,9 @@ Future _collectLicensesForComponent(_RepositoryDirectory componentRoot, { if (output[index].contains('Version: MPL 1.1/GPL 2.0/LGPL 2.1')) { throw 'Unexpected trilicense block found in:\n${output[index]}'; } - if (output[index].contains('The contents of this file are subject to the Mozilla Public License Version')) { + if (output[index].contains( + 'The contents of this file are subject to the Mozilla Public License Version', + )) { throw 'Unexpected MPL block found in:\n${output[index]}'; } if (output[index].contains('You should have received a copy of the GNU')) { @@ -1952,16 +2036,22 @@ Future _collectLicensesForComponent(_RepositoryDirectory componentRoot, { if (output[index].contains('Contents of this folder are ported from')) { throw 'Unexpected block found in:\n${output[index]}'; } - if (output[index].contains('https://github.com/w3c/web-platform-tests/tree/master/selectors-api')) { + if (output[index].contains( + 'https://github.com/w3c/web-platform-tests/tree/master/selectors-api', + )) { throw 'Unexpected W3C content found in:\n${output[index]}'; } - if (output[index].contains('http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html')) { + if (output[index].contains( + 'http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html', + )) { throw 'Unexpected W3C copyright found in:\n${output[index]}'; } if (output[index].contains('It is based on commit')) { throw 'Unexpected content found in:\n${output[index]}'; } - if (output[index].contains('The original code is covered by the dual-licensing approach described in:')) { + if (output[index].contains( + 'The original code is covered by the dual-licensing approach described in:', + )) { throw 'Unexpected old license reference found in:\n${output[index]}'; } if (output[index].contains('must choose')) { @@ -1980,13 +2070,17 @@ Future _collectLicensesForComponent(_RepositoryDirectory componentRoot, { // MAIN Future main(List arguments) async { - final ArgParser parser = ArgParser() - ..addOption('src', help: 'The root of the engine source.') - ..addOption('out', help: 'The directory where output is written. (Ignored if used with --release.)') - ..addOption('golden', help: 'The directory containing golden results.') - ..addFlag('quiet', help: 'If set, the diagnostic output is much less verbose.') - ..addFlag('verbose', help: 'If set, print additional information to help with development.') - ..addFlag('release', help: 'Print output in the format used for product releases.'); + final ArgParser parser = + ArgParser() + ..addOption('src', help: 'The root of the engine source.') + ..addOption( + 'out', + help: 'The directory where output is written. (Ignored if used with --release.)', + ) + ..addOption('golden', help: 'The directory containing golden results.') + ..addFlag('quiet', help: 'If set, the diagnostic output is much less verbose.') + ..addFlag('verbose', help: 'If set, print additional information to help with development.') + ..addFlag('release', help: 'Print output in the format used for product releases.'); final ArgResults argResults = parser.parse(arguments); final bool quiet = argResults['quiet'] as bool; @@ -1999,7 +2093,9 @@ Future main(List arguments) async { } if (!releaseMode) { if (argResults['out'] == null || argResults['golden'] == null) { - print('Flutter license script: Must provide --out and --golden directories in non-release mode'); + print( + 'Flutter license script: Must provide --out and --golden directories in non-release mode', + ); print(parser.usage); system.exit(1); } @@ -2016,7 +2112,9 @@ Future main(List arguments) async { try { system.stderr.writeln('Finding files...'); - final fs.FileSystemDirectory rootDirectory = fs.FileSystemDirectory.fromPath(argResults['src'] as String); + final fs.FileSystemDirectory rootDirectory = fs.FileSystemDirectory.fromPath( + argResults['src'] as String, + ); final _RepositoryDirectory root = _EngineSrcDirectory(rootDirectory); if (releaseMode) { @@ -2029,9 +2127,9 @@ Future main(List arguments) async { progress.label = 'Dumping results...'; progress.flush(); final String output = licenses - .where((GroupedLicense license) => license.body.isNotEmpty) - .map((GroupedLicense license) => license.toStringFormal()) - .join('\n${"-" * 80}\n'); + .where((GroupedLicense license) => license.body.isNotEmpty) + .map((GroupedLicense license) => license.toStringFormal()) + .join('\n${"-" * 80}\n'); print(output); progress.label = 'Done.'; progress.flush(); @@ -2047,7 +2145,9 @@ Future main(List arguments) async { outputSignaturePath: path.join(argResults['out'] as String, toolSignatureFilename), ); if (forceRunAll) { - system.stderr.writeln('Detected changes to license tool. Forcing license collection for all components.'); + system.stderr.writeln( + 'Detected changes to license tool. Forcing license collection for all components.', + ); } final List usedGoldens = []; bool isFirstComponent = true; @@ -2061,9 +2161,9 @@ Future main(List arguments) async { } else { // For other components, we need a clean repository that does not // contain any state left over from previous components. - componentRoot = _EngineSrcDirectory(rootDirectory) - .subdirectories - .firstWhere((_RepositoryDirectory dir) => dir.name == component.name); + componentRoot = _EngineSrcDirectory( + rootDirectory, + ).subdirectories.firstWhere((_RepositoryDirectory dir) => dir.name == component.name); } final String goldenFileName = 'licenses_${component.io.name}'; await _collectLicensesForComponent( @@ -2080,23 +2180,30 @@ Future main(List arguments) async { ); usedGoldens.add(goldenFileName); } - final Set unusedGoldens = system.Directory(argResults['golden'] as String).listSync() - .map((system.FileSystemEntity file) => path.basename(file.path)) - .where((String name) => name.startsWith('licenses_')) - .toSet() - ..removeAll(usedGoldens); + final Set unusedGoldens = + system.Directory(argResults['golden'] as String) + .listSync() + .map((system.FileSystemEntity file) => path.basename(file.path)) + .where((String name) => name.startsWith('licenses_')) + .toSet() + ..removeAll(usedGoldens); if (unusedGoldens.isNotEmpty) { - system.stderr.writeln('The following golden files in ${argResults['golden']} are unused and need to be deleted:'); + system.stderr.writeln( + 'The following golden files in ${argResults['golden']} are unused and need to be deleted:', + ); unusedGoldens.map((String s) => ' * $s').forEach(system.stderr.writeln); system.exit(1); } // write to disk the list of files we did _not_ cover, so it's easier to catch in diffs - final String excluded = (_RepositoryDirectory._excluded.map( - (fs.IoNode node) => node.fullName, - ).toSet().toList()..sort()).join('\n'); - system.File(path.join(argResults['out'] as String, 'excluded_files')).writeAsStringSync( - '$excluded\n', - ); + final String excluded = (_RepositoryDirectory._excluded + .map((fs.IoNode node) => node.fullName) + .toSet() + .toList() + ..sort()) + .join('\n'); + system.File( + path.join(argResults['out'] as String, 'excluded_files'), + ).writeAsStringSync('$excluded\n'); } } catch (e, stack) { system.stderr.writeln(); diff --git a/engine/src/flutter/tools/licenses/lib/paths.dart b/engine/src/flutter/tools/licenses/lib/paths.dart index 1062b57a1b..05fc37fda0 100644 --- a/engine/src/flutter/tools/licenses/lib/paths.dart +++ b/engine/src/flutter/tools/licenses/lib/paths.dart @@ -467,10 +467,16 @@ final List skippedFilePatterns = [ 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'\.~[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/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'^flutter/third_party/abseil-cpp/(?:.+/)*[^/]+_test\.[^/]+$'), RegExp(r'^flutter/third_party/angle/(?:.+/)*[^/]+_unittest\.[^/]+$'), @@ -478,6 +484,8 @@ final List skippedFilePatterns = [ RegExp(r'^flutter/third_party/boringssl/src/crypto/fipsmodule/bn/[^/]+.go$'), RegExp(r'^flutter/third_party/boringssl/src/crypto/fipsmodule/ec/[^/]+.go$'), RegExp(r'^flutter/third_party/dart/(?:.+/)*[^/]+_test\.[^/]+$'), - RegExp(r'^flutter/third_party/freetype2/docs/(?!FTL\.TXT$).+'), // ignore all documentation except the license + RegExp( + r'^flutter/third_party/freetype2/docs/(?!FTL\.TXT$).+', + ), // ignore all documentation except the license RegExp(r'^flutter/third_party/zlib/(?:.+/)*[^/]+_unittest\.[^/]+$'), ]; diff --git a/engine/src/flutter/tools/licenses/lib/patterns.dart b/engine/src/flutter/tools/licenses/lib/patterns.dart index d4a8b6ec01..1c6ab66517 100644 --- a/engine/src/flutter/tools/licenses/lib/patterns.dart +++ b/engine/src/flutter/tools/licenses/lib/patterns.dart @@ -17,7 +17,7 @@ const String kIndent = r'^((?:[-;@# copyrightStatementLeadingPatterns = [ - RegExp(r'^ *(?:Portions(?: created by the Initial Developer)?(?: are)? )?Copyright.+$', caseSensitive: false), + RegExp( + r'^ *(?:Portions(?: created by the Initial Developer)?(?: are)? )?Copyright.+$', + caseSensitive: false, + ), RegExp(r'^.*(?:All )?rights? reserved\.$', caseSensitive: false), RegExp(r'^.*© [0-9]{4} .+$'), ]; // patterns used by _splitLicense to extend the copyright block -final RegExp halfCopyrightPattern = RegExp(r'^(?: *(?:Copyright(?: \(c\))? [-0-9, ]+(?: by)?|Written [0-9]+)[ */]*)$', caseSensitive: false); +final RegExp halfCopyrightPattern = RegExp( + r'^(?: *(?:Copyright(?: \(c\))? [-0-9, ]+(?: by)?|Written [0-9]+)[ */]*)$', + caseSensitive: false, +); final RegExp trailingComma = RegExp(r',[ */]*$'); // copyright blocks end with the last line that matches this, rest is considered license @@ -128,7 +146,9 @@ final List copyrightStatementPatterns = [ RegExp(r'^FT_Raccess_Get_HeaderInfo\(\) and raccess_guess_darwin_hfsplus\(\) are$'), RegExp(r'^derived from ftobjs\.c\.$'), // RegExp(r'^ *Condition of use and distribution are the same than zlib :$'), - RegExp(r'^Unicode and the Unicode Logo are registered trademarks of Unicode, Inc\. in the U.S. and other countries\.$'), + RegExp( + r'^Unicode and the Unicode Logo are registered trademarks of Unicode, Inc\. in the U.S. and other countries\.$', + ), RegExp(r'^$'), ]; @@ -143,21 +163,35 @@ final List licenseFragments = [ RegExp(r'^ *For more info read ([^ ]+)$'), ]; -const String _linebreak = r' *(?:(?:\*/ *|[*#])?(?:\n\1 *(?:\*/ *)?)*\n\1\2 *)?'; +const String _linebreak = r' *(?:(?:\*/ *|[*#])?(?:\n\1 *(?:\*/ *)?)*\n\1\2 *)?'; const String _linebreakLoose = r' *(?:(?:\*/ *|[*#])?\r?\n(?:-|;|#|<|!|/|\*| |REM)*)*'; // LICENSE RECOGNIZERS -final RegExp lrLLVM = RegExp(r'--- LLVM Exceptions to the Apache 2\.0 License ----$', multiLine: true); +final RegExp lrLLVM = RegExp( + r'--- LLVM Exceptions to the Apache 2\.0 License ----$', + multiLine: true, +); final RegExp lrApache = RegExp(r'^(?: |\n)*Apache License\b'); final RegExp lrMPL = RegExp(r'^(?: |\n)*Mozilla Public License Version 2\.0\n'); final RegExp lrGPL = RegExp(r'^(?: |\n)*GNU GENERAL PUBLIC LICENSE\n'); -final RegExp lrAPSL = RegExp(r'^APPLE PUBLIC SOURCE LICENSE Version 2\.0 +- +August 6, 2003', expectNoMatch: true); -final RegExp lrMIT = RegExp(r'Permission(?: |\n)+is(?: |\n)+hereby(?: |\n)+granted,(?: |\n)+free(?: |\n)+of(?: |\n)+charge,(?: |\n)+to(?: |\n)+any(?: |\n)+person(?: |\n)+obtaining(?: |\n)+a(?: |\n)+copy(?: |\n)+of(?: |\n)+this(?: |\n)+software(?: |\n)+and(?: |\n)+associated(?: |\n)+documentation(?: |\n)+files(?: |\n)+\(the(?: |\n)+"Software"\),(?: |\n)+to(?: |\n)+deal(?: |\n)+in(?: |\n)+the(?: |\n)+Software(?: |\n)+without(?: |\n)+restriction,(?: |\n)+including(?: |\n)+without(?: |\n)+limitation(?: |\n)+the(?: |\n)+rights(?: |\n)+to(?: |\n)+use,(?: |\n)+copy,(?: |\n)+modify,(?: |\n)+merge,(?: |\n)+publish,(?: |\n)+distribute,(?: |\n)+sublicense,(?: |\n)+and/or(?: |\n)+sell(?: |\n)+copies(?: |\n)+of(?: |\n)+the(?: |\n)+Software,(?: |\n)+and(?: |\n)+to(?: |\n)+permit(?: |\n)+persons(?: |\n)+to(?: |\n)+whom(?: |\n)+the(?: |\n)+Software(?: |\n)+is(?: |\n)+furnished(?: |\n)+to(?: |\n)+do(?: |\n)+so,(?: |\n)+subject(?: |\n)+to(?: |\n)+the(?: |\n)+following(?: |\n)+conditions:'); +final RegExp lrAPSL = RegExp( + r'^APPLE PUBLIC SOURCE LICENSE Version 2\.0 +- +August 6, 2003', + expectNoMatch: true, +); +final RegExp lrMIT = RegExp( + r'Permission(?: |\n)+is(?: |\n)+hereby(?: |\n)+granted,(?: |\n)+free(?: |\n)+of(?: |\n)+charge,(?: |\n)+to(?: |\n)+any(?: |\n)+person(?: |\n)+obtaining(?: |\n)+a(?: |\n)+copy(?: |\n)+of(?: |\n)+this(?: |\n)+software(?: |\n)+and(?: |\n)+associated(?: |\n)+documentation(?: |\n)+files(?: |\n)+\(the(?: |\n)+"Software"\),(?: |\n)+to(?: |\n)+deal(?: |\n)+in(?: |\n)+the(?: |\n)+Software(?: |\n)+without(?: |\n)+restriction,(?: |\n)+including(?: |\n)+without(?: |\n)+limitation(?: |\n)+the(?: |\n)+rights(?: |\n)+to(?: |\n)+use,(?: |\n)+copy,(?: |\n)+modify,(?: |\n)+merge,(?: |\n)+publish,(?: |\n)+distribute,(?: |\n)+sublicense,(?: |\n)+and/or(?: |\n)+sell(?: |\n)+copies(?: |\n)+of(?: |\n)+the(?: |\n)+Software,(?: |\n)+and(?: |\n)+to(?: |\n)+permit(?: |\n)+persons(?: |\n)+to(?: |\n)+whom(?: |\n)+the(?: |\n)+Software(?: |\n)+is(?: |\n)+furnished(?: |\n)+to(?: |\n)+do(?: |\n)+so,(?: |\n)+subject(?: |\n)+to(?: |\n)+the(?: |\n)+following(?: |\n)+conditions:', +); final RegExp lrOpenSSL = RegExp(r'OpenSSL.+dual license', expectNoMatch: true); -final RegExp lrBSD = RegExp(r'Redistribution(?: |\n)+and(?: |\n)+use(?: |\n)+in(?: |\n)+source(?: |\n)+and(?: |\n)+binary(?: |\n)+forms(?:(?: |\n)+of(?: |\n)+the(?: |\n)+software(?: |\n)+as(?: |\n)+well(?: |\n)+as(?: |\n)+documentation)?,(?: |\n)+with(?: |\n)+or(?: |\n)+without(?: |\n)+modification,(?: |\n)+are(?: |\n)+permitted(?: |\n)+provided(?: |\n)+that(?: |\n)+the(?: |\n)+following(?: |\n)+conditions(?: |\n)+are(?: |\n)+met:'); -final RegExp lrPNG = RegExp(r'This code is released under the libpng license\.|PNG Reference Library License'); -final RegExp lrBison = RegExp(r'This special exception was added by the Free Software Foundation in *\n *version 2.2 of Bison.'); +final RegExp lrBSD = RegExp( + r'Redistribution(?: |\n)+and(?: |\n)+use(?: |\n)+in(?: |\n)+source(?: |\n)+and(?: |\n)+binary(?: |\n)+forms(?:(?: |\n)+of(?: |\n)+the(?: |\n)+software(?: |\n)+as(?: |\n)+well(?: |\n)+as(?: |\n)+documentation)?,(?: |\n)+with(?: |\n)+or(?: |\n)+without(?: |\n)+modification,(?: |\n)+are(?: |\n)+permitted(?: |\n)+provided(?: |\n)+that(?: |\n)+the(?: |\n)+following(?: |\n)+conditions(?: |\n)+are(?: |\n)+met:', +); +final RegExp lrPNG = RegExp( + r'This code is released under the libpng license\.|PNG Reference Library License', +); +final RegExp lrBison = RegExp( + r'This special exception was added by the Free Software Foundation in *\n *version 2.2 of Bison.', +); // Matching this exactly is important since it's likely there will be similar // licenses with more requirements. @@ -177,28 +211,32 @@ final RegExp lrZlib = RegExp( r'2\. Altered source versions must be plainly marked as such, and must not(?: be)?\n' r' (?: be)?misrepresented as being the original software\.\n' r'3\. This notice may not be removed or altered from any source(?: |\n )distribution\.' - r'$' // no more terms! + r'$', // no more terms! ); - // ASCII ART PATTERNS // If these images are found in a file, they are stripped before we look for license patterns. -final List> asciiArtImages = [ - r''' +final List> asciiArtImages = + [ + r''' ___ _ |_ _|_ __ (_) __ _ | || '_ \ | |/ _` | | || | | || | (_| | |___|_| |_|/ |\__,_| |__/''', -].map((String image) => image.split('\n')).toList(); - + ].map((String image) => image.split('\n')).toList(); // FORWARD REFERENCE class ForwardReferencePattern { - ForwardReferencePattern({ required this.firstPrefixIndex, required this.indentPrefixIndex, required this.pattern, required this.targetPattern }); + ForwardReferencePattern({ + required this.firstPrefixIndex, + required this.indentPrefixIndex, + required this.pattern, + required this.targetPattern, + }); final int firstPrefixIndex; final int indentPrefixIndex; final RegExp pattern; @@ -213,44 +251,36 @@ final List csForwardReferenceLicenses = csReferencesByFilename = [ - // used with _tryReferenceByFilename // libpng files @@ -288,9 +317,10 @@ final List csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByFilename = csReferencesByType = [ - // used with _tryReferenceByType // groups 1 and 2 are the prefix, group 3 is the license type - RegExp( kIndent + - r'Written by Andy Polyakov for the OpenSSL ' - r'project\. The module is, however, dual licensed under (OpenSSL) and ' - r'CRYPTOGAMS licenses depending on where you obtain it\. For further ' - r'details see http://www\.openssl\.org/~appro/cryptogams/\. ' - r'Permission to use under GPL terms is granted\.'.replaceAll(' ', _linebreak), + r'Written by Andy Polyakov for the OpenSSL ' + r'project\. The module is, however, dual licensed under (OpenSSL) and ' + r'CRYPTOGAMS licenses depending on where you obtain it\. For further ' + r'details see http://www\.openssl\.org/~appro/cryptogams/\. ' + r'Permission to use under GPL terms is granted\.' + .replaceAll(' ', _linebreak), multiLine: true, ), @@ -547,63 +583,57 @@ final List csReferencesByType = [ // BoringSSL RegExp( kIndent + - r'Rights for redistribution and usage in source and binary forms are ' - r'granted according to the (OpenSSL) license\. Warranty of any kind is ' - r'disclaimed\.' - .replaceAll(' ', _linebreak), + r'Rights for redistribution and usage in source and binary forms are ' + r'granted according to the (OpenSSL) license\. Warranty of any kind is ' + r'disclaimed\.' + .replaceAll(' ', _linebreak), multiLine: true, ), RegExp( kIndent + - ( - r'The portions of the attached software \("Contribution"\) is developed by ' - r'Nokia Corporation and is licensed pursuant to the (OpenSSL) open source ' - r'license\. ' - r'\n ' - r'The Contribution, originally written by Mika Kousa and Pasi Eronen of ' - r'Nokia Corporation, consists of the "PSK" \(Pre-Shared Key\) ciphersuites ' - r'support \(see RFC 4279\) to OpenSSL\. ' - r'\n ' - r'No patent licenses or other rights except those expressly stated in ' - r'the OpenSSL open source license shall be deemed granted or received ' - r'expressly, by implication, estoppel, or otherwise\. ' - r'\n ' - r'No assurances are provided by Nokia that the Contribution does not ' - r'infringe the patent or other intellectual property rights of any third ' - r'party or that the license provides you with all the necessary rights ' - r'to make use of the Contribution\. ' - r'\n ' - r'THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND\. IN ' - r'ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA ' - r'SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY ' - r'OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR ' - r'OTHERWISE\.' - .replaceAll(' ', _linebreak) - ), + (r'The portions of the attached software \("Contribution"\) is developed by ' + r'Nokia Corporation and is licensed pursuant to the (OpenSSL) open source ' + r'license\. ' + r'\n ' + r'The Contribution, originally written by Mika Kousa and Pasi Eronen of ' + r'Nokia Corporation, consists of the "PSK" \(Pre-Shared Key\) ciphersuites ' + r'support \(see RFC 4279\) to OpenSSL\. ' + r'\n ' + r'No patent licenses or other rights except those expressly stated in ' + r'the OpenSSL open source license shall be deemed granted or received ' + r'expressly, by implication, estoppel, or otherwise\. ' + r'\n ' + r'No assurances are provided by Nokia that the Contribution does not ' + r'infringe the patent or other intellectual property rights of any third ' + r'party or that the license provides you with all the necessary rights ' + r'to make use of the Contribution\. ' + r'\n ' + r'THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND\. IN ' + r'ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA ' + r'SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY ' + r'OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR ' + r'OTHERWISE\.' + .replaceAll(' ', _linebreak)), multiLine: true, ), // TODO(ianh): Confirm this is the right way to handle this. RegExp( kIndent + - r'.+ support in OpenSSL originally developed by ' - r'SUN MICROSYSTEMS, INC\., and contributed to the (OpenSSL) project\.' - .replaceAll(' ', _linebreak), + r'.+ support in OpenSSL originally developed by ' + r'SUN MICROSYSTEMS, INC\., and contributed to the (OpenSSL) project\.' + .replaceAll(' ', _linebreak), multiLine: true, ), // Brotli (MIT) - RegExp( - kIndent + - r'Distributed under (MIT) license\.', - multiLine: true - ), + RegExp(kIndent + r'Distributed under (MIT) license\.', multiLine: true), RegExp( kIndent + - r'This software is made available under the terms of the (ICU) License -- ICU 1\.8\.1 and later\.' - .replaceAll(' ', _linebreak), + r'This software is made available under the terms of the (ICU) License -- ICU 1\.8\.1 and later\.' + .replaceAll(' ', _linebreak), multiLine: true, ), ]; @@ -614,7 +644,8 @@ class LicenseReferencePattern { this.indentPrefixIndex = 2, this.licenseIndex = 3, this.checkLocalFirst = true, - this.spdx = false, // indicates whether this is a reference via the SPDX syntax rather than a statement in English + this.spdx = + false, // indicates whether this is a reference via the SPDX syntax rather than a statement in English required this.pattern, }); @@ -627,38 +658,25 @@ class LicenseReferencePattern { } final List csReferencesByIdentifyingReference = [ - // used with _tryReferenceByIdentifyingReference - LicenseReferencePattern( - pattern: RegExp( - kIndent + r'For terms of use, see ([^ \n]+)', - multiLine: true, - ) + pattern: RegExp(kIndent + r'For terms of use, see ([^ \n]+)', multiLine: true), ), LicenseReferencePattern( - pattern: RegExp( - kIndent + r'License & terms of use: ([^ \n]+)', - multiLine: true, - ) + pattern: RegExp(kIndent + r'License & terms of use: ([^ \n]+)', multiLine: true), ), LicenseReferencePattern( - pattern: RegExp( - kIndent + r'For more info read (MiniZip_info.txt)', - multiLine: true, - ) + pattern: RegExp(kIndent + r'For more info read (MiniZip_info.txt)', multiLine: true), ), // SPDX LicenseReferencePattern( checkLocalFirst: false, - spdx: true, // indicates that this is a reference via the SPDX syntax rather than a statement in English - pattern: RegExp( - kIndent + r'SPDX-License-Identifier: (.+)', - multiLine: true, - ) + spdx: + true, // indicates that this is a reference via the SPDX syntax rather than a statement in English + pattern: RegExp(kIndent + r'SPDX-License-Identifier: (.+)', multiLine: true), ), // Apache reference. @@ -669,21 +687,21 @@ final List csReferencesByIdentifyingReference = csReferencesByIdentifyingReference = ) You may obtain a copy of the License at *\n' - r'^\1\n' - r'^\1\2(http://opensource(?:\.|->)org/licenses/MIT) *\n' - r'^\1\n' - r'^\1\2Unless required by applicable law or agreed to in writing, software distributed *\n' - r'^\1\2under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR *\n' - r'^\1\2CONDITIONS OF ANY KIND, either express or implied(?:\.|->) See the License for the *\n' - r'^\1\2specific language governing permissions and limitations under the License(?:\.|->)', + r'Licensed under the MIT License \(the "License"\); you may not use this file except *\n' + r'^\1\2in compliance with the License(?:\.|->) You may obtain a copy of the License at *\n' + r'^\1\n' + r'^\1\2(http://opensource(?:\.|->)org/licenses/MIT) *\n' + r'^\1\n' + r'^\1\2Unless required by applicable law or agreed to in writing, software distributed *\n' + r'^\1\2under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR *\n' + r'^\1\2CONDITIONS OF ANY KIND, either express or implied(?:\.|->) See the License for the *\n' + r'^\1\2specific language governing permissions and limitations under the License(?:\.|->)', multiLine: true, caseSensitive: false, - ) + ), ), // Observatory (polymer) LicenseReferencePattern( checkLocalFirst: false, pattern: RegExp( - kIndent + r'This code may only be used under the BSD style license found at (http://polymer.github.io/LICENSE.txt)$', + kIndent + + r'This code may only be used under the BSD style license found at (http://polymer.github.io/LICENSE.txt)$', multiLine: true, caseSensitive: false, - ) + ), ), // LLVM (Apache License v2.0 with LLVM Exceptions) @@ -737,13 +756,11 @@ final List csReferencesByIdentifyingReference = csReferencesByIdentifyingReference = csTemplateLicenses = [ - // used with _tryInline, with needsCopyright: true (will only match if preceded by a copyright notice) // should have two groups, prefixes 1 and 2 // BoringSSL RegExp( kIndent + - r'Redistribution and use in source and binary forms, with or without *\n' - r'^\1\2modification, are permitted provided that the following conditions *\n' - r'^\1\2are met: *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of source code must retain the above copyright *\n' - r'^\1\2 *notice, this list of conditions and the following disclaimer\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)Redistributions in binary form must reproduce the above copyright *\n' - r'^\1\2 *notice, this list of conditions and the following disclaimer in *\n' - r'^\1\2 *the documentation and/or other materials provided with the *\n' - r'^\1\2 *distribution\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)All advertising materials mentioning features or use of this *\n' - r'^\1\2 *software must display the following acknowledgment: *\n' - r'^\1\2 *"This product includes software developed by the OpenSSL Project *\n' - r'^\1\2 *for use in the OpenSSL Toolkit\. \(http://www\.OpenSSL\.org/\)" *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *\n' - r'^\1\2 *endorse or promote products derived from this software without *\n' - r'^\1\2 *prior written permission\. +For written permission, please contact *\n' - r'^\1\2 *[^@ ]+@OpenSSL\.org\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)Products derived from this software may not be called "OpenSSL" *\n' - r'^\1\2 *nor may "OpenSSL" appear in their names without prior written *\n' - r'^\1\2 *permission of the OpenSSL Project\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of any form whatsoever must retain the following *\n' - r'^\1\2 *acknowledgment: *\n' - r'^\1\2 *"This product includes software developed by the OpenSSL Project *\n' - r'^\1\2 *for use in the OpenSSL Toolkit \(http://www\.OpenSSL\.org/\)" *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r"^\1\2THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY *\n" - r'^\1\2EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *\n' - r'^\1\2IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *\n' - r'^\1\2PURPOSE ARE DISCLAIMED\. +IN NO EVENT SHALL THE OpenSSL PROJECT OR *\n' - r'^\1\2ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *\n' - r'^\1\2SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \(INCLUDING, BUT *\n' - r'^\1\2NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *\n' - r'^\1\2LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) *\n' - r'^\1\2HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *\n' - r'^\1\2STRICT LIABILITY, OR TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) *\n' - r'^\1\2ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED *\n' - r'^\1\2OF THE POSSIBILITY OF SUCH DAMAGE\.', + r'Redistribution and use in source and binary forms, with or without *\n' + r'^\1\2modification, are permitted provided that the following conditions *\n' + r'^\1\2are met: *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of source code must retain the above copyright *\n' + r'^\1\2 *notice, this list of conditions and the following disclaimer\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)Redistributions in binary form must reproduce the above copyright *\n' + r'^\1\2 *notice, this list of conditions and the following disclaimer in *\n' + r'^\1\2 *the documentation and/or other materials provided with the *\n' + r'^\1\2 *distribution\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)All advertising materials mentioning features or use of this *\n' + r'^\1\2 *software must display the following acknowledgment: *\n' + r'^\1\2 *"This product includes software developed by the OpenSSL Project *\n' + r'^\1\2 *for use in the OpenSSL Toolkit\. \(http://www\.OpenSSL\.org/\)" *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *\n' + r'^\1\2 *endorse or promote products derived from this software without *\n' + r'^\1\2 *prior written permission\. +For written permission, please contact *\n' + r'^\1\2 *[^@ ]+@OpenSSL\.org\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)Products derived from this software may not be called "OpenSSL" *\n' + r'^\1\2 *nor may "OpenSSL" appear in their names without prior written *\n' + r'^\1\2 *permission of the OpenSSL Project\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of any form whatsoever must retain the following *\n' + r'^\1\2 *acknowledgment: *\n' + r'^\1\2 *"This product includes software developed by the OpenSSL Project *\n' + r'^\1\2 *for use in the OpenSSL Toolkit \(http://www\.OpenSSL\.org/\)" *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r"^\1\2THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY *\n" + r'^\1\2EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *\n' + r'^\1\2IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *\n' + r'^\1\2PURPOSE ARE DISCLAIMED\. +IN NO EVENT SHALL THE OpenSSL PROJECT OR *\n' + r'^\1\2ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *\n' + r'^\1\2SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \(INCLUDING, BUT *\n' + r'^\1\2NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *\n' + r'^\1\2LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) *\n' + r'^\1\2HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *\n' + r'^\1\2STRICT LIABILITY, OR TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) *\n' + r'^\1\2ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED *\n' + r'^\1\2OF THE POSSIBILITY OF SUCH DAMAGE\.', multiLine: true, caseSensitive: false, ), RegExp( kIndent + - r'(?:This package is an SSL implementation written *\n' - r'^\1\2by Eric Young \(eay@cryptsoft\.com\)\. *\n' - r'^\1\2The implementation was written so as to conform with Netscapes SSL\. *\n' - r'^(?:(?:\1\2?g? *)? *\n)*' - r'^\1\2This library is free for commercial and non-commercial use as long as *\n' - r'^\1\2the following conditions are aheared to\. +The following conditions *\n' - r'^\1\2apply to all code found in this distribution, be it the RC4, RSA, *\n' - r'^\1\2lhash, DES, etc\., code; not just the SSL code\. +The SSL documentation *\n' - r'^\1\2included with this distribution is covered by the same copyright terms *\n' - r'^\1\2except that the holder is Tim Hudson \(tjh@cryptsoft\.com\)\. *\n' - r'^(?:(?:\1\2?g? *)? *\n)*' - r"^\1\2Copyright remains Eric Young's, and as such any Copyright notices in *\n" - r'^\1\2the code are not to be removed\. *\n' - r'^\1\2If this package is used in a product, Eric Young should be given attribution *\n' - r'^\1\2as the author of the parts of the library used\. *\n' - r'^\1\2This can be in the form of a textual message at program startup or *\n' - r'^\1\2in documentation \(online or textual\) provided with the package\. *\n' - r'^(?:(?:\1\2?g? *)? *\n)*' - r'^\1\2)?Redistribution and use in source and binary forms, with or without *\n' - r'^\1\2modification, are permitted provided that the following conditions *\n' - r'^\1\2are met: *\n' - r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of source code must retain the copyright *\n' - r'^\1\2 *notice, this list of conditions and the following disclaimer\. *\n' - r'^\1\2(?:[-*1-9.)/ ]+)Redistributions in binary form must reproduce the above copyright *\n' - r'^\1\2 *notice, this list of conditions and the following disclaimer in the *\n' - r'^\1\2 *documentation and/or other materials provided with the distribution\. *\n' - r'^\1\2(?:[-*1-9.)/ ]+)All advertising materials mentioning features or use of this software *\n' - r'^\1\2 *must display the following acknowledgement: *\n' - r'^\1\2 *"This product includes cryptographic software written by *\n' - r'^\1\2 *Eric Young \(eay@cryptsoft\.com\)" *\n' - r"^\1\2 *The word 'cryptographic' can be left out if the rouines from the library *\n" // TODO(ianh): File a bug on the number of analyzer errors you get if you replace the " characters on this line with ' - r'^\1\2 *being used are not cryptographic related :-\)\. *\n' - r'^\1\2(?:[-*1-9.)/ ]+)If you include any Windows specific code \(or a derivative thereof\) fromg? *\n' - r'^\1\2 *the apps directory \(application code\) you must include an acknowledgement: *\n' - r'^\1\2 *"This product includes software written by Tim Hudson \(tjh@cryptsoft\.com\)" *\n' - r'^(?:(?:\1\2?g? *)? *\n)*' - r"^\1\2THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND *\n" - r'^\1\2ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *\n' - r'^\1\2IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *\n' - r'^\1\2ARE DISCLAIMED\. +IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE *\n' - r'^\1\2FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *\n' - r'^\1\2DAMAGES \(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *\n' - r'^\1\2OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) *\n' - r'^\1\2HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *\n' - r'^\1\2LIABILITY, OR TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY *\n' - r'^\1\2OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *\n' - r'^\1\2SUCH DAMAGE\. *\n' - r'^(?:(?:\1\2?g? *)? *\n)*' - r'^\1\2The licence and distribution terms for any publically available version or *\n' - r'^\1\2derivative of this code cannot be changed\. +i\.e\. +this code cannot simply be *\n' - r'^\1\2copied and put under another distribution licence *\n' - r'^\1\2\[including the GNU Public Licence\.\]', + r'(?:This package is an SSL implementation written *\n' + r'^\1\2by Eric Young \(eay@cryptsoft\.com\)\. *\n' + r'^\1\2The implementation was written so as to conform with Netscapes SSL\. *\n' + r'^(?:(?:\1\2?g? *)? *\n)*' + r'^\1\2This library is free for commercial and non-commercial use as long as *\n' + r'^\1\2the following conditions are aheared to\. +The following conditions *\n' + r'^\1\2apply to all code found in this distribution, be it the RC4, RSA, *\n' + r'^\1\2lhash, DES, etc\., code; not just the SSL code\. +The SSL documentation *\n' + r'^\1\2included with this distribution is covered by the same copyright terms *\n' + r'^\1\2except that the holder is Tim Hudson \(tjh@cryptsoft\.com\)\. *\n' + r'^(?:(?:\1\2?g? *)? *\n)*' + r"^\1\2Copyright remains Eric Young's, and as such any Copyright notices in *\n" + r'^\1\2the code are not to be removed\. *\n' + r'^\1\2If this package is used in a product, Eric Young should be given attribution *\n' + r'^\1\2as the author of the parts of the library used\. *\n' + r'^\1\2This can be in the form of a textual message at program startup or *\n' + r'^\1\2in documentation \(online or textual\) provided with the package\. *\n' + r'^(?:(?:\1\2?g? *)? *\n)*' + r'^\1\2)?Redistribution and use in source and binary forms, with or without *\n' + r'^\1\2modification, are permitted provided that the following conditions *\n' + r'^\1\2are met: *\n' + r'^\1\2(?:[-*1-9.)/ ]+)Redistributions of source code must retain the copyright *\n' + r'^\1\2 *notice, this list of conditions and the following disclaimer\. *\n' + r'^\1\2(?:[-*1-9.)/ ]+)Redistributions in binary form must reproduce the above copyright *\n' + r'^\1\2 *notice, this list of conditions and the following disclaimer in the *\n' + r'^\1\2 *documentation and/or other materials provided with the distribution\. *\n' + r'^\1\2(?:[-*1-9.)/ ]+)All advertising materials mentioning features or use of this software *\n' + r'^\1\2 *must display the following acknowledgement: *\n' + r'^\1\2 *"This product includes cryptographic software written by *\n' + r'^\1\2 *Eric Young \(eay@cryptsoft\.com\)" *\n' + r"^\1\2 *The word 'cryptographic' can be left out if the rouines from the library *\n" // TODO(ianh): File a bug on the number of analyzer errors you get if you replace the " characters on this line with ' + r'^\1\2 *being used are not cryptographic related :-\)\. *\n' + r'^\1\2(?:[-*1-9.)/ ]+)If you include any Windows specific code \(or a derivative thereof\) fromg? *\n' + r'^\1\2 *the apps directory \(application code\) you must include an acknowledgement: *\n' + r'^\1\2 *"This product includes software written by Tim Hudson \(tjh@cryptsoft\.com\)" *\n' + r'^(?:(?:\1\2?g? *)? *\n)*' + r"^\1\2THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND *\n" + r'^\1\2ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *\n' + r'^\1\2IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *\n' + r'^\1\2ARE DISCLAIMED\. +IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE *\n' + r'^\1\2FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *\n' + r'^\1\2DAMAGES \(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *\n' + r'^\1\2OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) *\n' + r'^\1\2HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *\n' + r'^\1\2LIABILITY, OR TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY *\n' + r'^\1\2OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *\n' + r'^\1\2SUCH DAMAGE\. *\n' + r'^(?:(?:\1\2?g? *)? *\n)*' + r'^\1\2The licence and distribution terms for any publically available version or *\n' + r'^\1\2derivative of this code cannot be changed\. +i\.e\. +this code cannot simply be *\n' + r'^\1\2copied and put under another distribution licence *\n' + r'^\1\2\[including the GNU Public Licence\.\]', multiLine: true, caseSensitive: false, ), // BSD-DERIVED LICENSES - RegExp( kIndent + - - // Some files in ANGLE prefix the license with a description of the license. - r'(?:BSD 2-Clause License \(https?://www.opensource.org/licenses/bsd-license.php\))?' + - _linebreak + - - ( - 'Redistribution and use in source and binary forms, with or without ' - 'modification, are permitted provided that the following conditions are met:' - .replaceAll(' ', _linebreak) - ) - + - - // the conditions: - r'(?:' + - - // indented blank lines - _linebreak + - - // truly blank lines - r'|\n+' + - - // ad clause - ucb - r'|(?:[-*1-9.)/ ]*)' + - ( - 'All advertising materials mentioning features or use of this software ' - 'must display the following acknowledgement: This product includes software ' - 'developed by the University of California, Berkeley and its contributors\\.' - .replaceAll(' ', _linebreak) - ) - + - - // ad clause - netbsd - r'|(?:[-*1-9.)/ ]*)' + - ( - 'All advertising materials mentioning features or use of this software ' - 'must display the following acknowledgement: This product includes software ' - 'developed by the NetBSD Foundation, Inc\\. and its contributors\\.' - .replaceAll(' ', _linebreak) - ) - + - - // ack clause - r'|(?:[-*1-9.)/ ]*)' + - ( - r'The origin of this software must not be misrepresented; you must not claim ' - r'that you wrote the original software\. If you use this software in a product, ' - r'an acknowledgment in the product documentation would be appreciated but is ' - r'not required\.' - .replaceAll(' ', _linebreak) - ) - + - - r'|(?:[-*1-9.)/ ]*)' + - ( - r'Altered source versions must be plainly marked as such, and must not be ' - r'misrepresented as being the original software\.' - .replaceAll(' ', _linebreak) - ) - + - - // no ad clauses - r'|(?:[-*1-9.)/ ]*)' + - ( - 'Neither my name, .+, nor the names of any other contributors to the code ' - 'use may not be used to endorse or promote products derived from this ' - 'software without specific prior written permission\\.' - .replaceAll(' ', _linebreak) - ) - + - - r'|(?:[-*1-9.)/ ]*)' + - ( - 'The name of the author may not be used to endorse or promote products ' - 'derived from this software without specific prior written permission\\.?' - .replaceAll(' ', _linebreak) - ) - + - - r'|(?:[-*1-9.)/ ]*)' + - ( - 'Neither the name of .+ nor the names of its contributors may be used ' - 'to endorse or promote products derived from this software without ' - 'specific prior written permission\\.' - .replaceAll(' ', _linebreak) - ) - + - - // notice clauses - r'|(?:[-*1-9.)/ ]*)' + - ( - 'Redistributions of source code must retain the above copyright notice, ' - 'this list of conditions and the following disclaimer\\.' - .replaceAll(' ', _linebreak) - ) - + - - r'|(?:[-*1-9.)/ ]*)' + - ( - '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\\.' - .replaceAll(' ', _linebreak) - ) - + - - r'|(?:[-*1-9.)/ ]*)' + - ( - 'Redistributions in binary form must reproduce the above copyright notice, ' - 'this list of conditions and the following disclaimer\\.' - .replaceAll(' ', _linebreak) - ) - + - - // end of conditions - r')*' - + - - // disclaimers - ( - 'THIS SOFTWARE IS PROVIDED (?:BY .+(?: .+)? )?["“`]+AS IS["”\']+,? AND ANY EXPRESS OR IMPLIED ' - 'WARRANTIES,(?::tabnew)? INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ' - 'MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\\. IN NO EVENT ' - 'SHALL .+(?: .+)? 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\\.' - .replaceAll(' ', _linebreak) - ), + // Some files in ANGLE prefix the license with a description of the license. + r'(?:BSD 2-Clause License \(https?://www.opensource.org/licenses/bsd-license.php\))?' + + _linebreak + + ('Redistribution and use in source and binary forms, with or without ' + 'modification, are permitted provided that the following conditions are met:' + .replaceAll(' ', _linebreak)) + + // the conditions: + r'(?:' + + // indented blank lines + _linebreak + + // truly blank lines + r'|\n+' + + // ad clause - ucb + r'|(?:[-*1-9.)/ ]*)' + + ('All advertising materials mentioning features or use of this software ' + 'must display the following acknowledgement: This product includes software ' + 'developed by the University of California, Berkeley and its contributors\\.' + .replaceAll(' ', _linebreak)) + + // ad clause - netbsd + r'|(?:[-*1-9.)/ ]*)' + + ('All advertising materials mentioning features or use of this software ' + 'must display the following acknowledgement: This product includes software ' + 'developed by the NetBSD Foundation, Inc\\. and its contributors\\.' + .replaceAll(' ', _linebreak)) + + // ack clause + r'|(?:[-*1-9.)/ ]*)' + + (r'The origin of this software must not be misrepresented; you must not claim ' + r'that you wrote the original software\. If you use this software in a product, ' + r'an acknowledgment in the product documentation would be appreciated but is ' + r'not required\.' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + (r'Altered source versions must be plainly marked as such, and must not be ' + r'misrepresented as being the original software\.' + .replaceAll(' ', _linebreak)) + + // no ad clauses + r'|(?:[-*1-9.)/ ]*)' + + ('Neither my name, .+, nor the names of any other contributors to the code ' + 'use may not be used to endorse or promote products derived from this ' + 'software without specific prior written permission\\.' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + ('The name of the author may not be used to endorse or promote products ' + 'derived from this software without specific prior written permission\\.?' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + ('Neither the name of .+ nor the names of its contributors may be used ' + 'to endorse or promote products derived from this software without ' + 'specific prior written permission\\.' + .replaceAll(' ', _linebreak)) + + // notice clauses + r'|(?:[-*1-9.)/ ]*)' + + ('Redistributions of source code must retain the above copyright notice, ' + 'this list of conditions and the following disclaimer\\.' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + ('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\\.' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + ('Redistributions in binary form must reproduce the above copyright notice, ' + 'this list of conditions and the following disclaimer\\.' + .replaceAll(' ', _linebreak)) + + // end of conditions + r')*' + + // disclaimers + ('THIS SOFTWARE IS PROVIDED (?:BY .+(?: .+)? )?["“`]+AS IS["”\']+,? AND ANY EXPRESS OR IMPLIED ' + 'WARRANTIES,(?::tabnew)? INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ' + 'MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\\. IN NO EVENT ' + 'SHALL .+(?: .+)? 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\\.' + .replaceAll(' ', _linebreak)), multiLine: true, caseSensitive: false, ), - // MIT-DERIVED LICENSES // Seen in Mesa, among others. RegExp( kIndent + - r'(?:' // this bit is optional - r'Licensed under the MIT license:\n' // seen in expat - r'\1\2? *\n' // blank line - r'\1\2' // this is the prefix for the next block (handled by kIndent if this optional bit is skipped) - r')?' // end of optional bit - + - ( - r'Permission is hereby granted, free of charge, to any person obtaining ' - r'a copy of this software and(?: /or)? associated documentation files \(the "(?:Software|Materials) "\), ' - r'to deal in the (?:Software|Materials) without restriction, including without limitation ' - r'the rights to use, copy, modify, merge, publish, distribute, sub license, ' - r'and/or sell copies of the (?:Software|Materials), and to permit persons to whom the ' - r'(?:Software|Materials) (?:is|are) furnished to do so, subject to the following conditions:' - .replaceAll(' ', _linebreak) - ) - + - r'(?:' - + - ( - r'(?:(?:\1\2?(?: *| -*))? *\n)*' // A version with "// -------" between sections was seen in ffx_spd, hence the -*. - - + - - r'|' - - r'\1\2 ' - r'The above copyright notice and this permission notice' - r'(?: \(including the next paragraph\))? ' - r'shall be included in all copies or substantial portions ' - r'of the (?:Software|Materials)\.' - - r'|' - - r'\1\2 ' - r'The above copyright notice including the dates of first publication and either this ' - r'permission notice or a reference to .+ shall be ' - r'included in all copies or substantial portions of the Software.' - - r'|' - - r'\1\2 ' - r'In addition, the following condition applies:' - - r'|' - - r'\1\2 ' - r'All redistributions must retain an intact copy of this copyright notice and disclaimer\.' - - r'|' - - r'\1\2 ' - r'MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS ' - r'STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND ' - r'HEADER INFORMATION ARE LOCATED AT https://www\.khronos\.org/registry/' - - r'|' - - r'\1\2 ' - r'THE (?:SOFTWARE|MATERIALS) (?:IS|ARE) PROVIDED "AS -? IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ' - r'OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ' - r'FITNESS FOR A PARTICULAR PURPOSE AND NON-?INFRINGEMENT\. IN NO EVENT SHALL ' - r'.+(?: .+)? BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ' - r'IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,(?: )?OUT OF OR IN ' - r'CONNECTION WITH THE (?:SOFTWARE|MATERIALS) OR THE USE OR OTHER DEALINGS IN THE (?:SOFTWARE|MATERIALS)\.' - - r'|' - - r'\1\2 ' - r'THE (?:SOFTWARE|MATERIALS) (?:IS|ARE) PROVIDED "AS -? IS" AND WITHOUT WARRANTY OF ANY KIND, ' - r'EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY ' - r'OR FITNESS FOR A PARTICULAR PURPOSE\.' - - r'|' - - r'\1\2 ' - r'IN NO EVENT SHALL .+ BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL ' - r'DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ' - r'WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING ' - r'OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE\.' - - r'|' - - r'\1\2 ' - r'Except as contained in this notice, the name of .+ shall not ' - r'be used in advertising or otherwise to promote the sale, use or other dealings in ' - r'this Software without prior written authorization from .+\.' - - .replaceAll(' ', _linebreak) - ) - + - r')*', + r'(?:' // this bit is optional + r'Licensed under the MIT license:\n' // seen in expat + r'\1\2? *\n' // blank line + r'\1\2' // this is the prefix for the next block (handled by kIndent if this optional bit is skipped) + r')?' // end of optional bit + + + (r'Permission is hereby granted, free of charge, to any person obtaining ' + r'a copy of this software and(?: /or)? associated documentation files \(the "(?:Software|Materials) "\), ' + r'to deal in the (?:Software|Materials) without restriction, including without limitation ' + r'the rights to use, copy, modify, merge, publish, distribute, sub license, ' + r'and/or sell copies of the (?:Software|Materials), and to permit persons to whom the ' + r'(?:Software|Materials) (?:is|are) furnished to do so, subject to the following conditions:' + .replaceAll(' ', _linebreak)) + + r'(?:' + + (r'(?:(?:\1\2?(?: *| -*))? *\n)*' // A version with "// -------" between sections was seen in ffx_spd, hence the -*. + + + r'|' + r'\1\2 ' + r'The above copyright notice and this permission notice' + r'(?: \(including the next paragraph\))? ' + r'shall be included in all copies or substantial portions ' + r'of the (?:Software|Materials)\.' + r'|' + r'\1\2 ' + r'The above copyright notice including the dates of first publication and either this ' + r'permission notice or a reference to .+ shall be ' + r'included in all copies or substantial portions of the Software.' + r'|' + r'\1\2 ' + r'In addition, the following condition applies:' + r'|' + r'\1\2 ' + r'All redistributions must retain an intact copy of this copyright notice and disclaimer\.' + r'|' + r'\1\2 ' + r'MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS ' + r'STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND ' + r'HEADER INFORMATION ARE LOCATED AT https://www\.khronos\.org/registry/' + r'|' + r'\1\2 ' + r'THE (?:SOFTWARE|MATERIALS) (?:IS|ARE) PROVIDED "AS -? IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ' + r'OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ' + r'FITNESS FOR A PARTICULAR PURPOSE AND NON-?INFRINGEMENT\. IN NO EVENT SHALL ' + r'.+(?: .+)? BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ' + r'IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,(?: )?OUT OF OR IN ' + r'CONNECTION WITH THE (?:SOFTWARE|MATERIALS) OR THE USE OR OTHER DEALINGS IN THE (?:SOFTWARE|MATERIALS)\.' + r'|' + r'\1\2 ' + r'THE (?:SOFTWARE|MATERIALS) (?:IS|ARE) PROVIDED "AS -? IS" AND WITHOUT WARRANTY OF ANY KIND, ' + r'EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY ' + r'OR FITNESS FOR A PARTICULAR PURPOSE\.' + r'|' + r'\1\2 ' + r'IN NO EVENT SHALL .+ BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL ' + r'DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ' + r'WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING ' + r'OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE\.' + r'|' + r'\1\2 ' + r'Except as contained in this notice, the name of .+ shall not ' + r'be used in advertising or otherwise to promote the sale, use or other dealings in ' + r'this Software without prior written authorization from .+\.'.replaceAll(' ', _linebreak)) + + r')*', multiLine: true, caseSensitive: false, ), RegExp( - kIndent + r'Boost Software License - Version 1\.0 - August 17th, 2003\n' + - r'\n' + - ( - r'\1\2Permission is hereby granted, free of charge, to any person or ' - r'organization obtaining a copy of the software and accompanying ' - r'documentation covered by this license \(the "Software"\) to use, ' - r'reproduce, display, distribute, execute, and transmit the Software, and ' - r'to prepare derivative works of the Software, and to permit third-parties ' - r'to whom the Software is furnished to do so, all subject to the following:\n' - .replaceAll(' ', _linebreak) - ) + - r'\n' + - ( - r'\1\2The copyright notices in the Software and this entire statement, ' - r'including the above license grant, this restriction and the following ' - r'disclaimer, must be included in all copies of the Software, in whole or ' - r'in part, and all derivative works of the Software, unless such copies or ' - r'derivative works are solely in the form of machine-executable object ' - r'code generated by a source language processor\.\n' - .replaceAll(' ', _linebreak) - ) + - r'\n' + - ( - r'\1\2THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ' - r'EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ' - r'MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND ' - r'NON-INFRINGEMENT\. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE ' - r'DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, ' - r'WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ' - r'CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ' - r'SOFTWARE\.' - .replaceAll(' ', _linebreak) - ), + kIndent + + r'Boost Software License - Version 1\.0 - August 17th, 2003\n' + + r'\n' + + (r'\1\2Permission is hereby granted, free of charge, to any person or ' + r'organization obtaining a copy of the software and accompanying ' + r'documentation covered by this license \(the "Software"\) to use, ' + r'reproduce, display, distribute, execute, and transmit the Software, and ' + r'to prepare derivative works of the Software, and to permit third-parties ' + r'to whom the Software is furnished to do so, all subject to the following:\n' + .replaceAll(' ', _linebreak)) + + r'\n' + + (r'\1\2The copyright notices in the Software and this entire statement, ' + r'including the above license grant, this restriction and the following ' + r'disclaimer, must be included in all copies of the Software, in whole or ' + r'in part, and all derivative works of the Software, unless such copies or ' + r'derivative works are solely in the form of machine-executable object ' + r'code generated by a source language processor\.\n' + .replaceAll(' ', _linebreak)) + + r'\n' + + (r'\1\2THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ' + r'EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ' + r'MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND ' + r'NON-INFRINGEMENT\. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE ' + r'DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, ' + r'WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ' + r'CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ' + r'SOFTWARE\.' + .replaceAll(' ', _linebreak)), multiLine: true, caseSensitive: false, ), @@ -1156,77 +1083,78 @@ final List csTemplateLicenses = [ // Seen in some ANGLE source. The usage falls under the "special exception" clause. RegExp( kIndent + - r'This program is free software: you can redistribute it and/or modify\n' - r'^(?:\1\2)?it under the terms of the GNU General Public License as published by\n' - r'^(?:\1\2)?the Free Software Foundation, either version 3 of the License, or\n' - r'^(?:\1\2)?\(at your option\) any later version.\n' - r'^(?:\1\2)?\n*' - r'^(?:\1\2)?This program is distributed in the hope that it will be useful,\n' - r'^(?:\1\2)?but WITHOUT ANY WARRANTY; without even the implied warranty of\n' - r'^(?:\1\2)?MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n' - r'^(?:\1\2)?GNU General Public License for more details.\n' - r'^(?:\1\2)?\n*' - r'^(?:\1\2)?You should have received a copy of the GNU General Public License\n' - r'^(?:\1\2)?along with this program. If not, see . \*/\n' - r'^(?:\1\2)?\n*' + - kIndent + - r'As a special exception, you may create a larger work that contains\n' - r'^(?:\1\2)?part or all of the Bison parser skeleton and distribute that work\n' - r"^(?:\1\2)?under terms of your choice, so long as that work isn't itself a\n" - r'^(?:\1\2)?parser generator using the skeleton or a modified version thereof\n' - r'^(?:\1\2)?as a parser skeleton. Alternatively, if you modify or redistribute\n' - r'^(?:\1\2)?the parser skeleton itself, you may \(at your option\) remove this\n' - r'^(?:\1\2)?special exception, which will cause the skeleton and the resulting\n' - r'^(?:\1\2)?Bison output files to be licensed under the GNU General Public\n' - r'^(?:\1\2)?License without this special exception.\n' - r'^(?:\1\2)?\n*' - r'^(?:\1\2)?This special exception was added by the Free Software Foundation in\n' - r'^(?:\1\2)?version 2.2 of Bison. \*/\n', + r'This program is free software: you can redistribute it and/or modify\n' + r'^(?:\1\2)?it under the terms of the GNU General Public License as published by\n' + r'^(?:\1\2)?the Free Software Foundation, either version 3 of the License, or\n' + r'^(?:\1\2)?\(at your option\) any later version.\n' + r'^(?:\1\2)?\n*' + r'^(?:\1\2)?This program is distributed in the hope that it will be useful,\n' + r'^(?:\1\2)?but WITHOUT ANY WARRANTY; without even the implied warranty of\n' + r'^(?:\1\2)?MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n' + r'^(?:\1\2)?GNU General Public License for more details.\n' + r'^(?:\1\2)?\n*' + r'^(?:\1\2)?You should have received a copy of the GNU General Public License\n' + r'^(?:\1\2)?along with this program. If not, see . \*/\n' + r'^(?:\1\2)?\n*' + + kIndent + + r'As a special exception, you may create a larger work that contains\n' + r'^(?:\1\2)?part or all of the Bison parser skeleton and distribute that work\n' + r"^(?:\1\2)?under terms of your choice, so long as that work isn't itself a\n" + r'^(?:\1\2)?parser generator using the skeleton or a modified version thereof\n' + r'^(?:\1\2)?as a parser skeleton. Alternatively, if you modify or redistribute\n' + r'^(?:\1\2)?the parser skeleton itself, you may \(at your option\) remove this\n' + r'^(?:\1\2)?special exception, which will cause the skeleton and the resulting\n' + r'^(?:\1\2)?Bison output files to be licensed under the GNU General Public\n' + r'^(?:\1\2)?License without this special exception.\n' + r'^(?:\1\2)?\n*' + r'^(?:\1\2)?This special exception was added by the Free Software Foundation in\n' + r'^(?:\1\2)?version 2.2 of Bison. \*/\n', multiLine: true, caseSensitive: false, ), // NVIDIA license found in glslang RegExp( - kIndent + r'NVIDIA Corporation\("NVIDIA"\) supplies this software to you in\n' - r'\1\2consideration of your agreement to the following terms, and your use,\n' - r'\1\2installation, modification or redistribution of this NVIDIA software\n' - r'\1\2constitutes acceptance of these terms\. If you do not agree with these\n' - r'\1\2terms, please do not use, install, modify or redistribute this NVIDIA\n' - r'\1\2software\.\n' - r'\1(?:\2)?\n' - r'\1\2In consideration of your agreement to abide by the following terms, and\n' - r'\1\2subject to these terms, NVIDIA grants you a personal, non-exclusive\n' - r"\1\2license, under NVIDIA's copyrights in this original NVIDIA software \(the\n" - r'\1\2"NVIDIA Software"\), to use, reproduce, modify and redistribute the\n' - r'\1\2NVIDIA Software, with or without modifications, in source and/or binary\n' - r'\1\2forms; provided that if you redistribute the NVIDIA Software, you must\n' - r'\1\2retain the copyright notice of NVIDIA, this notice and the following\n' - r'\1\2text and disclaimers in all such redistributions of the NVIDIA Software\.\n' - r'\1\2Neither the name, trademarks, service marks nor logos of NVIDIA\n' - r'\1\2Corporation may be used to endorse or promote products derived from the\n' - r'\1\2NVIDIA Software without specific prior written permission from NVIDIA\.\n' - r'\1\2Except as expressly stated in this notice, no other rights or licenses\n' - r'\1\2express or implied, are granted by NVIDIA herein, including but not\n' - r'\1\2limited to any patent rights that may be infringed by your derivative\n' - r'\1\2works or by other works in which the NVIDIA Software may be\n' - r'\1\2incorporated\. No hardware is licensed hereunder\.\n' - r'\1(?:\2)?\n' - r'\1\2THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT\n' - r'\1\2WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,\n' - r'\1\2INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,\n' - r'\1\2NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR\n' - r'\1\2ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER\n' - r'\1\2PRODUCTS\.\n' - r'\1(?:\2)?\n' - r'\1\2IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,\n' - r'\1\2INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES \(INCLUDING, BUT NOT LIMITED\n' - r'\1\2TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n' - r'\1\2USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) OR ARISING IN ANY WAY\n' - r'\1\2OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE\n' - r'\1\2NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,\n' - r'\1\2TORT \(INCLUDING NEGLIGENCE\), STRICT LIABILITY OR OTHERWISE, EVEN IF\n' - r'\1\2NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\.\n', + kIndent + + r'NVIDIA Corporation\("NVIDIA"\) supplies this software to you in\n' + r'\1\2consideration of your agreement to the following terms, and your use,\n' + r'\1\2installation, modification or redistribution of this NVIDIA software\n' + r'\1\2constitutes acceptance of these terms\. If you do not agree with these\n' + r'\1\2terms, please do not use, install, modify or redistribute this NVIDIA\n' + r'\1\2software\.\n' + r'\1(?:\2)?\n' + r'\1\2In consideration of your agreement to abide by the following terms, and\n' + r'\1\2subject to these terms, NVIDIA grants you a personal, non-exclusive\n' + r"\1\2license, under NVIDIA's copyrights in this original NVIDIA software \(the\n" + r'\1\2"NVIDIA Software"\), to use, reproduce, modify and redistribute the\n' + r'\1\2NVIDIA Software, with or without modifications, in source and/or binary\n' + r'\1\2forms; provided that if you redistribute the NVIDIA Software, you must\n' + r'\1\2retain the copyright notice of NVIDIA, this notice and the following\n' + r'\1\2text and disclaimers in all such redistributions of the NVIDIA Software\.\n' + r'\1\2Neither the name, trademarks, service marks nor logos of NVIDIA\n' + r'\1\2Corporation may be used to endorse or promote products derived from the\n' + r'\1\2NVIDIA Software without specific prior written permission from NVIDIA\.\n' + r'\1\2Except as expressly stated in this notice, no other rights or licenses\n' + r'\1\2express or implied, are granted by NVIDIA herein, including but not\n' + r'\1\2limited to any patent rights that may be infringed by your derivative\n' + r'\1\2works or by other works in which the NVIDIA Software may be\n' + r'\1\2incorporated\. No hardware is licensed hereunder\.\n' + r'\1(?:\2)?\n' + r'\1\2THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT\n' + r'\1\2WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,\n' + r'\1\2INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,\n' + r'\1\2NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR\n' + r'\1\2ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER\n' + r'\1\2PRODUCTS\.\n' + r'\1(?:\2)?\n' + r'\1\2IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,\n' + r'\1\2INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES \(INCLUDING, BUT NOT LIMITED\n' + r'\1\2TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n' + r'\1\2USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) OR ARISING IN ANY WAY\n' + r'\1\2OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE\n' + r'\1\2NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,\n' + r'\1\2TORT \(INCLUDING NEGLIGENCE\), STRICT LIABILITY OR OTHERWISE, EVEN IF\n' + r'\1\2NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\.\n', multiLine: true, ), @@ -1235,93 +1163,90 @@ final List csTemplateLicenses = [ // Seen in the NDK RegExp( kIndent + - r'Permission to use, copy, modify, and/or distribute this software for any *\n' - r'^\1\2purpose with or without fee is hereby granted, provided that the above *\n' - r'^\1\2copyright notice and this permission notice appear in all copies\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2THE SOFTWARE IS PROVIDED "AS IS" AND .+ DISCLAIMS ALL WARRANTIES(?: WITH)? *\n' - r'^\1\2(?:WITH )?REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF(?: MERCHANTABILITY)? *\n' - r'^\1\2(?:MERCHANTABILITY )?AND FITNESS\. +IN NO EVENT SHALL .+ BE LIABLE FOR(?: ANY(?: SPECIAL, DIRECT,)?)? *\n' - r'^\1\2(?:(?:ANY )?SPECIAL, DIRECT, )?INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES(?: WHATSOEVER RESULTING FROM)? *\n' - r'^\1\2(?:WHATSOEVER RESULTING FROM )?LOSS OF USE, DATA OR PROFITS, WHETHER IN AN(?: ACTION(?: OF CONTRACT, NEGLIGENCE)?)? *\n' - r'^\1\2(?:(?:ACTION )?OF CONTRACT, NEGLIGENCE )?OR OTHER TORTIOUS ACTION, ARISING OUT OF(?: OR IN(?: CONNECTION WITH THE USE OR)?)? *\n' - r'^\1\2(?:(?:OR IN )?CONNECTION WITH THE USE OR )?PERFORMANCE OF THIS SOFTWARE\.', + r'Permission to use, copy, modify, and/or distribute this software for any *\n' + r'^\1\2purpose with or without fee is hereby granted, provided that the above *\n' + r'^\1\2copyright notice and this permission notice appear in all copies\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2THE SOFTWARE IS PROVIDED "AS IS" AND .+ DISCLAIMS ALL WARRANTIES(?: WITH)? *\n' + r'^\1\2(?:WITH )?REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF(?: MERCHANTABILITY)? *\n' + r'^\1\2(?:MERCHANTABILITY )?AND FITNESS\. +IN NO EVENT SHALL .+ BE LIABLE FOR(?: ANY(?: SPECIAL, DIRECT,)?)? *\n' + r'^\1\2(?:(?:ANY )?SPECIAL, DIRECT, )?INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES(?: WHATSOEVER RESULTING FROM)? *\n' + r'^\1\2(?:WHATSOEVER RESULTING FROM )?LOSS OF USE, DATA OR PROFITS, WHETHER IN AN(?: ACTION(?: OF CONTRACT, NEGLIGENCE)?)? *\n' + r'^\1\2(?:(?:ACTION )?OF CONTRACT, NEGLIGENCE )?OR OTHER TORTIOUS ACTION, ARISING OUT OF(?: OR IN(?: CONNECTION WITH THE USE OR)?)? *\n' + r'^\1\2(?:(?:OR IN )?CONNECTION WITH THE USE OR )?PERFORMANCE OF THIS SOFTWARE\.', multiLine: true, ), // harfbuzz RegExp( kIndent + - r'Permission is hereby granted, without written agreement and without *\n' - r'^\1\2license or royalty fees, to use, copy, modify, and distribute this *\n' - r'^\1\2software and its documentation for any purpose, provided that the *\n' - r'^\1\2above copyright notice and the following two paragraphs appear in *\n' - r'^\1\2all copies of this software\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR *\n' - r'^\1\2DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES *\n' - r'^\1\2ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN *\n' - r'^\1\2IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH *\n' - r'^\1\2DAMAGE\. *\n' - r'^(?:(?:\1\2? *)? *\n)*' - r'^\1\2THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, *\n' - r'^\1\2BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND *\n' - r'^\1\2FITNESS FOR A PARTICULAR PURPOSE\. +THE SOFTWARE PROVIDED HEREUNDER IS *\n' - r'^\1\2ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO *\n' - r'^\1\2PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS\. *\n', + r'Permission is hereby granted, without written agreement and without *\n' + r'^\1\2license or royalty fees, to use, copy, modify, and distribute this *\n' + r'^\1\2software and its documentation for any purpose, provided that the *\n' + r'^\1\2above copyright notice and the following two paragraphs appear in *\n' + r'^\1\2all copies of this software\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR *\n' + r'^\1\2DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES *\n' + r'^\1\2ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN *\n' + r'^\1\2IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH *\n' + r'^\1\2DAMAGE\. *\n' + r'^(?:(?:\1\2? *)? *\n)*' + r'^\1\2THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, *\n' + r'^\1\2BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND *\n' + r'^\1\2FITNESS FOR A PARTICULAR PURPOSE\. +THE SOFTWARE PROVIDED HEREUNDER IS *\n' + r'^\1\2ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO *\n' + r'^\1\2PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS\. *\n', multiLine: true, ), // freetype2. RegExp( kIndent + - r'Permission to use, copy, modify, distribute, and sell this software and its ' - r'documentation for any purpose is hereby granted without fee, provided that ' - r'the above copyright notice appear in all copies and that both that ' - r'copyright notice and this permission notice appear in supporting ' - r'documentation\. ' - r'The above copyright notice and this permission notice shall be included in ' - r'all copies or substantial portions of the Software\. ' - r'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ' - r'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ' - r'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\. IN NO EVENT SHALL THE ' - r'OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN ' - r'AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ' - r'CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE\. ' - r'Except as contained in this notice, the name of The Open Group shall not be ' - r'used in advertising or otherwise to promote the sale, use or other dealings ' - r'in this Software without prior written authorization from The Open Group\. ' - .replaceAll(' ', _linebreak), + r'Permission to use, copy, modify, distribute, and sell this software and its ' + r'documentation for any purpose is hereby granted without fee, provided that ' + r'the above copyright notice appear in all copies and that both that ' + r'copyright notice and this permission notice appear in supporting ' + r'documentation\. ' + r'The above copyright notice and this permission notice shall be included in ' + r'all copies or substantial portions of the Software\. ' + r'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ' + r'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ' + r'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\. IN NO EVENT SHALL THE ' + r'OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN ' + r'AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ' + r'CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE\. ' + r'Except as contained in this notice, the name of The Open Group shall not be ' + r'used in advertising or otherwise to promote the sale, use or other dealings ' + r'in this Software without prior written authorization from The Open Group\. ' + .replaceAll(' ', _linebreak), multiLine: true, ), // libjpeg-turbo RegExp( kIndent + - r'Permission to use, copy, modify, and distribute this software and its ' - r'documentation for any purpose and without fee is hereby granted, provided ' - r'that the above copyright notice appear in all copies and that both that ' - r'copyright notice and this permission notice appear in supporting ' - r'documentation\. This software is provided "as is" without express or ' - r'implied warranty\.' - .replaceAll(' ', _linebreak), + r'Permission to use, copy, modify, and distribute this software and its ' + r'documentation for any purpose and without fee is hereby granted, provided ' + r'that the above copyright notice appear in all copies and that both that ' + r'copyright notice and this permission notice appear in supporting ' + r'documentation\. This software is provided "as is" without express or ' + r'implied warranty\.' + .replaceAll(' ', _linebreak), multiLine: true, ), ]; - // LICENSES WE JUST DISPLAY VERBATIM final List csNoticeLicenses = [ - // used with _tryInline, with needsCopyright: false // should have two groups, prefixes 1 and 2 - RegExp( kIndent + - r'COPYRIGHT NOTICE, DISCLAIMER, and LICENSE\n' - r'(?:\1.*\n)+?' - r'(?=\1\2END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE\.)', + r'COPYRIGHT NOTICE, DISCLAIMER, and LICENSE\n' + r'(?:\1.*\n)+?' + r'(?=\1\2END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE\.)', multiLine: true, ), @@ -1331,12 +1256,12 @@ final List csNoticeLicenses = [ // text verbatim should be enough. RegExp( kIndent + - r'Portions of the attached software \("Contribution"\) are developed by ' - r'SUN MICROSYSTEMS, INC\., and are contributed to the OpenSSL project\. ' - r'\n ' - r'The Contribution is licensed pursuant to the Eric Young open source ' - r'license provided above\.' - .replaceAll(' ', _linebreak), + r'Portions of the attached software \("Contribution"\) are developed by ' + r'SUN MICROSYSTEMS, INC\., and are contributed to the OpenSSL project\. ' + r'\n ' + r'The Contribution is licensed pursuant to the Eric Young open source ' + r'license provided above\.' + .replaceAll(' ', _linebreak), multiLine: true, ), @@ -1346,27 +1271,27 @@ final List csNoticeLicenses = [ // text verbatim should be enough. RegExp( kIndent + - r'Portions of the attached software \("Contribution"\) are developed by ' - r'SUN MICROSYSTEMS, INC\., and are contributed to the OpenSSL project\. ' - r'\n ' - r'The Contribution is licensed pursuant to the OpenSSL open source ' - r'license provided above\.' - .replaceAll(' ', _linebreak), + r'Portions of the attached software \("Contribution"\) are developed by ' + r'SUN MICROSYSTEMS, INC\., and are contributed to the OpenSSL project\. ' + r'\n ' + r'The Contribution is licensed pursuant to the OpenSSL open source ' + r'license provided above\.' + .replaceAll(' ', _linebreak), multiLine: true, ), // Freetype RegExp( kIndent + - r'This software was written by Alexander Peslyak in 2001\. No copyright is ' - r'claimed, and the software is hereby placed in the public domain\. In case ' - r'this attempt to disclaim copyright and place the software in the public ' - r'domain is deemed null and void, then the software is Copyright \(c\) 2001 ' - r'Alexander Peslyak and it is hereby released to the general public under the ' - r'following terms: Redistribution and use in source and binary forms, with or ' - r"without modification, are permitted\. There\'s ABSOLUTELY NO WARRANTY, " - r'express or implied\.(?: \(This is a heavily cut-down "BSD license"\.\))?' - .replaceAll(' ', _linebreak), + r'This software was written by Alexander Peslyak in 2001\. No copyright is ' + r'claimed, and the software is hereby placed in the public domain\. In case ' + r'this attempt to disclaim copyright and place the software in the public ' + r'domain is deemed null and void, then the software is Copyright \(c\) 2001 ' + r'Alexander Peslyak and it is hereby released to the general public under the ' + r'following terms: Redistribution and use in source and binary forms, with or ' + r"without modification, are permitted\. There\'s ABSOLUTELY NO WARRANTY, " + r'express or implied\.(?: \(This is a heavily cut-down "BSD license"\.\))?' + .replaceAll(' ', _linebreak), multiLine: true, ), @@ -1436,85 +1361,70 @@ final List csNoticeLicenses = [ RegExp( kIndent + - r'This file is provided as-is by Unicode, Inc\. \(The Unicode Consortium\)\. ' - r'No claims are made as to fitness for any particular purpose\. No ' - r'warranties of any kind are expressed or implied\. The recipient ' - r'agrees to determine applicability of information provided\. If this ' - r'file has been provided on optical media by Unicode, Inc\., the sole ' - r'remedy for any claim will be exchange of defective media within 90 ' - r'days of receipt\.\n' - r'\1\n' - r'\1\2Unicode, Inc\. hereby grants the right to freely use the information ' - r'supplied in this file in the creation of products supporting the ' - r'Unicode Standard, and to make copies of this file in any form for ' - r'internal or external distribution as long as this notice remains ' - r'attached\. ' - .replaceAll(' ', _linebreak), + r'This file is provided as-is by Unicode, Inc\. \(The Unicode Consortium\)\. ' + r'No claims are made as to fitness for any particular purpose\. No ' + r'warranties of any kind are expressed or implied\. The recipient ' + r'agrees to determine applicability of information provided\. If this ' + r'file has been provided on optical media by Unicode, Inc\., the sole ' + r'remedy for any claim will be exchange of defective media within 90 ' + r'days of receipt\.\n' + r'\1\n' + r'\1\2Unicode, Inc\. hereby grants the right to freely use the information ' + r'supplied in this file in the creation of products supporting the ' + r'Unicode Standard, and to make copies of this file in any form for ' + r'internal or external distribution as long as this notice remains ' + r'attached\. ' + .replaceAll(' ', _linebreak), multiLine: true, ), RegExp( kIndent + - r'We are also required to state that "The Graphics Interchange Format\(c\) ' - r'is the Copyright property of CompuServe Incorporated. GIF\(sm\) is a ' - r'Service Mark property of CompuServe Incorporated."' - .replaceAll(' ', _linebreak), + r'We are also required to state that "The Graphics Interchange Format\(c\) ' + r'is the Copyright property of CompuServe Incorporated. GIF\(sm\) is a ' + r'Service Mark property of CompuServe Incorporated."' + .replaceAll(' ', _linebreak), multiLine: true, ), - // ZLIB-LIKE LICENSES // Seen in libjpeg-turbo (with a copyright), zlib.h RegExp( kIndent + - r" This software is provided 'as-is', without any express or implied " - r'warranty\. In no event will the authors be held liable for any damages ' - r'arising from the use of this software\.' - .replaceAll(' ', _linebreak) - + - ( - r' Permission is granted to anyone to use this software for any purpose, ' - r'including commercial applications, and to alter it and redistribute it ' - r'freely, subject to the following restrictions:' - .replaceAll(' ', _linebreak) - ) - + - r'(?:' + - _linebreak + - r'(?:' + - r'|\n+' + - r'|(?:[-*1-9.)/ ]*)' + - ( - r'The origin of this software must not be misrepresented; you must not ' - r'claim that you wrote the original software\. If you use this software ' - r'in a product, an acknowledgment in the product documentation would be ' - r'appreciated but is not required\.' - .replaceAll(' ', _linebreak) - ) - + - r'|(?:[-*1-9.)/ ]*)' + - ( - r'Altered source versions must be plainly marked as such, and must not be ' - r'misrepresented as being the original software\. ' - .replaceAll(' ', _linebreak) - ) - + - r'|(?:[-*1-9.)/ ]*)' + - ( - r"If you meet \(any of\) the author\(s\), you're encouraged to buy them a beer, " - r'a drink or whatever is suited to the situation, given that you like the ' - r'software\. ' - .replaceAll(' ', _linebreak) - ) - + - r'|(?:[-*1-9.)/ ]*)' + - ( - r'This notice may not be removed or altered from any source distribution\.' - .replaceAll(' ', _linebreak) - ) - + - r'))+', + r" This software is provided 'as-is', without any express or implied " + r'warranty\. In no event will the authors be held liable for any damages ' + r'arising from the use of this software\.' + .replaceAll(' ', _linebreak) + + (r' Permission is granted to anyone to use this software for any purpose, ' + r'including commercial applications, and to alter it and redistribute it ' + r'freely, subject to the following restrictions:' + .replaceAll(' ', _linebreak)) + + r'(?:' + + _linebreak + + r'(?:' + + r'|\n+' + + r'|(?:[-*1-9.)/ ]*)' + + (r'The origin of this software must not be misrepresented; you must not ' + r'claim that you wrote the original software\. If you use this software ' + r'in a product, an acknowledgment in the product documentation would be ' + r'appreciated but is not required\.' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + (r'Altered source versions must be plainly marked as such, and must not be ' + r'misrepresented as being the original software\. ' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + (r"If you meet \(any of\) the author\(s\), you're encouraged to buy them a beer, " + r'a drink or whatever is suited to the situation, given that you like the ' + r'software\. ' + .replaceAll(' ', _linebreak)) + + r'|(?:[-*1-9.)/ ]*)' + + (r'This notice may not be removed or altered from any source distribution\.'.replaceAll( + ' ', + _linebreak, + )) + + r'))+', multiLine: true, caseSensitive: false, ), @@ -1524,11 +1434,11 @@ final List csStrayCopyrights = [ // a file in BoringSSL RegExp( kIndent + - r'DTLS code by Eric Rescorla ' - r'\n ' - r'Copyright \(C\) 2006, Network Resonance, Inc\. ' - r'Copyright \(C\) 2011, RTFM, Inc\.' - .replaceAll(' ', _linebreak), + r'DTLS code by Eric Rescorla ' + r'\n ' + r'Copyright \(C\) 2006, Network Resonance, Inc\. ' + r'Copyright \(C\) 2011, RTFM, Inc\.' + .replaceAll(' ', _linebreak), multiLine: true, ), @@ -1542,15 +1452,17 @@ final List csStrayCopyrights = [ // Found in a lot of ICU files RegExp( kIndent + - r'Copyright \([Cc]\) [-, 0-9{}]+ ' + '(?:Google, )?International Business Machines ' - r'Corporation(?:(?:, Google,?)? and others)?\. All [Rr]ights [Rr]eserved\.' - .replaceAll(' ', _linebreak), + r'Copyright \([Cc]\) [-, 0-9{}]+ ' + + '(?:Google, )?International Business Machines ' + r'Corporation(?:(?:, Google,?)? and others)?\. All [Rr]ights [Rr]eserved\.' + .replaceAll(' ', _linebreak), multiLine: true, ), // Found in ICU files RegExp( - kIndent + r'Copyright \([Cc]\) [-0-9,]+ IBM(?: Corp(?:oration)?)?(?:, Inc\.)?(?: and [Oo]thers)?\.(?: All rights reserved\.)?', + kIndent + + r'Copyright \([Cc]\) [-0-9,]+ IBM(?: Corp(?:oration)?)?(?:, Inc\.)?(?: and [Oo]thers)?\.(?: All rights reserved\.)?', multiLine: true, ), @@ -1567,57 +1479,44 @@ final List csStrayCopyrights = [ ), // Found in ICU files - RegExp( - kIndent + r'Copyright \(C\) [-,0-9]+ ,? Yahoo! Inc\.', - multiLine: true, - ), + RegExp(kIndent + r'Copyright \(C\) [-,0-9]+ ,? Yahoo! Inc\.', multiLine: true), + + // Found in some ICU files + RegExp(kIndent + r'Copyright [0-9]+ and onwards Google Inc.', multiLine: true), + + // Found in some ICU files + RegExp(kIndent + r'Copyright [0-9]+ Google Inc. All Rights Reserved.', multiLine: true), // Found in some ICU files RegExp( - kIndent + r'Copyright [0-9]+ and onwards Google Inc.', - multiLine: true, - ), - - // Found in some ICU files - RegExp( - kIndent + r'Copyright [0-9]+ Google Inc. All Rights Reserved.', - multiLine: true, - ), - - // Found in some ICU files - RegExp( - kIndent + r'Copyright \(C\) [-0-9]+, Apple Inc\.(?:; Unicode, Inc\.;)? and others\. All Rights Reserved\.', + kIndent + + r'Copyright \(C\) [-0-9]+, Apple Inc\.(?:; Unicode, Inc\.;)? and others\. All Rights Reserved\.', multiLine: true, ), // rapidjson RegExp( - kIndent + r'The above software in this distribution may have been modified by THL A29 Limited ' - r'\("Tencent Modifications"\)\. All Tencent Modifications are Copyright \(C\) 2015 THL A29 Limited\.' - .replaceAll(' ', _linebreak), + kIndent + + r'The above software in this distribution may have been modified by THL A29 Limited ' + r'\("Tencent Modifications"\)\. All Tencent Modifications are Copyright \(C\) 2015 THL A29 Limited\.' + .replaceAll(' ', _linebreak), multiLine: true, ), // minizip - RegExp( - kIndent + r'Copyright \(C\) [-0-9]+ Gilles Vollant', - multiLine: true, - ), + RegExp(kIndent + r'Copyright \(C\) [-0-9]+ Gilles Vollant', multiLine: true), // Skia - RegExp( - kIndent + r'Copyright [-0-9]+ Google LLC\.', - multiLine: true, - ), + RegExp(kIndent + r'Copyright [-0-9]+ Google LLC\.', multiLine: true), // flutter/third_party/inja/third_party/include/hayai/hayai_clock.hpp // Advice was to just ignore these copyright notices given the LICENSE.md file // in the same directory. RegExp( - kIndent + r'Copyright \(C\) 2011 Nick Bruun \n' - r'\1\2Copyright \(C\) 2013 Vlad Lazarenko \n' - r'\1\2Copyright \(C\) 2014 Nicolas Pauss ', + kIndent + + r'Copyright \(C\) 2011 Nick Bruun \n' + r'\1\2Copyright \(C\) 2013 Vlad Lazarenko \n' + r'\1\2Copyright \(C\) 2014 Nicolas Pauss ', multiLine: true, ), - ]; diff --git a/engine/src/flutter/tools/licenses/lib/regexp_debug.dart b/engine/src/flutter/tools/licenses/lib/regexp_debug.dart index 4ef019faf0..447ee632b7 100644 --- a/engine/src/flutter/tools/licenses/lib/regexp_debug.dart +++ b/engine/src/flutter/tools/licenses/lib/regexp_debug.dart @@ -14,8 +14,16 @@ class RegExp implements core.RegExp { 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) { + }) : _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); } @@ -43,28 +51,36 @@ class RegExp implements core.RegExp { 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( + '${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( + '/${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( + '/${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})'); + stderr.writeln( + '/${pattern.pattern}/ (${pattern.testCount} tests, ${pattern.matchCount} matches, ${pattern.source})', + ); } } } diff --git a/engine/src/flutter/tools/licenses/test/formatter_test.dart b/engine/src/flutter/tools/licenses/test/formatter_test.dart index 565763d18f..293f7f9364 100644 --- a/engine/src/flutter/tools/licenses/test/formatter_test.dart +++ b/engine/src/flutter/tools/licenses/test/formatter_test.dart @@ -18,9 +18,15 @@ void main() { }); 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 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\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 }); @@ -46,42 +52,45 @@ void main() { 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.' + 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. */' + '/* 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.' + '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.' + '/* 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.' + '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.', ); }); }