Skip to content

Commit

Permalink
put cache command under Base command class
Browse files Browse the repository at this point in the history
  • Loading branch information
voxsim committed Mar 7, 2017
1 parent 78dfc90 commit c76f977
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 57 deletions.
6 changes: 5 additions & 1 deletion __tests__/commands/install/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type Config from '../../../src/config';
import PackageResolver from '../../../src/package-resolver.js';
import {run as cache} from '../../../src/cli/commands/cache.js';
import CacheCommand from '../../../src/cli/commands/cache.js';
import {run as check} from '../../../src/cli/commands/check.js';
import * as constants from '../../../src/constants.js';
import * as reporters from '../../../src/reporters/index.js';
Expand All @@ -22,6 +22,10 @@ const path = require('path');
const stream = require('stream');
const os = require('os');

function cache(config: Config, reporter: reporters.Reporter, flags: Object, args: Array<string>): Promise<void> {
return new CacheCommand().run(config, reporter, flags, args);
}

async function mockConstants(base: Config, mocks: Object, cb: (config: Config) => Promise<void>): Promise<void> {
// We cannot put this function inside _helpers, because we need to change the "request" variable
// after resetting the modules. Updating this variable is required because some tests check what
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/_base.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* @flow */

export default class BaseCommand {
hasWrapper(): boolean {
hasWrapper(flags: Object, args: Array<string>): boolean {
return true;
}
}
61 changes: 61 additions & 0 deletions src/cli/commands/_sub-command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* @flow */

import BaseCommand from './_base.js';
import type {Reporter} from '../../reporters/index.js';
import type Config from '../../config.js';
import type {CLIFunction} from '../../types.js';
import {MessageError} from '../../errors.js';
import {camelCase, hyphenate} from '../../util/misc.js';

type SubCommands = {
[commandName: string]: CLIFunction,
};

type Usage = Array<string>;

export default class SubCommand extends BaseCommand {
rootCommandName: string;
subCommands: SubCommands;
subCommandNames: Array<string>;
usage: Usage;
examples: Array<string>;

constructor(rootCommandName: string, subCommands: SubCommands, usage?: Usage = []) {
super();
this.rootCommandName = rootCommandName;
this.subCommands = subCommands;
this.subCommandNames = Object.keys(subCommands).map(hyphenate);
this.usage = usage;
this.examples = usage.map((cmd: string): string => {
return `${rootCommandName} ${cmd}`;
});
}

setFlags(commander: Object) {
commander.usage(`${this.rootCommandName} [${this.subCommandNames.join('|')}] [flags]`);
}

async run(
config: Config,
reporter: Reporter,
flags: Object,
args: Array<string>,
): Promise<void> {
const subName: ?string = camelCase(args.shift() || '');
if (subName && this.subCommands[subName]) {
const command: CLIFunction = this.subCommands[subName];
const res = await command(config, reporter, flags, args);
if (res !== false) {
return Promise.resolve();
}
}

if (this.usage && this.usage.length) {
reporter.error(`${reporter.lang('usage')}:`);
for (const msg of this.usage) {
reporter.error(`yarn ${this.rootCommandName} ${msg}`);
}
}
return Promise.reject(new MessageError(reporter.lang('invalidCommand', this.subCommandNames.join(', '))));
}
}
112 changes: 58 additions & 54 deletions src/cli/commands/cache.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,76 @@
/* @flow */

import SubCommand from './_sub-command.js';
import type {Reporter} from '../../reporters/index.js';
import type Config from '../../config.js';
import buildSubCommands from './_build-sub-commands.js';
import * as fs from '../../util/fs.js';
import {METADATA_FILENAME} from '../../constants';

const path = require('path');

export function hasWrapper(flags: Object, args: Array<string>): boolean {
return args[0] !== 'dir';
}
export default class CacheCommand extends SubCommand {
constructor() {
super('cache', {
async ls(
config: Config,
reporter: Reporter,
flags: Object,
args: Array<string>,
): Promise<void> {
async function readCacheMetadata(
parentDir = config.cacheFolder,
metadataFile = METADATA_FILENAME,
): Promise<Array<Array<string>>> {
const folders = await fs.readdir(parentDir);
const packagesMetadata = [];

export const {run, setFlags} = buildSubCommands('cache', {
async ls(
config: Config,
reporter: Reporter,
flags: Object,
args: Array<string>,
): Promise<void> {
async function readCacheMetadata(
parentDir = config.cacheFolder,
metadataFile = METADATA_FILENAME,
): Promise<Array<Array<string>>> {
const folders = await fs.readdir(parentDir);
const packagesMetadata = [];
for (const folder of folders) {
if (folder[0] === '.') {
continue;
}

for (const folder of folders) {
if (folder[0] === '.') {
continue;
}
const loc = path.join(config.cacheFolder, parentDir.replace(config.cacheFolder, ''), folder);
// Check if this is a scoped package
if (!(await fs.exists(path.join(loc, metadataFile)))) {
// If so, recurrently read scoped packages metadata
packagesMetadata.push(...await readCacheMetadata(loc));
} else {
const {registry, package: manifest, remote} = await config.readPackageMetadata(loc);
packagesMetadata.push([manifest.name, manifest.version, registry, (remote && remote.resolved) || '']);
}
}

const loc = path.join(config.cacheFolder, parentDir.replace(config.cacheFolder, ''), folder);
// Check if this is a scoped package
if (!(await fs.exists(path.join(loc, metadataFile)))) {
// If so, recurrently read scoped packages metadata
packagesMetadata.push(...await readCacheMetadata(loc));
} else {
const {registry, package: manifest, remote} = await config.readPackageMetadata(loc);
packagesMetadata.push([manifest.name, manifest.version, registry, (remote && remote.resolved) || '']);
return packagesMetadata;
}
}

return packagesMetadata;
}
const body = await readCacheMetadata();

const body = await readCacheMetadata();
reporter.table(['Name', 'Version', 'Registry', 'Resolved'], body);
},

reporter.table(['Name', 'Version', 'Registry', 'Resolved'], body);
},
dir(
config: Config,
reporter: Reporter,
) {
reporter.log(config.cacheFolder);
},

dir(
config: Config,
reporter: Reporter,
) {
reporter.log(config.cacheFolder);
},
async clean(
config: Config,
reporter: Reporter,
flags: Object,
args: Array<string>,
): Promise<void> {
if (config.cacheFolder) {
await fs.unlink(config._cacheRootFolder);
await fs.mkdirp(config.cacheFolder);
reporter.success(reporter.lang('clearedCache'));
}
},
});
}

async clean(
config: Config,
reporter: Reporter,
flags: Object,
args: Array<string>,
): Promise<void> {
if (config.cacheFolder) {
await fs.unlink(config._cacheRootFolder);
await fs.mkdirp(config.cacheFolder);
reporter.success(reporter.lang('clearedCache'));
}
},
});
hasWrapper(flags: Object, args: Array<string>): boolean {
return args[0] !== 'dir';
}
}
2 changes: 1 addition & 1 deletion src/cli/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import * as access from './access.js'; export {access};
import * as add from './add.js'; export {add};
import bin from './bin.js'; export {bin};
import * as cache from './cache.js'; export {cache};
import 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};
Expand Down

0 comments on commit c76f977

Please sign in to comment.