Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use an alias system instead of camelCase function #3101

Merged
merged 2 commits into from
Apr 20, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions __tests__/cli/aliases.js

This file was deleted.

32 changes: 32 additions & 0 deletions __tests__/cli/unsupported-aliases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* @flow */

import unsupportedAliases from '../../src/cli/unsupported-aliases.js';

test('shorthands and affordances', () => {
expect(unsupportedAliases['run-script']).toBe('run');
expect(unsupportedAliases['c']).toBe('config');
expect(unsupportedAliases['i']).toBe('install');
expect(unsupportedAliases['ls']).toBe('list');
expect(unsupportedAliases['rb']).toBe('rebuild');
expect(unsupportedAliases['runScript']).toBe('run');
expect(unsupportedAliases['t']).toBe('test');
expect(unsupportedAliases['tst']).toBe('test');
expect(unsupportedAliases['un']).toBe('remove');
expect(unsupportedAliases['up']).toBe('upgrade');
expect(unsupportedAliases['v']).toBe('version');
expect(unsupportedAliases['add-user']).toBe('login');
expect(unsupportedAliases['dist-tag']).toBe('tag');
expect(unsupportedAliases['dist-tags']).toBe('tag');
expect(unsupportedAliases['adduser']).toBe('login');
expect(unsupportedAliases['author']).toBe('owner');
expect(unsupportedAliases['isntall']).toBe('install');
expect(unsupportedAliases['la']).toBe('list');
expect(unsupportedAliases['ll']).toBe('list');
expect(unsupportedAliases['r']).toBe('remove');
expect(unsupportedAliases['rm']).toBe('remove');
expect(unsupportedAliases['show']).toBe('info');
expect(unsupportedAliases['uninstall']).toBe('remove');
expect(unsupportedAliases['update']).toBe('upgrade');
expect(unsupportedAliases['verison']).toBe('version');
expect(unsupportedAliases['view']).toBe('info');
});
5 changes: 5 additions & 0 deletions __tests__/fixtures/index/run-generate-lock-entry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "test_generate_lock_entry",
"version": "1.0.0",
"license": "UNLICENSED"
}
45 changes: 43 additions & 2 deletions __tests__/index.js
Original file line number Diff line number Diff line change
@@ -211,20 +211,26 @@ test.concurrent('should not output JSON activity/progress if given --no-progress
});
});

