diff --git a/package.json b/package.json index babac5e..5183f10 100644 --- a/package.json +++ b/package.json @@ -59,18 +59,24 @@ "typescript-eslint": "7.6.0" }, "dependencies": { + "@xmldom/xmldom": "0.8.10", "axios": "1.6.8", "commander": "12.0.0", "docker-compose": "0.24.8", "exit-hook": "4.0.0", + "fast-xml-parser": "4.3.6", "js-yaml": "4.1.0", "mysql2": "3.9.4", "pg": "8.11.5", "sequelize": "6.37.2", "simple-git": "3.24.0", - "tedious": "18.1.0" + "tedious": "18.1.0", + "xpath": "0.0.34" }, "release": { - "branches": ["main", "next"] + "branches": [ + "main", + "next" + ] } } diff --git a/src/applications/amps.ts b/src/applications/amps.ts new file mode 100644 index 0000000..e1f3906 --- /dev/null +++ b/src/applications/amps.ts @@ -0,0 +1,59 @@ + +import { DOMParser, XMLSerializer } from '@xmldom/xmldom'; +import { XMLParser } from 'fast-xml-parser'; +import { existsSync, readFileSync } from 'fs' +import xpath from 'xpath'; + +import { SupportedApplications } from '../types/SupportedApplications'; + +export class AMPS { + + public static isAtlassianPlugin = (): boolean => { + try { + const hasPomFile = existsSync('./pom.xml'); + if (hasPomFile) { + const content = readFileSync('./pom.xml', 'utf8'); + const parser = new XMLParser(); + const pom = parser.parse(content); + return pom?.project?.packaging === 'atlassian-plugin'; + } + return false; + } catch (err) { + return false; + } + } + + public static getApplication(): SupportedApplications|null { + const applications = AMPS.getApplications(); + return applications.length === 1 ? applications[0] : null; + } + + public static getApplications(): Array { + const result = new Set(); + if (AMPS.isAtlassianPlugin()) { + const xml = readFileSync('./pom.xml', 'utf8'); + const doc = new DOMParser().parseFromString(xml, 'text/xml'); + const nodes = xpath.select('//*[local-name()=\'groupId\' and text()=\'com.atlassian.maven.plugins\']', doc); + if (Array.isArray(nodes)) { + nodes.forEach(node => { + const parentNode = node.parentNode; + if (parentNode) { + const parser = new XMLParser(); + const { plugin } = parser.parse(new XMLSerializer().serializeToString(parentNode)); + if (plugin?.artifactId?.includes(SupportedApplications.JIRA)) { + result.add(SupportedApplications.JIRA); + } else if (plugin?.artifactId?.includes(SupportedApplications.CONFLUENCE)) { + result.add(SupportedApplications.CONFLUENCE); + } else if (plugin?.artifactId?.includes(SupportedApplications.BAMBOO)) { + result.add(SupportedApplications.BAMBOO); + } else if (plugin?.artifactId?.includes(SupportedApplications.BITBUCKET)) { + result.add(SupportedApplications.BITBUCKET); + } + } + }); + } + } + return Array.from(result); + } + +} \ No newline at end of file diff --git a/src/applications/bamboo.ts b/src/applications/bamboo.ts index 8e02d1b..8333ed1 100644 --- a/src/applications/bamboo.ts +++ b/src/applications/bamboo.ts @@ -11,7 +11,7 @@ import { Base } from './base'; export class Bamboo extends Base { - name: SupportedApplications = 'bamboo'; + name = SupportedApplications.BAMBOO; database: DatabaseEngine; logFilePath = '/var/atlassian/application-data/bamboo/logs/atlassian-bamboo.log'; diff --git a/src/applications/bitbucket.ts b/src/applications/bitbucket.ts index 5cc0617..c4418b2 100644 --- a/src/applications/bitbucket.ts +++ b/src/applications/bitbucket.ts @@ -9,7 +9,7 @@ import { Base } from './base'; export class Bitbucket extends Base { - name: SupportedApplications = 'bitbucket'; + name = SupportedApplications.BITBUCKET; database: DatabaseEngine; logFilePath = '/var/atlassian/application-data/bitbucket/log/atlassian-bitbucket.log'; diff --git a/src/applications/confluence.ts b/src/applications/confluence.ts index 533b4f3..e39f96a 100644 --- a/src/applications/confluence.ts +++ b/src/applications/confluence.ts @@ -9,7 +9,7 @@ import { Base } from './base'; export class Confluence extends Base { - name: SupportedApplications = 'confluence'; + name = SupportedApplications.CONFLUENCE; database: DatabaseEngine; logFilePath = '/var/atlassian/application-data/confluence/logs/atlassian-confluence.log'; diff --git a/src/applications/jira.ts b/src/applications/jira.ts index b814455..cfbb9f5 100644 --- a/src/applications/jira.ts +++ b/src/applications/jira.ts @@ -9,7 +9,7 @@ import { Base } from './base'; export class Jira extends Base { - name: SupportedApplications = 'jira'; + name = SupportedApplications.JIRA; database: DatabaseEngine; logFilePath = '/var/atlassian/application-data/jira/log/atlassian-jira.log'; diff --git a/src/commands/run.ts b/src/commands/run.ts index 038e447..d3d5c1c 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -2,12 +2,25 @@ import { program } from 'commander'; +import { AMPS } from '../applications/amps'; +import { SupportedApplications } from '../types/SupportedApplications'; + +// Check if there is a command in the arguments +const isDefaultCommand = !process.argv.some(item => Object.values(SupportedApplications).includes(item as SupportedApplications)); +// If there is no command, check if we are running this within the context of an Atlassian Plugin project +if (isDefaultCommand) { + const application = AMPS.getApplication(); + if (application) { + const args = [ application, ...process.argv.splice(2) ]; + process.argv = [ ...process.argv.slice(0, 2), ...args ]; + } +} + program .name('dcdx run') .command('bamboo', 'Start Atlassian Bamboo (standalone)', { executableFile: './run-bamboo.js'}) .command('bitbucket', 'Start Atlassian Bitbucket (standalone)', { executableFile: './run-bitbucket.js'}) .command('confluence', 'Start Atlassian Confluence (standalone)', { executableFile: './run-confluence.js'}) - .command('jira', 'Start Atlassian Jira (standalone)', { executableFile: './run-jira.js'}) - -program.parse(); + .command('jira', 'Start Atlassian Jira (standalone)', { executableFile: './run-jira.js'}); +program.parse(process.argv); \ No newline at end of file diff --git a/src/types/SupportedApplications.ts b/src/types/SupportedApplications.ts index 5649169..da7613a 100644 --- a/src/types/SupportedApplications.ts +++ b/src/types/SupportedApplications.ts @@ -1,2 +1,7 @@ -export type SupportedApplications = 'jira'|'confluence'|'bitbucket'|'bamboo'; \ No newline at end of file +export enum SupportedApplications { + JIRA = 'jira', + CONFLUENCE = 'confluence', + BITBUCKET = 'bitbucket', + BAMBOO = 'bamboo' +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8b310e8..72d3689 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1389,6 +1389,13 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:0.8.10": + version: 0.8.10 + resolution: "@xmldom/xmldom@npm:0.8.10" + checksum: 10c0/c7647c442502720182b0d65b17d45d2d95317c1c8c497626fe524bda79b4fb768a9aa4fae2da919f308e7abcff7d67c058b102a9d641097e9a57f0b80187851f + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -2258,12 +2265,14 @@ __metadata: "@types/pg": "npm:8" "@typescript-eslint/eslint-plugin": "npm:7.6.0" "@typescript-eslint/parser": "npm:7.6.0" + "@xmldom/xmldom": "npm:0.8.10" axios: "npm:1.6.8" commander: "npm:12.0.0" docker-compose: "npm:0.24.8" eslint: "npm:9.0.0" eslint-plugin-simple-import-sort: "npm:12.0.0" exit-hook: "npm:4.0.0" + fast-xml-parser: "npm:4.3.6" js-yaml: "npm:4.1.0" mysql2: "npm:3.9.4" nodemon: "npm:3.1.0" @@ -2276,6 +2285,7 @@ __metadata: tedious: "npm:18.1.0" typescript: "npm:5.4.4" typescript-eslint: "npm:7.6.0" + xpath: "npm:0.0.34" bin: dcdx: ./lib/index.js languageName: unknown @@ -2830,6 +2840,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:4.3.6": + version: 4.3.6 + resolution: "fast-xml-parser@npm:4.3.6" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: 10c0/9ebe2ac142c6978cae423c39c2a9b561edb76be584317d578768ed4a006a61fc0e83abf8c6fe31029139c4ad15ea1f2e7b6720ba9e6eda0e5266d7f2770fb079 + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.16": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -6691,6 +6712,13 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^1.0.5": + version: 1.0.5 + resolution: "strnum@npm:1.0.5" + checksum: 10c0/64fb8cc2effbd585a6821faa73ad97d4b553c8927e49086a162ffd2cc818787643390b89d567460a8e74300148d11ac052e21c921ef2049f2987f4b1b89a7ff1 + languageName: node + linkType: hard + "super-regex@npm:^1.0.0": version: 1.0.0 resolution: "super-regex@npm:1.0.0" @@ -7352,6 +7380,13 @@ __metadata: languageName: node linkType: hard +"xpath@npm:0.0.34": + version: 0.0.34 + resolution: "xpath@npm:0.0.34" + checksum: 10c0/88335108884ca164421f7fed048ef1a18ab3f7b1ae446b627fd3f51fc2396dcce798601c5e426de3bbd55d5940b84cf2326c75cd76620c1b49491283b85de17a + languageName: node + linkType: hard + "xtend@npm:^4.0.0, xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2"