@ui5/task-adaptation
Version:
Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment
99 lines • 4.01 kB
JavaScript
import ResourceUtil from "./util/resourceUtil.js";
import { posix as path } from "path";
import { rename } from "./util/commonUtil.js";
const CHANGES_DIR = "changes/";
const CHANGES_EXT = ".change";
const MANIFEST_CHANGE = "appdescr_";
export default class AppVariant {
files;
resources;
id;
reference;
layer;
content;
static async fromWorkspace(workspace, projectNamespace) {
const EXTENSIONS_TO_PROCESS = "js,json,xml,html,properties,change,appdescr_variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change,variant,fioriversion,codeChange,xmlViewChange,context";
const resources = await workspace.byGlob(`/**/*.{${EXTENSIONS_TO_PROCESS}}`);
const files = await ResourceUtil.toFileMap(resources, projectNamespace);
return new AppVariant(files, resources);
}
static fromFiles(files) {
return new AppVariant(files);
}
constructor(files, resources) {
this.files = files;
this.resources = resources;
const manifestString = files.get("manifest.appdescr_variant");
this.validateManifest(manifestString);
const { reference, id, layer, content } = JSON.parse(manifestString);
this.reference = reference;
this.id = id;
this.layer = layer;
this.content = content;
}
getProcessedFiles() {
const files = new Map();
this.files.forEach((content, filename) => {
if (filename.startsWith(CHANGES_DIR)) {
if (!this.isManifestChange(filename, content)) {
files.set(filename, rename(content, this.reference, this.id));
}
}
else if (filename !== "manifest.appdescr_variant") {
files.set(filename, content);
}
});
return files;
}
getProcessedManifestChanges() {
// Order is important: apply manifest.json changes first, then *.change
// files. UI5 does the same.
const manifestChanges = structuredClone(this.content) ?? [];
this.files.forEach((content, filename) => {
if (this.isManifestChange(filename, content)) {
const change = JSON.parse(rename(content, this.reference, this.id));
this.updateRelativePaths(change, filename);
manifestChanges.push(change);
}
});
if (this.layer) {
manifestChanges.forEach(change => change.layer = this.layer ?? change.layer);
}
return manifestChanges;
}
validateManifest(manifest) {
if (!manifest) {
throw new Error("Adaptation project should contain manifest.appdescr_variant");
}
}
updateRelativePaths(change, filename) {
// TODO In future this should be handled by merger which needs to know change and target location
if (change.changeType === "appdescr_app_addAnnotationsToOData") {
for (const dataSource of Object.values(change?.content?.dataSource)) {
if (!dataSource.uri.startsWith("/")) {
const basepath = path.dirname(filename);
dataSource.uri = path.join(basepath.replace(/^\//, ""), dataSource.uri);
}
}
}
}
isManifestChange(filename, content) {
if (filename.endsWith(CHANGES_EXT)) {
const change = JSON.parse(content);
return change.changeType?.startsWith(MANIFEST_CHANGE);
}
return false;
}
omitDeletedResources(files, projectNamespace, taskUtil) {
if (!this.resources) {
return;
}
for (const resource of this.resources) {
const relativePath = ResourceUtil.relativeToRoot(resource.getPath(), projectNamespace);
if (!files.has(relativePath)) {
taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
}
}
}
}
//# sourceMappingURL=appVariantManager.js.map