/* * 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 , 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 } from 'license'; import { Snippet } from '../../Snippet'; import { DialogHandler } from '../../dialog'; 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 { this.cwd = cwd; await this.load_options_file (); if (!this.options) await this.gather_options (); await FileMapper.map_all_files ( this.cwd, this.fix_file_license.bind (this) ); 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 { 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, ''); } }