This repository has been archived by the owner on Jun 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): create the 'update-incident' command
- Loading branch information
Showing
13 changed files
with
233 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
const inquirer = require("inquirer"); | ||
|
||
const { logger, fse, grayMatter, LRU, path } = require("@statusfy/common"); | ||
const loadConfig = require("./config/load"); | ||
const { | ||
getIncidentsFromProject, | ||
generateIncident | ||
} = require("./utils/functions"); | ||
const cache = new LRU(); | ||
|
||
const getIncidentData = async filePath => { | ||
const key = `data:${filePath}`; | ||
let data = cache.get(key); | ||
|
||
if (!data) { | ||
const fileContent = await fse.readFile(filePath); | ||
data = grayMatter.parse(fileContent); | ||
|
||
cache.set(key, data); | ||
} | ||
|
||
return data; | ||
}; | ||
|
||
/* eslint-disable require-await */ | ||
module.exports = async function updateIncident(sourceDir, cliOptions = {}) { | ||
process.env.NODE_ENV = "development"; | ||
|
||
const config = loadConfig(sourceDir).config; | ||
const contentDir = path.join(sourceDir, config.content.dir); | ||
const incidentsList = await getIncidentsFromProject(contentDir); | ||
|
||
const questions = [ | ||
{ | ||
type: "list", | ||
name: "incident", | ||
message: "What incident do you want to update?", | ||
paginated: true, | ||
choices: incidentsList | ||
}, | ||
{ | ||
type: "confirm", | ||
name: "resolved", | ||
message: "The incident has been resolved?", | ||
async default(answers) { | ||
const { resolved } = (await getIncidentData( | ||
answers.incident.path | ||
)).data; | ||
return Boolean(resolved); | ||
} | ||
}, | ||
{ | ||
type: "list", | ||
name: "severity", | ||
message: "What is the severity of the incident?", | ||
choices: [ | ||
"under-maintenance", | ||
"degraded-performance", | ||
"partial-outage", | ||
"major-outage" | ||
], | ||
async default(answers) { | ||
const { severity } = (await getIncidentData( | ||
answers.incident.path | ||
)).data; | ||
return severity; | ||
} | ||
}, | ||
{ | ||
type: "checkbox", | ||
name: "affectedsystems", | ||
message: "What are the affected systems?", | ||
choices: config.content.systems, | ||
validate: value => { | ||
if (value.length > 0) { | ||
return true; | ||
} | ||
|
||
return "You must have an affected system!"; | ||
}, | ||
async default(answers) { | ||
const { affectedsystems } = (await getIncidentData( | ||
answers.incident.path | ||
)).data; | ||
return affectedsystems; | ||
} | ||
}, | ||
{ | ||
type: "confirm", | ||
name: "confirm", | ||
message: "Are you sure you want to update the incident?", | ||
default: false | ||
} | ||
]; | ||
|
||
inquirer.prompt(questions).then(async answers => { | ||
const { incident, resolved, severity, affectedsystems, confirm } = answers; | ||
|
||
try { | ||
if (confirm) { | ||
const modified = new Date().toISOString(); | ||
const locales = config.locales.map(l => l.code); | ||
const updatedFiles = []; | ||
|
||
for (let j = 0; j < locales.length; j++) { | ||
const locale = locales[j]; | ||
const localeIncidentPath = path.join( | ||
contentDir, | ||
config.defaultLocale !== locale ? locale : "", | ||
incident.name | ||
); | ||
const exists = await fse.pathExists(localeIncidentPath); | ||
|
||
if (exists) { | ||
try { | ||
const data = await getIncidentData(localeIncidentPath); | ||
const newMatter = { | ||
...data.data, | ||
modified, | ||
severity, | ||
affectedsystems, | ||
resolved | ||
}; | ||
|
||
const content = generateIncident( | ||
newMatter, | ||
data.content, | ||
config.content.frontMatterFormat || "yaml" | ||
); | ||
|
||
await fse.writeFile(localeIncidentPath, content); | ||
|
||
updatedFiles.push(localeIncidentPath); | ||
} catch (error) { | ||
logger.error(error); | ||
} | ||
} else { | ||
logger.warn(`This file couldn't be found:\n${localeIncidentPath}`); | ||
} | ||
} | ||
|
||
if (updatedFiles.length > 0) { | ||
const prefix = | ||
updatedFiles.length === 1 | ||
? "This file was successfully updated" | ||
: "These files were successfully updated"; | ||
|
||
logger.success(`${prefix}: \n${updatedFiles.join("\n")}`); | ||
} | ||
} | ||
} catch (error) { | ||
logger.fatal(error); | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
const { fse, grayMatter, chalk, path } = require("@statusfy/common"); | ||
|
||
const getIncidentsFromProject = async contentDir => { | ||
const files = await fse.readdir(contentDir); | ||
const incidentsList = []; | ||
|
||
for (let i = 0; i < files.length; i++) { | ||
const f = path.resolve(contentDir, files[i]); | ||
const ext = path.extname(f); | ||
const fileName = path.basename(f); | ||
|
||
if (ext === ".md") { | ||
const fileContent = await fse.readFile(f); | ||
const { data } = grayMatter.parse(fileContent); | ||
|
||
incidentsList.push({ | ||
value: { | ||
name: fileName, | ||
path: f | ||
}, | ||
name: `${fileName} > ${chalk.yellow(data.title)} (${chalk.green( | ||
data.date.toUTCString() | ||
)})` | ||
}); | ||
} | ||
} | ||
|
||
return incidentsList; | ||
}; | ||
|
||
const generateIncident = (data, content, format) => { | ||
let matterContent = grayMatter.stringify(content, data, format); | ||
|
||
if (["json", "toml"].includes(format)) { | ||
matterContent = matterContent.replace(/^---/, `---${format}`); | ||
} | ||
|
||
return matterContent; | ||
}; | ||
|
||
module.exports = { | ||
getIncidentsFromProject, | ||
generateIncident | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters