Skip to content

Commit

Permalink
feat: inject versions into friendly errors (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
tabrindle authored and GantMan committed Mar 30, 2018
1 parent dfe8fd8 commit d5ed9d4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 6 deletions.
13 changes: 13 additions & 0 deletions __tests__/command_helpers/checkCLI.ts
Expand Up @@ -19,6 +19,12 @@ const outOfDateCLI = {
semver: '10.99',
}

const injectVersion = {
binary: 'node',
semver: '~7.6',
error: "Wanted: '{{wantedVersion}}', Installed: '{{installedVersion}}'. Update with `nvm install {{wantedVersion}}`",
}

const context = require('gluegun/toolbox')

test('error on missing binary', async () => {
Expand All @@ -40,3 +46,10 @@ test('returns message on improper version', async () => {

expect(await checkCLI(outOfDateCLI, context)).toBe(message)
})

test('returns message with injected versions', async () => {
const message = `Wanted: '7.6', Installed: '7.5'. Update with \`nvm install 7.6\``
solidarityExtension(context)
context.solidarity.getVersion = () => '7.5'
expect(await checkCLI(injectVersion, context)).toBe(message)
})
10 changes: 10 additions & 0 deletions __tests__/command_helpers/checkRequirement.ts
Expand Up @@ -90,6 +90,16 @@ describe('checkRequirement', () => {
const result = await checkRequirement(rule, context)
expect(result).toEqual([[]])
})

test('inject versions', async () => {
checkCLI.mockImplementation(async () => "Wanted: '~1.5.1', Installed '1.3.2'")

const rule = toPairs({
YARN: [{ rule: 'cli', binary: 'yarn' }],
})[0]
const result = await checkRequirement(rule, context)
expect(result).toEqual(["Wanted: '~1.5.1', Installed '1.3.2'"])
})
})

describe('when rule: dir', () => {
Expand Down
26 changes: 21 additions & 5 deletions docs/options.md
Expand Up @@ -99,9 +99,11 @@ Lastly, if output has multiple versions, you can identify the index of the versi
```

### Friendly Errors
So what do we do if a rule fails? The return code will be non-zero, but that's not the most friendly option. You can set the `error` for any rule to give the user legible instruction on why the failure happened, and how they should solve it.

*e.g.* Prompt them to install the missing CLI
So what do we do if a rule fails? The return code will be non-zero, but that's not the most friendly option. You can set the `error` for any rule to give the user legible instruction on why the failure happened, and how they should solve it.

_e.g._ Prompt them to install the missing CLI

```json
"Watchman": [
{
Expand All @@ -112,12 +114,26 @@ So what do we do if a rule fails? The return code will be non-zero, but that's
]
```

In your error message, you can include `{{wantedVersion}}` and `{{installedVersion}}` to give the user version information, or even to customize scripts to help them install or update.

```json
"Yarn": [
{
"rule": "cli",
"binary": "yarn",
"error": "You have yarn@{{installedVersion}}, and need yarn@{{wantedVersion}}. Fix with `npm install -g yarn@{{wantedVersion}}`"
}
]
```

### Platform Specific Rules
Some rules are only essential for a given node platform. You can identify these rules with passing the `"platform"` property on any rule.

A platform property takes a string or and array of strings that identify the platforms that rule pertains to. Platforms can be any of the following: `["darwin", "macos", "freebsd", "linux", "sunos", "win32", "windows"]`
Some rules are only essential for a given node platform. You can identify these rules with passing the `"platform"` property on any rule.

A platform property takes a string or and array of strings that identify the platforms that rule pertains to. Platforms can be any of the following: `["darwin", "macos", "freebsd", "linux", "sunos", "win32", "windows"]`

_e.g._ Rule only performs a check on Mac and Linux

*e.g.* Rule only performs a check on Mac and Linux
```json
"Watchman": [
{
Expand Down
8 changes: 7 additions & 1 deletion src/extensions/functions/checkCLI.ts
Expand Up @@ -26,9 +26,15 @@ module.exports = async (rule: CLIRule, context: SolidarityRunContext): Promise<s
binarySemantic += '.0'
}

const customMessage = (rule.error || '')
.replace(/{{wantedVersion}}/gi, /\^|\~/.test(rule.semver) ? rule.semver.substr(1) : rule.semver)
.replace(/{{installedVersion}}/gi, binaryVersion)
const standardMessage = `${rule.binary}: you have '${binaryVersion}', but the project requires '${rule.semver}'`
const message = customMessage || standardMessage

// I can't get no satisfaction
if (!semver.satisfies(binarySemantic, rule.semver)) {
return `${rule.binary}: you have '${binaryVersion}', but the project requires '${rule.semver}'`
return message
}
}
}

0 comments on commit d5ed9d4

Please sign in to comment.