forked from kitschpatrol/shared-config
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2084e14
commit 5d1ab87
Showing
5 changed files
with
169 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,54 @@ | ||
{ | ||
"name": "@envsa/repo-config", | ||
"version": "8.2.0", | ||
"type": "module", | ||
"description": "Repository configuration and GitHub workflows for @envsa/shared-config.", | ||
"keywords": [ | ||
"shared-config", | ||
"github-actions", | ||
"cli", | ||
"envsa", | ||
"envsa-repo" | ||
], | ||
"homepage": "https://github.com/envsa/shared-config/packages/repo-config", | ||
"bugs": { | ||
"url": "https://github.com/envsa/shared-config/issues", | ||
"email": "[email protected]" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "[email protected]:envsa/shared-config.git", | ||
"directory": "packages/repo-config" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/envsa/shared-config/issues", | ||
"email": "[email protected]" | ||
}, | ||
"license": "MIT", | ||
"author": { | ||
"name": "Liam Rella", | ||
"email": "[email protected]", | ||
"url": "https://github.com/rellafella" | ||
}, | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=18.0.0", | ||
"pnpm": ">=8.0.0" | ||
}, | ||
"type": "module", | ||
"bin": { | ||
"repo-config": "bin/cli.js" | ||
"envsa-repo": "bin/cli.js" | ||
}, | ||
"files": [ | ||
"bin/*", | ||
"init/*" | ||
], | ||
"keywords": [ | ||
"shared-config", | ||
"github-actions", | ||
"cli" | ||
], | ||
"scripts": { | ||
"build": "../../scripts/build.ts && mdat readme", | ||
"build": "../../scripts/build.ts", | ||
"cli": "node ./bin/cli.js", | ||
"prepublishOnly": "pnpm run build" | ||
}, | ||
"dependencies": { | ||
"@pinojs/json-colorizer": "^4.0.0", | ||
"cosmiconfig": "^9.0.0", | ||
"execa": "^9.5.2", | ||
"fs-extra": "^11.2.0" | ||
"find-workspaces": "^0.3.1", | ||
"fs-extra": "^11.2.0", | ||
"prettier": "^3.5.1" | ||
}, | ||
"engines": { | ||
"node": ">=22.0.0", | ||
"pnpm": ">=10.0.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,5 @@ | ||
#!/usr/bin/env node | ||
import { buildCommands } from '$root/src/command-builder.ts'; | ||
import fse from 'fs-extra'; | ||
import path from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import { packageUp } from 'package-up'; | ||
import { buildCommands } from '../../../src/command-builder.js'; | ||
import { commandDefinition } from './command.js'; | ||
|
||
await buildCommands('repo-config', '[Repo Config]', 'gray', { | ||
init: {}, | ||
printConfig: { | ||
async command(logStream) { | ||
const destinationPackage = await packageUp(); | ||
if (destinationPackage === undefined) { | ||
logStream.write( | ||
'Error: The `--print-config` flag must be used in a directory with a package.json file somewhere above it\n', | ||
); | ||
return 1; | ||
} | ||
|
||
const sourcePackage = await packageUp({ cwd: fileURLToPath(import.meta.url) }); | ||
if (sourcePackage === undefined) { | ||
logStream.write('Error: The script being called was not in a package, weird.\n'); | ||
return 1; | ||
} | ||
|
||
const sourceDirectory = path.join(path.dirname(sourcePackage), 'init/'); | ||
const destinationDirectory = path.dirname(destinationPackage); | ||
|
||
let exitCode = 0; | ||
|
||
for (const file of await fse.readdir(sourceDirectory)) { | ||
const destinationPath = path.join(destinationDirectory, file); | ||
|
||
// Merge with existing, if present | ||
if (await fse.exists(destinationPath)) { | ||
const fileContent = await fse.readFile(destinationPath, 'utf8'); | ||
logStream.write(`💾 Contents of "${file}":\n`); | ||
logStream.write(fileContent); | ||
logStream.write('\n'); | ||
} else { | ||
logStream.write(`Error: Could not find ${file}\n`); | ||
exitCode = 1; | ||
} | ||
} | ||
|
||
return exitCode; | ||
}, | ||
}, | ||
}); | ||
await buildCommands(commandDefinition); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { type CommandDefinition, DESCRIPTION } from '../../../src/command-builder.js'; | ||
import { copyrightYearFixerCommand, copyrightYearLinterCommand } from './copyright-year-updater.js'; | ||
|
||
export const commandDefinition: CommandDefinition = { | ||
commands: { | ||
fix: { | ||
commands: [ | ||
{ | ||
execute: copyrightYearFixerCommand, | ||
name: copyrightYearLinterCommand.name, | ||
}, | ||
], | ||
description: `Fix common issues like outdated copyright years in license files. ${DESCRIPTION.packageRun} ${DESCRIPTION.monorepoRun}`, | ||
positionalArgumentMode: 'none', | ||
}, | ||
init: { | ||
locationOptionFlag: false, | ||
}, | ||
lint: { | ||
commands: [ | ||
{ | ||
execute: copyrightYearLinterCommand, | ||
name: copyrightYearFixerCommand.name, | ||
}, | ||
], | ||
description: `Check the repo for common issues. ${DESCRIPTION.packageRun} ${DESCRIPTION.monorepoRun}`, | ||
positionalArgumentMode: 'none', | ||
}, | ||
}, | ||
description: "Envsa's repository-related shared configuration tools.", | ||
logColor: 'gray', | ||
logPrefix: '[Repo Config]', | ||
name: 'envsa-repo', | ||
order: 1, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import fs from 'node:fs/promises'; | ||
import { restoreNodeWarnings, suppressNodeWarnings } from '../../../src/node-utils'; | ||
import { getPackageDirectory } from '../../../src/path-utils'; | ||
import { pluralize } from '../../../src/string-utils'; | ||
|
||
function updateLicenseContent(content: string, currentYear: number): string { | ||
// Match a four-digit range with optional spaces around the dash. | ||
const rangeRegex = /(\d{4})\s*-\s*(\d{4})/; | ||
const rangeMatch = rangeRegex.exec(content); | ||
|
||
if (rangeMatch) { | ||
const [, startYear, endYear] = rangeMatch; | ||
if (Number.parseInt(endYear, 10) !== currentYear) { | ||
const newRange = `${startYear}-${currentYear}`; | ||
return content.replace(rangeRegex, newRange); | ||
} | ||
return content; | ||
} | ||
|
||
// If no range was found, try matching a single four-digit year. | ||
const singleYearRegex = /(\d{4})/; | ||
const singleMatch = singleYearRegex.exec(content); | ||
if (singleMatch) { | ||
const [, year] = singleMatch; | ||
if (Number.parseInt(year, 10) !== currentYear) { | ||
const newRange = `${year}-${currentYear}`; | ||
return content.replace(singleYearRegex, newRange); | ||
} | ||
return content; | ||
} | ||
|
||
// Return original content if no year was found. | ||
return content; | ||
} | ||
|
||
async function copyrightYear(logStream: NodeJS.WritableStream, fix = false): Promise<number> { | ||
const currentYear = new Date().getFullYear(); | ||
const licenseFiles: string[] = []; | ||
|
||
// Use multiple glob patterns to cover different casings for "license.txt" | ||
const patterns = [ | ||
'**/license.txt', | ||
'**/LICENSE.txt', | ||
'**/License.txt', | ||
'**/LICENSE', | ||
'!node_modules/**', | ||
]; | ||
|
||
suppressNodeWarnings(); | ||
for await (const filePath of fs.glob(patterns, { | ||
cwd: getPackageDirectory(), // Will find monorepo packages | ||
withFileTypes: false, | ||
})) { | ||
licenseFiles.push(filePath); | ||
} | ||
restoreNodeWarnings(); | ||
|
||
const outdatedLicenseFiles: string[] = []; | ||
|
||
for (const filePath of licenseFiles) { | ||
try { | ||
const originalContent = await fs.readFile(filePath, 'utf8'); | ||
const updatedContent = updateLicenseContent(originalContent, currentYear); | ||
|
||
if (updatedContent !== originalContent) { | ||
outdatedLicenseFiles.push(filePath); | ||
if (fix) { | ||
await fs.writeFile(filePath, updatedContent, 'utf8'); | ||
} | ||
} | ||
} catch (error) { | ||
console.error(`Failed to process ${filePath}:`, error); | ||
} | ||
} | ||
|
||
if (outdatedLicenseFiles.length > 0) { | ||
logStream.write( | ||
`${fix ? 'Fixed' : 'Found'} ${outdatedLicenseFiles.length} license ${pluralize('file', outdatedLicenseFiles.length)} with outdated copyright year:\n`, | ||
); | ||
for (const outdatedLicenseFile of outdatedLicenseFiles) { | ||
logStream.write(` - ${outdatedLicenseFile}\n`); | ||
} | ||
|
||
return fix ? 0 : 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* Linter for the year in license files. | ||
*/ | ||
export async function copyrightYearLinterCommand(logStream: NodeJS.WritableStream) { | ||
return copyrightYear(logStream, false); | ||
} | ||
|
||
/** | ||
* Fixer for the year in license files. | ||
*/ | ||
export async function copyrightYearFixerCommand(logStream: NodeJS.WritableStream) { | ||
return copyrightYear(logStream, true); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.