forked from rapid-sensemaking-framework/rsf-runner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
113 lines (93 loc) · 3.91 KB
/
index.js
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
// RSF-SEQUENCE RUNNER!
require('dotenv').config()
const fs = require('fs')
const path = require('path')
const { INPUT_FILE_NAME, OUTPUT_FILE_NAME, readInput, writeOutput } = require('rfs-reader-writer')
// use a bash command helper like shelljs
const shell = require('shelljs')
// check if languages of operators are available, and any other validation
const validateSequence = (sequence) => {
if (sequence.length < 1) {
return {
valid: false,
message: "Sequence must contain at least 1 operator"
}
}
return {
valid: true,
message: ""
}
}
// dependencies file name, code file main, dependencies install command, run code command
const languageMaps = {
node: ['package.json', 'index.js', 'npm install', 'node index.js'],
rust: ['Cargo.toml', 'src/main.rs', null, 'cargo run']
}
// it will run this for each operator in the sequence
const runOperator = (sequence, index, input) => {
const operator = sequence[index]
console.log(`Running ${operator.id} operator`)
console.log(`description: ${operator.description || 'no description'}`)
// create a folder with the id of operator
console.log(`${operator.id}: Creating temporary directory for operator`)
fs.mkdirSync(path.join(__dirname, operator.id))
// write the dependencies file into the folder
console.log(`${operator.id}: Writing dependencies spec to file`)
const depsFileName = languageMaps[operator.language][0]
fs.writeFileSync(path.join(__dirname, operator.id, depsFileName), JSON.stringify(operator.dependencies_file))
// write the code file into the folder
console.log(`${operator.id}: Writing operator code to file`)
const codeFileName = languageMaps[operator.language][1]
fs.writeFileSync(path.join(__dirname, operator.id, codeFileName), operator.code_file)
// install any dependencies
const installDepsCommand = languageMaps[operator.language][2]
if (installDepsCommand) {
console.log(`${operator.id}: Installing dependencies`)
shell.cd(operator.id)
shell.exec(installDepsCommand, { silent: true })
shell.cd('..')
}
// write the input into the folder, as JSON
console.log(`${operator.id}: Writing operator input to JSON file`)
fs.writeFileSync(path.join(__dirname, operator.id, INPUT_FILE_NAME), JSON.stringify(input))
// execute the process, and wait for it to complete
console.log(`${operator.id}: Executing operator...`)
const runCommand = languageMaps[operator.language][3]
shell.cd(operator.id)
shell.exec(runCommand)
shell.cd('..')
console.log(`${operator.id}: complete`)
// on complete, move to next operator, providing the output of the
// last, as input for the next, until all the sequence is complete
const outputBuffer = fs.readFileSync(path.join(__dirname, operator.id, OUTPUT_FILE_NAME))
const output = JSON.parse(outputBuffer)
console.log(`${operator.id}: output: `, output)
// clean out the folder of the operator
shell.rm('-rf', path.join(__dirname, operator.id))
// call the next in the sequence, if there is one
if (sequence[index + 1]) {
// pass the output of this operator
// in as the input to the next one
runOperator(sequence, index + 1, output)
} else {
// otherwise store the results
writeOutput(__dirname, output)
}
}
// read in sequence file
const sequenceName = process.argv[2]
if (!sequenceName) {
console.log('Please pass a path to an rsf-sequence JSON file as an argument to this command')
process.exit(1)
}
const sequenceToRun = require(sequenceName)
const checkValid = validateSequence(sequenceToRun)
if (!checkValid.valid) {
console.log('Invalid sequence, exiting. Message:')
console.log(checkValid.message)
process.exit(1)
}
const initialIndex = 0
const initialInput = readInput(__dirname)
runOperator(sequenceToRun, initialIndex, initialInput)
// exit