Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

Commit

Permalink
Merge pull request #11 from Alorel/dev-yarn-proj
Browse files Browse the repository at this point in the history
Dev yarn proj
  • Loading branch information
Alorel committed Sep 12, 2018
2 parents 68ec844 + dc95d37 commit 8a541d9
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 66 deletions.
15 changes: 8 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/.idea/
/node_modules/
/dist/
/coverage/
/.nyc_output/
/.tmp/
/package-lock.json
/yarn-error.log
/*.tgz
/git_gpg_keys.asc
/tmp.ts
/tmp.js
.idea/
node_modules/
dist/
coverage/
.nyc_output/
yarn-error.log
*.tgz
git_gpg_keys.asc
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"json5": "^2.0.0",
"lodash": "^4.17.0",
"readline-sync": "^1.4.9",
"tslib": "^1.9.3",
"typescript-lazy-get-decorator": "^1.2.1",
"yamljs": "^0.3.0",
"yargs": "^12.0.0"
Expand Down Expand Up @@ -78,7 +79,6 @@
"source-map-support": "~0.5.9",
"tmp": "~0.0.33",
"ts-node": "~7.0.1",
"tslib": "~1.9.3",
"tslint": "~5.11.0",
"typescript": "~3.0.1",
"uuid": "~3.3.2"
Expand Down
51 changes: 14 additions & 37 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
import {values} from 'lodash';
import {Argv, CommandModule} from 'yargs';
import {addEmail, addName, addUserWebsite, HasEmail, HasName, HasUserWebsite} from '../commons/identity';
import {addEmail, addName, addUserWebsite} from '../commons/identity';
import {addConfig} from '../fns/addConfig';
import {cmdName} from '../fns/cmdName';
import {LicenseTpl} from '../interfaces/LicenseTpl';
import {Fixture} from '../lib/Fixture';
import {License, LICENSE_VALUES} from '../inc/License';
import {InitConf} from '../interfaces/InitConf';
import {initGitignore} from '../lib/init/initGitignore';
import {initLicense} from '../lib/init/initLicense';
import {PromptableConfig} from '../lib/PromptableConfig';

enum License {
MIT = 'MIT'
}

function isLicense(v: any): v is License {
return v === License.MIT;
}

interface Conf extends HasName, HasUserWebsite, HasEmail {
license: License;

skipLicense: boolean;
}

const command = cmdName(__filename);

const cmd: CommandModule = {
builder(argv: Argv) {
addConfig(argv, 'init');
addEmail(argv);
argv.option('license', {
choices: values(License),
choices: LICENSE_VALUES,
default: License.MIT,
describe: 'License to use',
string: true
});
addName(argv);

argv.option('skip-gitignore', {
boolean: true,
default: false,
describe: 'Don\'t generate gitignore'
});
argv.option('skip-license', {
boolean: true,
default: false,
Expand All @@ -47,25 +39,10 @@ const cmd: CommandModule = {
},
command,
describe: 'Project initialisation operations',
handler(conf: Conf) {
if (!isLicense(conf.license)) {
throw new Error('Invalid license');
}
handler(conf: InitConf) {
const c = new PromptableConfig(conf);

if (!conf.skipLicense) {
new Fixture('init/license')
.template<LicenseTpl>(
`${c.getPromptSelect('license', 'What license do you want to use? ', values(License))}.txt`,
{
email: c.getPromptEmail('email', 'What\'s your email? '),
name: c.getPrompt('name', 'What\'s your name? '),
url: c.getPrompt('userWebsite', 'What\'s your url? '),
year: new Date().getFullYear()
},
'LICENSE'
);
}
initLicense(c);
initGitignore(c);
}
};

Expand Down
11 changes: 11 additions & 0 deletions src/inc/License.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {values} from 'lodash';

export enum License {
MIT = 'MIT'
}

export function isLicense(v: any): v is License {
return v === License.MIT;
}

export const LICENSE_VALUES: string[] = <string[]>Object.freeze(values(License));
10 changes: 10 additions & 0 deletions src/interfaces/InitConf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {HasEmail, HasName, HasUserWebsite} from '../commons/identity';
import {License} from '../inc/License';

export interface InitConf extends HasName, HasUserWebsite, HasEmail {
license: License;

skipGitignore: boolean;

skipLicense: boolean;
}
54 changes: 54 additions & 0 deletions src/lib/LineReadWriter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as fs from 'fs';

function trim(s: string): string {
return s.trim();
}

export class LineReadWriter {
private readonly lines: string[];

private constructor(contents?: string, private readonly file?: string) {
this.lines = contents && (contents = contents.trim()) ? contents.split(/\n/g).map(trim) : [];
}

public static createFromContents(contents: string): LineReadWriter {
return new LineReadWriter(contents);
}

public static createFromFile(filepath: string): LineReadWriter {
try {
return new LineReadWriter(fs.readFileSync(filepath, 'utf8'), filepath);
} catch {
return new LineReadWriter(undefined, filepath);
}
}

public ensure(...lines: string[]): this {
const toAdd = new Set<string>();
for (const line of lines) {
if (!this.lines.includes(line)) {
toAdd.add(line);
}
}

if (toAdd.size) {
this.lines.push(...toAdd);
}

return this;
}

public save(): this {
if (!this.file) {
throw new Error('File not provided');
}

fs.writeFileSync(this.file, this.toString());

return this;
}

public toString(): string {
return this.lines.join('\n') + '\n';
}
}
20 changes: 20 additions & 0 deletions src/lib/init/initGitignore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {InitConf} from '../../interfaces/InitConf';
import {LineReadWriter} from '../LineReadWriter';
import {PromptableConfig} from '../PromptableConfig';

export function initGitignore(c: PromptableConfig<InitConf>): void {
if (!c.get('skipGitignore')) {
LineReadWriter.createFromFile('.gitignore')
.ensure(
'.idea/',
'node_modules/',
'dist/',
'coverage/',
'.nyc_output/',
'yarn-error.log',
'*.tgz',
'git_gpg_keys.asc'
)
.save();
}
}
25 changes: 25 additions & 0 deletions src/lib/init/initLicense.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {isLicense, LICENSE_VALUES} from '../../inc/License';
import {InitConf} from '../../interfaces/InitConf';
import {LicenseTpl} from '../../interfaces/LicenseTpl';
import {Fixture} from '../Fixture';
import {PromptableConfig} from '../PromptableConfig';

export function initLicense(c: PromptableConfig<InitConf>): void {
if (!c.get('skipLicense')) {
if (!isLicense(c.get('license'))) {
throw new Error('Invalid license');
}

new Fixture('init/license')
.template<LicenseTpl>(
`${c.getPromptSelect('license', 'What license do you want to use? ', LICENSE_VALUES)}.txt`,
{
email: c.getPromptEmail('email', 'What\'s your email? '),
name: c.getPrompt('name', 'What\'s your name? '),
url: c.getPrompt('userWebsite', 'What\'s your url? '),
year: new Date().getFullYear()
},
'LICENSE'
);
}
}
76 changes: 57 additions & 19 deletions test/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,67 @@ import {alo} from '../../src/alo';
import {tmpDir} from '../util/tmp-test';

describe('init', () => {
describe('license', () => {
let origCwd: string;
let tmpdir: string;
const baseArgs = [
'init',
'--name',
'foo',
'--email',
'foo@bar.com',
'--user-website',
'https://foo.com'
];

before('snapshot cwd', () => {
origCwd = process.cwd();
let origCwd: string;
let tmpdir: string;
const baseArgs = [
'init',
'--name',
'foo',
'--email',
'foo@bar.com',
'--user-website',
'https://foo.com'
];

before('snapshot cwd', () => {
origCwd = process.cwd();
});

after('restore cwd', () => {
if (origCwd) {
process.chdir(origCwd);
}
});

describe('gitignore', () => {
describe('Don\'t skip', () => {
before('change cwd', () => {
tmpdir = tmpDir();
process.chdir(tmpdir);
});

before('run', () => alo(baseArgs));

it('', async () => {
expect(await fs.readFile(join(tmpdir, '.gitignore'), 'utf8'))
.to.eq([
'.idea/',
'node_modules/',
'dist/',
'coverage/',
'.nyc_output/',
'yarn-error.log',
'*.tgz',
'git_gpg_keys.asc'
].join('\n') + '\n');
});
});

after('restore cwd', () => {
if (origCwd) {
process.chdir(origCwd);
}
describe('skip', () => {
before('change cwd', () => {
tmpdir = tmpDir();
process.chdir(tmpdir);
});

before('run', () => alo(baseArgs.concat('--skip-gitignore')));

it('', async () => {
expect(await fs.pathExists(join(tmpdir, '.gitignore'))).to.be.false;
});
});
});

describe('license', () => {
describe('Don\'t skip', () => {
let expected: string;

Expand Down
58 changes: 58 additions & 0 deletions test/general/LineReadWriter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {expect} from 'chai';
import * as fs from 'fs-extra';
import {LineReadWriter} from '../../src/lib/LineReadWriter';
import {tmpFile} from '../util/tmp-test';

describe('LineReadWriter', () => {
let contents: string;
let lines: string[];

before('init contents', async () => {
contents = (await fs.readFile(__filename, 'utf8')).trim()
.split(/\n/g)
.map(l => l.trim())
.join('\n');
});

before('init lines', () => {
lines = contents.split(/\n/g).map(l => l.trim());
});

it('from contents', () => {
expect(LineReadWriter.createFromContents(contents)['lines'])
.to.deep.eq(lines);
});

it('from file', () => {
expect(LineReadWriter.createFromFile(__filename)['lines'])
.to.deep.eq(lines);
});

it('toString()', () => {
expect(LineReadWriter.createFromContents(contents).toString())
.to.eq(`${contents}\n`);
});

it('ensure', () => {
const lrw = LineReadWriter.createFromContents('')
.ensure('foo', 'foo', 'bar');

expect(lrw['lines']).to.deep.eq(['foo', 'bar']);
});

describe('save', () => {
let p: string;

before('write', async () => {
p = tmpFile();
await fs.writeFile(p, 'qux\nbaz\n');
LineReadWriter.createFromFile(p)
.ensure('foo')
.save();
});

it('', async () => {
expect(await fs.readFile(p, 'utf8')).to.eq('qux\nbaz\nfoo\n');
});
});
});
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"target": "es2016",
"experimentalDecorators": true,
"emitDecoratorMetadata": false,
"noUnusedLocals": true,
Expand Down
Loading

0 comments on commit 8a541d9

Please sign in to comment.