From a66127ffc964a355cdd4ef42ef58a3edee85ba35 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Fri, 2 Jun 2023 09:58:44 +0800 Subject: [PATCH] Add CustomContexts class and related test cases - Implemented CustomContexts class to handle custom contexts. - Added methods to parse, get, and handle custom context commands. - Created test cases for CustomContexts class in customContext.test.ts. --- src/context/customContext.ts | 92 ++++++++++++++++++++++++++++++ test/context/customContext.test.ts | 36 ++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/context/customContext.ts create mode 100644 test/context/customContext.test.ts diff --git a/src/context/customContext.ts b/src/context/customContext.ts new file mode 100644 index 0000000..63d3728 --- /dev/null +++ b/src/context/customContext.ts @@ -0,0 +1,92 @@ +import fs from 'fs'; +import path from 'path'; +import { logger } from '../util/logger'; + +import { runCommandStringArrayAndWriteOutput, CommandResult } from '../util/commonUtil'; + + +export interface CustomContext { + name: string; + description: string; + command: string[]; + path: string; +} + +class CustomContexts { + private static instance: CustomContexts | null = null; + private contexts: CustomContext[] = []; + + private constructor() { + } + + public static getInstance(): CustomContexts { + if (!CustomContexts.instance) { + CustomContexts.instance = new CustomContexts(); + } + return CustomContexts.instance; + } + + public parseContexts(workflowsDir: string): void { + this.contexts = []; + + try { + const extensionDirs = fs.readdirSync(workflowsDir, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + for (const extensionDir of extensionDirs) { + const contextDirPath = path.join(workflowsDir, extensionDir, 'context'); + if (fs.existsSync(contextDirPath)) { + const contextDirs = fs.readdirSync(contextDirPath, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + for (const contextDir of contextDirs) { + const settingsPath = path.join(contextDirPath, contextDir, '_setting_.json'); + if (fs.existsSync(settingsPath)) { + const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8')); + const context: CustomContext = { + name: settings.name, + description: settings.description, + command: settings.command, + path: path.join(contextDirPath, contextDir) + }; + this.contexts.push(context); + } + } + } + } + } catch (error) { + logger.channel()?.error(`Failed to parse contexts: ${error}`); + logger.channel()?.show(); + } + } + + public getContexts(): CustomContext[] { + return this.contexts; + } + + public getContext(contextName: string): CustomContext | null { + const foundContext = this.contexts.find(context => context.name === contextName); + return foundContext ? foundContext : null; + } + + public async handleCommand(contextName: string, outputFile: string): Promise { + const context = this.getContext(contextName); + if (!context) { + logger.channel()?.error(`Context not found: ${contextName}`); + logger.channel()?.show(); + return null; + } + + const contextDir = context.path; + const commandArray = context.command.slice(); // Create a copy of the command array + commandArray.forEach((arg, index) => { + commandArray[index] = arg.replace('${CurDir}', contextDir); + }); + + return await runCommandStringArrayAndWriteOutput(commandArray, outputFile); + } +} + +export default CustomContexts; \ No newline at end of file diff --git a/test/context/customContext.test.ts b/test/context/customContext.test.ts new file mode 100644 index 0000000..2246408 --- /dev/null +++ b/test/context/customContext.test.ts @@ -0,0 +1,36 @@ +import { expect } from 'chai'; +import CustomContexts from '../../src/context/customContext'; +import fs from 'fs'; +import path from 'path'; + +describe('CustomContexts', () => { + const workflowsDir = path.join(__dirname, 'test-workflows'); + + before(() => { + // Create a test workflows directory with a sample _setting_.json file + if (!fs.existsSync(workflowsDir)) { + fs.mkdirSync(workflowsDir); + } + const extensionDir = path.join(workflowsDir, 'extension1', 'context', 'context1'); + fs.mkdirSync(extensionDir, { recursive: true }); + fs.writeFileSync(path.join(extensionDir, '_setting_.json'), JSON.stringify({ + name: 'test-context', + description: 'Test context', + command: ['echo', 'Hello, World!'] + })); + }); + + after(() => { + // Clean up the test workflows directory + fs.rmdirSync(workflowsDir, { recursive: true }); + }); + + it('should parse custom contexts', () => { + const customContexts = CustomContexts.getInstance(); + customContexts.parseContexts(workflowsDir); + const contexts = customContexts.getContexts(); + expect(contexts).to.have.lengthOf(1); + expect(contexts[0].name).to.equal('test-context'); + expect(contexts[0].description).to.equal('Test context'); + }); +}); \ No newline at end of file