chore: update license generation

This commit is contained in:
Krzysztof Moch
2025-04-22 13:35:46 +02:00
parent 474ad9ebed
commit 47e5a26819
4 changed files with 28806 additions and 5084 deletions
+34
View File
@@ -0,0 +1,34 @@
Custom License
License Terms
Copyright (c) 2024 TheWidlarzGroup
Scope of Use
This code is licensed for demonstration and contribution purposes only. You may view, execute, and contribute to this code solely within the designated repository (“Repository”) or an authorized fork of the Repository on GitHub for the sole purpose of contributing changes back to the Repository.
Forking and Contributions
You are permitted to create a fork of the Repository on GitHub exclusively for the purpose of contributing changes back to the original Repository.
Any fork of the Repository is subject to the same terms as this license and may not be used, distributed, or modified beyond the scope of preparing contributions to the original Repository.
All contributions to the Repository or any authorized fork are automatically licensed to the original author under the same terms as this license.
Prohibition on External Modification and Distribution
Modifying, adapting, or creating derivative works based on this code outside of the Repository or an authorized fork is strictly prohibited. Distribution of this code, in whole or in part, outside of GitHub without explicit written permission from the original author is also forbidden.
Non-Commercial Use Only, with Author Permission for Commercial Use
This code may not be used for commercial purposes. Any use of the code in a product, service, or other commercial setting is strictly prohibited unless explicit permission is granted in writing by TheWidlarzGroup.
TheWidlarzGroup reserves the right to grant commercial usage privileges at its discretion.
No Warranty
This code is provided "as is," without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the author be liable for any claim, damages, or other liability arising from or in connection with the code or the use or other dealings in the code.
Termination
Any violation of these terms will result in the immediate termination of this license.
Acceptance
By using, forking, and contributing to this code, you acknowledge that you have read and understood these terms and agree to be bound by them.
File diff suppressed because it is too large Load Diff
+2
View File
@@ -29,6 +29,8 @@
"nitrogen", "nitrogen",
"*.podspec", "*.podspec",
"react-native.config.js", "react-native.config.js",
"THIRD-PARTY-LICENSES",
"LICENSE",
"!ios/build", "!ios/build",
"!android/build", "!android/build",
"!android/gradle", "!android/gradle",
+143 -34
View File
@@ -1,17 +1,64 @@
const fs = require('fs'); import path from 'path';
const path = require('path'); import { fileURLToPath } from 'url';
// ESM replacement for __dirname
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootDir = path.join(__dirname, '..');
// Path to the package.json file & react-native-video package.json file // Path to the package.json file & react-native-video package.json file
const packageJsonPath = path.join(__dirname, 'package.json'); const packageJsonPath = path.join(rootDir, 'package.json');
const reactNativeVideoPackageJsonPath = path.join( const reactNativeVideoPackageJsonPath = path.join(
__dirname, rootDir,
'packages', 'packages',
'react-native-video', 'react-native-video',
'package.json' 'package.json'
); );
function getLicenseText(path) { // ANSI color codes
const packageJson = JSON.parse(fs.readFileSync(path, 'utf-8')); const colors = {
reset: '\x1b[0m',
cyan: '\x1b[36m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
gray: '\x1b[90m',
};
async function fetchLicenseFromGitHub(repository) {
if (!repository) return null;
let repoUrl = '';
if (typeof repository === 'string') {
repoUrl = repository;
} else if (repository.url) {
repoUrl = repository.url;
}
// Only handle GitHub URLs
const match = repoUrl.match(/github.com[:/](.+?)(?:\.git)?$/);
if (!match) return null;
const repoPath = match[1].replace(/\.git$/, '');
const branches = ['main', 'master'];
const licenseFiles = ['LICENSE', 'LICENSE.md', 'LICENSE.txt'];
for (const branch of branches) {
for (const file of licenseFiles) {
const rawUrl = `https://raw.githubusercontent.com/${repoPath}/${branch}/${file}`;
try {
const res = await fetch(rawUrl);
if (res.ok) {
const text = await res.text();
if (text && text.length > 0) {
return text;
}
}
} catch (e) {
// Ignore and try next
}
}
}
return null;
}
async function getLicenseText(pkgPath, processed = new Set(), stats = { found: 0, notFound: 0, skipped: 0, total: 0 }) {
const packageJson = JSON.parse(await Bun.file(pkgPath).text());
const dependencies = { const dependencies = {
...packageJson.dependencies, ...packageJson.dependencies,
...packageJson.devDependencies, ...packageJson.devDependencies,
@@ -19,11 +66,14 @@ function getLicenseText(path) {
const licenses = []; const licenses = [];
// Helper to create a unique key for each package
const getKey = (name, version) => `${name}@${version}`;
// Iterate through each dependency // Iterate through each dependency
for (const [packageName, version] of Object.entries(dependencies)) { for (const [packageName, versionRange] of Object.entries(dependencies)) {
try { try {
// Path to the package's directory in node_modules // Path to the package's directory in node_modules
const packagePath = path.join(__dirname, 'node_modules', packageName); const packagePath = path.join(rootDir, 'node_modules', packageName);
// Check if the package is react-native-video // Check if the package is react-native-video
if (packageName === 'react-native-video') { if (packageName === 'react-native-video') {
@@ -31,68 +81,127 @@ function getLicenseText(path) {
} }
// Check if package is at node_modules // Check if package is at node_modules
if (!fs.existsSync(packagePath)) { let depPackageJsonPath;
let depPackageJson;
try {
depPackageJsonPath = path.join(packagePath, 'package.json');
depPackageJson = JSON.parse(await Bun.file(depPackageJsonPath).text());
} catch {
console.log(`${colors.gray}└─ Skipping ${packageName}: not found in node_modules (probably dev dependency)${colors.reset}`);
stats.skipped++;
continue; continue;
} }
// Load package.json of the dependency const depVersion = depPackageJson.version;
const depPackageJsonPath = path.join(packagePath, 'package.json'); const key = getKey(packageName, depVersion);
const depPackageJson = JSON.parse( if (processed.has(key)) {
fs.readFileSync(depPackageJsonPath, 'utf-8') continue;
); }
processed.add(key);
stats.total++;
// Extract license info and version from the dependency's package.json console.log(`${colors.cyan}├─ Getting license for ${packageName}@${depVersion}${colors.reset}`);
// Extract license info from the dependency's package.json
const license = const license =
depPackageJson.license || 'License information not available'; depPackageJson.license || 'License information not available';
const depVersion = depPackageJson.version;
// Look for a LICENSE file in the dependency's directory // Look for a LICENSE file in the dependency's directory
let licenseText = 'License text not available'; let licenseText = 'License text not available';
const licenseFilePath = ['LICENSE', 'LICENSE.txt', 'LICENSE.md'] const licenseFilePath = ['LICENSE', 'LICENSE.txt', 'LICENSE.md']
.map((file) => path.join(packagePath, file)) .map((file) => path.join(packagePath, file));
.find(fs.existsSync); let foundLocal = false;
for (const filePath of licenseFilePath) {
if (licenseFilePath) { if (await Bun.file(filePath).exists()) {
licenseText = fs.readFileSync(licenseFilePath, 'utf-8'); console.log(`${colors.green}└─ Found license in local files (${path.basename(filePath)})${colors.reset}`);
licenseText = await Bun.file(filePath).text();
foundLocal = true;
stats.found++;
break;
}
}
// If not found locally, try to fetch from GitHub
if (!foundLocal && depPackageJson.repository) {
console.log(`${colors.yellow}├─ Fetching license from GitHub...${colors.reset}`);
const githubLicense = await fetchLicenseFromGitHub(depPackageJson.repository);
if (githubLicense) {
console.log(`${colors.green}└─ Found license on GitHub.${colors.reset}`);
licenseText = githubLicense;
stats.found++;
} else {
console.log(`${colors.red}└─ Could not find license on GitHub.${colors.reset}`);
stats.notFound++;
}
} else if (!foundLocal) {
console.log(`${colors.red}└─ Could not find license locally or on GitHub.${colors.reset}`);
stats.notFound++;
} }
// Add the formatted license information // Add the formatted license information
licenses.push(` licenses.push(`
### ${packageName} (${depVersion}) ### ${packageName} (${depVersion})
- **License**: ${license} - **License**: ${license}
- **Version**: ${version} - **Version**: ${depVersion}
${licenseText} ${licenseText}
`); `);
// Recursively process this dependency's dependencies
const subLicenses = await getLicenseText(depPackageJsonPath, processed, stats);
licenses.push(...subLicenses);
} catch (error) { } catch (error) {
console.error( console.error(
`Failed to retrieve license for ${packageName}: ${error.message}` `${colors.red}Failed to retrieve license for ${packageName}: ${error.message}${colors.reset}`
); );
} }
} }
return licenses;
} }
async function generateLicensesFile() { async function generateLicensesFile() {
const processed = new Set();
const stats = { found: 0, notFound: 0, skipped: 0, total: 0 };
const licenses = [ const licenses = [
getLicenseText(packageJsonPath), ...(await getLicenseText(packageJsonPath, processed, stats)),
getLicenseText(reactNativeVideoPackageJsonPath), ...(await getLicenseText(reactNativeVideoPackageJsonPath, processed, stats)),
]; ];
// Write to THIRD-PARTY-LICENSES file at ./packages/react-native-video // Write to THIRD-PARTY-LICENSES file at ./packages/react-native-video
fs.writeFileSync( await Bun.write(
path.join(__dirname, 'packages', 'react-native-video', 'THIRD-PARTY-LICENSES'), path.join(
licenses.join('\n---\n'), rootDir,
'utf-8' 'packages',
); 'react-native-video',
'THIRD-PARTY-LICENSES'
),
licenses.join('\n---\n')
);
console.log( console.log(
`THIRD-PARTY-LICENSES file generated at ${path.join(__dirname, 'packages', 'react-native-video', 'THIRD-PARTY-LICENSES')}` `THIRD-PARTY-LICENSES file generated at ${path.join(
rootDir,
'packages',
'react-native-video',
'THIRD-PARTY-LICENSES'
)}`
); );
// Copy LICENSE file to ./packages/react-native-video // Copy LICENSE file to ./packages/react-native-video
fs.copyFileSync( await Bun.write(
path.join(__dirname, 'LICENSE'), path.join(
path.join(__dirname, 'packages', 'react-native-video', 'LICENSE') rootDir,
'packages',
'react-native-video',
'LICENSE'
),
await Bun.file(path.join(rootDir, 'LICENSE')).text()
); );
// Print stats
console.log('\n' + colors.cyan + 'License Collection Stats:' + colors.reset);
console.log(`${colors.green} Found: ${stats.found}${colors.reset}`);
console.log(`${colors.red} Not found: ${stats.notFound}${colors.reset}`);
console.log(`${colors.gray} Skipped: ${stats.skipped}${colors.reset}`);
console.log(`${colors.cyan} Total unique packages: ${stats.total}${colors.reset}`);
} }
generateLicensesFile(); generateLicensesFile();