Skip to content

Commit 88e7de8

Browse files
committed
Update the RushSession.registerCloudBuildCacheProviderFactory API to allow a cache provider's factory function to return a promise.
1 parent d395b3d commit 88e7de8

File tree

8 files changed

+115
-108
lines changed

8 files changed

+115
-108
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Update the `RushSession.registerCloudBuildCacheProviderFactory` API to allow a cache provider's factory function to return a function.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class ChangeManager {
9393
// Warning: (ae-forgotten-export) The symbol "IBuildCacheJson" needs to be exported by the entry point index.d.ts
9494
//
9595
// @beta (undocumented)
96-
export type CloudBuildCacheProviderFactory = (buildCacheJson: IBuildCacheJson) => ICloudBuildCacheProvider;
96+
export type CloudBuildCacheProviderFactory = (buildCacheJson: IBuildCacheJson) => ICloudBuildCacheProvider | Promise<ICloudBuildCacheProvider>;
9797

9898
// @public
9999
export class CommonVersionsConfiguration {

libraries/rush-lib/src/api/BuildCacheConfiguration.ts

+26-18
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ interface IBuildCacheConfigurationOptions {
5656
rushConfiguration: RushConfiguration;
5757
rushUserConfiguration: RushUserConfiguration;
5858
rushSession: RushSession;
59+
cloudCacheProvider: ICloudBuildCacheProvider | undefined;
5960
}
6061

6162
/**
@@ -88,28 +89,23 @@ export class BuildCacheConfiguration {
8889
*/
8990
public readonly cloudCacheProvider: ICloudBuildCacheProvider | undefined;
9091

91-
private constructor(options: IBuildCacheConfigurationOptions) {
92-
this.buildCacheEnabled =
93-
EnvironmentConfiguration.buildCacheEnabled ?? options.buildCacheJson.buildCacheEnabled;
92+
private constructor({
93+
getCacheEntryId,
94+
buildCacheJson,
95+
rushUserConfiguration,
96+
rushConfiguration,
97+
cloudCacheProvider
98+
}: IBuildCacheConfigurationOptions) {
99+
this.buildCacheEnabled = EnvironmentConfiguration.buildCacheEnabled ?? buildCacheJson.buildCacheEnabled;
94100
this.cacheWriteEnabled =
95101
!!this.buildCacheEnabled && EnvironmentConfiguration.buildCacheWriteAllowed !== false;
96102

97-
this.getCacheEntryId = options.getCacheEntryId;
103+
this.getCacheEntryId = getCacheEntryId;
98104
this.localCacheProvider = new FileSystemBuildCacheProvider({
99-
rushUserConfiguration: options.rushUserConfiguration,
100-
rushConfiguration: options.rushConfiguration
105+
rushUserConfiguration: rushUserConfiguration,
106+
rushConfiguration: rushConfiguration
101107
});
102-
103-
const { buildCacheJson } = options;
104-
// Don't configure a cloud cache provider if local-only
105-
if (buildCacheJson.cacheProvider !== 'local-only') {
106-
const cloudCacheProviderFactory: CloudBuildCacheProviderFactory | undefined =
107-
options.rushSession.getCloudBuildCacheProviderFactory(buildCacheJson.cacheProvider);
108-
if (!cloudCacheProviderFactory) {
109-
throw new Error(`Unexpected cache provider: ${buildCacheJson.cacheProvider}`);
110-
}
111-
this.cloudCacheProvider = cloudCacheProviderFactory(buildCacheJson as ICloudBuildCacheJson);
112-
}
108+
this.cloudCacheProvider = cloudCacheProvider;
113109
}
114110

115111
/**
@@ -192,12 +188,24 @@ export class BuildCacheConfiguration {
192188
throw new AlreadyReportedError();
193189
}
194190

191+
let cloudCacheProvider: ICloudBuildCacheProvider | undefined;
192+
// Don't configure a cloud cache provider if local-only
193+
if (buildCacheJson.cacheProvider !== 'local-only') {
194+
const cloudCacheProviderFactory: CloudBuildCacheProviderFactory | undefined =
195+
rushSession.getCloudBuildCacheProviderFactory(buildCacheJson.cacheProvider);
196+
if (!cloudCacheProviderFactory) {
197+
throw new Error(`Unexpected cache provider: ${buildCacheJson.cacheProvider}`);
198+
}
199+
cloudCacheProvider = await cloudCacheProviderFactory(buildCacheJson as ICloudBuildCacheJson);
200+
}
201+
195202
return new BuildCacheConfiguration({
196203
buildCacheJson,
197204
getCacheEntryId,
198205
rushConfiguration,
199206
rushUserConfiguration,
200-
rushSession
207+
rushSession,
208+
cloudCacheProvider
201209
});
202210
}
203211
}

libraries/rush-lib/src/pluginFramework/RushSession.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export interface IRushSessionOptions {
1818
/**
1919
* @beta
2020
*/
21-
export type CloudBuildCacheProviderFactory = (buildCacheJson: IBuildCacheJson) => ICloudBuildCacheProvider;
21+
export type CloudBuildCacheProviderFactory = (
22+
buildCacheJson: IBuildCacheJson
23+
) => ICloudBuildCacheProvider | Promise<ICloudBuildCacheProvider>;
2224

2325
/**
2426
* @beta
@@ -60,6 +62,7 @@ export class RushSession {
6062
if (this._cloudBuildCacheProviderFactories.has(cacheProviderName)) {
6163
throw new Error(`A build cache provider factory for ${cacheProviderName} has already been registered`);
6264
}
65+
6366
this._cloudBuildCacheProviderFactories.set(cacheProviderName, factory);
6467
}
6568

Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4-
import { Import } from '@rushstack/node-core-library';
54
import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
65
import type {
7-
AmazonS3BuildCacheProvider,
86
IAmazonS3BuildCacheProviderOptionsAdvanced,
97
IAmazonS3BuildCacheProviderOptionsSimple
108
} from './AmazonS3BuildCacheProvider';
119

12-
const AmazonS3BuildCacheProviderModule: typeof import('./AmazonS3BuildCacheProvider') = Import.lazy(
13-
'./AmazonS3BuildCacheProvider',
14-
require
15-
);
16-
1710
const PLUGIN_NAME: string = 'AmazonS3BuildCachePlugin';
1811

1912
/**
@@ -54,54 +47,53 @@ export class RushAmazonS3BuildCachePlugin implements IRushPlugin {
5447

5548
public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
5649
rushSession.hooks.initialize.tap(PLUGIN_NAME, () => {
57-
rushSession.registerCloudBuildCacheProviderFactory(
58-
'amazon-s3',
59-
(buildCacheConfig): AmazonS3BuildCacheProvider => {
60-
type IBuildCache = typeof buildCacheConfig & {
61-
amazonS3Configuration: IAmazonS3ConfigurationJson;
62-
};
63-
const { amazonS3Configuration } = buildCacheConfig as IBuildCache;
64-
let options:
65-
| IAmazonS3BuildCacheProviderOptionsAdvanced
66-
| IAmazonS3BuildCacheProviderOptionsSimple
67-
| undefined;
68-
const { s3Endpoint, s3Bucket, s3Region } = amazonS3Configuration;
69-
const s3Prefix: undefined | string = amazonS3Configuration.s3Prefix || undefined;
70-
const isCacheWriteAllowed: boolean = !!amazonS3Configuration.isCacheWriteAllowed;
50+
rushSession.registerCloudBuildCacheProviderFactory('amazon-s3', async (buildCacheConfig) => {
51+
type IBuildCache = typeof buildCacheConfig & {
52+
amazonS3Configuration: IAmazonS3ConfigurationJson;
53+
};
54+
const { amazonS3Configuration } = buildCacheConfig as IBuildCache;
55+
let options:
56+
| IAmazonS3BuildCacheProviderOptionsAdvanced
57+
| IAmazonS3BuildCacheProviderOptionsSimple
58+
| undefined;
59+
const { s3Endpoint, s3Bucket, s3Region } = amazonS3Configuration;
60+
const s3Prefix: undefined | string = amazonS3Configuration.s3Prefix || undefined;
61+
const isCacheWriteAllowed: boolean = !!amazonS3Configuration.isCacheWriteAllowed;
7162

72-
if (s3Prefix && s3Prefix[0] === '/') {
73-
throw new Error('s3Prefix should not have a leading /');
74-
}
63+
if (s3Prefix && s3Prefix[0] === '/') {
64+
throw new Error('s3Prefix should not have a leading /');
65+
}
7566

76-
// mutually exclusive
77-
if (s3Bucket && s3Endpoint) {
78-
throw new Error('Only one of "s3Bucket" or "s3Endpoint" must be provided.');
79-
}
67+
// mutually exclusive
68+
if (s3Bucket && s3Endpoint) {
69+
throw new Error('Only one of "s3Bucket" or "s3Endpoint" must be provided.');
70+
}
8071

81-
if (s3Endpoint) {
82-
options = {
83-
// IAmazonS3BuildCacheProviderOptionsAdvanced
84-
s3Region,
85-
s3Endpoint,
86-
s3Prefix,
87-
isCacheWriteAllowed
88-
};
89-
}
90-
if (s3Bucket) {
91-
options = {
92-
// IAmazonS3BuildCacheProviderOptionsSimple
93-
s3Region,
94-
s3Bucket,
95-
s3Prefix,
96-
isCacheWriteAllowed
97-
};
98-
}
99-
if (!options) {
100-
throw new Error('You must provide either an s3Endpoint or s3Bucket');
101-
}
102-
return new AmazonS3BuildCacheProviderModule.AmazonS3BuildCacheProvider(options, rushSession);
72+
if (s3Endpoint) {
73+
options = {
74+
// IAmazonS3BuildCacheProviderOptionsAdvanced
75+
s3Region,
76+
s3Endpoint,
77+
s3Prefix,
78+
isCacheWriteAllowed
79+
};
10380
}
104-
);
81+
if (s3Bucket) {
82+
options = {
83+
// IAmazonS3BuildCacheProviderOptionsSimple
84+
s3Region,
85+
s3Bucket,
86+
s3Prefix,
87+
isCacheWriteAllowed
88+
};
89+
}
90+
if (!options) {
91+
throw new Error('You must provide either an s3Endpoint or s3Bucket');
92+
}
93+
94+
const { AmazonS3BuildCacheProvider } = await import('./AmazonS3BuildCacheProvider');
95+
return new AmazonS3BuildCacheProvider(options, rushSession);
96+
});
10597
});
10698
}
10799
}

rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4-
import { Import } from '@rushstack/node-core-library';
54
import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
65
import type { AzureEnvironmentName } from './AzureAuthenticationBase';
76

8-
const AzureStorageBuildCacheProviderModule: typeof import('./AzureStorageBuildCacheProvider') = Import.lazy(
9-
'./AzureStorageBuildCacheProvider',
10-
require
11-
);
12-
137
const PLUGIN_NAME: string = 'AzureStorageBuildCachePlugin';
148

159
/**
@@ -50,12 +44,13 @@ export class RushAzureStorageBuildCachePlugin implements IRushPlugin {
5044

5145
public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
5246
rushSession.hooks.initialize.tap(PLUGIN_NAME, () => {
53-
rushSession.registerCloudBuildCacheProviderFactory('azure-blob-storage', (buildCacheConfig) => {
47+
rushSession.registerCloudBuildCacheProviderFactory('azure-blob-storage', async (buildCacheConfig) => {
5448
type IBuildCache = typeof buildCacheConfig & {
5549
azureBlobStorageConfiguration: IAzureBlobStorageConfigurationJson;
5650
};
5751
const { azureBlobStorageConfiguration } = buildCacheConfig as IBuildCache;
58-
return new AzureStorageBuildCacheProviderModule.AzureStorageBuildCacheProvider({
52+
const { AzureStorageBuildCacheProvider } = await import('./AzureStorageBuildCacheProvider');
53+
return new AzureStorageBuildCacheProvider({
5954
storageAccountName: azureBlobStorageConfiguration.storageAccountName,
6055
storageContainerName: azureBlobStorageConfiguration.storageContainerName,
6156
azureEnvironment: azureBlobStorageConfiguration.azureEnvironment,

rush-plugins/rush-http-build-cache-plugin/src/RushHttpBuildCachePlugin.ts

+23-28
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import { Import } from '@rushstack/node-core-library';
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
24
import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
35
import type { HttpBuildCacheProvider, IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
46

5-
const HttpBuildCacheProviderModule: typeof import('./HttpBuildCacheProvider') = Import.lazy(
6-
'./HttpBuildCacheProvider',
7-
require
8-
);
9-
107
const PLUGIN_NAME: string = 'HttpBuildCachePlugin';
118

129
/**
@@ -56,31 +53,29 @@ export class RushHttpBuildCachePlugin implements IRushPlugin {
5653

5754
public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
5855
rushSession.hooks.initialize.tap(this.pluginName, () => {
59-
rushSession.registerCloudBuildCacheProviderFactory(
60-
'http',
61-
(buildCacheConfig): HttpBuildCacheProvider => {
62-
const config: IRushHttpBuildCachePluginConfig = (
63-
buildCacheConfig as typeof buildCacheConfig & {
64-
httpConfiguration: IRushHttpBuildCachePluginConfig;
65-
}
66-
).httpConfiguration;
56+
rushSession.registerCloudBuildCacheProviderFactory('http', async (buildCacheConfig) => {
57+
const config: IRushHttpBuildCachePluginConfig = (
58+
buildCacheConfig as typeof buildCacheConfig & {
59+
httpConfiguration: IRushHttpBuildCachePluginConfig;
60+
}
61+
).httpConfiguration;
6762

68-
const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
63+
const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
6964

70-
const options: IHttpBuildCacheProviderOptions = {
71-
pluginName: this.pluginName,
72-
rushProjectRoot: rushConfig.rushJsonFolder,
73-
url: url,
74-
uploadMethod: uploadMethod,
75-
headers: headers,
76-
tokenHandler: tokenHandler,
77-
cacheKeyPrefix: cacheKeyPrefix,
78-
isCacheWriteAllowed: !!isCacheWriteAllowed
79-
};
65+
const options: IHttpBuildCacheProviderOptions = {
66+
pluginName: this.pluginName,
67+
rushProjectRoot: rushConfig.rushJsonFolder,
68+
url: url,
69+
uploadMethod: uploadMethod,
70+
headers: headers,
71+
tokenHandler: tokenHandler,
72+
cacheKeyPrefix: cacheKeyPrefix,
73+
isCacheWriteAllowed: !!isCacheWriteAllowed
74+
};
8075

81-
return new HttpBuildCacheProviderModule.HttpBuildCacheProvider(options, rushSession);
82-
}
83-
);
76+
const { HttpBuildCacheProvider } = await import('./HttpBuildCacheProvider');
77+
return new HttpBuildCacheProvider(options, rushSession);
78+
});
8479
});
8580
}
8681
}

rush-plugins/rush-http-build-cache-plugin/src/HttpBuildCacheProvider.test.ts rush-plugins/rush-http-build-cache-plugin/src/test/HttpBuildCacheProvider.test.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
14
jest.mock('node-fetch', function () {
25
return Object.assign(jest.fn(), jest.requireActual('node-fetch'));
36
});
47

58
import fetch, { Response } from 'node-fetch';
6-
import { HttpBuildCacheProvider } from './HttpBuildCacheProvider';
79
import { RushSession, EnvironmentConfiguration } from '@rushstack/rush-sdk';
810
import { StringBufferTerminalProvider, Terminal } from '@rushstack/node-core-library';
911

12+
import { HttpBuildCacheProvider } from '../HttpBuildCacheProvider';
13+
1014
const EXAMPLE_OPTIONS = {
1115
url: 'https://buildcache.example.acme.com',
1216
tokenHandler: {

0 commit comments

Comments
 (0)