Skip to content

Commit

Permalink
Refactors to plugin loaders.
Browse files Browse the repository at this point in the history
  • Loading branch information
iclanton committed Jan 3, 2022
1 parent bbad4fb commit 645b5a3
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,34 @@
// See LICENSE in the project root for license information.

import * as path from 'path';
import { FileSystem, JsonFile, JsonObject, JsonSchema, ITerminal } from '@rushstack/node-core-library';
import { RushConfiguration } from '../../api/RushConfiguration';
import { FileSystem, JsonFile, JsonObject, JsonSchema } from '@rushstack/node-core-library';

import { IRushPluginConfiguration } from '../../api/RushPluginsConfiguration';
import { Autoinstaller } from '../../logic/Autoinstaller';
import { RushConstants } from '../../logic/RushConstants';
import { IRushPluginManifest, IRushPluginManifestJson, PluginLoaderBase } from './PluginLoaderBase';

export interface IRemotePluginLoaderOptions {
pluginConfiguration: IRushPluginConfiguration;
rushConfiguration: RushConfiguration;
terminal: ITerminal;
}
import {
IPluginLoaderOptions,
IRushPluginManifest,
IRushPluginManifestJson,
PluginLoaderBase
} from './PluginLoaderBase';

/**
* @beta
*/
export class RemotePluginLoader extends PluginLoaderBase {
export class AutoinstallerPluginLoader extends PluginLoaderBase<IRushPluginConfiguration> {
private _autoinstaller: Autoinstaller;

public constructor({ pluginConfiguration, rushConfiguration, terminal }: IRemotePluginLoaderOptions) {
super({
pluginConfiguration,
rushConfiguration,
terminal
});
this._autoinstaller = new Autoinstaller(pluginConfiguration.autoinstallerName, this._rushConfiguration);
}
public readonly packageFolder: string;

public constructor(options: IPluginLoaderOptions<IRushPluginConfiguration>) {
super(options);
this._autoinstaller = new Autoinstaller(
options.pluginConfiguration.autoinstallerName,
this._rushConfiguration
);

protected override onGetPackageFolder(): string {
return path.join(this._autoinstaller.folderFullPath, 'node_modules', this._packageName);
this.packageFolder = path.join(this._autoinstaller.folderFullPath, 'node_modules', this.packageName);
}

/**
Expand All @@ -43,15 +41,15 @@ export class RemotePluginLoader extends PluginLoaderBase {
}

public update(): void {
const packageName: string = this._packageName;
const pluginName: string = this._pluginName;
const packageFolder: string = this.getPackageFolder();
const packageName: string = this.packageName;
const pluginName: string = this.pluginName;
const packageFolder: string = this.packageFolder;
const manifestPath: string = path.join(packageFolder, RushConstants.rushPluginManifestFilename);

// validate
const manifest: IRushPluginManifestJson = JsonFile.loadAndValidate(
manifestPath,
RemotePluginLoader._jsonSchema
AutoinstallerPluginLoader._jsonSchema
);

FileSystem.copyFile({
Expand Down Expand Up @@ -108,7 +106,7 @@ export class RemotePluginLoader extends PluginLoaderBase {
if (FileSystem.isFileDoesNotExistError(e as Error)) {
if (optionsSchema) {
throw new Error(
`Plugin options are required by ${this._pluginName} from package ${this._packageName}, please create it at ${optionsJsonFilePath}.`
`Plugin options are required by ${this.pluginName} from package ${this.packageName}, please create it at ${optionsJsonFilePath}.`
);
} else {
return {};
Expand All @@ -126,17 +124,17 @@ export class RemotePluginLoader extends PluginLoaderBase {

protected override _getManifestPath(): string {
return path.join(
RemotePluginLoader.getPluginAutoinstallerStorePath(this._autoinstaller),
this._packageName,
AutoinstallerPluginLoader.getPluginAutoinstallerStorePath(this._autoinstaller),
this.packageName,
RushConstants.rushPluginManifestFilename
);
}

protected override _getCommandLineJsonFilePath(): string {
return path.join(
RemotePluginLoader.getPluginAutoinstallerStorePath(this._autoinstaller),
this._packageName,
this._pluginName,
AutoinstallerPluginLoader.getPluginAutoinstallerStorePath(this._autoinstaller),
this.packageName,
this.pluginName,
RushConstants.commandLineFilename
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import { Import } from '@rushstack/node-core-library';
import { IRushPluginConfigurationBase } from '../../api/RushPluginsConfiguration';
import { IPluginLoaderOptions, PluginLoaderBase } from './PluginLoaderBase';

import { PluginLoaderBase } from './PluginLoaderBase';
export interface IBuiltInPluginConfiguration extends IRushPluginConfigurationBase {
pluginPackageFolder: string;
}

/**
* Built-in plugin loader.
* Loading those plugins are directly installed by Rush.
* @remarks
* Used to load plugins that are dependencies of Rush.
*/
export class BuiltInPluginLoader extends PluginLoaderBase {
protected override onGetPackageFolder(): string {
const packageFolder: string = Import.resolvePackage({
baseFolderPath: __dirname,
packageName: this._packageName
});
return packageFolder;
export class BuiltInPluginLoader extends PluginLoaderBase<IBuiltInPluginConfiguration> {
public readonly packageFolder: string;

public constructor(options: IPluginLoaderOptions<IBuiltInPluginConfiguration>) {
super(options);
this.packageFolder = options.pluginConfiguration.pluginPackageFolder;
}
}
72 changes: 30 additions & 42 deletions apps/rush-lib/src/pluginFramework/PluginLoader/PluginLoaderBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,40 @@ export interface IRushPluginManifestJson {
plugins: IRushPluginManifest[];
}

export interface IPluginLoaderOptions {
pluginConfiguration: IRushPluginConfigurationBase;
export interface IPluginLoaderOptions<TPluginConfiguration extends IRushPluginConfigurationBase> {
pluginConfiguration: TPluginConfiguration;
rushConfiguration: RushConfiguration;
terminal: ITerminal;
}

export abstract class PluginLoaderBase {
export abstract class PluginLoaderBase<
TPluginConfiguration extends IRushPluginConfigurationBase = IRushPluginConfigurationBase
> {
protected static _jsonSchema: JsonSchema = JsonSchema.fromFile(
path.join(__dirname, '../../schemas/rush-plugin-manifest.schema.json')
);

public readonly packageName: Readonly<string>;
public readonly pluginName: Readonly<string>;
protected readonly _rushConfiguration: RushConfiguration;
protected readonly _packageName: Readonly<string>;
protected readonly _pluginName: Readonly<string>;
protected readonly _terminal: ITerminal;

protected _manifestCache!: Readonly<IRushPluginManifest>;

private _cachedPackageFolder: string | undefined = undefined;

public constructor({ pluginConfiguration, rushConfiguration, terminal }: IPluginLoaderOptions) {
this._packageName = pluginConfiguration.packageName;
this._pluginName = pluginConfiguration.pluginName;
this._rushConfiguration = rushConfiguration;
this._terminal = terminal;
}

/** Child classes use this to implement the lookup for getPackageFolder() */
protected abstract onGetPackageFolder(): string;
protected _manifestCache: Readonly<IRushPluginManifest> | undefined;

/**
* Returns the folder that should be used for resolving the plugin's NPM package.
* The folder that should be used for resolving the plugin's NPM package.
*/
public getPackageFolder(): string {
if (this._cachedPackageFolder === undefined) {
this._cachedPackageFolder = this.onGetPackageFolder();
}
return this._cachedPackageFolder;
public abstract readonly packageFolder: string;

public constructor({
pluginConfiguration,
rushConfiguration,
terminal
}: IPluginLoaderOptions<TPluginConfiguration>) {
this.packageName = pluginConfiguration.packageName;
this.pluginName = pluginConfiguration.pluginName;
this._rushConfiguration = rushConfiguration;
this._terminal = terminal;
}

public load(): IRushPlugin | undefined {
Expand All @@ -82,14 +78,6 @@ export abstract class PluginLoaderBase {
return this._loadAndValidatePluginPackage(resolvedPluginPath, pluginOptions);
}

public get packageName(): string {
return this._packageName;
}

public get pluginName(): string {
return this._pluginName;
}

public get pluginManifest(): IRushPluginManifest {
return this._getRushPluginManifest();
}
Expand All @@ -105,7 +93,7 @@ export abstract class PluginLoaderBase {
commandLineConfiguration.prependAdditionalPathFolder(additionalPathFolder);
}
commandLineConfiguration.shellCommandTokenContext = {
packageFolder: this.getPackageFolder()
packageFolder: this.packageFolder
};
return commandLineConfiguration;
}
Expand All @@ -114,7 +102,7 @@ export abstract class PluginLoaderBase {
return [
// Example: `@microsoft/rush-lib/node_modules/<packageName>/node_modules/.bin`
// Example: `common/autoinstaller/plugins/node_modules/<packageName>/node_modules/.bin`
path.join(this.getPackageFolder(), 'node_modules', '.bin')
path.join(this.packageFolder, 'node_modules', '.bin')
];
}

Expand All @@ -123,7 +111,7 @@ export abstract class PluginLoaderBase {
if (!commandLineJsonFilePath) {
return undefined;
}
return path.join(this.getPackageFolder(), commandLineJsonFilePath);
return path.join(this.packageFolder, commandLineJsonFilePath);
}

private _loadAndValidatePluginPackage(resolvedPluginPath: string, options?: JsonObject): IRushPlugin {
Expand Down Expand Up @@ -160,11 +148,11 @@ export abstract class PluginLoaderBase {
if (!entryPoint) {
return undefined;
}
const packageFolder: string = this.getPackageFolder();
const packageFolder: string = this.packageFolder;
const modulePath: string = path.join(packageFolder, entryPoint);
if (!FileSystem.exists(modulePath)) {
throw new InternalError(
`Unable to find entry point "${modulePath}" for rush plugin "${this._pluginName}".`
`Unable to find entry point "${modulePath}" for rush plugin "${this.pluginName}".`
);
}
return modulePath;
Expand Down Expand Up @@ -192,22 +180,22 @@ export abstract class PluginLoaderBase {
}

protected _getPluginOptionsJsonFilePath(): string {
return path.join(this._rushConfiguration.rushPluginOptionsFolder, `${this._pluginName}.json`);
return path.join(this._rushConfiguration.rushPluginOptionsFolder, `${this.pluginName}.json`);
}

protected _getRushPluginOptionsSchema(): JsonSchema | undefined {
const optionsSchema: string | undefined = this._getRushPluginManifest().optionsSchema;
if (!optionsSchema) {
return undefined;
}
const optionsSchemaFilePath: string = path.join(this.getPackageFolder(), optionsSchema);
const optionsSchemaFilePath: string = path.join(this.packageFolder, optionsSchema);
return JsonSchema.fromFile(optionsSchemaFilePath);
}

private _getRushPluginManifest(): IRushPluginManifest {
if (!this._manifestCache) {
const packageName: string = this._packageName;
const pluginName: string = this._pluginName;
const packageName: string = this.packageName;
const pluginName: string = this.pluginName;

const manifestPath: string = this._getManifestPath();

Expand Down Expand Up @@ -236,6 +224,6 @@ export abstract class PluginLoaderBase {
}

protected _getManifestPath(): string {
return path.join(this.getPackageFolder(), RushConstants.rushPluginManifestFilename);
return path.join(this.packageFolder, RushConstants.rushPluginManifestFilename);
}
}
Loading

0 comments on commit 645b5a3

Please sign in to comment.