Skip to content

Commit abef004

Browse files
committed
more details added πŸš€πŸš€πŸš€
1 parent 7e91666 commit abef004

File tree

14 files changed

+357
-72
lines changed

14 files changed

+357
-72
lines changed

β€Ž.env.sample

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
# Bot name
88
HUBOT_NAME=hubot
99

10-
# Required if using the default adapter which is slack
11-
HUBOT_SLACK_TOKEN=xoxb-YOUR-TOKEN-HERE
10+
# Port the bot http server will read on
11+
PORT=3000
12+
13+
# Required if using the slack adapter
14+
HUBOT_ADAPTER=slack
15+
HUBOT_SLACK_TOKEN=xoxb-YOUR-TOKEN-HERE
1216

1317
# Following ones are optional, but great as their current values.
1418

β€ŽDockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ FROM node:10-alpine
1919

2020
WORKDIR /hubot/code
2121

22-
ENV NODE_ENV production
23-
2422
ARG PORT=3000
2523

2624
ENV PORT ${PORT}
2725

26+
ENV NODE_ENV production
27+
2828
COPY --from=builder /app .
2929

3030
EXPOSE ${PORT}

β€ŽREADME.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ See https://github.com/mtsmfm/hubot-test-helper/issues/19
7373

7474
There is no brain persister installed, it's your job to install one if needed.
7575

76+
## How does the coffee script scripts can be run alongside typescript during development?
77+
78+
They don't.
79+
80+
There is a postinstall hook that calls the script [`tools/compile-coffee-deps.js`][tools/compile-coffee-deps.js]
81+
which is responsible for compilling the dependencies .coffee files to pure .js.
82+
7683
[robot.http]:https://hubot.github.com/docs/scripting/#making-http-calls
7784
[node-scoped-http-client]:https://github.com/technoweenie/node-scoped-http-client
7885
[hubot-test-helper]:https://github.com/mtsmfm/hubot-test-helper
7986
[example.spec.ts]: ./src/scripts/__tests__/example.spec.ts
87+
[tools/compile-coffee-deps.js]: ./tools/compile-coffee-deps.js

β€Žpackage.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"type": "git",
88
"url": "git://github.com/JCMais/hubot-typescript-boilerplate.git"
99
},
10+
"private": true,
1011
"keywords": [
1112
"chatops",
1213
"hubot",
@@ -15,16 +16,20 @@
1516
],
1617
"description": "ChatOps made easier",
1718
"dependencies": {
19+
"@slack/client": "^4.8.0",
20+
"@types/express": "^4.16.0",
1821
"@types/hubot": "^2.19.2",
22+
"@types/ramda": "^0.25.41",
1923
"axios": "^0.18.0",
20-
"coffeescript": "^2.3.2",
24+
"coffeescript": "1.12.7",
2125
"cross-env": "^5.2.0",
2226
"hubot": "^3.1.1",
2327
"hubot-diagnostics": "^1.0.0",
2428
"hubot-help": "^1.0.1",
2529
"hubot-rules": "^1.0.0",
2630
"hubot-scripts": "^2.17.2",
27-
"hubot-slack": "^4.5.5"
31+
"hubot-slack": "^4.5.5",
32+
"ramda": "^0.25.0"
2833
},
2934
"devDependencies": {
3035
"@types/jest": "^23.3.9",
@@ -50,14 +55,15 @@
5055
],
5156
"scripts": {
5257
"start": "node node_modules/hubot/bin/hubot.js --require ./build/scripts",
53-
"dev": "dotenv -e .env ts-node -- node_modules/hubot/bin/hubot.js --require ./src/scripts",
58+
"dev": "dotenv -e .env ts-node -- --files node_modules/hubot/bin/hubot.js --require ./src/scripts",
5459
"dev:watch": "nodemon",
5560
"clean": "rimraf build",
5661
"build": "yarn clean && tsc",
5762
"build:start": "yarn build && yarn start",
5863
"postinstall": "node ./tools/compile-coffee-deps.js && patch-package",
5964
"prepublishOnly": "yarn lint && yarn test && yarn build",
6065
"lint": "tslint --project tsconfig.json {src}/**/*.ts",
66+
"prettier": "prettier --write src/**/*.ts",
6167
"test": "jest",
6268
"heroku-postbuild": "yarn build"
6369
}

β€Žprettier.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
2-
semi: true,
2+
semi: false,
33
singleQuote: true,
44
trailingComma: 'all',
55
}

