mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 07:08:10 -05:00
* feat: add mock document generator demo * feat: add mock document generator * fixes * chore: refresh workflow cache * update lock * build * updates * more fixes * code rabbit feedback * compiles * save wip * updates * merge with dev and fixes * fix: align hoisting and demo Jest resolver (#1003) * chore(app): map common src paths and declare svg flag module * ci fix * update lock * save wip * chore: address yarn lock issues (#1004) * address yarn lock issues * fix postinstall * fix ci * use metro js proxy * android build working for /app * save wip * fix merge * pipeline fixes * format * fix pipelines * bump limit and split * fix pipeline issues * chore: decouple demo app build (#1013) * chore: decouple demo app build * chore: move demo app to workspace * chore: unpublish demo workspace * fix mobile sdk tests * updates * remove polyfills * update merge * update resolutions * update resolutions * fix merge * fix paths * save wip * save wip fixes rd2 * working android * update lock * save wip ios building * fix merge * readd public key * fixes * ci fixes * fixes * fix web building * fix ci * fix tests * update lock * fix ci rd2 * formatting and fix ci * fix * finalize ci fixes * fix tests and metro config paths for building * save wip * install missing package for pipeline * fix wip app building * wip react config * save working emulator compile * first round of pr fixes and feedback * clean up demo app artifacts from sdk * Add Gradle wrapper files for mobile-sdk-demo Android build - Added gradlew, gradlew.bat, and gradle/wrapper/ directory - Updated .gitignore to allow committing Gradle wrapper files - Fixes Android build error: spawn ./gradlew ENOENT * codex feedback and fixes * fix tests * file renames * revert back to dev * add types * coderabbit fixes * fix tests * fix tests * fix test * fixes * fix wip coderabbit issues * coderabbit suggestions rd 2 * fix ci pipelines and addresss warnings * cr fixes * convert kebab to camelCase * save wip fixes * update reinstall and lock files * fixes * remove file * fix lint * fix polyfill fallback issues * ensure that mock document is not on ofac list * prettier
245 lines
6.4 KiB
JavaScript
245 lines
6.4 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
|
|
|
/**
|
|
* Script to check and fix license header formatting
|
|
* Ensures there's a newline after license headers
|
|
*/
|
|
|
|
import { readdirSync, statSync, readFileSync, writeFileSync } from 'fs';
|
|
import path from 'path';
|
|
|
|
// Legacy composite format (being phased out)
|
|
const LEGACY_HEADER =
|
|
'// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11';
|
|
|
|
// Canonical multi-line format (preferred)
|
|
const CANONICAL_HEADER_LINES = [
|
|
'// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.',
|
|
'// SPDX-License-Identifier: BUSL-1.1',
|
|
'// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.',
|
|
];
|
|
|
|
function findFiles(
|
|
dir,
|
|
extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],
|
|
) {
|
|
const files = [];
|
|
|
|
function traverse(currentDir) {
|
|
const items = readdirSync(currentDir);
|
|
|
|
for (const item of items) {
|
|
const fullPath = path.join(currentDir, item);
|
|
const stat = statSync(fullPath);
|
|
|
|
if (stat.isDirectory()) {
|
|
// Skip node_modules, .git, and other common directories
|
|
if (
|
|
![
|
|
'node_modules',
|
|
'.git',
|
|
'dist',
|
|
'build',
|
|
'coverage',
|
|
'ios',
|
|
'android',
|
|
'.next',
|
|
'.turbo',
|
|
'.tamagui',
|
|
].includes(item)
|
|
) {
|
|
traverse(fullPath);
|
|
}
|
|
} else if (extensions.some(ext => item.endsWith(ext))) {
|
|
files.push(fullPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
traverse(dir);
|
|
return files;
|
|
}
|
|
|
|
function findLicenseHeaderIndex(lines) {
|
|
let i = 0;
|
|
// Skip shebang if present
|
|
if (lines[i]?.startsWith('#!')) i++;
|
|
// Skip leading blank lines
|
|
while (i < lines.length && lines[i].trim() === '') i++;
|
|
|
|
const currentLine = lines[i];
|
|
|
|
// Check for legacy composite format
|
|
if (currentLine === LEGACY_HEADER) {
|
|
return { index: i, type: 'legacy', valid: true, endIndex: i };
|
|
}
|
|
|
|
// Check for canonical multi-line format
|
|
if (currentLine === CANONICAL_HEADER_LINES[0]) {
|
|
const hasAllLines =
|
|
lines[i + 1] === CANONICAL_HEADER_LINES[1] &&
|
|
lines[i + 2] === CANONICAL_HEADER_LINES[2];
|
|
return {
|
|
index: i,
|
|
type: 'canonical',
|
|
valid: hasAllLines,
|
|
endIndex: hasAllLines ? i + 2 : i,
|
|
};
|
|
}
|
|
|
|
return { index: -1, type: 'none', valid: false };
|
|
}
|
|
|
|
function shouldRequireHeader(filePath, projectRoot) {
|
|
const relativePath = path.relative(projectRoot, filePath);
|
|
// Only require headers in app/ and packages/mobile-sdk-alpha/ directories
|
|
return (
|
|
relativePath.startsWith('app/') ||
|
|
relativePath.startsWith('packages/mobile-sdk-alpha/')
|
|
);
|
|
}
|
|
|
|
function checkLicenseHeader(
|
|
filePath,
|
|
{ requireHeader = false, projectRoot = process.cwd() } = {},
|
|
) {
|
|
const content = readFileSync(filePath, 'utf8');
|
|
const lines = content.split('\n');
|
|
const headerInfo = findLicenseHeaderIndex(lines);
|
|
|
|
const shouldHaveHeader =
|
|
requireHeader || shouldRequireHeader(filePath, projectRoot);
|
|
|
|
if (headerInfo.index === -1) {
|
|
if (shouldHaveHeader) {
|
|
return {
|
|
file: filePath,
|
|
issue: 'Missing or incorrect license header',
|
|
fixed: false,
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (!headerInfo.valid) {
|
|
return {
|
|
file: filePath,
|
|
issue: 'Incomplete or malformed license header',
|
|
fixed: false,
|
|
};
|
|
}
|
|
|
|
// Check if there's a newline after the license header
|
|
const headerEndIndex = headerInfo.endIndex;
|
|
if (lines[headerEndIndex + 1] !== '') {
|
|
return {
|
|
file: filePath,
|
|
issue: 'Missing newline after license header',
|
|
fixed: false,
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function fixLicenseHeader(filePath) {
|
|
const content = readFileSync(filePath, 'utf8');
|
|
const lines = content.split('\n');
|
|
const headerInfo = findLicenseHeaderIndex(lines);
|
|
|
|
if (headerInfo.index === -1) {
|
|
// No header exists - add the canonical header
|
|
const newLines = [
|
|
...CANONICAL_HEADER_LINES,
|
|
'', // Add newline after header
|
|
...lines,
|
|
];
|
|
const fixedContent = newLines.join('\n');
|
|
writeFileSync(filePath, fixedContent, 'utf8');
|
|
return true;
|
|
}
|
|
|
|
if (headerInfo.valid) {
|
|
const headerEndIndex = headerInfo.endIndex;
|
|
if (lines[headerEndIndex + 1] !== '') {
|
|
// Insert empty line after license header
|
|
lines.splice(headerEndIndex + 1, 0, '');
|
|
const fixedContent = lines.join('\n');
|
|
writeFileSync(filePath, fixedContent, 'utf8');
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function main() {
|
|
const args = process.argv.slice(2);
|
|
const isFix = args.includes('--fix');
|
|
const isCheck = args.includes('--check') || !isFix;
|
|
const requireHeader = args.includes('--require');
|
|
|
|
// Get all directory arguments (non-flag arguments)
|
|
const dirArgs = args.filter(arg => !arg.startsWith('--'));
|
|
const projectRoots =
|
|
dirArgs.length > 0
|
|
? dirArgs.map(dir => path.resolve(dir))
|
|
: [process.cwd()];
|
|
|
|
// Collect files from all directories
|
|
const files = [];
|
|
for (const projectRoot of projectRoots) {
|
|
files.push(...findFiles(projectRoot));
|
|
}
|
|
|
|
const issues = [];
|
|
|
|
for (const file of files) {
|
|
const issue = checkLicenseHeader(file, {
|
|
requireHeader,
|
|
projectRoot: process.cwd(),
|
|
});
|
|
if (issue) {
|
|
issues.push(issue);
|
|
|
|
if (isFix) {
|
|
const fixed = fixLicenseHeader(file);
|
|
if (fixed) {
|
|
issue.fixed = true;
|
|
console.log(`✅ Fixed: ${file}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isCheck) {
|
|
// Show which directories require headers
|
|
const requiredDirs = ['app/', 'packages/mobile-sdk-alpha/'];
|
|
console.log(`📋 License headers required in: ${requiredDirs.join(', ')}`);
|
|
|
|
if (issues.length === 0) {
|
|
console.log('✅ All license headers are properly formatted');
|
|
} else {
|
|
console.log(
|
|
`❌ Found ${issues.length} files with license header issues:`,
|
|
);
|
|
for (const issue of issues) {
|
|
console.log(` - ${issue.file}: ${issue.issue}`);
|
|
}
|
|
console.log('\nRun with --fix to automatically fix these issues');
|
|
process.exit(1);
|
|
}
|
|
} else if (isFix) {
|
|
const fixedCount = issues.filter(issue => issue.fixed).length;
|
|
console.log(`\n✅ Fixed ${fixedCount} files`);
|
|
}
|
|
}
|
|
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
main();
|
|
}
|