152 lines
4.4 KiB
TypeScript
Raw Normal View History

2020-04-16 07:45:48 +02:00
/*
* Copyright (C) SapphireCode - All Rights Reserved
* This file is part of Snippeteer which is released under BSD-3-Clause.
* See file 'LICENSE' for full license details.
2020-05-07 18:40:35 +02:00
* Created by Timo Hocker <timo@scode.ovh>, May 2020
2020-04-16 07:45:48 +02:00
*/
2020-04-15 20:21:00 +02:00
/* eslint-disable no-await-in-loop */
import path from 'path';
import fs from 'fs-extra';
import { Confirm, Input, AutoComplete } from 'enquirer';
// eslint-disable-next-line id-match
2020-04-26 11:57:42 +02:00
import { findLicense, getLicense } from 'license';
2020-04-15 20:21:00 +02:00
import { Snippet } from '../../Snippet';
2020-04-16 08:02:35 +02:00
import { DialogHandler } from '../../dialog';
2020-04-26 11:57:42 +02:00
import { modify_json } from '../../Helper';
2020-04-15 20:21:00 +02:00
import { CopyrightGenerator } from './copyright_generator';
import { FileMapper } from './file_mapper';
import { CopyrightOptions } from './copyright_options';
export default class Copyright implements Snippet {
2020-04-27 13:54:10 +02:00
private _options: CopyrightOptions | null = null;
private _cwd = '';
private _loaded_from_config = false;
2020-04-16 07:31:08 +02:00
2020-04-15 20:21:00 +02:00
async start (cwd: string): Promise<void> {
2020-04-27 13:54:10 +02:00
this._cwd = cwd;
2020-04-18 17:24:41 +02:00
await this.load_options_file ();
2020-04-27 13:54:10 +02:00
if (!this._options)
2020-04-16 07:31:08 +02:00
await this.gather_options ();
2020-04-15 20:21:00 +02:00
2020-04-27 13:54:10 +02:00
const options = this._options as CopyrightOptions;
2020-04-26 12:04:10 +02:00
2020-04-15 20:21:00 +02:00
await FileMapper.map_all_files (
2020-04-27 13:54:10 +02:00
this._cwd,
2020-04-18 17:24:41 +02:00
this.fix_file_license.bind (this)
2020-04-15 20:21:00 +02:00
);
2020-04-16 07:31:08 +02:00
2020-04-27 08:51:53 +02:00
await modify_json ((json) => {
2020-04-26 12:04:10 +02:00
json.author = `${options.author} <${options.email}>`;
json.license = options.has_license
? options.license
2020-04-26 11:57:42 +02:00
: 'UNLICENSED';
2020-04-26 12:07:23 +02:00
return json;
2020-04-26 11:57:42 +02:00
});
2020-04-26 12:04:10 +02:00
if (options.has_license) {
2020-04-26 11:57:42 +02:00
await fs.writeFile (
path.join (cwd, 'LICENSE'),
2020-04-26 12:04:10 +02:00
getLicense (options.license, {
name: options.author,
email: options.email,
project: options.software
2020-04-26 11:57:42 +02:00
})
);
}
2020-04-27 13:54:10 +02:00
if (!this._loaded_from_config && await new Confirm (
2020-04-18 17:24:41 +02:00
{ message: 'should those settings be saved for the next run?' }
)
.run ()
.catch (DialogHandler.catch))
this.save_options_file ();
2020-04-15 20:21:00 +02:00
}
2020-04-16 07:31:08 +02:00
private async gather_options (): Promise<void> {
2020-04-27 13:54:10 +02:00
this._options = (new CopyrightOptions);
this._options.author = await new Input ({ message: 'author' })
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-27 13:54:10 +02:00
this._options.email = await new Input ({ message: 'email' })
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-27 13:54:10 +02:00
this._options.company = await new Input ({ message: 'company' })
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-27 13:54:10 +02:00
this._options.software = await new Input ({ message: 'software name' })
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-27 13:54:10 +02:00
this._options.has_license = await new Confirm ({
2020-04-15 20:21:00 +02:00
message:
'would you like to specify a license?'
})
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-27 13:54:10 +02:00
if (this._options.has_license) {
this._options.license = await new AutoComplete ({
2020-04-15 20:21:00 +02:00
name: 'license',
message: 'choose a license',
limit: 10,
choices: findLicense ('')
})
2020-04-18 17:24:41 +02:00
.run ()
.catch (DialogHandler.catch);
2020-04-15 20:21:00 +02:00
}
}
2020-04-16 07:31:08 +02:00
private async load_options_file (): Promise<void> {
2020-04-27 13:54:10 +02:00
const file_path = path.join (this._cwd, '.liconfig.json');
this._options = null;
2020-04-15 20:21:00 +02:00
if (await fs.pathExists (file_path)) {
2020-04-16 08:00:53 +02:00
const options = JSON.parse (
2020-04-15 20:21:00 +02:00
await fs.readFile (file_path, 'utf-8')
);
2020-04-18 17:24:41 +02:00
// eslint-disable-next-line no-console
console.log (`author: ${options.author}
2020-04-16 08:00:53 +02:00
email: ${options.email}
company: ${options.company}
software name: ${options.software}
license: ${options.license}`);
2020-04-18 17:24:41 +02:00
const should_load = await new Confirm (
{ message: 'should those options be used?' }
)
.run ()
.catch (DialogHandler.catch);
if (should_load) {
2020-04-27 13:54:10 +02:00
this._options = options;
this._loaded_from_config = true;
}
2020-04-15 20:21:00 +02:00
}
}
2020-04-18 17:24:41 +02:00
private async save_options_file (): Promise<void> {
2020-04-27 13:54:10 +02:00
const file_path = path.join (this._cwd, '.liconfig.json');
2020-04-18 17:24:41 +02:00
await fs.writeFile (
file_path,
2020-04-27 13:54:10 +02:00
JSON.stringify (this._options, null, 2),
2020-04-18 17:24:41 +02:00
'utf-8'
);
2020-04-15 20:21:00 +02:00
}
2020-04-16 07:31:08 +02:00
private fix_file_license (
2020-04-15 20:21:00 +02:00
data: string,
2020-04-16 07:31:08 +02:00
filename: string
2020-04-15 20:21:00 +02:00
): string | null {
const regex = /\/\*\s+\*\sCopyright[\s\S]*?\*\/\n{0,2}/gu;
const shebang = /^#!.*?\n\n/gu;
const shebang_line = shebang.exec (data);
if (!(/\.(?:js|ts|mjs)$/u).test (filename) && !regex.test (data))
return null;
return (shebang_line ? shebang_line[0] : '')
2020-04-18 17:24:41 +02:00
+ CopyrightGenerator.get_copyright_notice (
2020-04-27 13:54:10 +02:00
this._options as CopyrightOptions
2020-04-18 17:24:41 +02:00
)
2020-04-15 20:21:00 +02:00
+ data.replace (regex, '')
.replace (shebang, '');
}
}