Skip to content

Commit

Permalink
fix: Revert back to 10.0.3 (#1700)
Browse files Browse the repository at this point in the history
fix: Accidently releasing the removal of CoffeeScript in a minor version.
fix: --help and the Windows test for it.

Revert "BREAKING CHANGES: Removed CoffeeScript support; .coffee files will no longer load (#1694)"
This reverts commit f11e5af.
  • Loading branch information
joeyguerra committed Nov 12, 2023
1 parent 2ca88f4 commit 7fa3841
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 82 deletions.
2 changes: 1 addition & 1 deletion bin/e2e-test.sh
Expand Up @@ -12,7 +12,7 @@ trap "{ CODE=$?; popd; rm -rf $TEMP_ROOT; exit $CODE; }" EXIT
echo "$ create hubot in $TEMP_ROOT"
echo "$ install Hubot from $HUBOT_FOLDER"
npm init -y
npm i $HUBOT_FOLDER
npm i $HUBOT_FOLDER coffeescript

./node_modules/.bin/hubot --create myhubot
cd myhubot
Expand Down
10 changes: 8 additions & 2 deletions bin/hubot
@@ -1,3 +1,9 @@
#!/usr/bin/env node
#!/usr/bin/env coffee

require('./hubot.js')
# While all other files have been converted to JavaScript via https://github.com/github/hubot/pull/1347,
# we left the `bin/hubot` file to remain in CoffeeScript in order prevent
# breaking existing 3rd party adapters of which some are still written in
# CoffeeScript themselves. We will deprecate and eventually remove this file
# in a future version of hubot

require './hubot.js'
14 changes: 11 additions & 3 deletions docs/adapters/development.md
Expand Up @@ -10,8 +10,10 @@ permalink: /adapters/development.html

All adapters inherit from the Adapter class in the `src/adapter.js` file.

If you're writing your adapter in ES2015, you must require the ES2015 entrypoint instead:

```javascript
const Adapter = require('hubot/index.js').Adapter;
const Adapter = require('hubot/es2015').Adapter;
```

There are certain methods that you will want to override. Here is a basic stub of what an extended Adapter class would look like:
Expand Down Expand Up @@ -58,7 +60,10 @@ exports.use = (robot) => new Sample(robot)
"dependencies": {
},
"peerDependencies": {
"hubot": ">= 11"
"hubot": ">=3.0"
},
"devDependencies": {
"coffeescript": ">=1.2.0"
}
```

Expand Down Expand Up @@ -112,7 +117,10 @@ Another option is to load the file from local disk.
"dependencies": {
},
"peerDependencies": {
"hubot": ">= 11"
"hubot": ">=9"
},
"devDependencies": {
"coffeescript": ">=2.7.0"
}
```

Expand Down
7 changes: 4 additions & 3 deletions docs/deploying/azure.md
Expand Up @@ -37,12 +37,13 @@ First, run the follow command to add `deploy.cmd` to your hubot directory. This

Then, edit this file and look for the sections that give you steps 1, 2 and 3. You're going to add a 4th step:

:: 4. Create Hubot file with a js extension
copy /Y "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\hubot" "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\hubot.js"
:: 4. Create Hubot file with a coffee extension
copy /Y "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\hubot" "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\hubot.coffee"

Now, create a new file in the base directory of hubot called `server.js` and put these two lines into it:

module.exports = require('hubot/bin/hubot.js');
require('coffeescript/register');
module.exports = require('hubot/bin/hubot.coffee');

Finally you will need to add the environment variables to the website to make sure it runs properly. You can either do it through the GUI (under configuration) or you can use the Azure PowerShell command line, as follows (example is showing slack as an adapter and mynewhubot as the website name).

Expand Down
74 changes: 35 additions & 39 deletions docs/scripting.md
Expand Up @@ -839,7 +839,7 @@ Listener middleware inserts logic between the listener matching a message and th
## Listener Middleware Examples
A fully functioning example can be found in [hubot-rate-limit](https://github.com/michaelansel/hubot-rate-limit/blob/master/src/rate-limit.coffee) (Note: this is a coffee version, non-async/await, and will not work with the latest Hubot since CoffeeScript support was removed in version 11).
A fully functioning example can be found in [hubot-rate-limit](https://github.com/michaelansel/hubot-rate-limit/blob/master/src/rate-limit.coffee) (Note, this is a coffee version, non-async/await).
A simple example of middleware logging command executions:
Expand Down Expand Up @@ -1005,55 +1005,51 @@ You may also want to install:
[Note: This section is still refering to Coffeescript, but we've update Hubot for Javascript. We'll have to replace this when we get a JavaScript example.]
Here is a sample script that tests the first couple of commands.
Here is a sample script that tests the first couple of commands in the [Hubot sample script](https://github.com/hubotio/generator-hubot/blob/master/generators/app/templates/scripts/example.coffee). This script uses *Mocha*, *chai*, *coffeescript*, and of course *hubot-test-helper*:
**test/example-test.mjs**
**test/example-test.coffee**
```javascript
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import Helper from 'hubot-test-helper'
```coffeescript
Helper = require('hubot-test-helper')
chai = require 'chai'

const helper = new Helper('../scripts/example.mjs')
expect = chai.expect

describe('example script', () => {
let room = null
beforeEach(() => {
room = helper.createRoom()
})
helper = new Helper('../scripts/example.coffee')

afterEach(() =>
room.destroy()
))
describe 'example script', ->
beforeEach ->
@room = helper.createRoom()

it("doesn't need badgers", async () => {
await room.user.say('alice', 'did someone call for a badger?')
assert.deepEqual(room.messages, [
['alice', 'did someone call for a badger?']
['hubot', 'Badgers? BADGERS? WE DON\'T NEED NO STINKIN BADGERS']
])
})
it("won't open the pod bay doors"), async () => {
await room.user.say('bob', '@hubot open the pod bay doors')
assert.deepEqual(room.messages, [
['bob', '@hubot open the pod bay doors']
['hubot', '@bob I\'m afraid I can\'t let you do that.']
])
})
it('will open the dutch doors'), async () => {
await room.user.say('bob', '@hubot open the dutch doors')
assert.deepEqual(room.messages, [
['bob', '@hubot open the dutch doors']
['hubot', '@bob Opening dutch doors']
])
})
}
afterEach ->
@room.destroy()

it 'doesn\'t need badgers', ->
@room.user.say('alice', 'did someone call for a badger?').then =>
expect(@room.messages).to.eql [
['alice', 'did someone call for a badger?']
['hubot', 'Badgers? BADGERS? WE DON\'T NEED NO STINKIN BADGERS']
]

it 'won\'t open the pod bay doors', ->
@room.user.say('bob', '@hubot open the pod bay doors').then =>
expect(@room.messages).to.eql [
['bob', '@hubot open the pod bay doors']
['hubot', '@bob I\'m afraid I can\'t let you do that.']
]

it 'will open the dutch doors', ->
@room.user.say('bob', '@hubot open the dutch doors').then =>
expect(@room.messages).to.eql [
['bob', '@hubot open the dutch doors']
['hubot', '@bob Opening dutch doors']
]
```
**sample output**
```sh
% node --test test/*.mjs
% mocha --require coffeescript/register test/*.coffee
example script
✓ doesn't need badgers
✓ won't open the pod bay doors
Expand Down
31 changes: 31 additions & 0 deletions es2015.js
@@ -0,0 +1,31 @@
'use strict'

const User = require('./src/user')
const Brain = require('./src/brain')
const Robot = require('./src/robot')
const Adapter = require('./src/adapter')
const Response = require('./src/response')
const Listener = require('./src/listener')
const Message = require('./src/message')
const DataStore = require('./src/datastore')

module.exports = {
User,
Brain,
Robot,
Adapter,
Response,
Listener: Listener.Listener,
TextListener: Listener.TextListener,
Message: Message.Message,
TextMessage: Message.TextMessage,
EnterMessage: Message.EnterMessage,
LeaveMessage: Message.LeaveMessage,
TopicMessage: Message.TopicMessage,
CatchAllMessage: Message.CatchAllMessage,
DataStore: DataStore.DataStore,
DataStoreUnavailable: DataStore.DataStoreUnavailable,
loadBot (adapter, enableHttpd, name, alias) {
return new module.exports.Robot(adapter, enableHttpd, name, alias)
}
}
63 changes: 36 additions & 27 deletions index.js
@@ -1,31 +1,40 @@
'use strict'
require('coffeescript/register')

const User = require('./src/user')
const Brain = require('./src/brain')
const Robot = require('./src/robot')
const Adapter = require('./src/adapter')
const Response = require('./src/response')
const Listener = require('./src/listener')
const Message = require('./src/message')
const DataStore = require('./src/datastore')

module.exports = {
User,
Brain,
Robot,
Adapter,
Response,
Listener: Listener.Listener,
TextListener: Listener.TextListener,
Message: Message.Message,
TextMessage: Message.TextMessage,
EnterMessage: Message.EnterMessage,
LeaveMessage: Message.LeaveMessage,
TopicMessage: Message.TopicMessage,
CatchAllMessage: Message.CatchAllMessage,
DataStore: DataStore.DataStore,
DataStoreUnavailable: DataStore.DataStoreUnavailable,
loadBot (adapter, enableHttpd, name, alias) {
return new module.exports.Robot(adapter, enableHttpd, name, alias)
const inherits = require('util').inherits

const hubotExport = require('./es2015')

// make all es2015 class declarations compatible with CoffeeScript’s extend
// see https://github.com/hubotio/evolution/pull/4#issuecomment-306437501
module.exports = Object.keys(hubotExport).reduce((map, current) => {
if (current !== 'loadBot') {
map[current] = makeClassCoffeeScriptCompatible(hubotExport[current])
} else {
map[current] = hubotExport[current]
}
return map
}, {})

function makeClassCoffeeScriptCompatible (klass) {
function CoffeeScriptCompatibleClass () {
const Hack = Function.prototype.bind.apply(klass, [null].concat([].slice.call(arguments)))
const instance = new Hack()

// pass methods from child to returned instance
for (const key in this) {
instance[key] = this[key]
}

// support for constructor methods which call super()
// in which this.* properties are set
for (const key in instance) {
this[key] = instance[key]
}

return instance
}
inherits(CoffeeScriptCompatibleClass, klass)

return CoffeeScriptCompatibleClass
}
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "hubot",
"version": "9.1.0",
"version": "0.0.0-development",
"author": "hubot",
"keywords": [
"github",
Expand All @@ -15,6 +15,7 @@
"url": "https://github.com/hubotio/hubot.git"
},
"dependencies": {
"coffeescript": "^2.7.0",
"connect-multiparty": "^2.2.0",
"express": "^4.18.2",
"express-basic-auth": "^1.2.1",
Expand Down
8 changes: 6 additions & 2 deletions src/robot.js
Expand Up @@ -328,6 +328,10 @@ class Robot {
}
}

async loadcoffee (filePath) {
return await this.loadjs(filePath)
}

async loadjs (filePath) {
const script = require(filePath)
if (typeof script === 'function') {
Expand All @@ -348,7 +352,7 @@ class Robot {
const full = path.join(filepath, path.basename(filename))

// see https://github.com/hubotio/hubot/issues/1355
if (['js', 'mjs'].indexOf(ext) === -1) {
if (['js', 'mjs', 'coffee'].indexOf(ext) === -1) {
this.logger.debug(`Skipping unsupported file type ${full}`)
return
}
Expand Down Expand Up @@ -476,7 +480,7 @@ class Robot {
try {
if (Array.from(HUBOT_DEFAULT_ADAPTERS).indexOf(this.adapterName) > -1) {
this.adapter = this.requireAdapterFrom(path.resolve(path.join(__dirname, 'adapters', this.adapterName)))
} else if (['.js', '.cjs'].includes(ext)) {
} else if (['.js', '.cjs', '.coffee'].includes(ext)) {
this.adapter = this.requireAdapterFrom(path.resolve(adapterPath))
} else if (['.mjs'].includes(ext)) {
this.adapter = await this.importAdapterFrom(pathToFileURL(path.resolve(adapterPath)).href)
Expand Down
4 changes: 2 additions & 2 deletions test/index_test.js → test/es2015_test.js
Expand Up @@ -8,7 +8,7 @@ const assert = require('assert/strict')
const { hook, reset } = require('./fixtures/RequireMocker.js')

// Hubot classes
const Hubot = require('../index.js')
const Hubot = require('../es2015.js')
const User = Hubot.User
const Brain = Hubot.Brain
const Robot = Hubot.Robot
Expand All @@ -23,7 +23,7 @@ const LeaveMessage = Hubot.LeaveMessage
const TopicMessage = Hubot.TopicMessage
const CatchAllMessage = Hubot.CatchAllMessage

describe('hubot/index', () => {
describe('hubot/es2015', () => {
it('exports User class', () => {
class MyUser extends User {}
const user = new MyUser('id123', { foo: 'bar' })
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/MockAdapter.mjs
@@ -1,6 +1,6 @@
'use strict'

import { Adapter } from '../../index.js'
import { Adapter } from '../../es2015.js' // eslint-disable-line import/no-unresolved

class MockAdapter extends Adapter {
constructor (robot) {
Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/TestScript.coffee
@@ -0,0 +1,9 @@
# Description: A test script for the robot to load
#
# Commands:
# hubot test - Responds with a test response
#

module.exports = (robot) ->
robot.respond 'test', (res) ->
res.send 'test response from coffeescript'

0 comments on commit 7fa3841

Please sign in to comment.