UNPKG

2.94 kBJavaScriptView Raw
1const path = require('path')
2const fs = require('fs')
3const parseIgnore = require('parse-gitignore')
4const { promisify } = require('util')
5const readFile = promisify(fs.readFile)
6const writeFile = promisify(fs.writeFile)
7
8function fileExists(filePath) {
9 return new Promise((resolve, reject) => {
10 fs.access(filePath, fs.F_OK, err => {
11 if (err) return resolve(false)
12 return resolve(true)
13 })
14 })
15}
16
17async function hasGitIgnore(dir) {
18 const gitIgnorePath = path.join(dir, '.gitignore')
19 const hasIgnore = await fileExists(gitIgnorePath)
20 return hasIgnore
21}
22
23function parser(input, fn = line => line) {
24 let lines = input.toString().split(/\r?\n/)
25 let section = { name: 'default', patterns: [] }
26 let state = { patterns: [], sections: [section] }
27
28 for (let line of lines) {
29 if (line.charAt(0) === '#') {
30 section = { name: line.slice(1).trim(), patterns: [] }
31 state.sections.push(section)
32 continue
33 }
34
35 if (line.trim() !== '') {
36 let pattern = fn(line, section, state)
37 section.patterns.push(pattern)
38 state.patterns.push(pattern)
39 }
40 }
41 return state
42}
43
44function stringify(state) {
45 return parseIgnore.stringify(state.sections, section => {
46 if (!section.patterns.length) {
47 return ''
48 }
49
50 return `# ${section.name}\n${section.patterns.join('\n')}\n\n`
51 })
52}
53
54function parse(input, fn) {
55 const state = parser(input, fn)
56
57 state.concat = i => {
58 const newState = parser(i, fn)
59
60 for (let s2 in newState.sections) {
61 const sec2 = newState.sections[s2]
62
63 let sectionExists = false
64 for (let s1 in state.sections) {
65 const sec1 = state.sections[s1]
66
67 // Join sections under common name
68 if (sec1.name === sec2.name) {
69 sectionExists = true
70 sec1.patterns = Array.from(new Set(sec1.patterns.concat(sec2.patterns)))
71 }
72 }
73
74 // Add new section
75 if (!sectionExists) {
76 state.sections.push(sec2)
77 }
78 }
79
80 return state
81 }
82
83 return state
84}
85
86async function ensureNetlifyIgnore(dir) {
87 const gitIgnorePath = path.join(dir, '.gitignore')
88 const ignoreContent = '# Local Netlify folder\n.netlify'
89
90 /* No .gitignore file. Create one and ignore .netlify folder */
91 if (!(await hasGitIgnore(dir))) {
92 await writeFile(gitIgnorePath, ignoreContent, 'utf8')
93 return false
94 }
95
96 let gitIgnoreContents
97 let ignorePatterns
98 try {
99 gitIgnoreContents = await readFile(gitIgnorePath, 'utf8')
100 ignorePatterns = parseIgnore.parse(gitIgnoreContents)
101 } catch (e) {
102 // ignore
103 }
104 /* Not ignoring .netlify folder. Add to .gitignore */
105 if (!ignorePatterns || !ignorePatterns.patterns.includes('.netlify')) {
106 const newContents = `${gitIgnoreContents}\n${ignoreContent}`
107 await writeFile(gitIgnorePath, newContents, 'utf8')
108 }
109}
110
111module.exports = {
112 parse: parse,
113 stringify: stringify,
114 format: parseIgnore.format,
115 ensureNetlifyIgnore
116}