Skip to content

Commit 84c154a

Browse files
authored
[rush] Fix an issue where the $schema property is dropped from common/config/rush/pnpm-config.json when running rush-pnpm patch-commit ... (microsoft#5397)
* Add the ability to get the original value. * Fix dropping of the $schema property. * Clean up usage of node path in the configiration file tests.
1 parent 3a6cedb commit 84c154a

File tree

12 files changed

+150
-212
lines changed

12 files changed

+150
-212
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Fix an issue where the `$schema` property is dropped from `common/config/rush/pnpm-config.json` when running `rush-pnpm patch-commit ...`",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@rushstack/heft-config-file",
5+
"comment": "Add the ability to get the original value of the `$schema` property.",
6+
"type": "minor"
7+
}
8+
],
9+
"packageName": "@rushstack/heft-config-file"
10+
}

common/reviews/api/heft-config-file.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
2020
static _formatPathForLogging: (path: string) => string;
2121
getObjectSourceFilePath<TObject extends object>(obj: TObject): string | undefined;
2222
getPropertyOriginalValue<TParentProperty extends object, TValue>(options: IOriginalValueOptions<TParentProperty>): TValue | undefined;
23+
getSchemaPropertyOriginalValue<TObject extends object>(obj: TObject): string | undefined;
2324
// (undocumented)
2425
protected _loadConfigurationFileInnerWithCache(terminal: ITerminal, resolvedConfigurationFilePath: string, projectFolderPath: string | undefined, onConfigurationFileNotFound?: IOnConfigurationFileNotFoundCallback): TConfigurationFile;
2526
// (undocumented)

