Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions dist/index.mjs

Large diffs are not rendered by default.

58 changes: 25 additions & 33 deletions src/task/src/git/gitInvoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,42 +102,17 @@ export default class GitInvoker {
}

if (variable === "GitHub" || variable === "GitHubEnterprise") {
const result: string | undefined =
process.env.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER;
if (typeof result === "undefined") {
this._logger.logWarning(
"'SYSTEM_PULLREQUEST_PULLREQUESTNUMBER' is undefined.",
);
return "";
}

if (!/^\d+$/u.test(result)) {
this._logger.logWarning(
`'SYSTEM_PULLREQUEST_PULLREQUESTNUMBER' is not numeric '${result}'.`,
);
return "";
}

return result;
}

const result: string | undefined =
process.env.SYSTEM_PULLREQUEST_PULLREQUESTID;
if (typeof result === "undefined") {
this._logger.logWarning(
"'SYSTEM_PULLREQUEST_PULLREQUESTID' is undefined.",
);
return "";
}

if (!/^\d+$/u.test(result)) {
this._logger.logWarning(
`'SYSTEM_PULLREQUEST_PULLREQUESTID' is not numeric '${result}'.`,
return (
this.getNumericEnvironmentVariable(
"SYSTEM_PULLREQUEST_PULLREQUESTNUMBER",
) ?? ""
);
return "";
}

return result;
return (
this.getNumericEnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTID") ??
""
);
}

private get targetBranch(): string {
Expand Down Expand Up @@ -220,6 +195,23 @@ export default class GitInvoker {
);
}

private getNumericEnvironmentVariable(variableName: string): string | null {
this._logger.logDebug("* GitInvoker.getNumericEnvironmentVariable()");

const value: string | undefined = process.env[variableName];
if (typeof value === "undefined") {
this._logger.logWarning(`'${variableName}' is undefined.`);
return null;
}

if (!/^\d+$/u.test(value)) {
this._logger.logWarning(`'${variableName}' is not numeric '${value}'.`);
return null;
}

return value;
}

