152 lines
4.4 KiB
TypeScript
152 lines
4.4 KiB
TypeScript
/*
|
|
* 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.
|
|
* Created by Timo Hocker <timo@scode.ovh>, April 2020
|
|
*/
|
|
|
|
/* 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
|
|
import { findLicense, getLicense } from 'license';
|
|
import { Snippet } from '../../Snippet';
|
|
import { DialogHandler } from '../../dialog';
|
|
import { modify_json } from '../../Helper';
|
|
import { CopyrightGenerator } from './copyright_generator';
|
|
import { FileMapper } from './file_mapper';
|
|
import { CopyrightOptions } from './copyright_options';
|
|
|
|
export default class Copyright implements Snippet {
|
|
private options: CopyrightOptions | null = null;
|
|
private cwd = '';
|
|
private loaded_from_config = false;
|
|
|
|
async start (cwd: string): Promise<void> {
|
|
this.cwd = cwd;
|
|
await this.load_options_file ();
|
|
if (!this.options)
|
|
await this.gather_options ();
|
|
|
|
const options = this.options as CopyrightOptions;
|
|
|
|
await FileMapper.map_all_files (
|
|
this.cwd,
|
|
this.fix_file_license.bind (this)
|
|
);
|
|
|
|
await modify_json ((json) => {
|
|
json.author = `${options.author} <${options.email}>`;
|
|
json.license = options.has_license
|
|
? options.license
|
|
: 'UNLICENSED';
|
|
return json;
|
|
});
|
|
|
|
if (options.has_license) {
|
|
await fs.writeFile (
|
|
path.join (cwd, 'LICENSE'),
|
|
getLicense (options.license, {
|
|
name: options.author,
|
|
email: options.email,
|
|
project: options.software
|
|
})
|
|
);
|
|
}
|
|
|
|
if (!this.loaded_from_config && await new Confirm (
|
|
{ message: 'should those settings be saved for the next run?' }
|
|
)
|
|
.run ()
|
|
.catch (DialogHandler.catch))
|
|
this.save_options_file ();
|
|
}
|
|
|
|
private async gather_options (): Promise<void> {
|
|
this.options = (new CopyrightOptions);
|
|
this.options.author = await new Input ({ message: 'author' })
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
this.options.email = await new Input ({ message: 'email' })
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
this.options.company = await new Input ({ message: 'company' })
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
this.options.software = await new Input ({ message: 'software name' })
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
this.options.has_license = await new Confirm ({
|
|
message:
|
|
'would you like to specify a license?'
|
|
})
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
if (this.options.has_license) {
|
|
this.options.license = await new AutoComplete ({
|
|
name: 'license',
|
|
message: 'choose a license',
|
|
limit: 10,
|
|
choices: findLicense ('')
|
|
})
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
}
|
|
}
|
|
|
|
private async load_options_file (): Promise<void> {
|
|
const file_path = path.join (this.cwd, '.liconfig.json');
|
|
this.options = null;
|
|
|
|
if (await fs.pathExists (file_path)) {
|
|
const options = JSON.parse (
|
|
await fs.readFile (file_path, 'utf-8')
|
|
);
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.log (`author: ${options.author}
|
|
email: ${options.email}
|
|
company: ${options.company}
|
|
software name: ${options.software}
|
|
license: ${options.license}`);
|
|
const should_load = await new Confirm (
|
|
{ message: 'should those options be used?' }
|
|
)
|
|
.run ()
|
|
.catch (DialogHandler.catch);
|
|
if (should_load) {
|
|
this.options = options;
|
|
this.loaded_from_config = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async save_options_file (): Promise<void> {
|
|
const file_path = path.join (this.cwd, '.liconfig.json');
|
|
await fs.writeFile (
|
|
file_path,
|
|
JSON.stringify (this.options, null, 2),
|
|
'utf-8'
|
|
);
|
|
}
|
|
|
|
private fix_file_license (
|
|
data: string,
|
|
filename: string
|
|
): 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] : '')
|
|
+ CopyrightGenerator.get_copyright_notice (
|
|
this.options as CopyrightOptions
|
|
)
|
|
+ data.replace (regex, '')
|
|
.replace (shebang, '');
|
|
}
|
|
}
|