Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Sapui5MavenSnapshotResolver: Use npm-dist.zip artifact for 1.116.0 and later #622

Merged
merged 5 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions lib/ui5Framework/Sapui5MavenSnapshotResolver.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from "node:path";
import os from "node:os";
import semver from "semver";
import AbstractResolver from "./AbstractResolver.js";
import Installer from "./maven/Installer.js";
import {getLogger} from "@ui5/logger";
Expand Down Expand Up @@ -50,6 +51,11 @@ class Sapui5MavenSnapshotResolver extends AbstractResolver {
cacheMode,
});
this._loadDistMetadata = null;

// TODO 4.0: Remove support for legacy snapshot versions
this._isLegacySnapshotVersion = semver.lt(this._version, "1.116.0-SNAPSHOT", {
includePrerelease: true
});
}
loadDistMetadata() {
if (!this._loadDistMetadata) {
Expand Down Expand Up @@ -95,8 +101,28 @@ class Sapui5MavenSnapshotResolver extends AbstractResolver {
}
const gav = metadata.gav.split(":");
let pkgName = metadata.npmPackageName;
if (!this._sources) {

// Use "npm-dist" artifact by default
let classifier;
let extension;
if (this._sources) {
// Use npm-sources artifact if sources are requested
classifier = "npm-sources";
extension = "zip";
} else {
// Add "prebuilt" suffix to package name
pkgName += "-prebuilt";

if (this._isLegacySnapshotVersion) {
// For legacy versions < 1.116.0-SNAPSHOT where npm-dist artifact is not
// yet available, use "default" JAR
classifier = null;
extension = "jar";
} else {
// Use "npm-dist" artifact by default
classifier = "npm-dist";
extension = "zip";
}
}

return {
Expand All @@ -112,8 +138,8 @@ class Sapui5MavenSnapshotResolver extends AbstractResolver {
groupId: gav[0],
artifactId: gav[1],
version: metadata.version,
classifier: this._sources ? "npm-sources" : null,
extension: this._sources ? "zip" : "jar",
classifier,
extension,
}),
};
}
Expand Down
6 changes: 1 addition & 5 deletions lib/ui5Framework/maven/Installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,7 @@ class Installer extends AbstractInstaller {
}

async _projectExists(targetDir) {
const markers = await Promise.all([
this._pathExists(path.join(targetDir, "package.json")),
this._pathExists(path.join(targetDir, ".ui5", "build-manifest.json"))
]);
return markers.includes(true);
return this._pathExists(path.join(targetDir, "package.json"));
}

async _pathExists(targetPath) {
Expand Down
170 changes: 166 additions & 4 deletions test/lib/ui5framework/Sapui5MavenSnapshotResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,69 @@ test.serial("Sapui5MavenSnapshotResolver: handleLibrary", async (t) => {

const resolver = new Sapui5MavenSnapshotResolver({
cwd: "/test-project/",
version: "1.75.0"
version: "1.116.0-SNAPSHOT"
});

const loadDistMetadataStub = sinon.stub(resolver, "loadDistMetadata");
loadDistMetadataStub.resolves({
libraries: {
"sap.ui.lib1": {
"npmPackageName": "@openui5/sap.ui.lib1",
"version": "1.116.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": [],
"gav": "x:y:z"
}
}
});

t.context.installPackageStub
.callsFake(async ({pkgName, version}) => {
throw new Error(`Unknown install call: ${pkgName}@${version}`);
})
.withArgs({
pkgName: "@openui5/sap.ui.lib1-prebuilt",
groupId: "x",
artifactId: "y",
version: "1.116.0-SNAPSHOT",
classifier: "npm-dist",
extension: "zip",
})
.resolves({pkgPath: "/foo/sap.ui.lib1"});


const promises = await resolver.handleLibrary("sap.ui.lib1");

t.true(promises.metadata instanceof Promise, "Metadata promise should be returned");
t.true(promises.install instanceof Promise, "Install promise should be returned");

const metadata = await promises.metadata;
t.deepEqual(metadata, {
"id": "@openui5/sap.ui.lib1-prebuilt",
"version": "1.116.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": []
}, "Expected library metadata should be returned");

t.deepEqual(await promises.install, {pkgPath: "/foo/sap.ui.lib1"}, "Install should resolve with expected object");
t.is(loadDistMetadataStub.callCount, 1, "loadDistMetadata should be called once");
});


test.serial("Sapui5MavenSnapshotResolver: handleLibrary - legacy version", async (t) => {
const {Sapui5MavenSnapshotResolver} = t.context;

const resolver = new Sapui5MavenSnapshotResolver({
cwd: "/test-project/",
version: "1.75.0-SNAPSHOT"
});

const loadDistMetadataStub = sinon.stub(resolver, "loadDistMetadata");
loadDistMetadataStub.resolves({
libraries: {
"sap.ui.lib1": {
"npmPackageName": "@openui5/sap.ui.lib1",
"version": "1.75.0",
"version": "1.75.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": [],
"gav": "x:y:z"
Expand All @@ -156,7 +210,7 @@ test.serial("Sapui5MavenSnapshotResolver: handleLibrary", async (t) => {
pkgName: "@openui5/sap.ui.lib1-prebuilt",
groupId: "x",
artifactId: "y",
version: "1.75.0",
version: "1.75.0-SNAPSHOT",
classifier: null,
extension: "jar",
})
Expand All @@ -171,7 +225,115 @@ test.serial("Sapui5MavenSnapshotResolver: handleLibrary", async (t) => {
const metadata = await promises.metadata;
t.deepEqual(metadata, {
"id": "@openui5/sap.ui.lib1-prebuilt",
"version": "1.75.0",
"version": "1.75.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": []
}, "Expected library metadata should be returned");

t.deepEqual(await promises.install, {pkgPath: "/foo/sap.ui.lib1"}, "Install should resolve with expected object");
t.is(loadDistMetadataStub.callCount, 1, "loadDistMetadata should be called once");
});

test.serial("Sapui5MavenSnapshotResolver: handleLibrary - sources requested", async (t) => {
const {Sapui5MavenSnapshotResolver} = t.context;

const resolver = new Sapui5MavenSnapshotResolver({
cwd: "/test-project/",
version: "1.116.0-SNAPSHOT",
sources: true
});

const loadDistMetadataStub = sinon.stub(resolver, "loadDistMetadata");
loadDistMetadataStub.resolves({
libraries: {
"sap.ui.lib1": {
"npmPackageName": "@openui5/sap.ui.lib1",
"version": "1.116.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": [],
"gav": "x:y:z"
}
}
});

t.context.installPackageStub
.callsFake(async ({pkgName, version}) => {
throw new Error(`Unknown install call: ${pkgName}@${version}`);
})
.withArgs({
pkgName: "@openui5/sap.ui.lib1",
groupId: "x",
artifactId: "y",
version: "1.116.0-SNAPSHOT",
classifier: "npm-sources",
extension: "zip",
})
.resolves({pkgPath: "/foo/sap.ui.lib1"});


const promises = await resolver.handleLibrary("sap.ui.lib1");

t.true(promises.metadata instanceof Promise, "Metadata promise should be returned");
t.true(promises.install instanceof Promise, "Install promise should be returned");

const metadata = await promises.metadata;
t.deepEqual(metadata, {
"id": "@openui5/sap.ui.lib1",
"version": "1.116.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": []
}, "Expected library metadata should be returned");

t.deepEqual(await promises.install, {pkgPath: "/foo/sap.ui.lib1"}, "Install should resolve with expected object");
t.is(loadDistMetadataStub.callCount, 1, "loadDistMetadata should be called once");
});

test.serial("Sapui5MavenSnapshotResolver: handleLibrary - sources requested with legacy version", async (t) => {
const {Sapui5MavenSnapshotResolver} = t.context;

const resolver = new Sapui5MavenSnapshotResolver({
cwd: "/test-project/",
version: "1.75.0-SNAPSHOT",
sources: true
});

const loadDistMetadataStub = sinon.stub(resolver, "loadDistMetadata");
loadDistMetadataStub.resolves({
libraries: {
"sap.ui.lib1": {
"npmPackageName": "@openui5/sap.ui.lib1",
"version": "1.75.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": [],
"gav": "x:y:z"
}
}
});

t.context.installPackageStub
.callsFake(async ({pkgName, version}) => {
throw new Error(`Unknown install call: ${pkgName}@${version}`);
})
.withArgs({
pkgName: "@openui5/sap.ui.lib1",
groupId: "x",
artifactId: "y",
version: "1.75.0-SNAPSHOT",
classifier: "npm-sources",
extension: "zip",
})
.resolves({pkgPath: "/foo/sap.ui.lib1"});


const promises = await resolver.handleLibrary("sap.ui.lib1");

t.true(promises.metadata instanceof Promise, "Metadata promise should be returned");
t.true(promises.install instanceof Promise, "Install promise should be returned");

const metadata = await promises.metadata;
t.deepEqual(metadata, {
"id": "@openui5/sap.ui.lib1",
"version": "1.75.0-SNAPSHOT",
"dependencies": [],
"optionalDependencies": []
}, "Expected library metadata should be returned");
Expand Down
72 changes: 66 additions & 6 deletions test/lib/ui5framework/maven/Installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -985,10 +985,12 @@ test.serial("_pathExists", async (t) => {
snapshotEndpointUrlCb: () => {}
});

statStub.resolves("/target/path/");
const pathExists = await installer._pathExists();
statStub.resolves();
const pathExists = await installer._pathExists("/target/path/");

t.is(pathExists, true, "Resolves the target path");
t.is(pathExists, true, "Target path exists");
t.is(statStub.callCount, 1, "stat got called once");
t.is(statStub.firstCall.firstArg, "/target/path/", "stat got called with expected argument");
});

test.serial("_pathExists file not found", async (t) => {
Expand All @@ -1001,9 +1003,9 @@ test.serial("_pathExists file not found", async (t) => {
});

statStub.throws({code: "ENOENT"});
const pathExists = await installer._pathExists();
const pathExists = await installer._pathExists("/target/path/");

t.is(pathExists, false, "Target path is not resolved");
t.is(pathExists, false, "Target path does not exist");
});

test.serial("_pathExists throws", async (t) => {
Expand All @@ -1019,7 +1021,65 @@ test.serial("_pathExists throws", async (t) => {
throw new Error("Error message");
});

await t.throwsAsync(installer._pathExists(), {
await t.throwsAsync(installer._pathExists("/target/path/"), {
message: "Error message",
}, "Threw with expected error message");
});

test.serial("_projectExists", async (t) => {
const {Installer} = t.context;

const installer = new Installer({
cwd: "/cwd/",
ui5HomeDir: "/ui5Home/",
snapshotEndpointUrlCb: () => {}
});

const pathExistsStub = sinon.stub(installer, "_pathExists").resolves(true);
const projectExists = await installer._projectExists("/target/path/");

t.is(projectExists, true, "Resolves the target path");
t.is(pathExistsStub.callCount, 1, "_pathExists got called once");
t.is(pathExistsStub.firstCall.firstArg, path.join("/target/path/package.json"),
"_pathExists got called with expected argument");
});

test.serial("_projectExists: Does not exist", async (t) => {
const {Installer} = t.context;

const installer = new Installer({
cwd: "/cwd/",
ui5HomeDir: "/ui5Home/",
snapshotEndpointUrlCb: () => {}
});

const pathExistsStub = sinon.stub(installer, "_pathExists").resolves(false);
const projectExists = await installer._projectExists("/target/path/");

t.is(projectExists, false, "Resolves the target path");
t.is(pathExistsStub.callCount, 1, "_pathExists got called once");
t.is(pathExistsStub.firstCall.firstArg, path.join("/target/path/package.json"),
"_pathExists got called with expected argument");
});

test.serial("_projectExists: Throws", async (t) => {
const {Installer} = t.context;

const installer = new Installer({
cwd: "/cwd/",
ui5HomeDir: "/ui5Home/",
snapshotEndpointUrlCb: () => {}
});

const pathExistsStub = sinon.stub(installer, "_pathExists").throws(() => {
throw new Error("Error message");
});

await t.throwsAsync(installer._projectExists("/target/path/"), {
message: "Error message",
}, "Threw with expected error message");

t.is(pathExistsStub.callCount, 1, "_pathExists got called once");
t.is(pathExistsStub.firstCall.firstArg, path.join("/target/path/package.json"),
"_pathExists got called with expected argument");
});