|
| 1 | +const convert = require('xml-js') |
| 2 | +const fs = require('fs') |
| 3 | +const os = require('os').type() |
| 4 | +const path = require('path') |
| 5 | +const slug = require('slug') |
| 6 | + |
| 7 | +module.exports = project => { |
| 8 | + let externalToolBuilders = [] |
| 9 | + let build = {} |
| 10 | + |
| 11 | + // Look for *.launch files in .externalToolBuilders folder |
| 12 | + fs.readdirSync(project).map(fileName => { |
| 13 | + const filePath = path.join(project, fileName) |
| 14 | + if (fs.statSync(filePath).isDirectory()) { |
| 15 | + const buildPath = path.join(filePath, '.externalToolBuilders') |
| 16 | + if (fs.existsSync(buildPath) && fs.statSync(buildPath).isDirectory()) { |
| 17 | + fs.readdirSync(buildPath).map(buildFile => { |
| 18 | + if (path.extname(buildFile) === '.launch') { |
| 19 | + externalToolBuilders.push(path.join(buildPath, buildFile)) |
| 20 | + } |
| 21 | + }) |
| 22 | + } |
| 23 | + } |
| 24 | + }) |
| 25 | + |
| 26 | + // Loop through found .externalToolBuilders files and parse build instructions |
| 27 | + if (externalToolBuilders.length > 0) { |
| 28 | + externalToolBuilders.map(launch => { |
| 29 | + const xml = fs.readFileSync(launch) |
| 30 | + const json = convert.xml2json(xml) |
| 31 | + const builder = json ? JSON.parse(json) : null |
| 32 | + const name = slug( |
| 33 | + path.basename(path.dirname(path.dirname(launch))).replace('_', '-') + |
| 34 | + '_' + |
| 35 | + path.basename(launch).replace('.launch', ''), |
| 36 | + {lower: true, replacement: '-'} |
| 37 | + ) |
| 38 | + |
| 39 | + // setup placeholder for this config file |
| 40 | + build[name] = { |
| 41 | + enabled: false, |
| 42 | + watch: [], |
| 43 | + cmd: { |
| 44 | + basedir: null, |
| 45 | + exec: null |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + if ( |
| 50 | + builder && |
| 51 | + typeof builder.elements !== 'undefined' && |
| 52 | + builder.elements.length === 1 && |
| 53 | + builder.elements[0].name === 'launchConfiguration' && |
| 54 | + builder.elements[0].elements |
| 55 | + ) { |
| 56 | + builder.elements[0].elements.map(elm => { |
| 57 | + // Get Watch Directories |
| 58 | + if (elm.attributes.key === 'org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE') { |
| 59 | + const buildScopeJson = convert.xml2json( |
| 60 | + elm.attributes.value.replace('${working_set:', '').replace(/}$/, '') |
| 61 | + ) |
| 62 | + const buildScope = buildScopeJson ? JSON.parse(buildScopeJson) : null |
| 63 | + |
| 64 | + if ( |
| 65 | + buildScope && |
| 66 | + typeof buildScope.elements !== 'undefined' && |
| 67 | + buildScope.elements.length === 1 && |
| 68 | + buildScope.elements[0].name === 'resources' && |
| 69 | + builder.elements[0].elements |
| 70 | + ) { |
| 71 | + buildScope.elements[0].elements.map(buildSrc => { |
| 72 | + build[name].watch.push(buildSrc.attributes.path) |
| 73 | + }) |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + // Check if we should enable this build |
| 78 | + if (elm.attributes.key === 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS') { |
| 79 | + build[name].enabled = |
| 80 | + elm.attributes.value.includes('full') || |
| 81 | + elm.attributes.value.includes('incremental') || |
| 82 | + elm.attributes.value.includes('auto') |
| 83 | + } |
| 84 | + |
| 85 | + // Get Build Instructuctions |
| 86 | + if (elm.attributes.key === 'org.eclipse.ui.externaltools.ATTR_LOCATION') { |
| 87 | + const buildFilePath = elm.attributes.value.replace('${workspace_loc:', '').replace(/}$/, '') |
| 88 | + const buildFileXml = fs.readFileSync(path.join(project, buildFilePath)) |
| 89 | + const buildFileJson = convert.xml2json(buildFileXml) |
| 90 | + const buildInstructions = buildFileJson ? JSON.parse(buildFileJson) : null |
| 91 | + |
| 92 | + if ( |
| 93 | + buildInstructions && |
| 94 | + typeof buildInstructions.elements !== 'undefined' && |
| 95 | + buildInstructions.elements.length === 1 && |
| 96 | + buildInstructions.elements[0].name === 'project' && |
| 97 | + buildInstructions.elements[0].elements |
| 98 | + ) { |
| 99 | + buildInstructions.elements[0].elements.map(buildInstruction => { |
| 100 | + build[name].cmd.basedir = |
| 101 | + typeof buildInstructions.elements[0].attributes.basedir !== 'undefined' |
| 102 | + ? path.join( |
| 103 | + project, |
| 104 | + path.basename(path.dirname(path.dirname(launch))), |
| 105 | + buildInstructions.elements[0].attributes.basedir |
| 106 | + ) |
| 107 | + : null |
| 108 | + buildInstruction.elements.map(instruction => { |
| 109 | + if (instruction.name === 'exec') { |
| 110 | + let exec = instruction.attributes.executable |
| 111 | + if ( |
| 112 | + (exec === 'cmd' && os === 'Windows_NT') || |
| 113 | + (exec !== 'cmd' && (os === 'Darwin' || os === 'Linux')) |
| 114 | + ) { |
| 115 | + instruction.elements.map(arg => { |
| 116 | + if (arg.name === 'arg') { |
| 117 | + exec = exec.concat(' ' + arg.attributes.value) |
| 118 | + } |
| 119 | + }) |
| 120 | + |
| 121 | + // Replace commands that are not needed outside Eclipse |
| 122 | + exec = exec.replace('/bin/bash -l -c ', '') |
| 123 | + exec = exec.replace(/\${basedir}/g, build[name].cmd.basedir) |
| 124 | + |
| 125 | + build[name].cmd.exec = exec |
| 126 | + } |
| 127 | + } |
| 128 | + }) |
| 129 | + }) |
| 130 | + } |
| 131 | + } |
| 132 | + }) |
| 133 | + } |
| 134 | + }) |
| 135 | + } |
| 136 | + |
| 137 | + return build |
| 138 | +} |
0 commit comments