-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Expand file tree
/
Copy pathHubot.mjs
More file actions
executable file
·175 lines (144 loc) · 4.83 KB
/
Copy pathHubot.mjs
File metadata and controls
executable file
·175 lines (144 loc) · 4.83 KB
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
167
168
169
170
171
172
173
174
175
'use strict'
import fs from 'node:fs'
import { resolve as pathResolve } from 'node:path'
import OptParse from '../src/OptParse.mjs'
import Hubot from '../index.mjs'
import create from '../src/GenHubot.mjs'
const switches = [
['-a', '--adapter HUBOT_ADAPTER', 'The Adapter to use, e.g. "Shell" (to load the default hubot Shell adapter)'],
['-f', '--file HUBOT_FILE', 'Path to adapter file, e.g. "./adapters/CustomAdapter.mjs"'],
['-c', '--create HUBOT_CREATE', 'Create a deployable hubot'],
['-d', '--disable-httpd HUBOT_HTTPD', 'Disable the HTTP server'],
['-s', '--httpdserver HUBOT_HTTPD_SERVER', 'An async factory function that receives this robot (via options) and returns or creates an HttpServerPort instance. Defaults to a factory that instantiates HttpServerPort'],
['-h', '--help', 'Display the help information'],
['-l', '--alias HUBOT_ALIAS', "Enable replacing the robot's name with alias"],
['-n', '--name HUBOT_NAME', 'The name of the robot in chat'],
['-r', '--require PATH', 'Alternative scripts path'],
['-t', '--config-check', "Test hubot's config to make sure it won't fail at startup"],
['-v', '--version', 'Displays the version of hubot installed'],
['-e', '--execute', 'Runs the command as if it were a hubot command']
]
const options = {
adapter: process.env.HUBOT_ADAPTER,
alias: process.env.HUBOT_ALIAS || false,
create: process.env.HUBOT_CREATE || false,
enableHttpd: process.env.HUBOT_HTTPD !== 'false',
scripts: process.env.HUBOT_SCRIPTS || [],
name: process.env.HUBOT_NAME || 'Hubot',
file: process.env.HUBOT_FILE,
configCheck: false,
httpdServer: process.env.HUBOT_HTTPD_SERVER,
}
const Parser = new OptParse(switches)
Parser.banner = 'Usage: hubot [options]'
Parser.on('adapter', (opt, value) => {
options.adapter = value
})
Parser.on('file', (opt, value) => {
options.file = value
})
Parser.on('create', function (opt, value) {
options.path = value
options.create = true
})
Parser.on('disable-httpd', opt => {
options.enableHttpd = false
})
Parser.on('httpdserver', (opt, value) => {
options.httpdServer = value
})
Parser.on('help', function (opt, value) {
console.log(Parser.toString())
return process.exit(0)
})
Parser.on('alias', function (opt, value) {
if (!value) {
value = '/'
}
options.alias = value
})
Parser.on('name', (opt, value) => {
options.name = value
})
Parser.on('execute', (opt, value) => {
options.execute = value
})
Parser.on('require', (opt, value) => {
options.scripts.push(value)
})
Parser.on('config-check', opt => {
options.configCheck = true
})
Parser.on('version', (opt, value) => {
options.version = true
})
Parser.on(undefined, (opt, value) => {
console.warn(`Unknown option: ${opt}`)
})
Parser.parse(process.argv)
if (options.create) {
options.hubotInstallationPath = process.env.HUBOT_INSTALLATION_PATH ?? 'hubot'
create(options.path, options)
process.exit(0)
}
if (options.file) {
options.adapter = options.file.split('/').pop().split('.')[0]
}
if (options.enableHttpd === true && !options.httpdServer) {
options.httpdServer = 'src/ports/ExpressHttpServerPort.mjs'
}
if (options.httpdServer) {
const httpdServerModulePath = pathResolve('.', options.httpdServer)
const httpdServerModule = await import(httpdServerModulePath)
options.enableHttpd = httpdServerModule.default
}
const robot = Hubot.loadBot(options.adapter, options.enableHttpd, options.name, options.alias)
export default robot
async function loadScripts () {
await robot.load(pathResolve('.', 'scripts'))
await robot.load(pathResolve('.', 'src', 'scripts'))
await loadExternalScripts()
const tasks = options.scripts.map((scriptPath) => {
if (scriptPath[0] === '/') {
return robot.load(scriptPath)
}
return robot.load(pathResolve('.', scriptPath))
})
await Promise.all(tasks)
}
async function loadExternalScripts () {
const externalScripts = pathResolve('.', 'external-scripts.json')
try {
const data = await fs.promises.readFile(externalScripts)
try {
robot.loadExternalScripts(JSON.parse(data))
} catch (error) {
console.error(`Error parsing JSON data from external-scripts.json: ${error}`)
process.exit(1)
}
} catch (e) {
robot.logger.info('No external-scripts.json found. Skipping.')
}
}
(async () => {
await robot.load(pathResolve('.', 'configuration'))
await robot.loadAdapter(options.file)
if (options.version) {
console.log(robot.version)
process.exit(0)
}
if (options.configCheck) {
await loadScripts()
console.log('OK')
process.exit(0)
}
robot.adapter.once('connected', async () => {
await loadScripts()
if (options.execute) {
await robot.receive(new Hubot.TextMessage(new Hubot.User('shell', { room: '#shell' }), `@${robot.name} ${options.execute.trim()}`))
robot.shutdown()
}
robot.emit('scripts have loaded', robot)
})
await robot.run()
})()