From ac30cf2a32733d60c8f2b7026da2e9dcdf95ec5b Mon Sep 17 00:00:00 2001 From: Hari Nugraha <15191978+haricnugraha@users.noreply.github.com> Date: Thu, 18 Apr 2024 11:56:08 +0700 Subject: [PATCH] Refactor: Separate Create Config Handler (#1272) * refactor: separate create config flag handler * docs: fix grammar --- README.md | 8 +- src/commands/monika.ts | 5 +- .../config/__tests__/create-config.test.ts | 240 ---------- src/components/config/create.test.ts | 429 ++++++++++++++++++ src/components/config/create.ts | 110 +++++ src/components/config/index.ts | 89 +--- src/utils/open-website.ts | 50 -- 7 files changed, 547 insertions(+), 384 deletions(-) delete mode 100644 src/components/config/__tests__/create-config.test.ts create mode 100644 src/components/config/create.test.ts create mode 100644 src/components/config/create.ts delete mode 100644 src/utils/open-website.ts diff --git a/README.md b/README.md index aa8cd2ae2..e7cc5b0f7 100644 --- a/README.md +++ b/README.md @@ -79,20 +79,20 @@ probes: followRedirects: 0 alerts: - assertion: response.status != 302 - message: You should not follow redirect + message: You should not follow the redirect - id: 'should follow redirect with default config' requests: - url: http://localhost:3000/absolute-redirect/20 alerts: - assertion: response.status == 302 - message: You are not follow redirect - - id: 'should follow redirect with customize config' + message: You are not following the redirect + - id: 'should follow redirect with customized config' requests: - url: http://localhost:3000/status/302 followRedirects: 2 alerts: - assertion: response.status == 302 - message: You are not follow redirect + message: You are not following the redirect ``` ##### MariaDB diff --git a/src/commands/monika.ts b/src/commands/monika.ts index cb82e426b..a653a2a0a 100644 --- a/src/commands/monika.ts +++ b/src/commands/monika.ts @@ -28,7 +28,8 @@ import pEvent from 'p-event' import type { Config } from '../interfaces/config' import type { Probe } from '../interfaces/probe' -import { createConfig, getConfig, isSymonModeFrom } from '../components/config' +import { getConfig, isSymonModeFrom } from '../components/config' +import { createConfig } from '../components/config/create' import { sortProbes } from '../components/config/sort' import { printAllLogs } from '../components/logger' import { flush } from '../components/logger/flush' @@ -350,7 +351,7 @@ export default class Monika extends Command { try { if (_flags['create-config']) { - await createConfig(_flags) + await createConfig() return } diff --git a/src/components/config/__tests__/create-config.test.ts b/src/components/config/__tests__/create-config.test.ts deleted file mode 100644 index 3049e6957..000000000 --- a/src/components/config/__tests__/create-config.test.ts +++ /dev/null @@ -1,240 +0,0 @@ -/********************************************************************************** - * MIT License * - * * - * Copyright (c) 2021 Hyperjump Technology * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * of this software and associated documentation files (the "Software"), to deal * - * in the Software without restriction, including without limitation the rights * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included in all * - * copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * - * SOFTWARE. * - **********************************************************************************/ - -import { expect } from 'chai' -import fs from 'fs' -import _ from 'lodash' - -import type { MonikaFlags } from '../../../flag' -import { createConfig } from '../' - -beforeEach(() => { - if (fs.existsSync('monika.har.yml')) { - fs.unlinkSync('monika.har.yml') - } - - if (fs.existsSync('monika.postman-basic.yml')) { - fs.unlinkSync('monika.postman-basic.yml') - } - - if (fs.existsSync('monika.postman-grouped.yml')) { - fs.unlinkSync('monika.postman-grouped.yml') - } - - if (fs.existsSync('sitemap.xml')) { - fs.unlinkSync('sitemap.xml') - } - - if (fs.existsSync('monika.insomnia.yml')) { - fs.unlinkSync('monika.insomnia.yml') - } - - if (fs.existsSync('monika.sitemap.yml')) { - fs.unlinkSync('monika.sitemap.yml') - } -}) - -describe('Har config', () => { - describe('Create config from har file', () => { - it('should create config from har file', async () => { - const flags = { - har: './src/components/config/__tests__/form_encoded.har', - output: 'monika.har.yml', - } as MonikaFlags - await createConfig(flags) - expect(fs.lstatSync('monika.har.yml').isFile()).to.be.true - - const generated = fs.readFileSync('monika.har.yml', 'utf8') - const expected = fs.readFileSync( - './src/components/config/__tests__/expected.har.yml', - 'utf8' - ) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) - -describe('Text config', () => { - describe('Create config from text file', () => { - it('should create config from text file', async () => { - const flags = { - text: './src/components/config/__tests__/textfile', - output: 'monika.textfile.yml', - force: true, - } as MonikaFlags - await createConfig(flags) - expect(fs.lstatSync('monika.textfile.yml').isFile()).to.be.true - - const generated = fs.readFileSync('monika.textfile.yml', 'utf8') - const expected = fs.readFileSync( - './src/components/config/__tests__/expected.textfile.yml', - 'utf8' - ) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) - -describe('Sitemap config', () => { - describe('Create config from xml file', () => { - it('should create config from xml file', async () => { - const flags = { - sitemap: './src/components/config/__tests__/sitemap.xml', - output: 'monika.sitemap.yml', - } as MonikaFlags - await createConfig(flags) - expect(fs.lstatSync('monika.sitemap.yml').isFile()).to.be.true - - const generated = fs.readFileSync('monika.sitemap.yml', 'utf8') - const expected = fs.readFileSync( - './src/components/config/__tests__/expected.sitemap.yml', - 'utf8' - ) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) - -describe('Sitemap config [--one-probe ]', () => { - describe('Create config from xml file', () => { - it('should create config from xml file', async () => { - const flags = { - sitemap: './src/components/config/__tests__/sitemap.xml', - output: 'monika.sitemap.yml', - 'one-probe': true, - } as MonikaFlags - await createConfig(flags) - expect(fs.lstatSync('monika.sitemap.yml').isFile()).to.be.true - - const generated = fs.readFileSync('monika.sitemap.yml', 'utf8') - const expected = fs.readFileSync( - './src/components/config/__tests__/expected.sitemap-oneprobe.yml', - 'utf8' - ) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) - -const getPostmanConfig = ({ grouped }: { grouped: boolean }) => { - if (grouped) { - const generated = fs.readFileSync('monika.postman-grouped.yml', 'utf8') - - const expected = fs.readFileSync( - './src/components/config/__tests__/mock_files/expected.postman-grouped.yml', - 'utf8' - ) - - return { generated, expected } - } - - const generated = fs.readFileSync('monika.postman-basic.yml', 'utf8') - - const expected = fs.readFileSync( - './src/components/config/__tests__/mock_files/expected.postman-basic.yml', - 'utf8' - ) - - return { generated, expected } -} - -describe('Postman config', () => { - describe('Create config from postman file', () => { - it('[v2.0] - should create config from basic postman file', async () => { - const flags = { - postman: - './src/components/config/__tests__/mock_files/basic-postman_collection-v2.0.json', - output: 'monika.postman-basic.yml', - } as MonikaFlags - - await createConfig(flags) - expect(fs.lstatSync('monika.postman-basic.yml').isFile()).to.be.true - - const { generated, expected } = getPostmanConfig({ grouped: false }) - expect(_.isEqual(generated, expected)).to.be.true - }) - - it('[v2.1] - should create config from basic postman file', async () => { - const flags = { - postman: - './src/components/config/__tests__/mock_files/basic-postman_collection-v2.1.json', - output: 'monika.postman-basic.yml', - } as MonikaFlags - - await createConfig(flags) - expect(fs.lstatSync('monika.postman-basic.yml').isFile()).to.be.true - - const { generated, expected } = getPostmanConfig({ grouped: false }) - expect(_.isEqual(generated, expected)).to.be.true - }) - - it('[v2.0] - should create config from grouped postman file', async () => { - const flags = { - postman: - './src/components/config/__tests__/mock_files/grouped-postman_collection-v2.0.json', - output: 'monika.postman-grouped.yml', - } as MonikaFlags - - await createConfig(flags) - expect(fs.lstatSync('monika.postman-grouped.yml').isFile()).to.be.true - - const { generated, expected } = getPostmanConfig({ grouped: true }) - expect(_.isEqual(generated, expected)).to.be.true - }) - - it('[v2.1] - should create config from grouped postman file', async () => { - const flags = { - postman: - './src/components/config/__tests__/mock_files/grouped-postman_collection-v2.1.json', - output: 'monika.postman-grouped.yml', - } as MonikaFlags - - await createConfig(flags) - expect(fs.lstatSync('monika.postman-grouped.yml').isFile()).to.be.true - - const { generated, expected } = getPostmanConfig({ grouped: true }) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) - -describe('Insomnia config', () => { - describe('Create config from insomnia file', () => { - it('should create config from insomnia file', async () => { - const flags = { - insomnia: './src/components/config/__tests__/petstore.insomnia.yaml', - output: 'monika.insomnia.yml', - } as MonikaFlags - await createConfig(flags) - expect(fs.lstatSync('monika.insomnia.yml').isFile()).to.be.true - - const generated = fs.readFileSync('monika.insomnia.yml', 'utf8') - const expected = fs.readFileSync( - './src/components/config/__tests__/expected.insomnia.yml', - 'utf8' - ) - expect(_.isEqual(generated, expected)).to.be.true - }) - }) -}) diff --git a/src/components/config/create.test.ts b/src/components/config/create.test.ts new file mode 100644 index 000000000..c0da2fb6a --- /dev/null +++ b/src/components/config/create.test.ts @@ -0,0 +1,429 @@ +import childProcess from 'node:child_process' +import { existsSync } from 'node:fs' +import { rename, readFile, writeFile, rm } from 'node:fs/promises' +import os from 'node:os' + +import { expect } from '@oclif/test' +import { type SinonStub, stub } from 'sinon' + +import { getContext, resetContext, setContext } from '../../context' +import { getErrorMessage } from '../../utils/catch-error-handler' +import { createConfig } from './create' + +describe('Create config', () => { + describe('Open Monika config generator', () => { + let osTypeStub: SinonStub + let spawnSyncStub: SinonStub + + beforeEach(() => { + osTypeStub = stub(os, 'type') + spawnSyncStub = stub(childProcess, 'spawnSync') + }) + + afterEach(() => { + osTypeStub.restore() + spawnSyncStub.restore() + }) + + it('should open Monika config generator using MacOS', async () => { + // arrange + osTypeStub.returns('Darwin') + + // act + await createConfig() + + // assert + const command = spawnSyncStub.args[0][0] + const url = spawnSyncStub.args[0][1][0] + + expect(command).eq('open') + expect(url).eq('https://hyperjumptech.github.io/monika-config-generator/') + }) + + it('should open Monika config generator using Linux', async () => { + // arrange + osTypeStub.returns('Linux') + + // act + await createConfig() + + // assert + const command = spawnSyncStub.args[0][0] + const url = spawnSyncStub.args[0][1][0] + + expect(command).eq('xdg-open') + expect(url).eq('https://hyperjumptech.github.io/monika-config-generator/') + }) + + it('should open Monika config generator using Windows', async () => { + // arrange + osTypeStub.returns('Windows NT') + + // act + await createConfig() + + // assert + const command = spawnSyncStub.args[0][0] + const url = spawnSyncStub.args[0][1][0] + + expect(command).eq('start') + expect(url).eq('https://hyperjumptech.github.io/monika-config-generator/') + }) + + it('should throw an error on unhandled OS', async () => { + // arrange + let errorMessage = '' + osTypeStub.returns('FreeBSD') + + // act + try { + await createConfig() + } catch (error) { + errorMessage = getErrorMessage(error) + } + + // assert + expect(errorMessage).to.include('Unknown operating system') + }) + }) + + describe('Converter', () => { + afterEach(() => { + resetContext() + }) + + it('should throw an error if file path is not found', async () => { + // arrange + const filepath = './example.har' + setContext({ flags: { ...getContext().flags, har: filepath } }) + let errorMessage = '' + + // act + try { + await createConfig() + } catch (error) { + errorMessage = getErrorMessage(error) + } + + // assert + expect(errorMessage).to.include("Couldn't found") + }) + + it('should convert from har', async () => { + // arrange + const output = 'monika.har.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + output, + har: './src/components/config/__tests__/form_encoded.har', + }, + }) + + // act + await createConfig() + + // assert + const generated = await readFile(output, { encoding: 'utf8' }) + const expected = await readFile( + './src/components/config/__tests__/expected.har.yml', + { encoding: 'utf8' } + ) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from insomnia', async () => { + // arrange + const output = 'monika.insomnia.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + insomnia: './src/components/config/__tests__/petstore.insomnia.yaml', + output, + }, + }) + + // act + await createConfig() + + // assert + const generated = await readFile(output, { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/expected.insomnia.yml', + { encoding: 'utf8' } + ) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from basic postman file v2.0', async () => { + // arrange + const output = 'monika.postman-basic.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + postman: + './src/components/config/__tests__/mock_files/basic-postman_collection-v2.0.json', + output, + }, + }) + + // act + await createConfig() + + // assert + const { generated, expected } = await getPostmanConfig() + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from grouped postman file v2.0', async () => { + // arrange + const output = 'monika.postman-grouped.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + postman: + './src/components/config/__tests__/mock_files/grouped-postman_collection-v2.0.json', + output, + }, + }) + + // act + await createConfig() + + // assert + const { generated, expected } = await getPostmanConfig(true) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from basic postman file v2.1', async () => { + // arrange + const output = 'monika.postman-basic.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + postman: + './src/components/config/__tests__/mock_files/basic-postman_collection-v2.0.json', + output: 'monika.postman-basic.yml', + }, + }) + + // act + await createConfig() + + // assert + const { generated, expected } = await getPostmanConfig() + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from grouped postman file v2.1', async () => { + // arrange + const output = 'monika.postman-grouped.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + postman: + './src/components/config/__tests__/mock_files/grouped-postman_collection-v2.1.json', + output, + }, + }) + + // act + await createConfig() + + // assert + const { generated, expected } = await getPostmanConfig(true) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from sitemap', async () => { + // arrange + const output = 'monika.sitemap.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + sitemap: './src/components/config/__tests__/sitemap.xml', + output, + }, + }) + + // act + await createConfig() + + // assert + const generated = await readFile('monika.sitemap.yml', { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/expected.sitemap.yml', + { encoding: 'utf8' } + ) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from sitemap - one probe', async () => { + // arrange + const output = 'monika.sitemap.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + sitemap: './src/components/config/__tests__/sitemap.xml', + output, + 'one-probe': true, + }, + }) + + // act + await createConfig() + + // assert + const generated = await readFile('monika.sitemap.yml', { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/expected.sitemap-oneprobe.yml', + { encoding: 'utf8' } + ) + expect(generated).eq(expected) + + await rm(output) + }) + + it('should convert from text', async () => { + // arrange + const output = 'monika.textfile.yml' + setContext({ + flags: { + ...getContext().flags, + force: true, + text: './src/components/config/__tests__/textfile', + output, + }, + }) + + // act + await createConfig() + + // assert + const generated = await readFile('monika.textfile.yml', { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/expected.textfile.yml', + { encoding: 'utf8' } + ) + expect(generated).eq(expected) + + await rm(output) + }) + }) + + describe('Writer', () => { + beforeEach(async () => { + if (existsSync('monika.yml')) { + await rename('monika.yml', 'monika.backup.yml') + } + }) + + afterEach(async () => { + if (existsSync('monika.backup.yml')) { + await rename('monika.backup.yml', 'monika.yml') + } + + resetContext() + }) + + it('should not prompt to overwrite existing file', async () => { + // arrange + setContext({ + flags: { + ...getContext().flags, + force: true, + text: './src/components/config/__tests__/textfile', + }, + }) + await writeFile('monika.yml', '', { encoding: 'utf8' }) + + // act + await createConfig() + + // assert + expect(existsSync('monika.yml')).eq(true) + await rm('monika.yml') + }) + + it('should write config to the output flag', async () => { + // arrange + if (existsSync('monika.yaml')) { + await rename('monika.yaml', 'monika.backup.yaml') + } + + setContext({ + flags: { + ...getContext().flags, + force: true, + output: 'monika.yaml', + text: './src/components/config/__tests__/textfile', + }, + }) + await writeFile('monika.yaml', '', { encoding: 'utf8' }) + + // act + await createConfig() + + // assert + expect(existsSync('monika.yaml')).eq(true) + await rm('monika.yaml') + if (existsSync('monika.backup.yaml')) { + await rename('monika.backup.yaml', 'monika.yaml') + } + }) + }) +}) + +async function getPostmanConfig(isGrouped = false) { + if (isGrouped) { + const generated = await readFile('monika.postman-grouped.yml', { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/mock_files/expected.postman-grouped.yml', + { encoding: 'utf8' } + ) + + return { generated, expected } + } + + const generated = await readFile('monika.postman-basic.yml', { + encoding: 'utf8', + }) + const expected = await readFile( + './src/components/config/__tests__/mock_files/expected.postman-basic.yml', + { encoding: 'utf8' } + ) + + return { generated, expected } +} diff --git a/src/components/config/create.ts b/src/components/config/create.ts new file mode 100644 index 000000000..5c7fb2f5d --- /dev/null +++ b/src/components/config/create.ts @@ -0,0 +1,110 @@ +import { spawnSync } from 'node:child_process' +import { existsSync } from 'node:fs' +import { writeFile } from 'node:fs/promises' +import { type } from 'node:os' + +import { ux } from '@oclif/core' +import yml from 'js-yaml' + +import { addDefaultNotifications } from './get' +import { parseConfig } from './parse' +import { getContext } from '../../context' +import { log } from '../../utils/pino' + +export async function createConfig(): Promise { + const { flags } = getContext() + + const isConvertFromOtherFormat = + flags.har || flags.insomnia || flags.postman || flags.sitemap || flags.text + if (!isConvertFromOtherFormat) { + log.info( + 'Opening Monika Configuration Generator in your default browser...' + ) + open('https://hyperjumptech.github.io/monika-config-generator/') + return + } + + const { path, type } = getPathAndType() + + if (!existsSync(path)) { + throw new Error(`Couldn't found the ${path} file.`) + } + + const parse = await parseConfig(path, type, flags) + const file = flags.output || 'monika.yml' + + if (existsSync(file) && !flags.force) { + const answer = await ux.ux.prompt( + `\n${file} file is already exists. Overwrite (Y/n)?` + ) + + if (answer.toLowerCase() !== 'y') { + log.warn( + 'Command cancelled. You can use the -o flag to specify an output file or --force to overwrite without prompting.' + ) + return + } + } + + const data = yml.dump(addDefaultNotifications(parse)) + await writeFile(file, data, { + encoding: 'utf8', + }) + log.info(`${file} file has been created.`) +} + +function open(url: string) { + const operatingSystem = type() + + switch (operatingSystem) { + case 'Darwin': { + spawnSync('open', [url]) + break + } + + case 'Linux': { + spawnSync('xdg-open', [url]) + break + } + + case 'Windows NT': { + spawnSync('start', [url]) + break + } + + default: { + throw new Error(`Unknown operating system: ${operatingSystem}`) + } + } +} + +type PathAndType = { + path: string + type: string +} + +function getPathAndType(): PathAndType { + const { flags } = getContext() + + if (flags.har) { + return { path: flags.har, type: 'har' } + } + + if (flags.insomnia) { + return { path: flags.insomnia, type: 'insomnia' } + } + + if (flags.postman) { + return { path: flags.postman, type: 'postman' } + } + + if (flags.sitemap) { + return { path: flags.sitemap, type: 'sitemap' } + } + + if (flags.text) { + return { path: flags.text, type: 'text' } + } + + throw new Error('Unknown format') +} diff --git a/src/components/config/index.ts b/src/components/config/index.ts index 5808b9911..7d9a8c7a5 100644 --- a/src/components/config/index.ts +++ b/src/components/config/index.ts @@ -23,8 +23,6 @@ **********************************************************************************/ import { watch } from 'chokidar' -import { ux } from '@oclif/core' -import { existsSync, writeFileSync } from 'fs' import isUrl from 'is-url' import events from '../../events' @@ -34,19 +32,12 @@ import { monikaFlagsDefaultValue } from '../../flag' import type { MonikaFlags } from '../../flag' import { getEventEmitter } from '../../utils/events' import { md5Hash } from '../../utils/hash' -import { open } from '../../utils/open-website' import { log } from '../../utils/pino' import { parseConfig } from './parse' import { validateConfig } from './validate' import { createConfigFile } from './create-config' -import yml from 'js-yaml' import { exit } from 'process' -import { - type ConfigType, - addDefaultNotifications, - getConfigFrom, - mergeConfigs, -} from './get' +import { type ConfigType, getConfigFrom, mergeConfigs } from './get' import { getProbes, setProbes } from './probe' import { getErrorMessage } from '../../utils/catch-error-handler' @@ -231,84 +222,6 @@ function watchConfigFile({ flags, path }: WatchConfigFileParams) { } } -const getPathAndTypeFromFlag = (flags: MonikaFlags) => { - let path = flags.config?.[0] - let type = 'monika' - - if (flags.postman) { - path = flags.postman - type = 'postman' - } - - if (flags.har) { - path = flags.har - type = 'har' - } - - if (flags.insomnia) { - path = flags.insomnia - type = 'insomnia' - } - - if (flags.sitemap) { - path = flags.sitemap - type = 'sitemap' - } - - if (flags.text) { - path = flags.text - type = 'text' - } - - return { - path, - type, - } -} - -export const createConfig = async (flags: MonikaFlags): Promise => { - if ( - !flags.har && - !flags.postman && - !flags.insomnia && - !flags.sitemap && - !flags.text - ) { - log.info( - 'Opening Monika Configuration Generator in your default browser...' - ) - open('https://hyperjumptech.github.io/monika-config-generator/') - } else { - const { path, type } = getPathAndTypeFromFlag(flags) - - if (!existsSync(path)) { - log.error(`Couldn't found the ${path} file.`) - return - } - - const parse = await parseConfig(path, type, flags) - const result = addDefaultNotifications(parse) - const file = flags.output || 'monika.yml' - - if (existsSync(file) && !flags.force) { - const ans = await ux.ux.prompt( - `\n${file} file is already exists. Overwrite (Y/n)?` - ) - - if (ans.toLowerCase() !== 'y') { - log.warn( - `Command cancelled. You can use the -o flag to specify an output file or --force to overwrite without prompting.` - ) - return - } - } - - const yamlDoc = yml.dump(result) - writeFileSync(file, yamlDoc, 'utf8') - log.info(`${file} file has been created.`) - } -} - export function isSymonModeFrom({ symonKey, symonUrl, diff --git a/src/utils/open-website.ts b/src/utils/open-website.ts deleted file mode 100644 index 7d6c7610a..000000000 --- a/src/utils/open-website.ts +++ /dev/null @@ -1,50 +0,0 @@ -/********************************************************************************** - * MIT License * - * * - * Copyright (c) 2021 Hyperjump Technology * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * of this software and associated documentation files (the "Software"), to deal * - * in the Software without restriction, including without limitation the rights * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included in all * - * copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * - * SOFTWARE. * - **********************************************************************************/ - -import { spawnSync } from 'child_process' -import { type } from 'os' - -export const open = (url: string): void => { - const operatingSystem = type() - switch (operatingSystem) { - case 'Darwin': { - spawnSync('open', [url]) - break - } - - case 'Linux': { - spawnSync('xdg-open', [url]) - break - } - - case 'Windows NT': { - spawnSync('start', [url]) - break - } - - default: { - throw new Error(`Unknown operating system: ${operatingSystem}`) - } - } -}