cli-memento-mori
Version:
A CLI tool to visualize life's journey with a Memento Mori calendar.
134 lines (112 loc) • 3.72 kB
JavaScript
const fs = require('fs');
const path = require('path');
const { program } = require('commander');
const prompts = require('prompts');
const chalk = require('chalk');
// Default configuration values
const DEFAULT_CONFIG = {
markedColor: '#BB443E',
daysLeftColor: '#8C9A55',
birthdate: null,
};
// Path to the configuration file
const CONFIG_FILE_PATH = path.join(__dirname, 'config.json');
// Function to load configuration from file
const loadConfig = () => {
try {
return JSON.parse(fs.readFileSync(CONFIG_FILE_PATH, 'utf-8'));
} catch (error) {
return DEFAULT_CONFIG;
}
};
// Function to save configuration to file
const saveConfig = (config) => {
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(config, null, 2));
};
// Function to display help information
const showHelp = () => {
console.log(`
Usage: memento-mori [options]
Options:
--config.color <color> Set color for days lived (e.g., "red", "#FF0000")
--config.birthdate <birthdate> Set birthdate (e.g., "01/18/1998", "01.18.1998")
--help Display this help message
`);
};
// Function to validate color format
const isValidColor = (color) => {
return /^#([0-9a-fA-F]{3}){1,2}$/.test(color) || ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray'].includes(color.toLowerCase());
};
// Function to validate birthdate format
const isValidBirthdate = (birthdate) => {
return /^\d{1,2}[\/.-]\d{1,2}[\/.-]\d{4}$/.test(birthdate);
};
// Function to display the Memento Mori grid
const displayMementoMori = (config) => {
const currentDate = new Date();
const birthdate = new Date(config.birthdate);
const totalDays = Math.floor((new Date(birthdate.getFullYear() + 70, birthdate.getMonth(), birthdate.getDate()) - birthdate) / (1000 * 60 * 60 * 24));
const daysLived = Math.floor((currentDate - birthdate) / (1000 * 60 * 60 * 24));
let grid = '';
for (let i = 0; i < totalDays; i++) {
if (i < daysLived) {
grid += chalk.hex(config.markedColor)(' • ');
} else {
grid += chalk.hex(config.daysLeftColor)(' • ');
}
if ((i + 1) % 50 === 0) {
grid += '\n';
}
}
const daysLeft = totalDays - daysLived;
const yearsLeft = Math.floor(daysLeft / 365);
console.log(grid);
console.log(" ")
console.log("You have:")
console.log(`${daysLeft} days left. Or`)
console.log(`${yearsLeft} years left.`)
};
// Define CLI options and actions
program
.option('--config.color <color>', 'Set color for days lived')
.option('--config.birthdate <birthdate>', 'Set birthdate')
.option('-h','--help', 'Display help message')
.parse(process.argv);
const options = program.opts();
let birthdate = options['config.birthdate']
let markedColor = options['config.markedColor']
let daysLeftColor = options['config.daysLeftColor']
// Handle --help flag
if (options.help) {
showHelp();
process.exit();
}
// Load configuration from file
let config = loadConfig();
// Update configuration with command-line arguments
if (markedColor && isValidColor(markedColor)) {
config.markedColor = markedColor;
}
if (daysLeftColor && isValidColor(daysLeftColor)) {
config.daysLeftColor = daysLeftColor;
}
if (birthdate && isValidBirthdate(birthdate)) {
config.birthdate = birthdate;
}
// If birthdate is not set, prompt the user to enter it
if (!config.birthdate) {
(async () => {
const response = await prompts({
type: 'date',
name: 'birthdate',
message: 'Please enter your birthdate (MM/DD/YYYY):'
});
config.birthdate = response.birthdate;
saveConfig(config);
displayMementoMori(config);
})();
} else {
saveConfig(config);
displayMementoMori(config);
}