β€Žsrc/scripts/#1-startup.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Description:
2+
// fs.readDir (method used by hubot to iterate over this dir)
3+
// returns the files sorted on Node.js, so this script is going to be read first.
4+
// That way you can use this as an startup script
5+
6+
import { Robot } from 'hubot'
7+
import SlackAdapter from 'hubot-slack'
8+
9+
module.exports = async function startup(robot: Robot<SlackAdapter>) {}
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
import Helper from 'hubot-test-helper';
2-
import mockAxios from 'jest-mock-axios';
1+
import Helper from 'hubot-test-helper'
2+
import mockAxios from 'jest-mock-axios'
33

4-
const helper = new Helper('../example.ts');
4+
const helper = new Helper('../example.ts')
55

6-
let room = (null as unknown) as ReturnType<typeof helper.createRoom>;
6+
let room = (null as unknown) as ReturnType<typeof helper.createRoom>
77

88
beforeEach(() => {
99
room = helper.createRoom({
1010
httpd: false,
11-
});
11+
})
1212

1313
// cleaning up the mess left behind the previous test
14-
mockAxios.reset();
15-
});
14+
mockAxios.reset()
15+
})
1616

1717
it('should work correctly when user posts a link', async function() {
18-
const url = 'http://google.com';
18+
const url = 'http://google.com'
1919

20-
await room.user.say('user1', url);
20+
await room.user.say('user1', `hubot ${url}`)
2121

2222
// we could just mock axios using jest itself, see https://github.com/knee-cola/jest-mock-axios/issues/3#issuecomment-369057670
23-
mockAxios.mockResponse();
23+
mockAxios.mockResponse()
2424

25-
await global.delay(10);
25+
await global.delay(10)
2626

27-
expect(mockAxios.get).toHaveBeenCalledWith(url);
27+
expect(mockAxios.get).toHaveBeenCalledWith(url)
2828

2929
expect(room.messages).toEqual([
30-
['user1', 'http://google.com'],
30+
['user1', 'hubot http://google.com'],
3131
['hubot', 'ok1: http://google.com'],
3232
['hubot', 'ok2: http://google.com'],
33-
]);
34-
});
33+
])
34+
})

β€Žsrc/scripts/example.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,16 @@
1616
//
1717
// Author:
1818
// JCMais
19-
import { Robot } from 'hubot';
20-
import axios from 'axios';
19+
import { Robot } from 'hubot'
20+
import axios from 'axios'
2121

2222
module.exports = async function example(robot: Robot<{}>) {
23-
robot.hear(/(http(?:s?):\/\/(\S*))/i, async res => {
24-
const url = res.match[1];
25-
res.send(`ok1: ${url}`);
23+
robot.respond(/(http(?:s?):\/\/(\S*))/i, async res => {
24+
const url = res.match[1]
25+
res.send(`ok1: ${url}`)
2626

27-
res.send('Ok!')
27+
await axios.get(url)
2828

29-
await axios.get(url);
30-
31-
res.send(`ok2: ${url}`);
32-
});
33-
};
29+
res.send(`ok2: ${url}`)
30+
})
31+
}

β€Žsrc/scripts/health.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Description:
2+
// Add /health endpoing that can be used for checking for bot health
3+
import { Robot } from 'hubot'
4+
import SlackAdapter from 'hubot-slack'
5+
6+
module.exports = async function example(robot: Robot<SlackAdapter>) {
7+
robot.router
8+
}

β€Žtools/compile-coffee-deps.js

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,94 @@
11
// This is necessary so we don't have coffeescript files being required
2-
const path = require('path');
3-
const fs = require('fs');
2+
const path = require('path')
3+
const fs = require('fs')
44
const { execSync } = require('child_process')
55

6-
const scriptsToCheck = require('../external-scripts.json');
6+
const scriptsToCheck = require('../external-scripts.json')
77

8-
const cwd = path.join(__dirname, '..');
8+
const cwd = path.join(__dirname, '..')
99

