diff --git a/.eslintignore b/.eslintignore index f0f2a1aa..1c419d2e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ build/ test/fixtures/ +template/ diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index a425d3f7..00000000 --- a/.prettierrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - singleQuote: true, - trailingComma: 'es5', -}; diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..c0d494b2 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/package.json b/package.json index fdeed196..5c32ce13 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "CHANGELOG.md", "build/src", "build/template", - ".prettierrc.js", + ".prettierrc.json", "tsconfig-google.json", "tsconfig.json", ".eslintrc.json" diff --git a/src/clean.ts b/src/clean.ts index 37892e07..d711749f 100644 --- a/src/clean.ts +++ b/src/clean.ts @@ -16,8 +16,8 @@ import chalk = require('chalk'); import * as ts from 'typescript'; -import { Options } from './cli'; -import { getTSConfig, rimrafp } from './util'; +import {Options} from './cli'; +import {getTSConfig, rimrafp} from './util'; interface TSConfig { compilerOptions: ts.CompilerOptions; diff --git a/src/cli.ts b/src/cli.ts index f30e7980..7c5208fa 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -19,9 +19,9 @@ import * as path from 'path'; import * as meow from 'meow'; import * as updateNotifier from 'update-notifier'; -import { init } from './init'; -import { clean } from './clean'; -import { isYarnUsed } from './util'; +import {init} from './init'; +import {clean} from './clean'; +import {isYarnUsed} from './util'; import * as execa from 'execa'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -76,11 +76,11 @@ const cli = meow({ $ gts fix src/file1.ts src/file2.ts $ gts clean`, flags: { - help: { type: 'boolean' }, - yes: { type: 'boolean', alias: 'y' }, - no: { type: 'boolean', alias: 'n' }, - 'dry-run': { type: 'boolean' }, - yarn: { type: 'boolean' }, + help: {type: 'boolean'}, + yes: {type: 'boolean', alias: 'y'}, + no: {type: 'boolean', alias: 'n'}, + 'dry-run': {type: 'boolean'}, + yarn: {type: 'boolean'}, }, }); @@ -149,7 +149,7 @@ async function run(verb: string, files: string[]): Promise { } } -updateNotifier({ pkg: packageJson }).notify(); +updateNotifier({pkg: packageJson}).notify(); if (cli.input.length < 1) { usage(); diff --git a/src/init.ts b/src/init.ts index 9e41186d..a0bdc7aa 100644 --- a/src/init.ts +++ b/src/init.ts @@ -17,7 +17,7 @@ import * as cp from 'child_process'; import * as fs from 'fs'; import * as inquirer from 'inquirer'; import * as path from 'path'; -import { ncp } from 'ncp'; +import {ncp} from 'ncp'; import * as util from 'util'; import { @@ -29,8 +29,8 @@ import { DefaultPackage, } from './util'; -import { Options } from './cli'; -import { PackageJson } from '@npm/types'; +import {Options} from './cli'; +import {PackageJson} from '@npm/types'; import chalk = require('chalk'); // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -47,7 +47,7 @@ const DEFAULT_PACKAGE_JSON: PackageJson = { files: ['build/src'], license: 'Apache-2.0', keywords: [], - scripts: { test: 'echo "Error: no test specified" && exit 1' }, + scripts: {test: 'echo "Error: no test specified" && exit 1'}, }; async function query( @@ -158,7 +158,6 @@ export async function addDependencies( } function formatJson(object: {}) { - // TODO: preserve the indent from the input file. const json = JSON.stringify(object, null, ' '); return `${json}\n`; } @@ -231,7 +230,7 @@ async function generateESLintConfig(options: Options): Promise { async function generateTsConfig(options: Options): Promise { const config = formatJson({ extends: './node_modules/gts/tsconfig-google.json', - compilerOptions: { rootDir: '.', outDir: 'build' }, + compilerOptions: {rootDir: '.', outDir: 'build'}, include: ['src/**/*.ts', 'test/**/*.ts'], }); return generateConfigFile(options, './tsconfig.json', config); @@ -239,10 +238,10 @@ async function generateTsConfig(options: Options): Promise { async function generatePrettierConfig(options: Options): Promise { const style = await read( - path.join(__dirname, '../../.prettierrc.js'), + path.join(__dirname, '../../.prettierrc.json'), 'utf8' ); - return generateConfigFile(options, './.prettierrc.js', style); + return generateConfigFile(options, './.prettierrc.json', style); } export async function installDefaultTemplate( @@ -321,7 +320,7 @@ export async function init(options: Options): Promise { cp.spawnSync( getPkgManagerCommand(options.yarn), ['install', '--ignore-scripts'], - { stdio: 'inherit' } + {stdio: 'inherit'} ); } diff --git a/src/util.ts b/src/util.ts index f04719c8..f66a0995 100644 --- a/src/util.ts +++ b/src/util.ts @@ -17,7 +17,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as rimraf from 'rimraf'; -import { promisify } from 'util'; +import {promisify} from 'util'; import * as ncp from 'ncp'; import * as writeFileAtomic from 'write-file-atomic'; @@ -37,7 +37,7 @@ export interface DefaultPackage extends Bag { } export async function readJsonp(jsonPath: string) { - const contents = await readFilep(jsonPath, { encoding: 'utf8' }); + const contents = await readFilep(jsonPath, {encoding: 'utf8'}); return JSON.parse(contents); } @@ -101,7 +101,7 @@ async function getBase( * @param inherited is then loaded and overwrites base */ function combineTSConfig(base: ConfigFile, inherited: ConfigFile): ConfigFile { - const result: ConfigFile = { compilerOptions: {} }; + const result: ConfigFile = {compilerOptions: {}}; Object.assign(result, base, inherited); Object.assign( diff --git a/test/kitchen.ts b/test/kitchen.ts index e0f3c34b..ce35bae7 100644 --- a/test/kitchen.ts +++ b/test/kitchen.ts @@ -2,16 +2,16 @@ import chalk = require('chalk'); import * as cp from 'child_process'; import * as fs from 'fs-extra'; import * as tmp from 'tmp'; -import { assert } from 'chai'; +import {assert} from 'chai'; import * as path from 'path'; -import { describe, it, before, after } from 'mocha'; +import {describe, it, before, after} from 'mocha'; import spawn = require('cross-spawn'); import execa = require('execa'); // eslint-disable-next-line @typescript-eslint/no-var-requires const pkg = require('../../package.json'); const keep = !!process.env.GTS_KEEP_TEMPDIRS; -const stagingDir = tmp.dirSync({ keep, unsafeCleanup: true }); +const stagingDir = tmp.dirSync({keep, unsafeCleanup: true}); const stagingPath = stagingDir.name; const execOpts = { cwd: `${stagingPath}${path.sep}kitchen`, @@ -60,7 +60,7 @@ describe('🚰 kitchen sink', () => { // Ensure config files got generated. fs.accessSync(path.join(kitchenPath, 'tsconfig.json')); fs.accessSync(path.join(kitchenPath, '.eslintrc.json')); - fs.accessSync(path.join(kitchenPath, '.prettierrc.js')); + fs.accessSync(path.join(kitchenPath, '.prettierrc.json')); // Compilation shouldn't have happened. Hence no `build` directory. const dirContents = fs.readdirSync(kitchenPath); @@ -71,8 +71,8 @@ describe('🚰 kitchen sink', () => { // Use from a directory different from where we have locally installed. This // simulates use as a globally installed module. const GTS = path.resolve(stagingPath, 'kitchen/node_modules/.bin/gts'); - const tmpDir = tmp.dirSync({ keep, unsafeCleanup: true }); - const opts = { cwd: path.join(tmpDir.name, 'kitchen') }; + const tmpDir = tmp.dirSync({keep, unsafeCleanup: true}); + const opts = {cwd: path.join(tmpDir.name, 'kitchen')}; // Copy test files. fs.copySync(fixturesPath, tmpDir.name); @@ -128,7 +128,7 @@ describe('🚰 kitchen sink', () => { const res = await execa( 'npm', ['run', 'check'], - Object.assign({}, { reject: false }, execOpts) + Object.assign({}, {reject: false}, execOpts) ); assert.strictEqual(res.exitCode, 1); assert.include(res.stdout, 'assigned a value but'); diff --git a/test/test-clean.ts b/test/test-clean.ts index 9b8f0b09..3910be85 100644 --- a/test/test-clean.ts +++ b/test/test-clean.ts @@ -18,11 +18,11 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; -import { clean } from '../src/clean'; -import { nop } from '../src/util'; +import {clean} from '../src/clean'; +import {nop} from '../src/util'; -import { withFixtures } from 'inline-fixtures'; -import { describe, it } from 'mocha'; +import {withFixtures} from 'inline-fixtures'; +import {describe, it} from 'mocha'; describe('clean', () => { const OPTIONS = { @@ -31,7 +31,7 @@ describe('clean', () => { dryRun: false, yes: false, no: false, - logger: { log: nop, error: nop, dir: nop }, + logger: {log: nop, error: nop, dir: nop}, }; it('should gracefully error if tsconfig is missing', () => { @@ -44,7 +44,7 @@ describe('clean', () => { }); it('should gracefully error if tsconfig does not have valid outDir', () => { - return withFixtures({ 'tsconfig.json': JSON.stringify({}) }, async () => { + return withFixtures({'tsconfig.json': JSON.stringify({})}, async () => { const deleted = await clean(OPTIONS); assert.strictEqual(deleted, false); }); @@ -52,7 +52,7 @@ describe('clean', () => { it('should avoid deleting .', () => { return withFixtures( - { 'tsconfig.json': JSON.stringify({ compilerOptions: { outDir: '.' } }) }, + {'tsconfig.json': JSON.stringify({compilerOptions: {outDir: '.'}})}, async () => { const deleted = await clean(OPTIONS); assert.strictEqual(deleted, false); @@ -66,7 +66,7 @@ describe('clean', () => { withFixtures( { 'tsconfig.json': JSON.stringify({ - compilerOptions: { outDir: '../out' }, + compilerOptions: {outDir: '../out'}, }), }, async () => { @@ -81,7 +81,7 @@ describe('clean', () => { const OUT = 'outputDirectory'; return withFixtures( { - 'tsconfig.json': JSON.stringify({ compilerOptions: { outDir: OUT } }), + 'tsconfig.json': JSON.stringify({compilerOptions: {outDir: OUT}}), [OUT]: {}, }, async dir => { diff --git a/test/test-init.ts b/test/test-init.ts index 35f63295..b3b03a43 100644 --- a/test/test-init.ts +++ b/test/test-init.ts @@ -19,13 +19,13 @@ import * as cp from 'child_process'; import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; -import { accessSync } from 'fs'; -import { PackageJson } from '@npm/types'; -import { withFixtures, Fixtures } from 'inline-fixtures'; -import { describe, it, beforeEach, afterEach } from 'mocha'; +import {accessSync} from 'fs'; +import {PackageJson} from '@npm/types'; +import {withFixtures, Fixtures} from 'inline-fixtures'; +import {describe, it, beforeEach, afterEach} from 'mocha'; -import { nop, readJsonp as readJson, DefaultPackage } from '../src/util'; -import { Options } from '../src/cli'; +import {nop, readJsonp as readJson, DefaultPackage} from '../src/util'; +import {Options} from '../src/cli'; import * as init from '../src/init'; const OPTIONS: Options = { @@ -34,12 +34,12 @@ const OPTIONS: Options = { dryRun: false, yes: false, no: false, - logger: { log: nop, error: nop, dir: nop }, + logger: {log: nop, error: nop, dir: nop}, }; -const OPTIONS_YES = Object.assign({}, OPTIONS, { yes: true }); -const OPTIONS_NO = Object.assign({}, OPTIONS, { no: true }); -const OPTIONS_YARN = Object.assign({}, OPTIONS_YES, { yarn: true }); -const MINIMAL_PACKAGE_JSON = { name: 'name', version: 'v1.1.1' }; +const OPTIONS_YES = Object.assign({}, OPTIONS, {yes: true}); +const OPTIONS_NO = Object.assign({}, OPTIONS, {no: true}); +const OPTIONS_YARN = Object.assign({}, OPTIONS_YES, {yarn: true}); +const MINIMAL_PACKAGE_JSON = {name: 'name', version: 'v1.1.1'}; function hasExpectedScripts(packageJson: PackageJson): boolean { return ( @@ -75,7 +75,7 @@ describe('init', () => { }); it('addScripts should add a scripts section if none exists', async () => { - const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON }; + const pkg: PackageJson = {...MINIMAL_PACKAGE_JSON}; const result = await init.addScripts(pkg, OPTIONS); assert.strictEqual(result, true); // made edits. assert.ok(pkg.scripts); @@ -94,7 +94,7 @@ describe('init', () => { }; const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON, - scripts: { ...SCRIPTS }, + scripts: {...SCRIPTS}, }; const result = await init.addScripts(pkg, OPTIONS_NO); assert.strictEqual(result, false); // no edits. @@ -113,7 +113,7 @@ describe('init', () => { }; const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON, - scripts: { ...SCRIPTS }, + scripts: {...SCRIPTS}, }; const result = await init.addScripts(pkg, OPTIONS_YES); assert.strictEqual(result, true); // made edits. @@ -121,7 +121,7 @@ describe('init', () => { }); it('addDependencies should add a deps section if none exists', async () => { - const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON }; + const pkg: PackageJson = {...MINIMAL_PACKAGE_JSON}; const result = await init.addDependencies(pkg, OPTIONS); assert.strictEqual(result, true); // made edits. assert.ok(pkg.devDependencies); @@ -135,32 +135,30 @@ describe('init', () => { }; const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON, - devDependencies: { ...DEPS }, + devDependencies: {...DEPS}, }; - const OPTIONS_NO = Object.assign({}, OPTIONS, { no: true }); + const OPTIONS_NO = Object.assign({}, OPTIONS, {no: true}); const result = await init.addDependencies(pkg, OPTIONS_NO); assert.strictEqual(result, false); // no edits. assert.deepStrictEqual(pkg.devDependencies, DEPS); }); it('addDependencies should edit existing deps on yes', async () => { - const DEPS = { gts: 'something', typescript: 'or the other' }; + const DEPS = {gts: 'something', typescript: 'or the other'}; const pkg: PackageJson = { ...MINIMAL_PACKAGE_JSON, - devDependencies: { ...DEPS }, + devDependencies: {...DEPS}, }; const result = await init.addDependencies(pkg, OPTIONS_YES); assert.strictEqual(result, true); // made edits. assert.notDeepStrictEqual(pkg.devDependencies, DEPS); }); - // TODO: test generateConfigFile - // init it('init should read local package.json', () => { - const originalContents = { some: 'property' }; + const originalContents = {some: 'property'}; return withFixtures( - { 'package.json': JSON.stringify(originalContents) }, + {'package.json': JSON.stringify(originalContents)}, async () => { const result = await init.init(OPTIONS_YES); assert.strictEqual(result, true); @@ -193,7 +191,7 @@ describe('init', () => { it('init should support yarn', () => { return withFixtures( { - 'package.json': JSON.stringify({ name: 'test' }), + 'package.json': JSON.stringify({name: 'test'}), 'yarn.lock': '', }, async () => { @@ -269,23 +267,6 @@ describe('init', () => { }); }); - // FIXME: It seems that on CirrusCI we are able to access inside - // directories where permissions may otherwise forbid access. Enable - // once this has been opened as an issue against Cirrus and fixed. - // it('should not install the default template if the source directory is not accessible', () => { - // const FIXTURES: Fixtures = { - // src: { - // mode: 0o000, - // content: { - // 'README.md': 'Hello World.', - // }, - // }, - // }; - // return withFixtures(FIXTURES, async dir => { - // await assertRejects(init.installDefaultTemplate(OPTIONS_YES)); - // }); - // }); - it('should not install the default template if the source directory already exists and does contain ts files', () => { const EXISTING = 'src'; const FIXTURES: Fixtures = { diff --git a/test/test-util.ts b/test/test-util.ts index b4998c9b..8b735aea 100644 --- a/test/test-util.ts +++ b/test/test-util.ts @@ -15,8 +15,8 @@ */ import * as assert from 'assert'; import * as path from 'path'; -import { PathLike } from 'fs'; -import { describe, it } from 'mocha'; +import {PathLike} from 'fs'; +import {describe, it} from 'mocha'; import { ConfigFile, getTSConfig, @@ -54,7 +54,7 @@ const PATH_TO_CONFIG3 = path.resolve(FAKE_DIRECTORY, 'FAKE_CONFIG3'); describe('util', () => { it('get should parse the correct tsconfig file', async () => { - const FAKE_CONFIG1 = { files: ['b'] }; + const FAKE_CONFIG1 = {files: ['b']}; function fakeReadFilep( configPath: string, @@ -70,9 +70,9 @@ describe('util', () => { }); it('should throw an error if it finds a circular reference', () => { - const FAKE_CONFIG1 = { files: ['b'], extends: 'FAKE_CONFIG2' }; - const FAKE_CONFIG2 = { extends: 'FAKE_CONFIG3' }; - const FAKE_CONFIG3 = { extends: 'tsconfig.json' }; + const FAKE_CONFIG1 = {files: ['b'], extends: 'FAKE_CONFIG2'}; + const FAKE_CONFIG2 = {extends: 'FAKE_CONFIG3'}; + const FAKE_CONFIG3 = {extends: 'tsconfig.json'}; const myMap = new Map(); myMap.set(PATH_TO_TSCONFIG, FAKE_CONFIG1); myMap.set(PATH_TO_CONFIG2, FAKE_CONFIG2); @@ -88,14 +88,14 @@ describe('util', () => { it('should follow dependency chain caused by extends files', async () => { const FAKE_CONFIG1 = { - compilerOptions: { a: 'n' }, + compilerOptions: {a: 'n'}, files: ['b'], extends: 'FAKE_CONFIG2', }; - const FAKE_CONFIG2 = { include: ['/stuff/*'], extends: 'FAKE_CONFIG3' }; - const FAKE_CONFIG3 = { exclude: ['doesnt/look/like/anything/to/me'] }; + const FAKE_CONFIG2 = {include: ['/stuff/*'], extends: 'FAKE_CONFIG3'}; + const FAKE_CONFIG3 = {exclude: ['doesnt/look/like/anything/to/me']}; const combinedConfig = { - compilerOptions: { a: 'n' }, + compilerOptions: {a: 'n'}, files: ['b'], include: ['/stuff/*'], exclude: ['doesnt/look/like/anything/to/me'], @@ -114,10 +114,10 @@ describe('util', () => { }); it('when a file contains an extends field, the base file is loaded first then overridden by the inherited files', async () => { - const FAKE_CONFIG1 = { files: ['b'], extends: 'FAKE_CONFIG2' }; - const FAKE_CONFIG2 = { files: ['c'], extends: 'FAKE_CONFIG3' }; - const FAKE_CONFIG3 = { files: ['d'] }; - const combinedConfig = { compilerOptions: {}, files: ['b'] }; + const FAKE_CONFIG1 = {files: ['b'], extends: 'FAKE_CONFIG2'}; + const FAKE_CONFIG2 = {files: ['c'], extends: 'FAKE_CONFIG3'}; + const FAKE_CONFIG3 = {files: ['d']}; + const combinedConfig = {compilerOptions: {}, files: ['b']}; const myMap = new Map(); myMap.set(PATH_TO_TSCONFIG, FAKE_CONFIG1); myMap.set(PATH_TO_CONFIG2, FAKE_CONFIG2); @@ -131,9 +131,9 @@ describe('util', () => { }); it('when reading a file, all filepaths should be relative to the config file currently being read', async () => { - const FAKE_CONFIG1 = { files: ['b'], extends: './foo/FAKE_CONFIG2' }; - const FAKE_CONFIG2 = { include: ['c'], extends: './bar/FAKE_CONFIG3' }; - const FAKE_CONFIG3 = { exclude: ['d'] }; + const FAKE_CONFIG1 = {files: ['b'], extends: './foo/FAKE_CONFIG2'}; + const FAKE_CONFIG2 = {include: ['c'], extends: './bar/FAKE_CONFIG3'}; + const FAKE_CONFIG3 = {exclude: ['d']}; const combinedConfig = { compilerOptions: {}, exclude: ['d'],