From 3b44ed19a325cb3579f497693d57be66b3a6caa4 Mon Sep 17 00:00:00 2001 From: Matt Carvin <90224411+mcarvin8@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:12:53 -0500 Subject: [PATCH] feat: rename purge flag to prepurge and add postpurge flag to disassemble class --- README.md | 14 +++++++-- src/service/buildDisassembledFiles.ts | 7 +++++ src/service/disassembleXMLFileHandler.ts | 23 ++++++++++---- test/main.spec.ts | 39 +++++++++++++++++++++--- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 109f661..165c536 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ npm install xml-disassembler ## Disassembling Files +Disassemble 1 or multiple XML files in the immediate directory (`xmlPath`), without recursion. Each XML will be disassembled into their own sub-directories using their base name (everything before the first `.` in the file-name). + Import the `DisassembleXMLFileHandler` class from the package. ```typescript @@ -37,8 +39,10 @@ FLAGS - xmlPath: Directory containing the XML files to disassemble (must be directory). This will only disassemble files in the immediate directory. - uniqueIdElements: (Optional) Comma-separated list of unique and required ID elements used to name disassembled files for nested elements. Defaults to SHA-256 hash if unique ID elements are undefined or not found. -- purge: (Optional) Boolean value. If set to true, purge pre-existing disassembled directories prior to disassembling the file. +- prepurge: (Optional) Boolean value. If set to true, purge pre-existing disassembled directories prior to disassembling the file. Defaults to false. +- postpurge: (Optional) Boolean value. If set to true, purge the original XML file after disassembling it. + Defaults to false. */ import { DisassembleXMLFileHandler } from "xml-disassembler"; @@ -47,7 +51,8 @@ await handler.disassemble({ xmlPath: "test/baselines/general", uniqueIdElements: "application,apexClass,name,externalDataSource,flow,object,apexPage,recordType,tab,field", - purge: true, + prepurge: true, + postpurge: true, }); ``` @@ -117,6 +122,8 @@ will be disassembled as such: ## Reassembling Files +Reassemble 1 XML directory (`xmlPath`) containing disassembled files back into 1 XML file. + Import the `ReassembleXMLFileHandler` class from the package. ```typescript @@ -177,7 +184,8 @@ await disassembleHandler.disassemble({ xmlPath: "test/baselines/general", uniqueIdElements: "application,apexClass,name,externalDataSource,flow,object,apexPage,recordType,tab,field", - purge: true, + prepurge: true, + postpurge: true, }); const reassembleHandler = new ReassembleXMLFileHandler(); diff --git a/src/service/buildDisassembledFiles.ts b/src/service/buildDisassembledFiles.ts index 1bc6139..57ca0bc 100644 --- a/src/service/buildDisassembledFiles.ts +++ b/src/service/buildDisassembledFiles.ts @@ -1,6 +1,7 @@ "use strict"; import * as fs from "node:fs"; +import * as promise from "node:fs/promises"; import * as path from "node:path"; import { logger } from "@src/index"; import { XMLParser } from "fast-xml-parser"; @@ -16,6 +17,8 @@ export function buildDisassembledFiles( uniqueIdElements: string | undefined, baseName: string, indent: string, + postpurge: boolean, + parentPath: string, ): void { const xmlParser = new XMLParser(XML_PARSER_OPTION); const result = xmlParser.parse(xmlString) as Record; @@ -105,6 +108,10 @@ export function buildDisassembledFiles( fs.writeFileSync(leafOutputPath, leafFile); logger.debug(`Created disassembled file: ${leafOutputPath}`); + if (postpurge) { + const originalFilePath = path.resolve(`${parentPath}/${baseName}.xml`); + promise.unlink(originalFilePath); + } } } diff --git a/src/service/disassembleXMLFileHandler.ts b/src/service/disassembleXMLFileHandler.ts index 132c7de..2fc9831 100644 --- a/src/service/disassembleXMLFileHandler.ts +++ b/src/service/disassembleXMLFileHandler.ts @@ -8,9 +8,15 @@ export class DisassembleXMLFileHandler { async disassemble(xmlAttributes: { xmlPath: string; uniqueIdElements?: string; - purge?: boolean; + prepurge?: boolean; + postpurge?: boolean; }): Promise { - const { xmlPath, uniqueIdElements, purge = false } = xmlAttributes; + const { + xmlPath, + uniqueIdElements, + prepurge = false, + postpurge = false, + } = xmlAttributes; const fileStat = await fs.stat(xmlPath); if (!fileStat.isDirectory()) { @@ -24,7 +30,8 @@ export class DisassembleXMLFileHandler { xmlPath, filePath, uniqueIdElements, - purge, + prepurge, + postpurge, }); } } @@ -33,9 +40,11 @@ export class DisassembleXMLFileHandler { xmlPath: string; filePath: string; uniqueIdElements?: string; - purge?: boolean; + prepurge: boolean; + postpurge: boolean; }): Promise { - const { xmlPath, filePath, uniqueIdElements, purge } = xmlAttributes; + const { xmlPath, filePath, uniqueIdElements, prepurge, postpurge } = + xmlAttributes; if (filePath.endsWith(".xml")) { logger.debug(`Parsing file to disassemble: ${filePath}`); @@ -46,7 +55,7 @@ export class DisassembleXMLFileHandler { let outputPath; outputPath = path.join(xmlPath, baseName); - if (purge) { + if (prepurge) { await fs.rm(outputPath, { recursive: true }); } @@ -56,6 +65,8 @@ export class DisassembleXMLFileHandler { uniqueIdElements, fullName, INDENT, + postpurge, + xmlPath, ); } } diff --git a/test/main.spec.ts b/test/main.spec.ts index 73f4469..8b3512d 100644 --- a/test/main.spec.ts +++ b/test/main.spec.ts @@ -1,3 +1,4 @@ +import * as fs from "node:fs/promises"; import { DisassembleXMLFileHandler, ReassembleXMLFileHandler, @@ -24,12 +25,13 @@ describe("main function", () => { xmlPath: "test/baselines/general", uniqueIdElements: "application,apexClass,name,externalDataSource,flow,object,apexPage,recordType,tab,field", + postpurge: true, }); // Ensure that the logger.debug spy was called with the correct message expect(logger.error).not.toHaveBeenCalled(); }); - it('should reassemble a general XML file (nested and leaf elements) with a namespace and file extension."', async () => { + it('should reassemble a general XML file (nested and leaf elements) with a namespace and alternate file extension."', async () => { const handler = new ReassembleXMLFileHandler(); await handler.reassemble({ xmlPath: "test/baselines/general/HR_Admin", @@ -44,12 +46,13 @@ describe("main function", () => { await handler.disassemble({ xmlPath: "test/baselines/cdata", uniqueIdElements: "apiName", + postpurge: true, }); // Ensure that the logger.debug spy was called with the correct message expect(logger.error).not.toHaveBeenCalled(); }); - it("should reassemble a XML file with CDATA.", async () => { + it("should reassemble a XML file with CDATA. and no alternate file extension.", async () => { const handler = new ReassembleXMLFileHandler(); await handler.reassemble({ xmlPath: "test/baselines/cdata/VidLand_US", @@ -63,6 +66,7 @@ describe("main function", () => { await handler.disassemble({ xmlPath: "test/baselines/comments", uniqueIdElements: "invalid", + postpurge: true, }); // Ensure that the logger.debug spy was called with the correct message @@ -83,6 +87,17 @@ describe("main function", () => { xmlPath: "test/baselines/child-unique-id-element", uniqueIdElements: "apexClass,name,object,field,layout,actionName,targetReference,assignToReference,choiceText,promptText", + postpurge: true, + }); + + // Ensure that the logger.debug spy was called with the correct message + expect(logger.error).not.toHaveBeenCalled(); + }); + it("should reassemble a XML file with a deeply nested unique ID element.", async () => { + const handler = new ReassembleXMLFileHandler(); + await handler.reassemble({ + xmlPath: "test/baselines/child-unique-id-element/Get_Info", + fileExtension: "flow-meta.xml", }); // Ensure that the logger.debug spy was called with the correct message @@ -92,12 +107,13 @@ describe("main function", () => { const handler = new DisassembleXMLFileHandler(); await handler.disassemble({ xmlPath: "test/baselines/array-of-leafs", + postpurge: true, }); // Ensure that the logger.debug spy was called with the correct message expect(logger.error).not.toHaveBeenCalled(); }); - it("should disassemble a XML file with an array of leaf elements and no defined unique ID element.", async () => { + it("should reassemble a XML file with an array of leaf elements and no defined unique ID element.", async () => { const handler = new ReassembleXMLFileHandler(); await handler.reassemble({ xmlPath: "test/baselines/array-of-leafs/Dreamhouse", @@ -111,7 +127,18 @@ describe("main function", () => { const handler = new DisassembleXMLFileHandler(); await handler.disassemble({ xmlPath: "test/baselines/array-of-leafs", - purge: true, + prepurge: true, + postpurge: true, + }); + + // Ensure that the logger.debug spy was called with the correct message + expect(logger.error).not.toHaveBeenCalled(); + }); + it("should reassemble the files from the previous test (prepurge).", async () => { + const handler = new ReassembleXMLFileHandler(); + await handler.reassemble({ + xmlPath: "test/baselines/array-of-leafs/Dreamhouse", + fileExtension: "app-meta.xml", }); // Ensure that the logger.debug spy was called with the correct message @@ -125,6 +152,10 @@ describe("main function", () => { "application,apexClass,name,externalDataSource,flow,object,apexPage,recordType,tab,field", }); + // Delete the original file manaully to ensure false "postpurge" is tested + // but ensure the file is recreated by the next test + fs.unlink("test/baselines/no-namespace/HR_Admin.permissionset-meta.xml"); + // Ensure that the logger.debug spy was called with the correct message expect(logger.error).not.toHaveBeenCalled(); });