Skip to content

Commit

Permalink
Standardizing output from generators (#331)
Browse files Browse the repository at this point in the history
  • Loading branch information
scalvert authored Apr 28, 2020
1 parent 9e107f8 commit 67c01a7
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 121 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
},
"npm": false
},
"resolutions": {
"type-fest": "^0.13.1"
},
"volta": {
"node": "12.16.2",
"yarn": "1.22.4"
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,9 @@ Checkup uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to find

The search stops when one of these is found, and Checkup uses that object.

The .checkuprc file (without extension) can be in JSON or YAML format. You can add a filename extension to help your text editor provide syntax checking and highlighting:
The .checkuprc file (without extension) can be in JSON or JavaScript format. You can add a filename extension to help your text editor provide syntax checking and highlighting:

- .checkup.json
- .checkup.yaml / .checkup.yml
- .checkup.js

You can also specify an explicit path to a configuration via the command line, which will override any configurations found in any `.checkuprc.*` files
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@checkup/core": "0.0.10",
"@oclif/command": "^1",
"@oclif/config": "^1",
"@oclif/errors": "^1.2.2",
"@oclif/plugin-help": "^3",
"chalk": "^4.0.0",
"checkup-plugin-ember": "0.0.10",
Expand Down
36 changes: 23 additions & 13 deletions packages/cli/src/commands/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import * as chalk from 'chalk';
import * as debug from 'debug';

import { basename, join } from 'path';
import { existsSync, readdirSync } from 'fs';

import Command from '@oclif/command';
import { IConfig } from '@oclif/config';
import { createEnv } from 'yeoman-environment';
import { flags } from '@oclif/command';
import { readdirSync } from 'fs';
import { rmdirSync } from 'fs';

export interface Options {
Expand All @@ -20,6 +20,7 @@ export interface Options {

export default class GenerateCommand extends Command {
private _generators!: string[];
private baseDir: string;

static description = 'Runs a generator to scaffold Checkup code';

Expand Down Expand Up @@ -49,6 +50,7 @@ export default class GenerateCommand extends Command {
constructor(argv: string[], config: IConfig) {
super(argv, config);

this.baseDir = process.cwd();
this.debug = debug('checkup:generator');
}

Expand Down Expand Up @@ -90,18 +92,26 @@ export default class GenerateCommand extends Command {

env.register(require.resolve(`../generators/${type}`), `checkup:${type}`);

await new Promise((resolve, reject) => {
env.run(`checkup:${type}`, generatorOptions, (err: Error | null) => {
if (err) {
reject(err);
} else {
// this is ugly, but I couldn't find the correct configuration to ignore
// generating the yeoman repository directory in the cwd
rmdirSync(join(process.cwd(), '.yo-repository'));

resolve();
}
try {
await new Promise((resolve, reject) => {
env.run(`checkup:${type}`, generatorOptions, (err: Error | null) => {
if (err) {
reject(err);
} else {
// this is ugly, but I couldn't find the correct configuration to ignore
// generating the yeoman repository directory in the cwd
let yoRepoPath = join(this.baseDir, '.yo-repository');

if (existsSync(yoRepoPath)) {
rmdirSync(yoRepoPath);
}

resolve();
}
});
});
});
} catch (error) {
this.error(error);
}
}
}
10 changes: 10 additions & 0 deletions packages/cli/src/generators/base-generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as Generator from 'yeoman-generator';
import * as chalk from 'chalk';

import { getVersion } from '../helpers/get-version';

export default class GeneratorBase extends Generator {
headline(name: string) {
this.log(`Generating ${chalk.bold.white(name)} ${chalk.dim(`(checkup v${getVersion()})`)}`);
}
}
10 changes: 7 additions & 3 deletions packages/cli/src/generators/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Generator from 'yeoman-generator';
import * as chalk from 'chalk';

import {
CheckupConfigFormat,
Expand All @@ -8,8 +8,9 @@ import {
} from '@checkup/core';

import { Answers } from 'inquirer';
import BaseGenerator from './base-generator';

export default class ConfigGenerator extends Generator {
export default class ConfigGenerator extends BaseGenerator {
private answers!: Answers;
private configService!: CheckupConfigService;

Expand All @@ -24,6 +25,8 @@ export default class ConfigGenerator extends Generator {
}

async prompting() {
this.headline('checkup config');

this.answers = await this.prompt([
{
name: 'format',
Expand All @@ -41,6 +44,7 @@ export default class ConfigGenerator extends Generator {
}

async writing() {
this.configService.write();
let configPath = this.configService.write();
this.log(` ${chalk.green('create')} ${configPath}`);
}
}
24 changes: 7 additions & 17 deletions packages/cli/src/generators/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import * as Generator from 'yeoman-generator';
import * as chalk from 'chalk';
import * as path from 'path';

import { getVersion } from '../helpers/get-version';
import { Answers } from 'inquirer';
import BaseGenerator from './base-generator';

const PLUGIN_DIR_PATTERN = /checkup-plugin-.*/;

export default class PluginGenerator extends Generator {
answers!: {
typescript: boolean;
description: string;
author: string;
repository: string;
};
export default class PluginGenerator extends BaseGenerator {
answers!: Answers;

private get _ext() {
return this.options.typescript ? 'ts' : 'js';
Expand All @@ -29,11 +23,9 @@ export default class PluginGenerator extends Generator {
}

async prompting() {
this.log(
`Adding ${chalk.bold.white(this.options.name)} plugin. Version: ${chalk.bold.white(
getVersion()
)}`
);
this._normalizeName();

this.headline(this.options.name);

const defaults = {
typescript: true,
Expand Down Expand Up @@ -73,8 +65,6 @@ export default class PluginGenerator extends Generator {
]);
}

this._normalizeName();

this.options.typescript = this.answers.typescript;
this.options.description = this.answers.description;
this.options.author = this.answers.author;
Expand Down
23 changes: 7 additions & 16 deletions packages/cli/src/generators/task.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as Generator from 'yeoman-generator';
import * as Errors from '@oclif/errors';
import * as _ from 'lodash';
import * as chalk from 'chalk';
import * as path from 'path';
import * as t from '@babel/types';

import { Category, Priority } from '@checkup/core';

import { Answers } from 'inquirer';
import AstTransformer from '../helpers/ast';
import BaseGenerator from './base-generator';
import { Options } from '../commands/generate';
import { PackageJson } from 'type-fest';
import { getVersion } from '../helpers/get-version';

interface TaskOptions extends Options {
taskResultClass: string;
Expand All @@ -20,14 +20,9 @@ interface TaskOptions extends Options {
priority: string;
}

export default class TaskGenerator extends Generator {
export default class TaskGenerator extends BaseGenerator {
packageJson!: PackageJson;

answers!: {
typescript: boolean;
category: string;
priority: string;
};
answers!: Answers;

private get _ts() {
let devDeps = this.packageJson.devDependencies;
Expand All @@ -49,14 +44,10 @@ export default class TaskGenerator extends Generator {
!this.packageJson ||
!(this.packageJson.keywords && this.packageJson.keywords.includes('oclif-plugin'))
) {
throw new Error('not in a plugin directory');
Errors.error('You must be in a Checkup plugin directory in order to run the task generator');
}

this.log(
`Adding a ${chalk.bold.white(this.options.name)} task to ${chalk.bold.white(
this.packageJson.name
)}. Version: ${chalk.bold.white(getVersion())}`
);
this.headline(`${this.options.name}-task`);

const defaults = {
typescript: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,3 @@ exports[`checkup-config-service should write the config on calling write for Jav
\\"tasks\\": {}
}"
`;
exports[`checkup-config-service should write the config on calling write for YAML files 1`] = `
"plugins: []
tasks: {}
"
`;
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as path from 'path';

import { CheckupConfig, CheckupConfigFormat } from '../../src';

import { CheckupProject } from '@checkup/test-helpers';
import * as path from 'path';
import * as yaml from 'js-yaml';
import CosmiconfigService from '../../src/configuration/cosmiconfig-service';

describe('cosmiconfig-service-factory', () => {
const formatToWriteMapper: Record<CheckupConfigFormat, (config: CheckupConfig) => string> = {
JSON: (config) => JSON.stringify(config, null, 2),
YAML: (config) => yaml.safeDump(config),
JavaScript: (config) => `module.exports = ${JSON.stringify(config, null, 2)}`,
};
const defaultConfig = {
Expand Down Expand Up @@ -42,7 +42,7 @@ describe('cosmiconfig-service-factory', () => {
expect(result).toBeNull();
});

it.each([[CheckupConfigFormat.JSON], [CheckupConfigFormat.YAML]])(
it.each([[CheckupConfigFormat.JSON], [CheckupConfigFormat.JavaScript]])(
'should correctly search extensionless %s config files',
async (configFormat: CheckupConfigFormat) => {
project.files['.checkuprc'] = formatToWriteMapper[configFormat](defaultConfig);
Expand All @@ -58,8 +58,6 @@ describe('cosmiconfig-service-factory', () => {
it.each([
['.checkuprc.js', CheckupConfigFormat.JavaScript],
['.checkuprc.json', CheckupConfigFormat.JSON],
['.checkuprc.yml', CheckupConfigFormat.YAML],
['.checkuprc.yaml', CheckupConfigFormat.YAML],
['checkup.config.js', CheckupConfigFormat.JavaScript],
])(
'should correctly search config files of type %s',
Expand All @@ -74,7 +72,7 @@ describe('cosmiconfig-service-factory', () => {
}
);

it.each([[CheckupConfigFormat.JSON], [CheckupConfigFormat.YAML]])(
it.each([[CheckupConfigFormat.JSON], [CheckupConfigFormat.JavaScript]])(
'should correctly load extensionless %s config files',
async (configFormat: CheckupConfigFormat) => {
project.files['.checkuprc'] = formatToWriteMapper[configFormat](defaultConfig);
Expand All @@ -92,8 +90,6 @@ describe('cosmiconfig-service-factory', () => {
it.each([
['.checkuprc.js', CheckupConfigFormat.JavaScript],
['.checkuprc.json', CheckupConfigFormat.JSON],
['.checkuprc.yml', CheckupConfigFormat.YAML],
['.checkuprc.yaml', CheckupConfigFormat.YAML],
['checkup.config.js', CheckupConfigFormat.JavaScript],
])(
'should correctly load config files of type %s',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CheckupConfigFormat } from '../../src';
import * as path from 'path';

import { CheckupConfigFormat } from '../../src';
import getInitializationConfigLoader from '../../src/configuration/loaders/get-initialization-loader';

describe('get-initialization-loader', () => {
Expand All @@ -23,12 +24,4 @@ describe('get-initialization-loader', () => {
expect(loaderValue.filepath).toEqual(path.join('.', '.checkuprc'));
expect(loaderValue.config).toStrictEqual(defaultConfig);
});

it('yaml config loader returns correct value', async () => {
const loaderValue = await getInitializationConfigLoader('.', CheckupConfigFormat.YAML)();

expect(loaderValue.format).toEqual(CheckupConfigFormat.YAML);
expect(loaderValue.filepath).toEqual(path.join('.', '.checkuprc'));
expect(loaderValue.config).toStrictEqual(defaultConfig);
});
});
2 changes: 0 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
"fp-ts": "^2.5.4",
"globby": "^11.0.0",
"io-ts": "^2.2.1",
"js-yaml": "^3.13.1",
"resolve": "^1.17.0"
},
"devDependencies": {
"@types/chalk": "^2.2.0",
"@types/eslint": "^6.8.0",
"@types/js-yaml": "^3.12.3",
"@types/resolve": "^1.14.0",
"eslint-plugin-jest": "^23.8.2"
},
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/configuration/checkup-config-service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as debug from 'debug';
import * as fs from 'fs';
import * as yaml from 'js-yaml';

import { CheckupConfig, CheckupConfigFormat, CheckupConfigLoader } from '../types/configuration';

import { RuntimeCheckupConfig } from '../types/runtime-types';
import { basename } from 'path';
import { fold } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';

Expand All @@ -18,7 +18,6 @@ export default class CheckupConfigService {
(config: CheckupConfig) => string
> = {
JSON: (config) => JSON.stringify(config, null, 2),
YAML: (config) => yaml.safeDump(config),
JavaScript: (config) => `module.exports = ${JSON.stringify(config, null, 2)}`,
};
private readonly configPath: string;
Expand Down Expand Up @@ -46,6 +45,8 @@ export default class CheckupConfigService {
write() {
const configToWrite = CheckupConfigService.formatToWriteMapper[this.format](this.get());
fs.writeFileSync(this.configPath, configToWrite);

return basename(this.configPath);
}

/**
Expand Down
Loading

0 comments on commit 67c01a7

Please sign in to comment.