Skip to content

Commit

Permalink
[INTERNAL] Sapui5MavenSnapshotResolver: Expose cacheMode parameter th…
Browse files Browse the repository at this point in the history
…rough all APIs

This allows consumers to control the cache behavior when using
SNAPSHOT versions.

Also, remove unused 'resolverConfig' option from ui5Framework
  • Loading branch information
RandomByte committed Apr 28, 2023
1 parent 1f0a408 commit fafa114
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 34 deletions.
18 changes: 12 additions & 6 deletions lib/graph/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const log = getLogger("generateProjectGraph");
* Whether framework dependencies should be added to the graph
* @param {string} [options.workspaceName]
* Name of the workspace configuration that should be used if any is provided
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [options.cacheMode]
* Cache mode to use when consuming SNAPSHOT versions
* @param {string} [options.workspaceConfigPath=ui5-workspace.yaml]
* Workspace configuration file to use if no object has been provided
* @param {@ui5/project/graph/Workspace~Configuration} [options.workspaceConfiguration]
Expand All @@ -40,7 +42,7 @@ const log = getLogger("generateProjectGraph");
*/
export async function graphFromPackageDependencies({
cwd, rootConfiguration, rootConfigPath,
versionOverride, resolveFrameworkDependencies = true,
versionOverride, cacheMode, resolveFrameworkDependencies = true,
workspaceName /* TODO 4.0: default workspaceName to "default" ? */,
workspaceConfiguration, workspaceConfigPath = "ui5-workspace.yaml"
}) {
Expand Down Expand Up @@ -71,7 +73,7 @@ export async function graphFromPackageDependencies({
const projectGraph = await projectGraphBuilder(provider, workspace);

if (resolveFrameworkDependencies) {
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride, workspace});
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride, cacheMode, workspace});
}

