Address review feedback
- Remove cli changeset, piggy-back on existing ones - Rename getHasYarnPlugin -> hasYarnPlugin(workspaceDir?) - Make SuccessCache constructor private, add static create() - Consolidate duplicate @backstage/cli-node imports Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Migrated `getHasYarnPlugin` and `SuccessCache` to use the implementations from `@backstage/cli-node`.
|
||||
@@ -2,4 +2,4 @@
|
||||
'@backstage/cli-node': patch
|
||||
---
|
||||
|
||||
Added `getHasYarnPlugin` and `SuccessCache` exports, moved from `@backstage/cli`.
|
||||
Added `hasYarnPlugin` and `SuccessCache` exports, moved from `@backstage/cli`.
|
||||
|
||||
@@ -93,15 +93,15 @@ export type ConcurrentTasksOptions<TItem> = {
|
||||
worker: (item: TItem) => Promise<void>;
|
||||
};
|
||||
|
||||
// @public
|
||||
export function getHasYarnPlugin(): Promise<boolean>;
|
||||
|
||||
// @public
|
||||
export class GitUtils {
|
||||
static listChangedFiles(ref: string): Promise<string[]>;
|
||||
static readFileAtRef(path: string, ref: string): Promise<string>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function hasYarnPlugin(workspaceDir?: string): Promise<boolean>;
|
||||
|
||||
// @public
|
||||
export function isMonoRepo(): Promise<boolean>;
|
||||
|
||||
@@ -226,7 +226,8 @@ export function runWorkerQueueThreads<TItem, TResult, TContext>(
|
||||
|
||||
// @public
|
||||
export class SuccessCache {
|
||||
constructor(name: string, basePath?: string);
|
||||
// (undocumented)
|
||||
static create(name: string, basePath?: string): SuccessCache;
|
||||
// (undocumented)
|
||||
read(): Promise<Set<string>>;
|
||||
static trimPaths(input: string): string;
|
||||
|
||||
+5
-1
@@ -40,7 +40,11 @@ export class SuccessCache {
|
||||
return input.replaceAll(targetPaths.rootDir, '');
|
||||
}
|
||||
|
||||
constructor(name: string, basePath?: string) {
|
||||
static create(name: string, basePath?: string): SuccessCache {
|
||||
return new SuccessCache(name, basePath);
|
||||
}
|
||||
|
||||
private constructor(name: string, basePath?: string) {
|
||||
this.#path = resolvePath(basePath ?? DEFAULT_CACHE_BASE_PATH, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { getHasYarnPlugin } from './yarnPlugin';
|
||||
export { hasYarnPlugin } from './yarnPlugin';
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
import { createMockDirectory } from '@backstage/backend-test-utils';
|
||||
import { overrideTargetPaths } from '@backstage/cli-common/testUtils';
|
||||
import { getHasYarnPlugin } from './yarnPlugin';
|
||||
import { hasYarnPlugin } from './yarnPlugin';
|
||||
|
||||
const mockDir = createMockDirectory();
|
||||
overrideTargetPaths(mockDir.path);
|
||||
|
||||
describe('getHasYarnPlugin', () => {
|
||||
describe('hasYarnPlugin', () => {
|
||||
beforeEach(() => {
|
||||
mockDir.clear();
|
||||
});
|
||||
@@ -29,7 +29,7 @@ describe('getHasYarnPlugin', () => {
|
||||
it('should return false when .yarnrc.yml does not exist', async () => {
|
||||
mockDir.setContent({});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ describe('getHasYarnPlugin', () => {
|
||||
'.yarnrc.yml': '',
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('getHasYarnPlugin', () => {
|
||||
'.yarnrc.yml': 'plugins: []',
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ plugins:
|
||||
`,
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ plugins:
|
||||
`,
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
@@ -86,7 +86,7 @@ plugins:
|
||||
`,
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
@@ -95,7 +95,7 @@ plugins:
|
||||
'.yarnrc.yml': 'invalid: yaml: content: [',
|
||||
});
|
||||
|
||||
await expect(getHasYarnPlugin()).rejects.toThrow();
|
||||
await expect(hasYarnPlugin()).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('should throw error when .yarnrc.yml has unexpected structure', async () => {
|
||||
@@ -105,21 +105,22 @@ plugins: "not an array"
|
||||
`,
|
||||
});
|
||||
|
||||
await expect(getHasYarnPlugin()).rejects.toThrow(
|
||||
await expect(hasYarnPlugin()).rejects.toThrow(
|
||||
'Unexpected content in .yarnrc.yml',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle plugins with different structure', async () => {
|
||||
it('should resolve from a custom workspace directory', async () => {
|
||||
mockDir.setContent({
|
||||
'.yarnrc.yml': `
|
||||
'custom-dir': {
|
||||
'.yarnrc.yml': `
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-backstage.cjs
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
const result = await getHasYarnPlugin();
|
||||
const result = await hasYarnPlugin(mockDir.resolve('custom-dir'));
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import { resolve as resolvePath } from 'node:path';
|
||||
import yaml from 'yaml';
|
||||
import z from 'zod';
|
||||
import { targetPaths } from '@backstage/cli-common';
|
||||
@@ -30,13 +31,17 @@ const yarnRcSchema = z.object({
|
||||
});
|
||||
|
||||
/**
|
||||
* Detects whether the Backstage Yarn plugin is installed in the target repository.
|
||||
* Detects whether the Backstage Yarn plugin is installed in the given workspace directory.
|
||||
*
|
||||
* @returns Promise<boolean> - true if the plugin is installed, false otherwise
|
||||
* @param workspaceDir - The workspace root directory to check. Defaults to the target root.
|
||||
* @returns Promise resolving to true if the plugin is installed, false otherwise
|
||||
* @public
|
||||
*/
|
||||
export async function getHasYarnPlugin(): Promise<boolean> {
|
||||
const yarnRcPath = targetPaths.resolveRoot('.yarnrc.yml');
|
||||
export async function hasYarnPlugin(workspaceDir?: string): Promise<boolean> {
|
||||
const yarnRcPath = resolvePath(
|
||||
workspaceDir ?? targetPaths.rootDir,
|
||||
'.yarnrc.yml',
|
||||
);
|
||||
const yarnRcContent = await fs.readFile(yarnRcPath, 'utf-8').catch(e => {
|
||||
if (e.code === 'ENOENT') {
|
||||
return '';
|
||||
|
||||
@@ -24,11 +24,11 @@ import {
|
||||
BackstagePackageJson,
|
||||
Lockfile,
|
||||
runWorkerQueueThreads,
|
||||
SuccessCache,
|
||||
} from '@backstage/cli-node';
|
||||
import { targetPaths } from '@backstage/cli-common';
|
||||
|
||||
import { createScriptOptionsParser } from '../../lib/optionsParser';
|
||||
import { SuccessCache } from '@backstage/cli-node';
|
||||
|
||||
function depCount(pkg: BackstagePackageJson) {
|
||||
const deps = pkg.dependencies ? Object.keys(pkg.dependencies).length : 0;
|
||||
@@ -41,7 +41,7 @@ function depCount(pkg: BackstagePackageJson) {
|
||||
export async function command(opts: OptionValues, cmd: Command): Promise<void> {
|
||||
let packages = await PackageGraph.listTargetPackages();
|
||||
|
||||
const cache = new SuccessCache('lint', opts.successCacheDir);
|
||||
const cache = SuccessCache.create('lint', opts.successCacheDir);
|
||||
const cacheContext = opts.successCache
|
||||
? {
|
||||
entries: await cache.read(),
|
||||
|
||||
@@ -31,7 +31,7 @@ import { isError, NotFoundError } from '@backstage/errors';
|
||||
import { resolve as resolvePath } from 'node:path';
|
||||
|
||||
import {
|
||||
getHasYarnPlugin,
|
||||
hasYarnPlugin,
|
||||
Lockfile,
|
||||
runConcurrentTasks,
|
||||
} from '@backstage/cli-node';
|
||||
@@ -76,7 +76,7 @@ function extendsDefaultPattern(pattern: string): boolean {
|
||||
export default async (opts: OptionValues) => {
|
||||
const lockfilePath = targetPaths.resolveRoot('yarn.lock');
|
||||
const lockfile = await Lockfile.load(lockfilePath);
|
||||
const hasYarnPlugin = await getHasYarnPlugin();
|
||||
const yarnPluginEnabled = await hasYarnPlugin();
|
||||
|
||||
let pattern = opts.pattern;
|
||||
|
||||
@@ -130,7 +130,7 @@ export default async (opts: OptionValues) => {
|
||||
});
|
||||
}
|
||||
|
||||
if (hasYarnPlugin) {
|
||||
if (yarnPluginEnabled) {
|
||||
console.log();
|
||||
console.log(
|
||||
`Updating yarn plugin to v${releaseManifest.releaseVersion}...`,
|
||||
@@ -214,7 +214,7 @@ export default async (opts: OptionValues) => {
|
||||
const oldLockfileRange = await asLockfileVersion(oldRange);
|
||||
|
||||
const useBackstageRange =
|
||||
hasYarnPlugin &&
|
||||
yarnPluginEnabled &&
|
||||
// Only use backstage:^ versions if the package is present in
|
||||
// the manifest for the release we're bumping to.
|
||||
releaseManifest.packages.find(
|
||||
@@ -254,7 +254,7 @@ export default async (opts: OptionValues) => {
|
||||
if (extendsDefaultPattern(pattern)) {
|
||||
await bumpBackstageJsonVersion(
|
||||
releaseManifest.releaseVersion,
|
||||
hasYarnPlugin,
|
||||
yarnPluginEnabled,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
@@ -319,7 +319,7 @@ export default async (opts: OptionValues) => {
|
||||
console.log();
|
||||
}
|
||||
|
||||
if (hasYarnPlugin) {
|
||||
if (yarnPluginEnabled) {
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.blue(
|
||||
|
||||
@@ -28,7 +28,7 @@ import { Lockfile } from '@backstage/cli-node';
|
||||
import { targetPaths } from '@backstage/cli-common';
|
||||
|
||||
import { createPackageVersionProvider } from '../../../../lib/version';
|
||||
import { getHasYarnPlugin } from '@backstage/cli-node';
|
||||
import { hasYarnPlugin } from '@backstage/cli-node';
|
||||
|
||||
const builtInHelpers = {
|
||||
camelCase,
|
||||
@@ -55,9 +55,9 @@ export class PortableTemplater {
|
||||
/* ignored */
|
||||
}
|
||||
|
||||
const hasYarnPlugin = await getHasYarnPlugin();
|
||||
const yarnPluginEnabled = await hasYarnPlugin();
|
||||
const versionProvider = createPackageVersionProvider(lockfile, {
|
||||
preferBackstageProtocol: hasYarnPlugin,
|
||||
preferBackstageProtocol: yarnPluginEnabled,
|
||||
});
|
||||
|
||||
const templater = new PortableTemplater(
|
||||
|
||||
@@ -22,7 +22,7 @@ import yargs from 'yargs';
|
||||
import { run as runJest, yargsOptions as jestYargsOptions } from 'jest-cli';
|
||||
import { relative as relativePath } from 'node:path';
|
||||
import { Command, OptionValues } from 'commander';
|
||||
import { Lockfile, PackageGraph } from '@backstage/cli-node';
|
||||
import { Lockfile, PackageGraph, SuccessCache } from '@backstage/cli-node';
|
||||
|
||||
import {
|
||||
runCheck,
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
findOwnPaths,
|
||||
isChildPath,
|
||||
} from '@backstage/cli-common';
|
||||
import { SuccessCache } from '@backstage/cli-node';
|
||||
|
||||
type JestProject = {
|
||||
displayName: string;
|
||||
@@ -333,7 +332,7 @@ export async function command(opts: OptionValues, cmd: Command): Promise<void> {
|
||||
);
|
||||
}
|
||||
|
||||
const cache = new SuccessCache('test', opts.successCacheDir);
|
||||
const cache = SuccessCache.create('test', opts.successCacheDir);
|
||||
const graph = await getPackageGraph();
|
||||
|
||||
// Shared state for the bridge
|
||||
|
||||
Reference in New Issue
Block a user