private initialize(): void {
this._logger.logDebug("* GitInvoker.initialize()");

Expand Down
23 changes: 12 additions & 11 deletions src/task/src/metrics/codeMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License.
*/

import * as path from "node:path";
import type { CodeFileMetricInterface } from "./codeFileMetricInterface.js";
import CodeMetricsData from "./codeMetricsData.js";
import type { FixedLengthArrayInterface } from "../utilities/fixedLengthArrayInterface.js";
Expand All @@ -27,7 +28,7 @@ export default class CodeMetrics {
private readonly _logger: Logger;
private readonly _runnerInvoker: RunnerInvoker;

private _isInitialized = false;
private _initializePromise: Promise<void> | null = null;
private readonly _filesNotRequiringReview: string[] = [];
private readonly _deletedFilesNotRequiringReview: string[] = [];
private _size = "";
Expand Down Expand Up @@ -83,7 +84,7 @@ export default class CodeMetrics {
this._logger.logDebug("* CodeMetrics.getFilesNotRequiringReview()");

await this.initialize();
return this._filesNotRequiringReview;
return [...this._filesNotRequiringReview];
}

/**
Expand All @@ -94,7 +95,7 @@ export default class CodeMetrics {
this._logger.logDebug("* CodeMetrics.getDeletedFilesNotRequiringReview()");

await this.initialize();
return this._deletedFilesNotRequiringReview;
return [...this._deletedFilesNotRequiringReview];
}

/**
Expand Down Expand Up @@ -158,15 +159,18 @@ export default class CodeMetrics {
private async initialize(): Promise<void> {
this._logger.logDebug("* CodeMetrics.initialize()");

if (this._isInitialized) {
return;
}
this._initializePromise ??= this.performInitialization();

return this._initializePromise;
}

private async performInitialization(): Promise<void> {
this._logger.logDebug("* CodeMetrics.performInitialization()");

const gitDiffSummary: string = (
await this._gitInvoker.getDiffSummary()
).trim();

this._isInitialized = true;
if (gitDiffSummary !== "") {
this.initializeMetrics(gitDiffSummary);
}
Expand Down Expand Up @@ -284,10 +288,7 @@ export default class CodeMetrics {
private matchFileExtension(fileName: string): boolean {
this._logger.logDebug("* CodeMetrics.matchFileExtension()");

const fileExtensionIndex: number = fileName.lastIndexOf(".");
const fileExtension: string = fileName
.substring(fileExtensionIndex + 1)
.toLowerCase();
const fileExtension: string = path.extname(fileName).slice(1).toLowerCase();
const result: boolean = this._inputs.codeFileExtensions.has(fileExtension);
Comment on lines 288 to 292
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path.extname() returns an empty string for dotfiles like .env, so fileExtension becomes "" and these files will never match even though InputsDefault.codeFileExtensions includes "env". This is a behavior change vs the previous lastIndexOf('.') logic and likely causes .env-style files to be incorrectly excluded from metrics. Consider special-casing dotfiles (e.g., when extname is empty and the basename starts with a single '.') or adding a fallback extraction so .env maps to env, and add/adjust a unit test to lock in the intended behavior.

Copilot uses AI. Check for mistakes.

this._logger.logDebug(
Expand Down
115 changes: 69 additions & 46 deletions src/task/src/metrics/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,59 +172,61 @@ export default class Inputs {
private initializeBaseSize(baseSize: string | null): void {
this._logger.logDebug("* Inputs.initializeBaseSize()");

const convertedValue: number =
baseSize === null ? NaN : parseInt(baseSize, decimalRadix);
if (!Number.isNaN(convertedValue) && convertedValue > 0) {
this._baseSize = convertedValue;
const baseSizeString: string = this._baseSize.toLocaleString();
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.settingBaseSize",
baseSizeString,
),
);
return;
}

const baseSizeString: string = InputsDefault.baseSize.toLocaleString();
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.adjustingBaseSize",
baseSizeString,
),
this.initializeNumeric(
baseSize,
(value: string): number => parseInt(value, decimalRadix),
(value: number): boolean => value > 0,
(value: number): void => {
this._baseSize = value;
},
(valueString: string): void => {
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.settingBaseSize",
valueString,
),
);
},
InputsDefault.baseSize,
(valueString: string): void => {
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.adjustingBaseSize",
valueString,
),
);
},
);
this._baseSize = InputsDefault.baseSize;
}

private initializeGrowthRate(growthRate: string | null): void {
this._logger.logDebug("* Inputs.initializeGrowthRate()");

const convertedValue: number =
growthRate === null ? NaN : parseFloat(growthRate);
if (
!Number.isNaN(convertedValue) &&
Number.isFinite(convertedValue) &&
convertedValue > 1.0
) {
this._growthRate = convertedValue;
const growthRateString: string = this._growthRate.toLocaleString();
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.settingGrowthRate",
growthRateString,
),
);
return;
}

const growthRateString: string = InputsDefault.growthRate.toLocaleString();
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.adjustingGrowthRate",
growthRateString,
),
this.initializeNumeric(
growthRate,
(value: string): number => parseFloat(value),
(value: number): boolean => Number.isFinite(value) && value > 1.0,
(value: number): void => {
this._growthRate = value;
},
(valueString: string): void => {
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.settingGrowthRate",
valueString,
),
);
},
InputsDefault.growthRate,
(valueString: string): void => {
this._logger.logInfo(
this._runnerInvoker.loc(
"metrics.inputs.adjustingGrowthRate",
valueString,
),
);
},
);
this._growthRate = InputsDefault.growthRate;
}

private initializeTestFactor(testFactor: string | null): void {
Expand Down Expand Up @@ -266,6 +268,27 @@ export default class Inputs {
this._testFactor = InputsDefault.testFactor;
}

private initializeNumeric(
inputValue: string | null,
parser: (value: string) => number,
validator: (value: number) => boolean,
setter: (value: number) => void,
settingMessage: (valueString: string) => void,
defaultValue: number,
adjustingMessage: (valueString: string) => void,
): void {
const convertedValue: number =
inputValue === null ? NaN : parser(inputValue);
if (!Number.isNaN(convertedValue) && validator(convertedValue)) {
setter(convertedValue);
settingMessage(convertedValue.toLocaleString());
return;
}

adjustingMessage(defaultValue.toLocaleString());
setter(defaultValue);
}

private initializeAlwaysCloseComment(
alwaysCloseComment: string | null,
): void {
Expand Down
7 changes: 0 additions & 7 deletions src/task/src/metrics/inputsDefault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ export const codeFileExtensions: string[] = [
"php",
"aw",
"ctp",
"fcgi",
"inc",
"php3",
"php4",
Expand All @@ -146,7 +145,6 @@ export const codeFileExtensions: string[] = [
"hh",
"hpp",
"hxx",
"inc",
"inl",
"ino",
"ipp",
Expand All @@ -157,7 +155,6 @@ export const codeFileExtensions: string[] = [
// C
"c",
"cats",
"h",
"idc",
// C: OpenCL
"cl",
Expand All @@ -174,10 +171,8 @@ export const codeFileExtensions: string[] = [
"sh",
"bash",
"bats",
"cgi",
"command",
"env",
"fcgi",
"ksh",
"tmux",
"tool",
Expand All @@ -200,7 +195,6 @@ export const codeFileExtensions: string[] = [
"rb",
"builder",
"eye",
"fcgi",
"gemspec",
"god",
"jbuilder",
Expand All @@ -216,7 +210,6 @@ export const codeFileExtensions: string[] = [
"rbx",
"ru",
"ruby",
"spec",
"thor",
"watchr",
];
Loading
Loading