Skip to content

Instantly share code, notes, and snippets.

@paul-vd
Last active May 19, 2022 11:44
Show Gist options
  • Save paul-vd/b30d8ce6d67176d532cb03c5edfb8abb to your computer and use it in GitHub Desktop.
Save paul-vd/b30d8ce6d67176d532cb03c5edfb8abb to your computer and use it in GitHub Desktop.
z-dev cli
/* eslint-disable no-console */
const path = require("path");
const fs = require("fs");
const { promisify } = require("util");
const yargs = require("yargs");
const readdir = promisify(fs.readdir);
/**
* Look ma, it's cp -R.
* @param {string} source The path to the thing to copy.
* @param {string} target The path to the new copy.
*/
const copy = function (source, target) {
if (!fs.existsSync(source)) {
console.warn(`Source ${source} does not exist.`);
return;
}
const targetDirectory = path.dirname(target);
if (!fs.existsSync(targetDirectory)) {
fs.mkdirSync(targetDirectory, {
recursive: true,
});
}
const stats = fs.statSync(source);
const isDirectory = stats.isDirectory();
if (isDirectory) {
fs.readdirSync(source).forEach(function (childItemName) {
copy(path.join(source, childItemName), path.join(target, childItemName));
});
} else {
fs.copyFileSync(source, target);
}
};
const ROOT_BACKUP_FOLDER = path.join("./z-dev", "backups");
const BackupHelper = (backupName = "default") => {
const slugify = (str) => {
str = str.replace(/^\s+|\s+$/g, ""); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
for (var i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
}
str = str
.replace(/[^a-z0-9 -]/g, "") // remove invalid chars
.replace(/\s+/g, "-") // collapse whitespace and replace by -
.replace(/-+/g, "-"); // collapse dashes
return str;
};
const BACKUP_NAME = slugify(backupName);
const BACKUP_FOLDER = path.join(ROOT_BACKUP_FOLDER, BACKUP_NAME);
return {
backupFolder: BACKUP_FOLDER,
backupName: BACKUP_NAME,
};
};
const hideBin = (argv) => argv.slice(2);
yargs(hideBin(process.argv))
.command(
"backup [name]",
"Backups your local config and files",
(yargs) =>
yargs
.option("include", {
description: "Include files and folders in backup",
alias: "i",
type: "array",
})
.option("exclude", {
description: "Exclude files and folders from backup",
alias: "e",
type: "array",
}),
(argv) => {
const backup = BackupHelper(argv.name);
const includes = argv.include || [];
const excludes = argv.exclude || [];
const backupFilesAndFolders = [
"./.env",
".front-commerce.js",
"./src/config",
...includes,
]
.filter((filePath) => !excludes.includes(path.join(filePath)))
.map((filePath) => ({
path: filePath,
relativePath: path.join(process.cwd(), filePath),
}));
backupFilesAndFolders.forEach((p) => {
const source = p.relativePath;
const target = path.join(backup.backupFolder, p.path);
copy(source, target);
});
}
)
.command(
"restore [name]",
"Restores a backed-up up instance",
(yargs) => {
return yargs.positional("name", {
description: "The backup to restore",
alias: "n",
type: "string",
coerce: async (arg) => {
if (!fs.existsSync(ROOT_BACKUP_FOLDER)) {
console.error(
`No backups exist, to create a backup use the 'backup' command'`
);
return process.exit(0);
}
const options = await readdir(ROOT_BACKUP_FOLDER);
if (!options.includes(arg)) {
console.error(
`Backup '${arg}' does not exist, available backups:\n -`,
options.join("\n -")
);
return process.exit(0);
}
return arg;
},
});
},
async (argv) => {
const name = await argv.name;
const backup = BackupHelper(name);
console.log(`Restoring backup '${backup.backupName}'`);
copy(backup.backupFolder, process.cwd());
}
)
.help()
.parse();
@paul-vd
Copy link
Author

paul-vd commented May 19, 2022

A simple node-based CLI to backup files and configuration for development.

Backup

Backups your local files and folders with the backup <name> command

Command Description Type
--include, -i Include files and folders in backup [array]
--exclude, -e Exclude files and folders from backup [array]

Usage

$ node `./z-dev/z-dev-cli.js backup my-backup-name

Restore

Restores a backed-up instance with the restore <name> command

Usage

$ node `./z-dev/z-dev-cli.js restore my-backup-name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment