diff --git a/packages/cli-hooks/README.md b/packages/cli-hooks/README.md index a671b5e53..09e711a88 100644 --- a/packages/cli-hooks/README.md +++ b/packages/cli-hooks/README.md @@ -50,11 +50,12 @@ installed. ### Supported Hooks The hooks that are currently supported for use within the Slack CLI include -`check-update`, `get-hooks`, `get-manifest`, and `start`: +`check-update`, `doctor`, `get-hooks`, `get-manifest`, and `start`: | Hook Name | CLI Command | File |Description | | -------------- | ---------------- | ---- | ----------- | | `check-update` | `slack update` | [`check-update.js`](./src/check-update.js) | Checks the project's Slack dependencies to determine whether or not any packages need to be updated. | +| `doctor` | `slack doctor` | [`doctor.js`](./src/doctor.js) | Returns runtime versions and other system dependencies required by the application. | | `get-hooks` | All | [`get-hooks.js`](./src/get-hooks.js) | Fetches the list of available hooks for the CLI from this repository. | | `get-manifest` | `slack manifest` | [`get-manifest.js`](./src/get-manifest.js) | Converts a `manifest.json` file into a valid manifest JSON payload. | | `start` | `slack run` | [`start.js`](./src/start.js) | While developing locally, the CLI manages a socket connection with Slack's backend and utilizes this hook for events received via this connection. | diff --git a/packages/cli-hooks/package.json b/packages/cli-hooks/package.json index 693deddee..3a92f3c84 100644 --- a/packages/cli-hooks/package.json +++ b/packages/cli-hooks/package.json @@ -1,6 +1,6 @@ { "name": "@slack/cli-hooks", - "version": "1.0.0", + "version": "1.1.0", "description": "Node implementation of the contract between the Slack CLI and Bolt for JavaScript", "author": "Slack Technologies, LLC", "license": "MIT", @@ -13,6 +13,7 @@ "main": "src/get-hooks.js", "files": [ "src/check-update.js", + "src/doctor.js", "src/get-hooks.js", "src/get-manifest.js", "src/protocols.js", @@ -42,9 +43,10 @@ "test": "c8 mocha src/*.spec.js" }, "bin": { + "slack-cli-check-update": "src/check-update.js", + "slack-cli-doctor": "src/doctor.js", "slack-cli-get-hooks": "src/get-hooks.js", "slack-cli-get-manifest": "src/get-manifest.js", - "slack-cli-check-update": "src/check-update.js", "slack-cli-start": "src/start.js" }, "dependencies": { diff --git a/packages/cli-hooks/src/doctor.js b/packages/cli-hooks/src/doctor.js new file mode 100755 index 000000000..6f10fee71 --- /dev/null +++ b/packages/cli-hooks/src/doctor.js @@ -0,0 +1,52 @@ +#!/usr/bin/env node + +import { fileURLToPath } from 'url'; +import fs from 'fs'; + +import { getProtocol } from './protocols.js'; + +/** + * Implementation of the optional doctor script hook for the Slack CLI. + * Printed as an object containing information about the system runtime. + */ + +if (fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) { + const protocol = getProtocol(process.argv.slice(1)); + protocol.respond(JSON.stringify(doctor())); // eslint-disable-line no-console +} + +/** + * Standardized communication format between the SDK and CLI regarding runtimes. + * @typedef DoctorResponse + * @property {RuntimeVersion[]} versions - Existing system dependencies present. + */ + +/** + * Information about all of the installed runtime dependencies. + * @typedef RuntimeVersion + * @property {string} name - Name of the runtime dependency. + * @property {string} current - Version found on the system. + */ + +/** + * Contains available hooks and other configurations available to the SDK. + * @returns {DoctorResponse} Information about the hooks currently supported. + */ +export default function doctor() { + return { + versions: [ + { + name: 'node', + current: process.versions.node, + }, + { + name: 'v8', + current: process.versions.v8, + }, + { + name: 'modules', + current: process.versions.modules, + }, + ], + }; +} diff --git a/packages/cli-hooks/src/doctor.spec.js b/packages/cli-hooks/src/doctor.spec.js new file mode 100644 index 000000000..aa0ea346d --- /dev/null +++ b/packages/cli-hooks/src/doctor.spec.js @@ -0,0 +1,16 @@ +import { describe, it } from 'mocha'; +import assert from 'assert'; + +import doctor from './doctor.js'; + +describe('doctor implementation', async () => { + it('should return versions of runtime dependencies', async () => { + const { versions } = doctor(); + assert(versions[0].name === 'node'); + assert(versions[0].current === process.versions.node); + assert(versions[1].name === 'v8'); + assert(versions[1].current === process.versions.v8); + assert(versions[2].name === 'modules'); + assert(versions[2].current === process.versions.modules); + }); +}); diff --git a/packages/cli-hooks/src/get-hooks.js b/packages/cli-hooks/src/get-hooks.js index 1a3556da9..8b6ca7abb 100755 --- a/packages/cli-hooks/src/get-hooks.js +++ b/packages/cli-hooks/src/get-hooks.js @@ -6,8 +6,8 @@ import fs from 'fs'; import { SUPPORTED_NAMED_PROTOCOLS } from './protocols.js'; /** - * Implementation the get-hooks script hook required by the Slack CLI. - * Printed as an object containing featured provided by the SDK. + * Implementation of the get-hooks script hook required by the Slack CLI. + * Printed as an object containing features provided by the SDK. */ if (fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) { @@ -45,8 +45,9 @@ if (fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) { export default function getHooks() { return { hooks: { - 'get-manifest': 'npx -q --no-install -p @slack/cli-hooks slack-cli-get-manifest', + doctor: 'npx -q --no-install -p @slack/cli-hooks slack-cli-doctor', 'check-update': 'npx -q --no-install -p @slack/cli-hooks slack-cli-check-update', + 'get-manifest': 'npx -q --no-install -p @slack/cli-hooks slack-cli-get-manifest', start: 'npx -q --no-install -p @slack/cli-hooks slack-cli-start', }, config: { diff --git a/packages/cli-hooks/src/get-hooks.spec.js b/packages/cli-hooks/src/get-hooks.spec.js index acbedc9d8..d0536eb22 100644 --- a/packages/cli-hooks/src/get-hooks.spec.js +++ b/packages/cli-hooks/src/get-hooks.spec.js @@ -6,8 +6,9 @@ import getHooks from './get-hooks.js'; describe('get-hooks implementation', async () => { it('should return scripts for required hooks', async () => { const { hooks } = getHooks(); - assert(hooks['get-manifest'] === 'npx -q --no-install -p @slack/cli-hooks slack-cli-get-manifest'); + assert(hooks.doctor === 'npx -q --no-install -p @slack/cli-hooks slack-cli-doctor'); assert(hooks['check-update'] === 'npx -q --no-install -p @slack/cli-hooks slack-cli-check-update'); + assert(hooks['get-manifest'] === 'npx -q --no-install -p @slack/cli-hooks slack-cli-get-manifest'); assert(hooks.start === 'npx -q --no-install -p @slack/cli-hooks slack-cli-start'); });