From 91cbe763c9265d5520e0763ce287716e2555d468 Mon Sep 17 00:00:00 2001 From: Joey Guerra Date: Sun, 13 Aug 2023 22:36:16 -0500 Subject: [PATCH] fix: Loading .mjs Adapter from file and scripts failing on Windows (#1662) * fix: on Windows, getting ERR_UNSUPPORTED_ESM_URL_SCHEME error when trying to load an adpater * fix: ERR_UNSUPPORTED_ESM_URL_SCHEME on Windows * chore: Fixing loading adapter by file on Windows * Didn't seem to run * Still failing * Setting environment variables in Window is diff. * adapter worked, but now the mjs scripts are failing to load * fix: Setting HUBOT_ADAPTER to a file path on Windows failed to load the adapter fix: .mjs files were failing to load on Windows for the same reason --- .github/workflows/nodejs-windows.yml | 15 ++++++------ bin/hubot.js | 14 +++++------ src/robot.js | 4 ++-- test/hubot_test.js | 36 +++++++++++++++------------- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/.github/workflows/nodejs-windows.yml b/.github/workflows/nodejs-windows.yml index 060c3a3c5..283d7032c 100644 --- a/.github/workflows/nodejs-windows.yml +++ b/.github/workflows/nodejs-windows.yml @@ -1,20 +1,16 @@ name: Node.js (Windows) CI - on: push: - branches: [ "main" ] + branches: + - main schedule: - - cron: '5 4 * * 0' - + - cron: '5 4 * * 0' jobs: npm-test: - runs-on: windows-latest - strategy: matrix: node-version: [18.x] - steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} @@ -23,4 +19,7 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - - run: npm test + - name: Run Tests + env: + HUBOT_LOG_LEVEL: debug + run: npm test \ No newline at end of file diff --git a/bin/hubot.js b/bin/hubot.js index 62a9d48d7..c3e4aa399 100755 --- a/bin/hubot.js +++ b/bin/hubot.js @@ -8,13 +8,13 @@ const OptParse = require('optparse') const Hubot = require('..') const switches = [ - ['-a', '--adapter ADAPTER', 'The Adapter to use, e.g. "shell" (to load the default hubot shell adapter)'], - ['-f', '--file PATH', 'Path to adapter file, e.g. "./adapters/CustomAdapter.mjs"'], - ['-c', '--create PATH', 'Create a deployable hubot'], - ['-d', '--disable-httpd DISABLE_HTTPD', 'Disable the HTTP server'], + ['-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'], ['-h', '--help', 'Display the help information'], - ['-l', '--alias ALIAS', "Enable replacing the robot's name with alias"], - ['-n', '--name NAME', 'The name of the robot in chat'], + ['-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'] @@ -97,6 +97,7 @@ if (options.create) { if (options.file) { options.adapter = options.file.split('/').pop().split('.')[0] } + const robot = Hubot.loadBot(options.adapter, options.enableHttpd, options.name, options.alias) module.exports = robot @@ -107,7 +108,6 @@ async function loadScripts () { loadExternalScripts() const tasks = options.scripts.map((scriptPath) => { - console.log('loadding', scriptPath) if (scriptPath[0] === '/') { return robot.load(scriptPath) } diff --git a/src/robot.js b/src/robot.js index 34dcc8fc1..891390e83 100644 --- a/src/robot.js +++ b/src/robot.js @@ -347,7 +347,7 @@ class Robot { } async loadmjs (filePath) { - const script = await import(filePath) + const script = await import(pathToFileURL(filePath)) if (typeof script?.default === 'function') { script.default(this) } else { @@ -526,7 +526,7 @@ class Robot { try { this.adapter = this.requireAdapterFrom(adapterPathInCurrentWorkingDirectory) } catch (err) { - if (err.name === 'SyntaxError' && err.message.includes('Cannot use import statement outside a module')) { + if (err.name === 'SyntaxError') { this.adapter = await this.importAdapterFrom(adapterPathInCurrentWorkingDirectory) } else { throw err diff --git a/test/hubot_test.js b/test/hubot_test.js index ac9ef23b3..bdb23a667 100644 --- a/test/hubot_test.js +++ b/test/hubot_test.js @@ -1,6 +1,6 @@ 'use strict' -/* global describe, it, before, after */ +/* global describe, it */ /* eslint-disable no-unused-expressions */ const path = require('path') @@ -10,25 +10,27 @@ const expect = chai.expect const root = __dirname.replace(/test$/, '') const { TextMessage, User } = require('../index.js') -describe('hubot', () => { - let hubot - before(() => { - process.env.HUBOT_ADAPTER = path.join('..', 'test', 'fixtures', 'MockAdapter.mjs') - hubot = require('../bin/hubot.js') - }) - after(() => { - hubot.shutdown() - delete process.env.HUBOT_ADAPTER - }) - it('should export robot instance', done => { - hubot.loadFile(path.resolve(root, 'test/fixtures'), 'TestScript.mjs').then(() => { +describe('Running bin/hubot.js', () => { + it('should load adapter from HUBOT_FILE environment variable', done => { + process.env.HUBOT_HTTPD = 'false' + process.env.HUBOT_FILE = path.resolve(root, 'test', 'fixtures', 'MockAdapter.mjs') + const hubot = require('../bin/hubot.js') + setTimeout(function () { hubot.adapter.on('reply', (envelope, ...strings) => { expect(strings[0]).to.equal('test response from .mjs script') + delete process.env.HUBOT_FILE + delete process.env.HUBOT_HTTPD + hubot.shutdown() done() }) - hubot.receive(new TextMessage(new User('mocha', { room: '#mocha' }), 'Hubot test')) - expect(hubot.hasLoadedTestMjsScript).to.be.true - expect(hubot.name).to.equal('Hubot') - }).catch(done) + hubot.loadFile(path.resolve(root, 'test', 'fixtures'), 'TestScript.mjs').then(() => { + hubot.receive(new TextMessage(new User('mocha', { room: '#mocha' }), '@Hubot test')) + expect(hubot.hasLoadedTestMjsScript).to.be.true + expect(hubot.name).to.equal('Hubot') + }).catch(err => { + hubot.shutdown() + done(err) + }) + }, 1000) }) })