common/reviews/api/rush-lib.api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ export interface IPnpmLockfilePolicies {
761761

762762
// @internal
763763
export interface _IPnpmOptionsJson extends IPackageManagerOptionsJsonBase {
764+
// (undocumented)
765+
$schema?: string;
764766
alwaysFullInstall?: boolean;
765767
alwaysInjectDependenciesFromOtherSubspaces?: boolean;
766768
autoInstallPeers?: boolean;
@@ -1183,7 +1185,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration
11831185
// (undocumented)
11841186
readonly jsonFilename: string | undefined;
11851187
// @internal (undocumented)
1186-
static loadFromJsonFileOrThrow(jsonFilename: string, commonTempFolder: string): PnpmOptionsConfiguration;
1188+
static loadFromJsonFileOrThrow(jsonFilePath: string, commonTempFolder: string): PnpmOptionsConfiguration;
11871189
// @internal (undocumented)
11881190
static loadFromJsonObject(json: _IPnpmOptionsJson, commonTempFolder: string): PnpmOptionsConfiguration;
11891191
readonly pnpmLockfilePolicies: IPnpmLockfilePolicies | undefined;

libraries/heft-config-file/src/ConfigurationFileBase.ts

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,32 @@ export const CONFIGURATION_FILE_FIELD_ANNOTATION: unique symbol = Symbol(
160160
'configuration-file-field-annotation'
161161
);
162162

163-
export interface IAnnotatedField<TField> {
164-
[CONFIGURATION_FILE_FIELD_ANNOTATION]: IConfigurationFileFieldAnnotation<TField>;
163+
export interface IAnnotatedField<
164+
TField,
165+
TConfigurationFileFieldAnnotation extends
166+
IConfigurationFileFieldAnnotation<TField> = IConfigurationFileFieldAnnotation<TField>
167+
> {
168+
[CONFIGURATION_FILE_FIELD_ANNOTATION]: TConfigurationFileFieldAnnotation;
165169
}
166170

171+
type IAnnotatedObject<TParentProperty> = Partial<IAnnotatedField<TParentProperty>>;
172+
type IRootAnnotatedObject<TParentProperty> = Partial<
173+
IAnnotatedField<TParentProperty, IRootConfigurationFileFieldAnnotation<TParentProperty>>
174+
>;
175+
167176
interface IConfigurationFileFieldAnnotation<TField> {
168177
configurationFilePath: string | undefined;
169178
originalValues: { [propertyName in keyof TField]: unknown };
170179
}
171180

181+
interface IRootConfigurationFileFieldAnnotation<TField> extends IConfigurationFileFieldAnnotation<TField> {
182+
schemaPropertyOriginalValue?: string;
183+
}
184+
185+
interface IObjectWithSchema {
186+
$schema?: string;
187+
}
188+
172189
/**
173190
* Options provided to the custom resolver specified in {@link ICustomJsonPathMetadata}.
174191
*
@@ -453,15 +470,8 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
453470
* loaded from.
454471
*/
455472
public getObjectSourceFilePath<TObject extends object>(obj: TObject): string | undefined {
456-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
457-
const annotation: IConfigurationFileFieldAnnotation<TObject> | undefined = (obj as any)[
458-
CONFIGURATION_FILE_FIELD_ANNOTATION
459-
];
460-
if (annotation) {
461-
return annotation.configurationFilePath;
462-
}
463-
464-
return undefined;
473+
const { [CONFIGURATION_FILE_FIELD_ANNOTATION]: annotation }: IAnnotatedObject<TObject> = obj;
474+
return annotation?.configurationFilePath;
465475
}
466476

467477
/**
@@ -471,15 +481,22 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
471481
public getPropertyOriginalValue<TParentProperty extends object, TValue>(
472482
options: IOriginalValueOptions<TParentProperty>
473483
): TValue | undefined {
474-
const {
475-
[CONFIGURATION_FILE_FIELD_ANNOTATION]: annotation
476-
}: { [CONFIGURATION_FILE_FIELD_ANNOTATION]?: IConfigurationFileFieldAnnotation<TParentProperty> } =
477-
options.parentObject;
478-
if (annotation?.originalValues.hasOwnProperty(options.propertyName)) {
479-
return annotation.originalValues[options.propertyName] as TValue;
484+
const { parentObject, propertyName } = options;
485+
const { [CONFIGURATION_FILE_FIELD_ANNOTATION]: annotation }: IAnnotatedObject<TParentProperty> =
486+
parentObject;
487+
if (annotation?.originalValues.hasOwnProperty(propertyName)) {
488+
return annotation.originalValues[propertyName] as TValue;
480489
}
481490
}
482491

492+
/**
493+
* Get the original value of the `$schema` property from the original configuration file, it one was present.
494+
*/
495+
public getSchemaPropertyOriginalValue<TObject extends object>(obj: TObject): string | undefined {
496+
const { [CONFIGURATION_FILE_FIELD_ANNOTATION]: annotation }: IRootAnnotatedObject<TObject> = obj;
497+
return annotation?.schemaPropertyOriginalValue;
498+
}
499+
483500
protected _loadConfigurationFileInnerWithCache(
484501
terminal: ITerminal,
485502
resolvedConfigurationFilePath: string,
@@ -979,14 +996,21 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
979996

980997
// Need to do a dance with the casting here because while we know that JSON keys are always
981998
// strings, TypeScript doesn't.
982-
return this._mergeObjects(
999+
const result: Partial<TConfigurationFile> = this._mergeObjects(
9831000
parentConfiguration as { [key: string]: unknown },
9841001
configurationJson as { [key: string]: unknown },
9851002
resolvedConfigurationFilePath,
9861003
this._defaultPropertyInheritance,
9871004
this._propertyInheritanceTypes as IPropertiesInheritance<{ [key: string]: unknown }>,
9881005
ignoreProperties
9891006
) as Partial<TConfigurationFile>;
1007+
1008+
const schemaPropertyOriginalValue: string | undefined = (configurationJson as IObjectWithSchema).$schema;
1009+
(result as unknown as Required<IRootAnnotatedObject<{}>>)[
1010+
CONFIGURATION_FILE_FIELD_ANNOTATION
1011+
].schemaPropertyOriginalValue = schemaPropertyOriginalValue;
1012+
1013+
return result;
9901014
}
9911015

9921016
private _mergeObjects<TField extends { [key: string]: unknown }>(

0 commit comments

Comments
 (0)