Passed
Push — master ( b3170c...2ddb0e )
by Barry
01:25
created

src/processFile.js   A

Complexity

Total Complexity 22
Complexity/F 4.4

Size

Lines of Code 110
Function Count 5

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 0
nc 1
dl 0
loc 110
rs 10
c 2
b 0
f 0
wmc 22
mnd 5
bc 27
fnc 5
bpm 5.4
cpm 4.4
noi 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A processFile.js ➔ ??? 0 16 3
A processFile.js ➔ analyseCommandString 0 20 4
A processFile.js ➔ runCliCmd 0 9 2
D processFile.js ➔ processText 0 42 10
A processFile.js ➔ crossPlatformCmds 0 12 3
1
const debug = require('debug')('mdprepare:processFile')
2
const {execSync} = require('child_process')
3
const fs = require('fs')
4
const os = require('os')
5
const path = require('path')
6
const h = require('./helpers.js')
7
8
export default function (filePath, clear) {
9
  // this function accepts a markdown filename and runs any mdprepare code which is embedded in that file
10
  debug(filePath)
11
  try {
12
    var txt = fs.readFileSync(filePath, 'utf8')
13
  } catch (err) {
14
    throw Error('file not found')
15
  }
16
  try {
17
    let p = processText(txt, clear, path.dirname(path.resolve(process.cwd(), filePath)))
18
    fs.writeFileSync(filePath, p)
19
  } catch (err) {
20
    throw Error('unable to write to file')
21
  }
22
  return true
23
}
24
25
export function processText (txt, clear, fileDirName) {
26
  let posn = 0
27
  let r = ''
28
  let x
29
  let y
30
  let t
31
  let frm
32
  let eolIsCRLF = (txt.indexOf('\r\n') !== -1)
33
  while (true) {
34
    x = h.findMdpCode(txt, posn)
35
    y = h.findMdpInsert(txt, posn)
36
    t = h.earlierOf(x, y)
37
    if (t.start === -1) {
38
      r = r + txt.substring(posn)
39
      break
40
    } else {
41
      r = r + txt.substring(posn, t.internalStart)
42
      frm = t.internalStart + t.internalLength
43
      analyseCommandString(t)
44
      if (t.info.cliCommand === 'ERROR: mdpInsert command not found') {
45
        // the mdpInsert command was not present so we don't insert or remove anything, just leave as is
46
        r = r + txt.substr(t.internalStart, t.internalLength)
47
      } else {
48
        if (clear !== true) {
49
          let insertText = t.prepend + runCliCmd(t.info.cliCommand, fileDirName)
50
          if (insertText.substr(-1) !== '\n' && t.postpend.length > 0) { insertText += '\n' }
51
          insertText += t.postpend
52
          r = r + h.replaceLineEndings(insertText, eolIsCRLF)
53
        }
54
        if (r.substr(-1) === '\n') {
55
          // we don't want to introduce 2 CRLFs or LFs so remove all lines between the start and end lines
56
          if (txt.substr(frm, 1) === '\r') { frm++ }
57
          /* istanbul ignore else  */
58
          if (txt.substr(frm, 1) === '\n') { frm++ }
59
        }
60
      }
61
      posn = t.start + t.length
62
      r = r + txt.substring(frm, posn)
63
    }
64
  }
65
  return r
66
}
67
68
function analyseCommandString (t) {
69
  // looks at the command string, checks it is a valid mdpInsert and populates .cli, .prepend and .postpend
70
  if (typeof t.info === 'undefined') { t.info = {} }
71
  let x = t.commandString.indexOf('mdpInsert ')
72
  if (x === -1) {
73
    t.info.cliCommand = 'ERROR: mdpInsert command not found'
74
    return
75
  }
76
  let regex = /mdpInsert ((`{3,}|~{3,})[^ ]*) /
77
  let regexResult = regex.exec(t.commandString)
78
  if (regexResult === null) {
79
    t.info.cliCommand = t.commandString.substr(x + 10)
80
    t.prepend = ''
81
    t.postpend = ''
82
  } else {
83
    t.info.cliCommand = t.commandString.substr(x + regexResult[0].length)
84
    t.prepend = regexResult[1] + '\n'
85
    t.postpend = regexResult[2]
86
  }
87
}
88
89
export function runCliCmd (str, wDirName) {
90
  // wDirName is either an absolute path or a relative path to the directory node was run from
91
  let cmd = crossPlatformCmds(str)
92
  try {
93
    return execSync(cmd, {cwd: wDirName})
94
  } catch (err) {
95
    return 'ERROR: ' + err.message
96
  }
97
}
98
99
function crossPlatformCmds (cmd) {
100
  // does limited cross platform translation of limited commands
101
  let r = cmd
102
  /* istanbul ignore if  */
103
  if (os.platform() === 'win32') {
104
    if (cmd.substr(0, 4) === 'cat ') {
105
      r = r.replace('cat ', 'type ')
106
      r = r.replace(/\//g, '\\')
107
    }
108
  }
109
  return r
110
}
111