return projectGraph;
Expand All @@ -93,14 +95,16 @@ export async function graphFromPackageDependencies({
* Configuration file to use for the root module instead the default ui5.yaml. Either a path relative to
* <code>cwd</code> or an absolute path. In both case, platform-specific path segment separators must be used.
* @param {string} [options.versionOverride] Framework version to use instead of the one defined in the root project
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [options.cacheMode]
* Cache mode to use when consuming SNAPSHOT versions
* @param {string} [options.resolveFrameworkDependencies=true]
* Whether framework dependencies should be added to the graph
* @returns {Promise<@ui5/project/graph/ProjectGraph>} Promise resolving to a Project Graph instance
*/
export async function graphFromStaticFile({
filePath = "projectDependencies.yaml", cwd,
rootConfiguration, rootConfigPath,
versionOverride, resolveFrameworkDependencies = true
versionOverride, cacheMode, resolveFrameworkDependencies = true
}) {
log.verbose(`Creating project graph using static file...`);
const {
Expand All @@ -121,7 +125,7 @@ export async function graphFromStaticFile({
const projectGraph = await projectGraphBuilder(provider);

if (resolveFrameworkDependencies) {
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride});
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride, cacheMode});
}

return projectGraph;
Expand All @@ -143,14 +147,16 @@ export async function graphFromStaticFile({
* Configuration file to use for the root module instead the default ui5.yaml. Either a path relative to
* <code>cwd</code> or an absolute path. In both case, platform-specific path segment separators must be used.
* @param {string} [options.versionOverride] Framework version to use instead of the one defined in the root project
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [options.cacheMode]
* Cache mode to use when consuming SNAPSHOT versions
* @param {string} [options.resolveFrameworkDependencies=true]
* Whether framework dependencies should be added to the graph
* @returns {Promise<@ui5/project/graph/ProjectGraph>} Promise resolving to a Project Graph instance
*/
export async function graphFromObject({
dependencyTree, cwd,
rootConfiguration, rootConfigPath,
versionOverride, resolveFrameworkDependencies = true
versionOverride, cacheMode, resolveFrameworkDependencies = true
}) {
log.verbose(`Creating project graph using object...`);
const {
Expand All @@ -169,7 +175,7 @@ export async function graphFromObject({
const projectGraph = await projectGraphBuilder(dependencyTreeProvider);

if (resolveFrameworkDependencies) {
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride});
await ui5Framework.enrichProjectGraph(projectGraph, {versionOverride, cacheMode});
}

return projectGraph;
Expand Down
6 changes: 3 additions & 3 deletions lib/graph/helpers/ui5Framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,10 @@ export default {
* @param {object} [options]
* @param {string} [options.versionOverride] Framework version to use instead of the root projects framework
* version
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [options.cacheMode]
* Cache mode to use when consuming SNAPSHOT versions
* @param {@ui5/project/graph/Workspace} [options.workspace]
* Optional workspace instance to use for overriding node resolutions
* @param {object} [options.resolverConfig]
* Optional configuration object to use for the resolvers
* @returns {Promise<@ui5/project/graph/ProjectGraph>}
* Promise resolving with the given graph instance to allow method chaining
*/
Expand Down Expand Up @@ -369,7 +369,7 @@ export default {
cwd: rootProject.getRootPath(),
version,
providedLibraryMetadata,
...options.resolverConfig,
cacheMode: options.cacheMode
});

let startTime;
Expand Down
5 changes: 3 additions & 2 deletions lib/ui5Framework/Sapui5MavenSnapshotResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class Sapui5MavenSnapshotResolver extends AbstractResolver {
* @param {string} [options.cwd=process.cwd()] Current working directory
* @param {string} [options.ui5HomeDir="~/.ui5"] UI5 home directory location. This will be used to store packages,
* metadata and configuration used by the resolvers. Relative to `process.cwd()`
* @param {string} [options.cacheMode="default"] Can be "default" (cache everything, invalidate after 9 hours),
* "off" (do not cache) and "force" (use cache only - no requests)
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [options.cacheMode=Default]
* Cache mode to use
*/
constructor(options) {
super(options);
Expand Down Expand Up @@ -136,6 +136,7 @@ class Sapui5MavenSnapshotResolver extends AbstractResolver {
snapshotEndpointUrl = process.env.UI5_MAVEN_SNAPSHOT_ENDPOINT_URL || snapshotEndpointUrl;

if (!snapshotEndpointUrl) {
// Return an unexecuted promise instead of the resolved URL here.
// If we resolve the settings.xml at this point, we'd need to always ask the end
// user for confirmation. In some cases where the resources are already cached,
// this is not necessary and we could skip it as a real request to the repository won't
Expand Down
18 changes: 18 additions & 0 deletions lib/ui5Framework/maven/CacheMode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@


/**
* Cache modes for maven consumption
*
* @public
* @readonly
* @enum {string}
* @property {string} Default Cache everything, invalidate after 9 hours
* @property {string} Force Use cache only
* @property {string} Off Do not use the cache
* @module @ui5/project/ui5Framework/maven/CacheMode
*/
export default {
Default: "Default",
Force: "Force",
Off: "Off"
};
16 changes: 10 additions & 6 deletions lib/ui5Framework/maven/Installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const StreamZip = _StreamZip.async;
import {promisify} from "node:util";
import Registry from "./Registry.js";
import AbstractInstaller from "../AbstractInstaller.js";
import CacheMode from "./CacheMode.js";
import {rimraf} from "rimraf";
const stat = promisify(fs.stat);
const readFile = promisify(fs.readFile);
Expand All @@ -26,10 +27,9 @@ class Installer extends AbstractInstaller {
* @param {Function} parameters.snapshotEndpointUrlCb Callback that returns a Promise <string>,
* resolving to the Maven repository URL.
* Example: <code>https://registry.corp/vendor/build-snapshots/</code>
* @param {string} [parameters.cacheMode="default"] Can be "default" (cache everything, invalidate after 9 hours),
* "off" (do not cache), "force" (use cache only - no requests)
* @param {module:@ui5/project/ui5Framework/maven/CacheMode} [parameters.cacheMode=Default] Cache mode to use
*/
constructor({ui5HomeDir, snapshotEndpointUrlCb, cacheMode = "default"}) {
constructor({ui5HomeDir, snapshotEndpointUrlCb, cacheMode = CacheMode.Default}) {
super(ui5HomeDir);

this._artifactsDir = path.join(ui5HomeDir, "framework", "artifacts");
Expand All @@ -43,6 +43,10 @@ class Installer extends AbstractInstaller {
if (!this._snapshotEndpointUrlCb) {
throw new Error(`Installer: Missing Snapshot-Endpoint URL callback parameter`);
}
if (!Object.values(CacheMode).includes(cacheMode)) {
throw new Error(`Installer: Invalid value '${cacheMode}' for cacheMode parameter. ` +
`Must be one of ${Object.values(CacheMode).join(", ")}`);
}

log.verbose(`Installing Maven artifacts to: ${this._artifactsDir}`);
log.verbose(`Installing Packages to: ${this._packagesDir}`);
Expand Down Expand Up @@ -119,16 +123,16 @@ class Installer extends AbstractInstaller {
return this._synchronize("metadata-" + fsId, async () => {
const localMetadata = await this._getLocalArtifactMetadata(fsId);

if (this._cacheMode === "force" && !localMetadata.revision) {
if (this._cacheMode === CacheMode.Force && !localMetadata.revision) {
throw new Error(`Could not find artifact ` +
`${logId} in local cache`);
}

const now = new Date().getTime();
const timeSinceLastCheck = now - localMetadata.lastCheck;

if (this._cacheMode !== "force" &&
(timeSinceLastCheck > CACHE_TIME || this._cacheMode === "off")) {
if (this._cacheMode !== CacheMode.Force &&
(timeSinceLastCheck > CACHE_TIME || this._cacheMode === CacheMode.Off)) {
// No cached metadata (-> timeSinceLastCheck equals time since 1970) or
// too old metadata or disabled cache
// => Retrieve metadata from repository
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"./ui5Framework/Sapui5MavenSnapshotResolver": "./lib/ui5Framework/Sapui5MavenSnapshotResolver.js",
"./ui5Framework/Openui5Resolver": "./lib/ui5Framework/Openui5Resolver.js",
"./ui5Framework/Sapui5Resolver": "./lib/ui5Framework/Sapui5Resolver.js",
"./ui5Framework/maven/CacheMode": "./lib/ui5Framework/maven/CacheMode.js",
"./validation/validator": "./lib/validation/validator.js",
"./validation/ValidationError": "./lib/validation/ValidationError.js",
"./graph/ProjectGraph": "./lib/graph/ProjectGraph.js",
Expand Down
6 changes: 4 additions & 2 deletions test/lib/graph/graph.integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ test.serial("graphFromPackageDependencies with inactive workspace file at custom
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride",
workspaceName: "default",
workspaceConfigPath: path.join(libraryHPath, "custom-ui5-workspace.yaml")
workspaceConfigPath: path.join(libraryHPath, "custom-ui5-workspace.yaml"),
cacheMode: "force"
});

t.is(res, "graph");
Expand All @@ -276,6 +277,7 @@ test.serial("graphFromPackageDependencies with inactive workspace file at custom
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride",
workspace: null
workspace: null,
cacheMode: "force"
}, "enrichProjectGraph got called with correct options");
});
26 changes: 18 additions & 8 deletions test/lib/graph/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ test.serial("graphFromPackageDependencies", async (t) => {
cwd: "cwd",
rootConfiguration: "rootConfiguration",
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride"
versionOverride: "versionOverride",
cacheMode: "off"
});

t.is(res, "graph");
Expand All @@ -81,7 +82,8 @@ test.serial("graphFromPackageDependencies", async (t) => {
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride",
workspace: undefined
workspace: undefined,
cacheMode: "off"
}, "enrichProjectGraph got called with correct options");
});

Expand All @@ -98,6 +100,7 @@ test.serial("graphFromPackageDependencies with workspace name", async (t) => {
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride",
workspaceName: "dolphin",
cacheMode: "off"
});

t.is(res, "graph");
Expand Down Expand Up @@ -128,7 +131,8 @@ test.serial("graphFromPackageDependencies with workspace name", async (t) => {
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride",
workspace: "workspace"
workspace: "workspace",
cacheMode: "off"
}, "enrichProjectGraph got called with correct options");
});

Expand Down Expand Up @@ -225,6 +229,7 @@ test.serial("graphFromPackageDependencies with empty workspace", async (t) => {
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride",
workspaceName: "dolphin",
cacheMode: "off"
});

t.is(res, "graph");
Expand Down Expand Up @@ -255,7 +260,8 @@ test.serial("graphFromPackageDependencies with empty workspace", async (t) => {
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride",
workspace: null
workspace: null,
cacheMode: "off"
}, "enrichProjectGraph got called with correct options");
});

Expand Down Expand Up @@ -290,7 +296,8 @@ test.serial("graphFromStaticFile", async (t) => {
filePath: "file/path",
rootConfiguration: "rootConfiguration",
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride"
versionOverride: "versionOverride",
cacheMode: "off"
});

t.is(res, "graph");
Expand All @@ -316,7 +323,8 @@ test.serial("graphFromStaticFile", async (t) => {
t.is(enrichProjectGraphStub.getCall(0).args[0], "graph",
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride"
versionOverride: "versionOverride",
cacheMode: "off"
}, "enrichProjectGraph got called with correct options");
});

Expand Down Expand Up @@ -351,7 +359,8 @@ test.serial("usingObject", async (t) => {
dependencyTree: "dependencyTree",
rootConfiguration: "rootConfiguration",
rootConfigPath: "/rootConfigPath",
versionOverride: "versionOverride"
versionOverride: "versionOverride",
cacheMode: "off"
});

t.is(res, "graph");
Expand All @@ -371,7 +380,8 @@ test.serial("usingObject", async (t) => {
t.is(enrichProjectGraphStub.getCall(0).args[0], "graph",
"enrichProjectGraph got called with graph");
t.deepEqual(enrichProjectGraphStub.getCall(0).args[1], {
versionOverride: "versionOverride"
versionOverride: "versionOverride",
cacheMode: "off"
}, "enrichProjectGraph got called with correct options");
});

Expand Down
14 changes: 11 additions & 3 deletions test/lib/graph/helpers/ui5Framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ test.serial("enrichProjectGraph", async (t) => {

t.is(t.context.Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.deepEqual(t.context.Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: dependencyTree.configuration.framework.version,
providedLibraryMetadata: undefined
Expand Down Expand Up @@ -177,7 +178,7 @@ test.serial("enrichProjectGraph: without framework configuration", async (t) =>

test.serial("enrichProjectGraph SNAPSHOT", async (t) => {
const {sinon, ui5Framework, utils, Sapui5MavenSnapshotResolverInstallStub} = t.context;
process.env.UI5_MAVEN_SNAPSHOT_ENDPOINT = "__url__";
process.env.UI5_MAVEN_SNAPSHOT_ENDPOINT_URL = "__url__";

const dependencyTree = {
id: "test1",
Expand Down Expand Up @@ -216,7 +217,9 @@ test.serial("enrichProjectGraph SNAPSHOT", async (t) => {
const provider = new DependencyTreeProvider({dependencyTree});
const projectGraph = await projectGraphBuilder(provider);

await ui5Framework.enrichProjectGraph(projectGraph);
await ui5Framework.enrichProjectGraph(projectGraph, {
cacheMode: "force"
});

t.is(getFrameworkLibrariesFromGraphStub.callCount, 1, "getFrameworkLibrariesFromGraph should be called once");

Expand Down Expand Up @@ -263,7 +266,7 @@ test.serial("enrichProjectGraph SNAPSHOT", async (t) => {
"application.a"
], "Traversed graph in correct order");

delete process.env.UI5_MAVEN_SNAPSHOT_ENDPOINT;
delete process.env.UI5_MAVEN_SNAPSHOT_ENDPOINT_URL;
});

test.serial("enrichProjectGraph: With versionOverride", async (t) => {
Expand Down Expand Up @@ -313,6 +316,7 @@ test.serial("enrichProjectGraph: With versionOverride", async (t) => {

t.is(Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.deepEqual(Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: "1.99.9",
providedLibraryMetadata: undefined
Expand Down Expand Up @@ -451,6 +455,7 @@ test.serial("enrichProjectGraph should resolve framework project with version an
t.is(getFrameworkLibrariesFromGraphStub.callCount, 1, "getFrameworkLibrariesFromGrap should be called once");
t.is(Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.deepEqual(Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: "1.2.3",
providedLibraryMetadata: undefined
Expand Down Expand Up @@ -531,6 +536,7 @@ test.serial("enrichProjectGraph should resolve framework project " +
t.is(Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.is(getFrameworkLibrariesFromGraphStub.callCount, 1, "getFrameworkLibrariesFromGraph should be called once");
t.deepEqual(Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: "1.99.9",
providedLibraryMetadata: undefined
Expand Down Expand Up @@ -794,6 +800,7 @@ test.serial("enrichProjectGraph should use framework library metadata from works

t.is(Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.deepEqual(Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: "1.111.1",
providedLibraryMetadata: workspaceFrameworkLibraryMetadata
Expand Down Expand Up @@ -851,6 +858,7 @@ test.serial("enrichProjectGraph should allow omitting framework version in case

t.is(Sapui5ResolverStub.callCount, 1, "Sapui5Resolver#constructor should be called once");
t.deepEqual(Sapui5ResolverStub.getCall(0).args, [{
cacheMode: undefined,
cwd: dependencyTree.path,
version: undefined,
providedLibraryMetadata: workspaceFrameworkLibraryMetadata
Expand Down
Loading

0 comments on commit fafa114

Please sign in to comment.