Skip to content

Commit

Permalink
Merge dd0d6ca into 816cd76
Browse files Browse the repository at this point in the history
  • Loading branch information
chimurai committed Jan 21, 2020
2 parents 816cd76 + dd0d6ca commit 09df9e5
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 17 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ module.exports = {
yarn: '~1.17.3',
nginx: {
semver: '>= 1.16.x',
optional: true // optional (won't fail)
optional: true, // optional (won't fail)
installMessage: '<install instruction>', // custom message when binary is not found
updateMessage: '<update instruction>' // custom message when binary has wrong version
},
httpd: {
semver: '^1.x',
Expand All @@ -58,7 +60,7 @@ $ npx requirements
Or use a custom path:

```bash
$ npx requirements --config=<filepath>
$ npx requirements --config <filepath>
```

# CLI options
Expand Down Expand Up @@ -105,8 +107,19 @@ checkSoftware() returns an Array with results
];
```

# testing

```bash
# test functionality
yarn build
node bin/requirements.js --config tests/requirements.config.js

# unit tests
yarn test
```

# license

The MIT License (MIT)

Copyright (c) 2017-2019 Steven Chim
Copyright (c) 2017-2020 Steven Chim
52 changes: 52 additions & 0 deletions src/__tests__/results.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as fs from 'fs';
import { isAllOK, getMessages } from '../results';
import { RawResult } from '../types';

describe('results', () => {
describe('all results OK', () => {
it('should indicate all results are OK', async () => {
const rawResults: RawResult[] = [
{
bin: 'mvn',
satisfies: true
} as RawResult
];

const result = isAllOK(rawResults);
expect(result).toBe(true);
});

it('should indicate all results are OK', async () => {
const rawResults: RawResult[] = [
{
bin: 'mvn',
satisfies: false
} as RawResult
];

const result = isAllOK(rawResults);
expect(result).toBe(false);
});
});

describe('custom messages', () => {
it('should return messages', async () => {
const rawResults: RawResult[] = [
{
bin: 'mvn',
installed: false,
installMessage: '<mvn install instructions>'
} as RawResult,
{
bin: 'nginx',
satisfies: false,
updateMessage: '<nginx update instructions>'
} as RawResult
];

const result = getMessages(rawResults);
const expectation = ['<mvn install instructions>', '<nginx update instructions>'];
expect(result).toEqual(expectation);
});
});
});
9 changes: 5 additions & 4 deletions src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import * as yargs from 'yargs';
import * as path from 'path';
import * as chalk from 'chalk';
import { checkSoftware } from './requirements';
import { renderTable } from './reporter';
import { renderTable, renderMessages } from './reporter';
import { Configuration } from './types';
import { scaffold } from './scaffold';
import { isAllOK, getMessages } from './results';

export async function exec(_debug_argv_?) {
const argv = _debug_argv_ ?? getArgv();
Expand All @@ -21,17 +22,17 @@ export async function exec(_debug_argv_?) {
const config = getConfiguration(argv);
let rawResults = await checkSoftware(config.software);

const ALL_OK = rawResults
.filter(result => !result.optional)
.every(result => result.satisfies === true);
const ALL_OK = isAllOK(rawResults);

if (argv.debug) {
console.debug('👀 RAW data:\n', rawResults);
console.debug('👀 yargs:\n', argv);
}

if (!ALL_OK && !argv.force) {
const messages = getMessages(rawResults);
console.error(renderTable(rawResults));
console.log(renderMessages(messages));
throw new Error(`❌ Not all requirements are satisfied`);
}

Expand Down
4 changes: 4 additions & 0 deletions src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import * as logSymbols from 'log-symbols';
import * as chalk from 'chalk';
import { RawResult } from './types';

export function renderMessages(messages: string[] = []) {
return messages.map(message => `${chalk.red('❗️')} ${message}`).join('\n') + '\n';
}

export function renderTable(rawResults: RawResult[] = []) {
let results = rawResults.map(item => {
const { bin, semver, installed, version, satisfies, optional } = item;
Expand Down
18 changes: 18 additions & 0 deletions src/results.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { RawResult } from './types';

export function isAllOK(rawResults: RawResult[]) {
return rawResults.filter(result => !result.optional).every(result => result.satisfies === true);
}

export function getMessages(rawResults: RawResult[]) {
const notInstalledItems = rawResults.filter(item => !item.installed && item.installMessage);
const unsatisfiedInstalledItems = rawResults.filter(
item => !item.satisfies && item.updateMessage
);

const messages = [...notInstalledItems, ...unsatisfiedInstalledItems].map(item => {
return item.installMessage || item.updateMessage;
});

return messages;
}
6 changes: 4 additions & 2 deletions src/scaffold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ const TEMPLATE = `module.exports = {
node: '^${semver.clean(process.version)}',
nginx: {
semver: '^666.x',
optional: true // won't fail if missing or wrong version
optional: true // won't fail if missing or wrong version
},
// httpd: {
// semver: '^2.x',
// flag: '-v' // custom flag to print version
// flag: '-v', // custom flag to print version
// installMessage: '<install instruction>', // custom message when binary is not found
// updateMessage: '<update instruction>', // custom message when binary has wrong version
// },
}
};`;
Expand Down
11 changes: 5 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ export type ConfigurationValue = ConfigurationStringValue | ConfigurationObjectV

export type ConfigurationStringValue = string;

export type ConfigurationObjectValue = {
export interface ConfigurationObjectValue {
semver: string;
flag: string;
optional?: boolean;
};
installMessage?: string;
updateMessage?: string;
}

export interface RawResult {
export interface RawResult extends ConfigurationObjectValue {
bin: string;
semver: string;
flag: string;
installed: boolean;
version?: string;
satisfies?: boolean;
optional?: boolean;
}
8 changes: 6 additions & 2 deletions tests/requirements.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ module.exports = {
git: '~1.9.4 || 2.0.0 - 2.10.0',
node: '8 || 10 || 12',
npm: '>= 6.x',
yarn: '>= 1.19.x',
yarn: {
semver: '1.16.x',
updateMessage: `Outdated 'yarn' found. Run 'brew upgrade yarn' to update.`
},
mvn: '^3.x',
nginx: {
semver: '^6.x',
optional: true
optional: true,
installMessage: `This project is configured for NGINX but 'nginx' was not found on your path. Run 'brew install nginx' to install.`
},
httpd: {
semver: '^2.x',
Expand Down

0 comments on commit 09df9e5

Please sign in to comment.