10-
scriptsToCheck.forEach((npmModule) => {
10+
const getModulePackageJson = npmModule =>
11+
path.join(cwd, 'node_modules', npmModule, 'package.json')
1112

12-
const packageJsonPath = path.join(cwd, 'node_modules', npmModule, 'package.json');
13+
const compileCoffeeFilesInsidePackage = npmModule => {
14+
console.log(`Compilling .coffee files inside module ${npmModule}`)
15+
try {
16+
execSync(`yarn coffee -c node_modules/${npmModule}`, {
17+
cwd,
18+
})
19+
} catch (err) {
20+
console.error(
21+
`Error while trying to compile coffee files on package ${npmModule}`,
22+
)
23+
console.error(err)
24+
return false
25+
}
26+
27+
return true
28+
}
29+
30+
function compileSlackAdapter() {
31+
console.log('Compilling .coffee files inside slack adapter')
32+
33+
const packageJsonPath = getModulePackageJson('hubot-slack')
1334

1435
if (!fs.existsSync(packageJsonPath)) {
15-
console.warn(`No package.json file found for hubot script package ${npmModule}.`)
16-
console.warn(`If this package does exists you will have to compile the .coffee files on it by running:`)
17-
console.warn(`yarn coffeescript -c node_modules/${npmModule}`)
18-
return;
36+
console.warn(`No package.json file found for hubot slack adapter.`)
37+
console.warn(
38+
`If this package does exists you will have to compile the .coffee files on it by running:`,
39+
)
40+
console.warn(` $ yarn coffeescript -c node_modules/slack-adapter`)
41+
console.warn(
42+
`If you are not using that adapter you can safely ignore this warning and remove this call on:`,
43+
)
44+
console.warn(` tools/compile-coffee-deps.js`)
45+
return
1946
}
2047

21-
const packageJson = require(`${npmModule}/package.json`);
48+
const hasCompiled = compileCoffeeFilesInsidePackage('hubot-slack')
2249

23-
const mainFile = path.parse(packageJson.main)
24-
const ext = path.extname(packageJson.main)
50+
// no need to change package.json, since main there does not have an extension.
51+
}
2552

26-
const shouldCompile = mainFile.ext === '.coffee';
53+
function compileExternalScripts() {
54+
scriptsToCheck.forEach(npmModule => {
55+
const packageJsonPath = getModulePackageJson(npmModule)
2756

28-
if (shouldCompile) {
29-
console.log(`Compilling .coffee files inside module ${npmModule}`)
30-
try {
31-
execSync(`yarn coffee -c node_modules/${npmModule}`, {
32-
cwd,
33-
})
34-
} catch (err) {
35-
console.error(`Error while trying to compile coffee files on package ${npmModule}`)
36-
console.error(err);
37-
return;
57+
if (!fs.existsSync(packageJsonPath)) {
58+
console.warn(
59+
`No package.json file found for hubot script package ${npmModule}.`,
60+
)
61+
console.warn(
62+
`If this package does exists you will have to compile the .coffee files on it by running:`,
63+
)
64+
console.warn(`yarn coffeescript -c node_modules/${npmModule}`)
65+
return
3866
}
3967

40-
packageJson.main = path.format({
41-
...mainFile,
42-
ext: '.js',
43-
base: null,
44-
});
68+
const packageJson = require(`${npmModule}/package.json`)
4569

46-
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
47-
}
48-
})
70+
const mainFile = path.parse(packageJson.main)
71+
const ext = path.extname(packageJson.main)
72+
73+
const shouldCompile = mainFile.ext === '.coffee'
74+
75+
if (shouldCompile) {
76+
const hasCompiled = compileCoffeeFilesInsidePackage(npmModule)
77+
78+
if (!hasCompiled) return
79+
80+
packageJson.main = path.format({
81+
...mainFile,
82+
ext: '.js',
83+
base: null,
84+
})
85+
86+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
87+
}
88+
})
89+
}
90+
91+
;(function run() {
92+
compileSlackAdapter()
93+
compileExternalScripts()
94+
})()

β€Žtypes/custom/hubot.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// https://stackoverflow.com/a/53346014/710693
2+
// This import serves no purpose except to make the file a module
3+
// (so that the following statement is a module augmentation rather
4+
// than a module declaration) and could be replaced with `export {}`.
5+
import * as hubot from 'hubot'
6+
7+
import { Application } from 'express'
8+
9+
declare module 'hubot' {
10+
interface Message {
11+
mentions: string[]
12+
}
13+
14+
interface Robot<A> {
15+
router: Application
16+
}
17+
}

β€Žtypes/custom/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/// <reference path="global.d.ts" />
2+
/// <reference path="hubot.d.ts" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare module 'hubot-slack' {
2+
interface Options {
3+
token: string;
4+
}
5+
6+
class SlackAdapter {
7+
options: Options;
8+
}
9+
10+
export = SlackAdapter;
11+
}

0 commit comments

Comments
Β (0)