/* * 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 , May 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 { public is_active (): boolean { return true; } private _options: CopyrightOptions | null = null; private _cwd = ''; private _loaded_from_config = false; async start (cwd: string): Promise { 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 = { name: options.author, email: 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 { 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 { 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 { 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 { // eslint-disable-next-line max-len const regex = /\/\*\s+\*\sCopyright[\s\S]*?(?:Created by.*?, (?[a-z]+ [0-9]+)[\s\S]*?|\s)\*\/\n{0,2}/gui; const shebang = /^#!.*?\n\n/gu; const shebang_line = shebang.exec (data); if (!(/\.(?:js|ts|mjs)$/u).test (filename) && !regex.test (data)) return null; const res = regex.exec (data); return ( (shebang_line ? shebang_line[0] : '') + CopyrightGenerator.get_copyright_notice ( this._options as CopyrightOptions, res?.groups?.date ) + data.replace (regex, '') .replace (shebang, '') ); } }