@eclipse-glsp/cli
Advanced tools
Comparing version 1.1.0-next.28fb493.121 to 1.1.0-next.2fda3cf.122
@@ -5,5 +5,5 @@ export interface HeaderCheckOptions { | ||
fileExtensions: string[]; | ||
headerPattern: string; | ||
json: boolean; | ||
excludeDefaults: boolean; | ||
autoFix: boolean; | ||
severity: Severity; | ||
@@ -17,3 +17,3 @@ } | ||
export declare function checkHeaders(rootDir: string, options: HeaderCheckOptions): void; | ||
export declare function displayValidationResult(rootDir: string, results: ValidationResult[], options: HeaderCheckOptions): void; | ||
export declare function handleValidationResults(rootDir: string, results: ValidationResult[], options: HeaderCheckOptions): void; | ||
interface ValidationResult { | ||
@@ -20,0 +20,0 @@ file: string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.displayValidationResult = exports.checkHeaders = exports.CheckHeaderCommand = void 0; | ||
exports.handleValidationResults = exports.checkHeaders = exports.CheckHeaderCommand = void 0; | ||
/******************************************************************************** | ||
* Copyright (c) 2022 EclipseSource and others. | ||
* Copyright (c) 2022-2023 EclipseSource and others. | ||
* | ||
@@ -24,2 +24,3 @@ * This program and the accompanying materials are made available under the | ||
const minimatch = require("minimatch"); | ||
const readline = require("readline-sync"); | ||
const sh = require("shelljs"); | ||
@@ -35,2 +36,4 @@ const command_util_1 = require("../util/command-util"); | ||
const YEAR_RANGE_REGEX = /\d{4}(?:-d{4})?/g; | ||
const HEADER_PATTERN = 'Copyright \\([cC]\\) \\d{4}(-d{4})?'; | ||
const AUTO_FIX_MESSAGE = 'Fix copyright header violations'; | ||
exports.CheckHeaderCommand = (0, command_util_1.baseCommand)() // | ||
@@ -47,3 +50,2 @@ .name('checkHeaders') | ||
.option('--no-exclude-defaults', 'Disables the default excludes patterns. Only explicitly passed exclude patterns (-e, --exclude) are considered') | ||
.option('-p, --headerPattern <pattern>', 'Regex pattern to extract the copyright year (range) from the header', 'Copyright \\([cC]\\) \\d{4}(-d{4})?') | ||
.option('-j, --json', 'Also persist validation results as json file', false) | ||
@@ -53,2 +55,3 @@ .addOption(new commander_1.Option('-s, --severity <severity>', 'The severity of validation results that should be printed.') | ||
.default('error', '"error" (only)')) | ||
.option('-a, --autoFix', 'Auto apply & commit fixes without prompting the user', false) | ||
.action(checkHeaders); | ||
@@ -67,4 +70,4 @@ function checkHeaders(rootDir, options) { | ||
} | ||
const result = validate(rootDir, files, options); | ||
displayValidationResult(rootDir, result, options); | ||
const results = validate(rootDir, files, options); | ||
handleValidationResults(rootDir, results, options); | ||
} | ||
@@ -91,5 +94,5 @@ exports.checkHeaders = checkHeaders; | ||
// Derives all files with valid headers, their copyright years and all files with no or invalid headers | ||
const filesWithHeader = sh.grep('-l', options.headerPattern, files).stdout.trim().split('\n'); | ||
const filesWithHeader = sh.grep('-l', HEADER_PATTERN, files).stdout.trim().split('\n'); | ||
const copyrightYears = sh | ||
.grep(options.headerPattern, files) | ||
.grep(HEADER_PATTERN, files) | ||
.stdout.trim() | ||
@@ -107,3 +110,3 @@ .split('\n') | ||
noHeaders.forEach((file, i) => { | ||
printValidationProgress(i + 1, allFilesLength, file); | ||
printFileProgress(i + 1, allFilesLength, `Validating ${file}`); | ||
results.push({ file: path.resolve(rootDir, file), violation: 'noOrMissingHeader', severity: 'error' }); | ||
@@ -121,8 +124,8 @@ }); | ||
filesWithHeader.forEach((file, i) => { | ||
printValidationProgress(i + 1 + noHeadersLength, allFilesLength, file); | ||
printFileProgress(i + 1 + noHeadersLength, allFilesLength, `Validating ${file}`); | ||
const result = { | ||
currentStartYear: copyrightYears[i].shift(), | ||
expectedStartYear: (0, git_util_1.getFirstModificationDate)(file).getFullYear(), | ||
expectedStartYear: (0, git_util_1.getFirstModificationDate)(file, rootDir, AUTO_FIX_MESSAGE).getFullYear(), | ||
currentEndYear: copyrightYears[i].shift(), | ||
expectedEndYear: defaultEndYear !== null && defaultEndYear !== void 0 ? defaultEndYear : (0, git_util_1.getLastModificationDate)(file).getFullYear(), | ||
expectedEndYear: defaultEndYear !== null && defaultEndYear !== void 0 ? defaultEndYear : (0, git_util_1.getLastModificationDate)(file, rootDir, AUTO_FIX_MESSAGE).getFullYear(), | ||
file, | ||
@@ -192,13 +195,16 @@ severity: 'ok', | ||
} | ||
function printValidationProgress(currentFileCount, maxFileCount, file) { | ||
process.stdout.clearLine(0); | ||
process.stdout.cursorTo(0); | ||
process.stdout.write(`[${currentFileCount} of ${maxFileCount}] Validating ${file}`); | ||
function printFileProgress(currentFileCount, maxFileCount, message, clear = true) { | ||
if (clear) { | ||
process.stdout.clearLine(0); | ||
process.stdout.cursorTo(0); | ||
} | ||
process.stdout.write(`[${currentFileCount} of ${maxFileCount}] ${message}`); | ||
if (!clear) { | ||
process.stdout.write('\n'); | ||
} | ||
} | ||
function displayValidationResult(rootDir, results, options) { | ||
function handleValidationResults(rootDir, results, options) { | ||
logger_1.LOGGER.newLine(); | ||
logger_1.LOGGER.info(`Header validation for ${results.length} files completed`); | ||
const violations = results.filter(result => result.severity === 'error'); | ||
logger_1.LOGGER.info(`Found ${violations.length} copyright header violations:`); | ||
logger_1.LOGGER.newLine(); | ||
// Adjust results to print based on configured severity level | ||
@@ -212,2 +218,4 @@ let toPrint = results; | ||
} | ||
logger_1.LOGGER.info(`Found ${toPrint.length} copyright header violations:`); | ||
logger_1.LOGGER.newLine(); | ||
toPrint.forEach((result, i) => logger_1.LOGGER.info(`${i + 1}. `, result.file, ':', toPrintMessage(result))); | ||
@@ -218,5 +226,9 @@ logger_1.LOGGER.newLine(); | ||
} | ||
if (violations.length > 0 && (options.autoFix || readline.keyInYN('Do you want automatically fix copyright year range violations?'))) { | ||
const toFix = violations.filter(violation => violation.severity === 'error' && isDateValidationResult(violation)); | ||
fixViolations(rootDir, toFix, options); | ||
} | ||
logger_1.LOGGER.info('Check completed'); | ||
} | ||
exports.displayValidationResult = displayValidationResult; | ||
exports.handleValidationResults = handleValidationResults; | ||
function toPrintMessage(result) { | ||
@@ -242,2 +254,23 @@ const colors = { | ||
} | ||
function fixViolations(rootDir, violations, options) { | ||
logger_1.LOGGER.newLine(); | ||
violations.forEach((violation, i) => { | ||
printFileProgress(i + 1, violations.length, `Fix ${violation.file}`, false); | ||
const fixedStartYear = violation.currentStartYear < violation.expectedStartYear ? violation.currentStartYear : violation.expectedStartYear; | ||
const currentRange = `${violation.currentStartYear}${violation.currentEndYear ? '-' + violation.currentEndYear : ''}`; | ||
let fixedRange = `${fixedStartYear}`; | ||
if (violation.expectedEndYear !== violation.expectedStartYear || fixedStartYear !== violation.expectedStartYear) { | ||
fixedRange = `${fixedStartYear}-${violation.expectedEndYear}`; | ||
} | ||
sh.sed('-i', RegExp('Copyright \\([cC]\\) ' + currentRange), `Copyright (c) ${fixedRange}`, violation.file); | ||
}); | ||
logger_1.LOGGER.newLine(); | ||
if (options.autoFix || readline.keyInYN('Do you want to create a commit for the fixed files?')) { | ||
logger_1.LOGGER.newLine(); | ||
const files = violations.map(violation => violation.file).join(' '); | ||
sh.exec(`git add ${files}`, (0, command_util_1.getShellConfig)()); | ||
sh.exec(`git commit -m "${AUTO_FIX_MESSAGE}"`); | ||
logger_1.LOGGER.newLine(); | ||
} | ||
} | ||
function isDateValidationResult(object) { | ||
@@ -244,0 +277,0 @@ return 'currentStartYear' in object && 'expectedStartYear' in object && 'expectedEndYear' in object; |
/******************************************************************************** | ||
* Copyright (c) 2022 EclipseSource and others. | ||
* Copyright (c) 2022-2022 EclipseSource and others. | ||
* | ||
@@ -33,5 +33,6 @@ * This program and the accompanying materials are made available under the | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
export declare function getLastModificationDate(filePath?: string, repoRoot?: string): Date | undefined; | ||
export declare function getLastModificationDate(filePath?: string, repoRoot?: string, excludeMessage?: string): Date | undefined; | ||
/** | ||
@@ -41,5 +42,6 @@ * Returns the last modification date of a file in a git repo. | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
export declare function getFirstModificationDate(filePath: string, repoRoot?: string): Date | undefined; | ||
export declare function getFirstModificationDate(filePath: string, repoRoot?: string, excludeMessage?: string): Date | undefined; | ||
export declare function getFilesOfCommit(commitHash: string, repoRoot?: string): string[]; | ||
@@ -46,0 +48,0 @@ /** |
"use strict"; | ||
/******************************************************************************** | ||
* Copyright (c) 2022 EclipseSource and others. | ||
* Copyright (c) 2022-2022 EclipseSource and others. | ||
* | ||
@@ -73,7 +73,9 @@ * This program and the accompanying materials are made available under the | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
function getLastModificationDate(filePath, repoRoot) { | ||
function getLastModificationDate(filePath, repoRoot, excludeMessage) { | ||
cdIfPresent(repoRoot); | ||
const result = sh.exec(`git log -1 --pretty="format:%ci" ${filePath !== null && filePath !== void 0 ? filePath : ''}`, (0, command_util_1.getShellConfig)()); | ||
const additionalArgs = excludeMessage ? `--grep="${excludeMessage}" --invert-grep` : ''; | ||
const result = sh.exec(`git log -1 ${additionalArgs} --pretty="format:%ci" ${filePath !== null && filePath !== void 0 ? filePath : ''}`, (0, command_util_1.getShellConfig)()); | ||
if (result.code !== 0) { | ||
@@ -89,7 +91,9 @@ return undefined; | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
function getFirstModificationDate(filePath, repoRoot) { | ||
function getFirstModificationDate(filePath, repoRoot, excludeMessage) { | ||
cdIfPresent(repoRoot); | ||
const result = sh.exec(`git log --pretty="format:%ci" --follow ${filePath}`, (0, command_util_1.getShellConfig)()); | ||
const additionalArgs = excludeMessage ? `--grep="${excludeMessage}" --invert-grep` : ''; | ||
const result = sh.exec(`git log ${additionalArgs} --pretty="format:%ci" --follow ${filePath}`, (0, command_util_1.getShellConfig)()); | ||
if (result.code !== 0) { | ||
@@ -96,0 +100,0 @@ return undefined; |
{ | ||
"name": "@eclipse-glsp/cli", | ||
"version": "1.1.0-next.28fb493.121+28fb493", | ||
"version": "1.1.0-next.2fda3cf.122+2fda3cf", | ||
"description": "CLI Tooling & scripts for GLSP components", | ||
@@ -52,3 +52,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"@eclipse-glsp/config": "1.1.0-next.28fb493.121+28fb493", | ||
"@eclipse-glsp/config": "1.1.0-next.2fda3cf.122+2fda3cf", | ||
"@types/glob": "^8.0.0", | ||
@@ -64,3 +64,3 @@ "@types/node-fetch": "2.6.2", | ||
}, | ||
"gitHead": "28fb4937509ef26d95a20996b342a8344f116238" | ||
"gitHead": "2fda3cf3b1e1c2dc1665f692efd5f50239b3da4b" | ||
} |
@@ -18,3 +18,3 @@ # Eclipse GLSP - CLI | ||
It checks for each file (matching the include pattern) whether the defined copyright range is in line with the first and last modification date in the git repository. | ||
Found violations are printed to the console. | ||
Found violations are printed to the console and can be fixed automatically. | ||
The validation check can be restricted to pending changes and/or the last commit e.g. to validate a commit before creating a PR. | ||
@@ -33,10 +33,10 @@ | ||
Options: | ||
-t, --type <type> The scope of the check. In addition to a full recursive check, is also possible to only consider pending changes or the last commit (choices: "full", "changes", "lastCommit", | ||
default: "full") | ||
-t, --type <type> The scope of the check. In addition to a full recursive check, is also possible to only consider pending changes or the last commit (choices: "full", "changes", "lastCommit", default: | ||
"full") | ||
-f, --fileExtensions <extensions...> File extensions that should be checked (default: ["ts","tsx"]) | ||
-e, --exclude <exclude...> File patterns that should be excluded from the check. New exclude patterns are added to the default patterns (default: [**/@(node_modules|lib|dist|bundle)/**]) | ||
--no-exclude-defaults Disables the default excludes patterns. Only explicitly passed exclude patterns (-e, --exclude) are considered | ||
-p, --headerPattern <pattern> Regex pattern to extract the copyright year (range) from the header (default: "Copyright \\([cC]\\) \\d{4}(-d{4})?") | ||
-j, --json Also persist validation results as json file (default: false) | ||
-s, --severity <severity> The severity of validation results that should be printed. (choices: "error", "warn", "ok", default: "error" (only)) | ||
-a, --autoFix Auto apply & commit fixes without prompting the user (default: false) | ||
-h, --help display help for command | ||
@@ -43,0 +43,0 @@ ``` |
/******************************************************************************** | ||
* Copyright (c) 2022 EclipseSource and others. | ||
* Copyright (c) 2022-2023 EclipseSource and others. | ||
* | ||
@@ -21,4 +21,5 @@ * This program and the accompanying materials are made available under the | ||
import * as minimatch from 'minimatch'; | ||
import * as readline from 'readline-sync'; | ||
import * as sh from 'shelljs'; | ||
import { baseCommand, configureShell } from '../util/command-util'; | ||
import { baseCommand, configureShell, getShellConfig } from '../util/command-util'; | ||
import { | ||
@@ -32,2 +33,3 @@ getChangesOfLastCommit, | ||
} from '../util/git-util'; | ||
import { LOGGER } from '../util/logger'; | ||
@@ -40,5 +42,5 @@ import { validateGitDirectory } from '../util/validation-util'; | ||
fileExtensions: string[]; | ||
headerPattern: string; | ||
json: boolean; | ||
excludeDefaults: boolean; | ||
autoFix: boolean; | ||
severity: Severity; | ||
@@ -56,2 +58,4 @@ } | ||
const YEAR_RANGE_REGEX = /\d{4}(?:-d{4})?/g; | ||
const HEADER_PATTERN = 'Copyright \\([cC]\\) \\d{4}(-d{4})?'; | ||
const AUTO_FIX_MESSAGE = 'Fix copyright header violations'; | ||
@@ -82,7 +86,2 @@ export const CheckHeaderCommand = baseCommand() // | ||
) | ||
.option( | ||
'-p, --headerPattern <pattern>', | ||
'Regex pattern to extract the copyright year (range) from the header', | ||
'Copyright \\([cC]\\) \\d{4}(-d{4})?' | ||
) | ||
.option('-j, --json', 'Also persist validation results as json file', false) | ||
@@ -94,2 +93,3 @@ .addOption( | ||
) | ||
.option('-a, --autoFix', 'Auto apply & commit fixes without prompting the user', false) | ||
.action(checkHeaders); | ||
@@ -111,4 +111,4 @@ | ||
} | ||
const result = validate(rootDir, files, options); | ||
displayValidationResult(rootDir, result, options); | ||
const results = validate(rootDir, files, options); | ||
handleValidationResults(rootDir, results, options); | ||
} | ||
@@ -138,5 +138,5 @@ | ||
// Derives all files with valid headers, their copyright years and all files with no or invalid headers | ||
const filesWithHeader = sh.grep('-l', options.headerPattern, files).stdout.trim().split('\n'); | ||
const filesWithHeader = sh.grep('-l', HEADER_PATTERN, files).stdout.trim().split('\n'); | ||
const copyrightYears = sh | ||
.grep(options.headerPattern, files) | ||
.grep(HEADER_PATTERN, files) | ||
.stdout.trim() | ||
@@ -157,3 +157,3 @@ .split('\n') | ||
noHeaders.forEach((file, i) => { | ||
printValidationProgress(i + 1, allFilesLength, file); | ||
printFileProgress(i + 1, allFilesLength, `Validating ${file}`); | ||
results.push({ file: path.resolve(rootDir, file), violation: 'noOrMissingHeader', severity: 'error' }); | ||
@@ -172,9 +172,9 @@ }); | ||
filesWithHeader.forEach((file, i) => { | ||
printValidationProgress(i + 1 + noHeadersLength, allFilesLength, file); | ||
printFileProgress(i + 1 + noHeadersLength, allFilesLength, `Validating ${file}`); | ||
const result: DateValidationResult = { | ||
currentStartYear: copyrightYears[i].shift()!, | ||
expectedStartYear: getFirstModificationDate(file)!.getFullYear(), | ||
expectedStartYear: getFirstModificationDate(file, rootDir, AUTO_FIX_MESSAGE)!.getFullYear(), | ||
currentEndYear: copyrightYears[i].shift(), | ||
expectedEndYear: defaultEndYear ?? getLastModificationDate(file)!.getFullYear(), | ||
expectedEndYear: defaultEndYear ?? getLastModificationDate(file, rootDir, AUTO_FIX_MESSAGE)!.getFullYear(), | ||
file, | ||
@@ -252,15 +252,17 @@ severity: 'ok', | ||
function printValidationProgress(currentFileCount: number, maxFileCount: number, file: string): void { | ||
process.stdout.clearLine(0); | ||
process.stdout.cursorTo(0); | ||
process.stdout.write(`[${currentFileCount} of ${maxFileCount}] Validating ${file}`); | ||
function printFileProgress(currentFileCount: number, maxFileCount: number, message: string, clear = true): void { | ||
if (clear) { | ||
process.stdout.clearLine(0); | ||
process.stdout.cursorTo(0); | ||
} | ||
process.stdout.write(`[${currentFileCount} of ${maxFileCount}] ${message}`); | ||
if (!clear) { | ||
process.stdout.write('\n'); | ||
} | ||
} | ||
export function displayValidationResult(rootDir: string, results: ValidationResult[], options: HeaderCheckOptions): void { | ||
export function handleValidationResults(rootDir: string, results: ValidationResult[], options: HeaderCheckOptions): void { | ||
LOGGER.newLine(); | ||
LOGGER.info(`Header validation for ${results.length} files completed`); | ||
const violations = results.filter(result => result.severity === 'error'); | ||
LOGGER.info(`Found ${violations.length} copyright header violations:`); | ||
LOGGER.newLine(); | ||
// Adjust results to print based on configured severity level | ||
@@ -273,2 +275,6 @@ let toPrint = results; | ||
} | ||
LOGGER.info(`Found ${toPrint.length} copyright header violations:`); | ||
LOGGER.newLine(); | ||
toPrint.forEach((result, i) => LOGGER.info(`${i + 1}. `, result.file, ':', toPrintMessage(result))); | ||
@@ -281,2 +287,10 @@ | ||
} | ||
if (violations.length > 0 && (options.autoFix || readline.keyInYN('Do you want automatically fix copyright year range violations?'))) { | ||
const toFix = violations.filter( | ||
violation => violation.severity === 'error' && isDateValidationResult(violation) | ||
) as DateValidationResult[]; | ||
fixViolations(rootDir, toFix, options); | ||
} | ||
LOGGER.info('Check completed'); | ||
@@ -310,2 +324,28 @@ } | ||
function fixViolations(rootDir: string, violations: DateValidationResult[], options: HeaderCheckOptions): void { | ||
LOGGER.newLine(); | ||
violations.forEach((violation, i) => { | ||
printFileProgress(i + 1, violations.length, `Fix ${violation.file}`, false); | ||
const fixedStartYear = | ||
violation.currentStartYear < violation.expectedStartYear ? violation.currentStartYear : violation.expectedStartYear; | ||
const currentRange = `${violation.currentStartYear}${violation.currentEndYear ? '-' + violation.currentEndYear : ''}`; | ||
let fixedRange = `${fixedStartYear}`; | ||
if (violation.expectedEndYear !== violation.expectedStartYear || fixedStartYear !== violation.expectedStartYear) { | ||
fixedRange = `${fixedStartYear}-${violation.expectedEndYear}`; | ||
} | ||
sh.sed('-i', RegExp('Copyright \\([cC]\\) ' + currentRange), `Copyright (c) ${fixedRange}`, violation.file); | ||
}); | ||
LOGGER.newLine(); | ||
if (options.autoFix || readline.keyInYN('Do you want to create a commit for the fixed files?')) { | ||
LOGGER.newLine(); | ||
const files = violations.map(violation => violation.file).join(' '); | ||
sh.exec(`git add ${files}`, getShellConfig()); | ||
sh.exec(`git commit -m "${AUTO_FIX_MESSAGE}"`); | ||
LOGGER.newLine(); | ||
} | ||
} | ||
// Helper types | ||
@@ -312,0 +352,0 @@ interface ValidationResult { |
/******************************************************************************** | ||
* Copyright (c) 2022 EclipseSource and others. | ||
* Copyright (c) 2022-2022 EclipseSource and others. | ||
* | ||
@@ -74,7 +74,9 @@ * This program and the accompanying materials are made available under the | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
export function getLastModificationDate(filePath?: string, repoRoot?: string): Date | undefined { | ||
export function getLastModificationDate(filePath?: string, repoRoot?: string, excludeMessage?: string): Date | undefined { | ||
cdIfPresent(repoRoot); | ||
const result = sh.exec(`git log -1 --pretty="format:%ci" ${filePath ?? ''}`, getShellConfig()); | ||
const additionalArgs = excludeMessage ? `--grep="${excludeMessage}" --invert-grep` : ''; | ||
const result = sh.exec(`git log -1 ${additionalArgs} --pretty="format:%ci" ${filePath ?? ''}`, getShellConfig()); | ||
if (result.code !== 0) { | ||
@@ -89,7 +91,9 @@ return undefined; | ||
* @param repoRoot The path to the repo root. If undefined the current working directory is used. | ||
* @param excludeMessage Only consider commits that don`t match the excludeMessage | ||
* @returns The date or undefined if the file is outside of the git repo. | ||
*/ | ||
export function getFirstModificationDate(filePath: string, repoRoot?: string): Date | undefined { | ||
export function getFirstModificationDate(filePath: string, repoRoot?: string, excludeMessage?: string): Date | undefined { | ||
cdIfPresent(repoRoot); | ||
const result = sh.exec(`git log --pretty="format:%ci" --follow ${filePath}`, getShellConfig()); | ||
const additionalArgs = excludeMessage ? `--grep="${excludeMessage}" --invert-grep` : ''; | ||
const result = sh.exec(`git log ${additionalArgs} --pretty="format:%ci" --follow ${filePath}`, getShellConfig()); | ||
if (result.code !== 0) { | ||
@@ -96,0 +100,0 @@ return undefined; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 4 instances in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
264124
70
3495
5
12
60