test.concurrent('should interpolate aliases', async () => {
test.concurrent('should interpolate unsupported aliases', async () => {
await expectAnErrorMessage(
execCommand('i', [], 'run-add', true),
'Did you mean `yarn install`?',
);
});

test.concurrent('should display correct documentation link for aliases', async () => {
test.concurrent('should display correct documentation link for unsupported aliases', async () => {
await expectAnInfoMessageAfterError(
execCommand('i', [], 'run-add', true),
'Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.',
);
});

test.concurrent('should show help and ignore unsupported aliases', async () => {
const stdout = await execCommand('i', ['--help'], 'run-help');
expect(stdout[stdout.length - 1])
.toEqual('Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.');
});

test.concurrent('should run help of run command if --help is before --', async () => {
const stdout = await execCommand('run', ['custom-script', '--help', '--'], 'run-custom-script-with-arguments');
expect(stdout[0]).toEqual('Usage: yarn [command] [flags]');
@@ -286,3 +292,38 @@ test.concurrent('should throws missing command for constructor command', async (
'Command \"constructor\" not found',
);
});

test.concurrent('should show help and ignore constructor command', async () => {
const stdout = await execCommand('constructor', ['--help'], 'run-help');
expectHelpOutput(stdout);
});

test.concurrent('should run command with hyphens', async () => {
const stdout = await execCommand('generate-lock-entry', [], 'run-generate-lock-entry');
expect(stdout[0]).toMatch(/# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY./);
expect(stdout[1]).toMatch(/# yarn lockfile v1/);
});

test.concurrent('should run camelised command for command with hyphens', async () => {
const stdout = await execCommand('generateLockEntry', [], 'run-generate-lock-entry');
expect(stdout[0]).toMatch(/# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY./);
expect(stdout[1]).toMatch(/# yarn lockfile v1/);
});

test.concurrent('should run help for command with hyphens', async () => {
const stdout = await execCommand('generate-lock-entry', ['--help'], 'run-generate-lock-entry');
const lastLines = stdout.slice(stdout.length - 4);
expect(lastLines[0]).toMatch(/yarn generate-lock-entry/);
expect(lastLines[1]).toMatch(/yarn generate-lock-entry --use-manifest .\/package.json/);
expect(lastLines[2]).toMatch(/yarn generate-lock-entry --resolved local-file.tgz#hash/);
expect(lastLines[3]).toMatch(/Visit https:\/\/yarnpkg.com\/en\/docs\/cli\/generate-lock-entry/);
});

test.concurrent('should run help for camelised command', async () => {
const stdout = await execCommand('generateLockEntry', ['--help'], 'run-generate-lock-entry');
const lastLines = stdout.slice(stdout.length - 4);
expect(lastLines[0]).toMatch(/yarn generate-lock-entry/);
expect(lastLines[1]).toMatch(/yarn generate-lock-entry --use-manifest .\/package.json/);
expect(lastLines[2]).toMatch(/yarn generate-lock-entry --resolved local-file.tgz#hash/);
expect(lastLines[3]).toMatch(/Visit https:\/\/yarnpkg.com\/en\/docs\/cli\/generate-lock-entry/);
});
39 changes: 3 additions & 36 deletions src/cli/aliases.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,6 @@
/* @flow */

const shorthands: { [key: string]: string } = {
c: 'config',
i: 'install',
la: 'list',
ll: 'list',
ln: 'link',
ls: 'list',
r: 'remove',
rb: 'rebuild',
rm: 'remove',
t: 'test',
tst: 'test',
un: 'remove',
up: 'upgrade',
v: 'version',
};

const affordances: { [key: string]: string } = {
'add-user': 'login',
adduser: 'login',
author: 'owner',
'dist-tag': 'tag',
'dist-tags': 'tag',
isntall: 'install',
'run-script': 'run',
runScript: 'run',
show: 'info',
uninstall: 'remove',
update: 'upgrade',
verison: 'version',
view: 'info',
};

export default ({
...shorthands,
...affordances,
export default({
'upgrade-interactive': 'upgradeInteractive',
'generate-lock-entry': 'generateLockEntry',
}: { [key: string]: string });
17 changes: 6 additions & 11 deletions src/cli/commands/help.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* @flow */

import * as commands from './index.js';
import commands from './index.js';
import * as constants from '../../constants.js';
import type {Reporter} from '../../reporters/index.js';
import type Config from '../../config.js';
import {sortAlpha, hyphenate, camelCase} from '../../util/misc.js';
import {sortAlpha, hyphenate} from '../../util/misc.js';
const chalk = require('chalk');

export function hasWrapper(): boolean {
@@ -19,15 +19,10 @@ export function run(
commander: Object,
args: Array<string>,
): Promise<void> {
const getDocsLink = (name) => `${constants.YARN_DOCS}${name || ''}`;
const getDocsInfo = (name) => 'Visit ' + chalk.bold(getDocsLink(name)) + ' for documentation about this command.';

if (args.length) {
const commandName = camelCase(args.shift());

if (commandName) {
const commandName = args.shift();
if (Object.prototype.hasOwnProperty.call(commands, commandName)) {
const command = commands[commandName];

if (command) {
command.setFlags(commander);
const examples: Array<string> = (command && command.examples) || [];
@@ -40,15 +35,15 @@ export function run(
console.log();
});
}
commander.on('--help', () => console.log(' ' + getDocsInfo(commandName) + '\n'));

commander.on('--help', () => console.log(' ' + command.getDocsInfo + '\n'));
commander.help();
return Promise.resolve();
}
}
}

commander.on('--help', () => {
const getDocsLink = (name) => `${constants.YARN_DOCS}${name || ''}`;
console.log(' Commands:\n');
for (const name of Object.keys(commands).sort(sortAlpha)) {
if (commands[name].useless) {
152 changes: 110 additions & 42 deletions src/cli/commands/index.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,117 @@
/* @flow */
import {ConsoleReporter, JSONReporter} from '../../reporters/index.js';
import * as constants from '../../constants.js';
import {MessageError} from '../../errors.js';
import Config from '../../config.js';

import * as access from './access.js'; export {access};
import * as add from './add.js'; export {add};
import * as bin from './bin.js'; export {bin};
import * as cache from './cache.js'; export {cache};
import * as check from './check.js'; export {check};
import * as clean from './clean.js'; export {clean};
import * as config from './config.js'; export {config};
import * as generateLockEntry from './generate-lock-entry.js'; export {generateLockEntry};
import * as global from './global.js'; export {global};
import * as help from './help.js'; export {help};
import * as import_ from './import.js'; export {import_ as import};
import * as info from './info.js'; export {info};
import * as init from './init.js'; export {init};
import * as install from './install.js'; export {install};
import * as licenses from './licenses.js'; export {licenses};
import * as link from './link.js'; export {link};
import * as login from './login.js'; export {login};
import * as logout from './logout.js'; export {logout};
import * as list from './list.js'; export {list};
import * as outdated from './outdated.js'; export {outdated};
import * as owner from './owner.js'; export {owner};
import * as pack from './pack.js'; export {pack};
import * as publish from './publish.js'; export {publish};
import * as remove from './remove.js'; export {remove};
import * as run from './run.js'; export {run};
import * as tag from './tag.js'; export {tag};
import * as team from './team.js'; export {team};
import * as unlink from './unlink.js'; export {unlink};
import * as upgrade from './upgrade.js'; export {upgrade};
import * as version from './version.js'; export {version};
import * as versions from './versions.js'; export {versions};
import * as why from './why.js'; export {why};
import * as upgradeInteractive from './upgrade-interactive.js'; export {upgradeInteractive};
const chalk = require('chalk');

const getDocsLink = (name) => `${constants.YARN_DOCS}${name || ''}`;
const getDocsInfo = (name) => 'Visit ' + chalk.bold(getDocsLink(name)) + ' for documentation about this command.';

import * as access from './access.js';
import * as add from './add.js';
import * as bin from './bin.js';
import * as cache from './cache.js';
import * as check from './check.js';
import * as clean from './clean.js';
import * as config from './config.js';
import * as generateLockEntry from './generate-lock-entry.js';
import * as global from './global.js';
import * as help from './help.js';
import * as import_ from './import.js';
import * as info from './info.js';
import * as init from './init.js';
import * as install from './install.js';
import * as licenses from './licenses.js';
import * as link from './link.js';
import * as login from './login.js';
import * as logout from './logout.js';
import * as list from './list.js';
import * as outdated from './outdated.js';
import * as owner from './owner.js';
import * as pack from './pack.js';
import * as publish from './publish.js';
import * as remove from './remove.js';
import * as run from './run.js';
import * as tag from './tag.js';
import * as team from './team.js';
import * as unlink from './unlink.js';
import * as upgrade from './upgrade.js';
import * as version from './version.js';
import * as versions from './versions.js';
import * as why from './why.js';
import * as upgradeInteractive from './upgrade-interactive.js';

import buildUseless from './_useless.js';

export const lockfile = buildUseless(
"The lockfile command isn't necessary. `yarn install` will produce a lockfile.",
);
const commands = {
access,
add,
bin,
cache,
check,
clean,
config,
dedupe: buildUseless(
"The dedupe command isn't necessary. `yarn install` will already dedupe.",
),
generateLockEntry,
global,
help,
import: import_,
info,
init,
install,
licenses,
link,
lockfile: buildUseless(
"The lockfile command isn't necessary. `yarn install` will produce a lockfile.",
),
login,
logout,
list,
outdated,
owner,
pack,
prune: buildUseless(
"The prune command isn't necessary. `yarn install` will prune extraneous packages.",
),
publish,
remove,
run,
tag,
team,
unlink,
upgrade,
version,
versions,
why,
upgradeInteractive,
};

for (const key in commands) {
commands[key].getDocsInfo = getDocsInfo(key);
}

import aliases from '../aliases.js';

for (const key in aliases) {
commands[key] = commands[aliases[key]];
commands[key].getDocsInfo = getDocsInfo(key);
}

import unsupportedAliases from '../unsupported-aliases.js';

export const dedupe = buildUseless(
"The dedupe command isn't necessary. `yarn install` will already dedupe.",
);
for (const key in unsupportedAliases) {
commands[key] = {
run(config: Config, reporter: ConsoleReporter | JSONReporter): Promise<void> {
throw new MessageError(`Did you mean \`yarn ${unsupportedAliases[key]}\`?`);
},
setFlags: () => {},
hasWrapper: () => true,
getDocsInfo: getDocsInfo(unsupportedAliases[key]),
};
}

export const prune = buildUseless(
"The prune command isn't necessary. `yarn install` will prune extraneous packages.",
);
export default (commands);
Loading