UNPKG

@ui5/task-adaptation

Version:

Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment

102 lines 4.89 kB
import ResourceUtil from "./util/resourceUtil.js"; import { posix as path } from "path"; import { renameResources } from "./util/commonUtil.js"; 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"; export default class AppVariantManager { static async process(appVariantResources, projectNamespace, taskUtil) { for (const resource of appVariantResources) { this.omitFiles(resource, taskUtil); } await this.updateChanges(appVariantResources, projectNamespace); return this.getAppVariantInfo(appVariantResources); } static getAppVariantResourcesToProcess(workspace) { return workspace.byGlob(`/**/*.{${EXTENSIONS_TO_PROCESS}}`); } static async updateChanges(appVariantResources, projectNamespace) { const changesFolder = ResourceUtil.getResourcePath(projectNamespace, "changes"); const changes = new Map(); const resourcesByPath = new Map(); let manifest; for (const resource of appVariantResources) { if (this.isManifestAppVariant(resource)) { manifest = await ResourceUtil.getJson(resource); } const resourcePath = resource.getPath(); const basename = path.dirname(resourcePath); if (basename.startsWith(changesFolder)) { changes.set(resourcePath, await ResourceUtil.getString(resource)); resourcesByPath.set(resourcePath, resource); } } this.updateRelativePaths(changes, projectNamespace); this.validateManifest(manifest); const renamedChanges = renameResources(changes, manifest.reference, manifest.id); renamedChanges.forEach((renamedContent, resourcePath) => { const resource = resourcesByPath.get(resourcePath); ResourceUtil.setString(resource, renamedContent); }); } static isManifestChange(resource) { const changesManifestFolder = path.join("changes", "manifest"); const resourcePath = typeof resource === "string" ? resource : resource.getPath(); const dirname = path.dirname(resourcePath); return dirname.endsWith(changesManifestFolder); } static isManifestAppVariant(resource) { const MANIFEST_APP_VARIANT = "manifest.appdescr_variant"; const basename = path.basename(resource.getPath()); return basename === MANIFEST_APP_VARIANT; } static async getAppVariantInfo(appVariantResources) { let manifest; const manifestChanges = []; for (const resource of appVariantResources) { if (this.isManifestAppVariant(resource)) { manifest = await ResourceUtil.getJson(resource); } else if (this.isManifestChange(resource)) { const content = await ResourceUtil.getString(resource); manifestChanges.push(JSON.parse(content)); } } this.validateManifest(manifest); // Order is important: apply manifest.json changes first, then *.change // files. UI5 does the same. const changes = (manifest.content ?? []).concat(manifestChanges); return { id: manifest.id, reference: manifest.reference, layer: manifest.layer, changes }; } static validateManifest(manifest) { if (!manifest) { throw new Error("Adaptation project should contain manifest.appdescr_variant"); } } // TODO In future this should be handled by merger which needs to know change and target location static updateRelativePaths(changes, projectNamespace) { changes.forEach((jsonString, resourcePath) => { if (this.isManifestChange(resourcePath)) { const change = JSON.parse(jsonString); if (change.changeType === "appdescr_app_addAnnotationsToOData") { for (const dataSource of Object.values(change.content.dataSource)) { if (!dataSource.uri.startsWith("/")) { const basepath = path.dirname(ResourceUtil.relativeToRoot(resourcePath, projectNamespace)); dataSource.uri = path.join(basepath.replace(/^\//, ""), dataSource.uri); } } changes.set(resourcePath, JSON.stringify(change)); } } }); } static omitFiles(resource, taskUtil) { if (this.isManifestAppVariant(resource) || this.isManifestChange(resource)) { taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true); } } } //# sourceMappingURL=appVariantManager.js.map