4 // This script reads the project composer.lock file to generate
5 // clear license details for our PHP dependencies.
7 $rootPath = dirname(__DIR__, 2);
8 $outputPath = "{$rootPath}/dev/licensing/js-library-licenses.txt";
9 $outputSeparator = "\n-----------\n";
13 ...glob("{$rootPath}/node_modules/*/package.json"),
14 ...glob("{$rootPath}/node_modules/@*/*/package.json"),
17 $packageOutput = array_map(packageToOutput(...), $packages);
19 $licenseInfo = implode($outputSeparator, $packageOutput) . "\n";
20 file_put_contents($outputPath, $licenseInfo);
22 echo "License information written to {$outputPath}\n";
23 echo implode("\n", $warnings);
25 function dd(mixed $data): never {
30 function packageToOutput(string $packagePath): string
33 $package = json_decode(file_get_contents($packagePath));
34 $output = ["{$package->name}"];
36 $license = $package->license ?? '';
38 $output[] = "License: {$license}";
40 warn("Package {$package->name}: No license found");
43 $licenseFile = findLicenseFile($package->name, $packagePath);
45 $relLicenseFile = str_replace("{$rootPath}/", '', $licenseFile);
46 $output[] = "License File: {$relLicenseFile}";
47 $copyright = findCopyright($licenseFile);
49 $output[] = "Copyright: {$copyright}";
51 warn("Package {$package->name}: no copyright found in its license");
55 $source = $package->repository->url ?? $package->repository ?? '';
57 $output[] = "Source: {$source}";
60 $link = $package->homepage ?? $source;
62 $output[] = "Link: {$link}";
65 return implode("\n", $output);
68 function findLicenseFile(string $packageName, string $packagePath): string
70 $licenseNameOptions = [
71 'license', 'LICENSE', 'License',
72 'license.*', 'LICENSE.*', 'License.*',
73 'license-*.*', 'LICENSE-*.*', 'License-*.*',
75 $packageDir = dirname($packagePath);
78 foreach ($licenseNameOptions as $option) {
79 $search = glob("{$packageDir}/$option");
80 array_push($foundLicenses, ...$search);
83 if (count($foundLicenses) > 1) {
84 warn("Package {$packageName}: more than one license file found");
87 if (count($foundLicenses) > 0) {
88 $fileName = basename($foundLicenses[0]);
89 return "{$packageDir}/{$fileName}";
92 warn("Package {$packageName}: no license files found");
96 function findCopyright(string $licenseFile): string
98 $fileContents = file_get_contents($licenseFile);
99 $pattern = '/^.*?copyright (\(c\)|\d{4})[\s\S]*?(\n\n|\.\n)/mi';
101 preg_match($pattern, $fileContents, $matches);
102 $copyright = trim($matches[0] ?? '');
104 if (str_contains($copyright, 'i.e.')) {
108 $emailPattern = '/([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i';
109 return preg_replace_callback($emailPattern, obfuscateEmail(...), $copyright);
112 function obfuscateEmail(array $matches): string
114 return preg_replace('/[^@.]/', '*', $matches[1]);
117 function warn(string $text): void
120 $warnings[] = "WARN:" . $text;