/
replication.ts
166 lines (147 loc) · 4.43 KB
/
replication.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
var { system, filesystem } = require('gluegun')
const fs = require('fs')
const path = require('path')
const readline = require('readline')
const yaml = require('js-yaml')
var rimraf = require('rimraf')
const {
resolveReplicantWorkDir
} = require('../src/replication/replication-process')
let loadRecipe = recipe => {
const rawData = fs.readFileSync(recipe)
let recipeJson = JSON.parse(rawData)
if (recipeJson.templateName === undefined) {
// this transformation relies on the fact that default template name is {replicanteName_timestamp}
const candidates = fs
.readdirSync(`${resolveReplicantWorkDir()}/_templates`, {
withFileTypes: true
})
.filter(dir => dir.isDirectory())
.map(dir => path.basename(dir.name))
.filter(dir => dir.startsWith(recipeJson.replicantName))
.sort()
.reverse()
if (candidates) {
recipeJson.templateName = path.basename(candidates[0])
} else
throw new Error(
`Template not found for replicante ${recipeJson.replicantName} with timestamped directory`
)
}
return recipeJson
}
const readTemplateForRecipe = recipe => {
const templatePath = `${resolveReplicantWorkDir()}/_templates/${
recipe.templateName
}/new`
if (fs.existsSync(templatePath)) return fs.readdirSync(templatePath)
return ''
}
const templateFileExists = (recipe, fileName) => {
const filePath = `${resolveReplicantWorkDir()}/_templates/${
recipe.templateName
}/new/${fileName}`
return filesystem.exists(filePath)
}
const readTemplateFileHeader = async (recipe, fileName) => {
const fileStream = fs.createReadStream(
`${resolveReplicantWorkDir()}/_templates/${
recipe.templateName
}/new/${fileName}`
)
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
})
let header = ''
let dividerCount = 0
for await (const line of rl) {
if (line.startsWith('---')) dividerCount++
else header += line + '\n'
if (dividerCount == 2) break
}
fileStream.close()
return yaml.load(header)
}
const readFileDiscardingHeader = fullPath => {
const fullContent = filesystem.read(fullPath)
const parts = fullContent.split('---\n')
const templateContent = parts[2]
return templateContent
}
const readTemplateFileContent = (recipe, fileName /*, options*/) => {
const filePath = `${resolveReplicantWorkDir()}/_templates/${
recipe.templateName
}/new/${fileName}`
return readFileDiscardingHeader(filePath)
}
const deleteReplicantDirectory = () => {
try {
return rimraf.sync(resolveReplicantWorkDir())
} catch (e) {
console.error(e)
return false
}
}
const readReplicantFileContent = (recipe, fileNameParts): string => {
const targetFile = path.join(...fileNameParts)
const filePath = path.join(
resolveReplicantWorkDir(),
recipe.replicantName,
targetFile
)
return filesystem.read(filePath)
}
const readSampleBinaryFile = (recipe, fileNameParts): Buffer => {
const targetFile = path.join(...fileNameParts)
const filePath = path.join(`test-infrasctructure`, `fixtures`, targetFile)
const fullPath = path.resolve(filePath)
return fs.readFileSync(fullPath, { encoding: null })
}
const readReplicantBinaryFile = (recipe, fileNameParts): Buffer => {
const targetFile = path.join(...fileNameParts)
const filePath = path.join(
resolveReplicantWorkDir(),
recipe.replicantName,
targetFile
)
return fs.readFileSync(filePath, { encoding: null })
}
let cli = cmd => {
let src = filesystem.path(__dirname, '..')
return system.run(
'node ' + filesystem.path(src, 'bin', 'replicante') + ` ${cmd}`
)
}
let createReplicant = async (sampleDirectory, fixtureRecipeToUse, options?) => {
await filesystem.removeAsync(resolveReplicantWorkDir())
let samplePath = filesystem.resolve(
`./test-infrasctructure/fixtures/${sampleDirectory}`
)
let recipeFilePath = filesystem.resolve(
`./test-infrasctructure/fixtures/${fixtureRecipeToUse}`
)
return await cli(`create ${samplePath} ${recipeFilePath} ${options}`).then(
cliOutput => {
const recipe = loadRecipe(recipeFilePath)
return {
recipe,
output: cliOutput,
templateFiles: readTemplateForRecipe(recipe)
}
}
)
}
export {
cli,
createReplicant,
loadRecipe,
readTemplateForRecipe,
readTemplateFileHeader,
readTemplateFileContent,
templateFileExists,
deleteReplicantDirectory,
readReplicantFileContent,
readSampleBinaryFile,
readReplicantBinaryFile
}