UNPKG

@ui5/task-adaptation

Version:

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

118 lines 5.11 kB
import { dotToUnderscore, isManifestChange } from "./util/commonUtil.js"; import FilesUtil from "./util/filesUtil.js"; import ResourceUtil from "./util/resourceUtil.js"; import { posix as path } from "path"; import { moveFile, moveFiles } from "./util/movingHandler/fileMoveHandler.js"; const CHANGES_EXT = ".change"; export default class AppVariant { files; resources; id; reference; layer; content; prefix = ""; movedFiles = new Map(); renaming = new Map(); 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; // Prefix is a subfolder for the app variant to store js, fragments, // annotations and i18n files. It can be anything, but for convenience // it is an app variant id. this.prefix = dotToUnderscore(this.id); } getProcessedFiles() { const { files, renamingPaths } = moveFiles(this.files, this.prefix, this.id); // Directly rename files that with new paths, this ensures no conflict in further renaming // In later remaming it's not possible to find correct prefix of moved files return FilesUtil.rename(files, renamingPaths); } ; /** * Since we moved files, we need to update paths where they were referenced. * To do this we use renameMap function along with renaming ids. */ getRenamingForMovedFiles() { const renaming = new Map(); const slashToDot = (str) => str.replaceAll("\/", "."); this.renaming.forEach((newPath, oldPath) => { renaming.set(slashToDot(oldPath), slashToDot(newPath)); }); return renaming; } ; getProcessedManifestChanges() { // Order: manifest changes first, then *.change files const manifestChanges = structuredClone(this.content) ?? []; this.files.forEach((content, filename) => { if (filename.endsWith(CHANGES_EXT)) { const change = JSON.parse(content); if (isManifestChange(filename, content)) { const { newFilename } = moveFile(filename, content, this.prefix, this.id); this.updateRelativePaths(change, newFilename); 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); } } } } /** * 3p. We not only omit files, which were moved or deleted from the resulted * file set, but also update existing adaptation project resources with * renamed content, otherwise flexibility-bundle will contain not renamed * content of files. */ 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); if (this.movedFiles.has(relativePath)) { const newPath = this.movedFiles.get(relativePath); const renamedContent = files.get(newPath); resource.setString(renamedContent); } } } } } //# sourceMappingURL=appVariantManager.js.map