Skip to content

Commit

Permalink
Recursively merge repo and package options (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
ecraig12345 committed Nov 26, 2024
1 parent f8663ba commit 786cd63
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
7 changes: 7 additions & 0 deletions change/beachball-0135a02c-03dd-43e8-ad06-d4c76cdb12dd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "major",
"comment": "Recursively merge repo and package options. This has a very slight chance of causing a change in behavior if anyone had both a repo-level config, and some package-level package.json \"beachball\" config that set nested object options (which was never intentionally supported).",
"packageName": "beachball",
"email": "[email protected]",
"dependentChangeType": "patch"
}
49 changes: 46 additions & 3 deletions src/options/getOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BeachballOptions } from '../types/BeachballOptions';
import type { BeachballOptions, CliOptions, PackageOptions, RepoOptions } from '../types/BeachballOptions';
import { getCliOptions } from './getCliOptions';
import { getRepoOptions } from './getRepoOptions';
import { getDefaultOptions } from './getDefaultOptions';
Expand All @@ -8,6 +8,49 @@ import { getDefaultOptions } from './getDefaultOptions';
*/
export function getOptions(argv: string[]): BeachballOptions {
const cliOptions = getCliOptions(argv);
// TODO: proper recursive merging
return { ...getDefaultOptions(), ...getRepoOptions(cliOptions), ...cliOptions };
return mergeOptions({
defaultOptions: getDefaultOptions(),
repoOptions: getRepoOptions(cliOptions),
cliOptions,
});
}

/**
* Merge options. Arrays will overwrite.
*/
export function mergeOptions(params: {
defaultOptions?: BeachballOptions;
repoOptions?: RepoOptions;
cliOptions?: CliOptions;
packageOptions?: Partial<PackageOptions>;
}): BeachballOptions {
return mergeObjects(
params.defaultOptions,
params.repoOptions,
params.packageOptions,
params.cliOptions
) as BeachballOptions;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function mergeObjects(...objects: (Record<string, any> | undefined)[]) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const acc: Record<string, any> = {};

for (const obj of objects) {
if (!obj || typeof obj !== 'object') {
continue;
}

for (const [key, val] of Object.entries(obj)) {
if (val && typeof val === 'object' && !Array.isArray(val)) {
acc[key] = mergeObjects([acc[key] || {}, val]);
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
acc[key] = val;
}
}
}

return acc;
}
9 changes: 2 additions & 7 deletions src/options/getPackageInfosWithOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getRepoOptions } from './getRepoOptions';
import { getDefaultOptions } from './getDefaultOptions';
import { env } from '../env';
import type { PackageInfos } from '../types/PackageInfo';
import { mergeOptions } from './getOptions';

/**
* Fill in options to convert `workspace-tools` `PackageInfos` to the format used in this repo,
Expand Down Expand Up @@ -34,13 +35,7 @@ export function getPackageInfosWithOptions(wsPackageInfos: WSPackageInfo[]): Pac
peerDependencies: packageJson.peerDependencies,
optionalDependencies: packageJson.optionalDependencies,
private: packageJson.private !== undefined ? packageJson.private : false,
// TODO: proper recursive merging
combinedOptions: {
...defaultOptions,
...repoOptions,
...packageOptions,
...cliOptions,
},
combinedOptions: mergeOptions({ defaultOptions, repoOptions, cliOptions, packageOptions }),
packageOptions,
};
}
Expand Down

0 comments on commit 786cd63

Please sign in to comment.