namespace _mimir { /** */ function get_stamp() : string { const date : Date = (new Date(Date.now())); return lib_plankton.string.coin( // "{{year}}{{month}}{{day}}T{{hour}}{{minute}}{{second}}", "{{year}}-{{month}}-{{day}}", { "year": date.getFullYear().toFixed(0).padStart(4, "0"), "month": (date.getMonth() + 1).toFixed(0).padStart(2, "0"), "day": date.getDate().toFixed(0).padStart(2, "0"), "hour": date.getHours().toFixed(0).padStart(2, "0"), "minute": date.getMinutes().toFixed(0).padStart(2, "0"), "second": date.getSeconds().toFixed(0).padStart(2, "0"), } ); } /** */ export async function main( args_raw : Array ) : Promise { // args const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler({ "action": lib_plankton.args.class_argument.positional({ "index": 0, "type": lib_plankton.args.enum_type.string, "mode": lib_plankton.args.enum_mode.replace, "default": "run", "name": "action", "info": lib_plankton.string.coin( "{{description}}:\n{{options}}\n\t\t", { "description": "what to do", "options": ( [ { "name": "conf-schema", "description": "conf-schema" }, { "name": "conf-expose", "description": "conf-expose" }, { "name": "init", "description": "init" }, { "name": "run", "description": "run" }, ] .map( entry => lib_plankton.string.coin( "\t\t- {{name}}\n\t\t\t{{description}}\n", { "name": entry.name, "description": entry.description, } ) ) .join("") ), } ), }), "conf_path": lib_plankton.args.class_argument.volatile({ "indicators_long": ["conf_path"], "indicators_short": ["c"], "type": lib_plankton.args.enum_type.string, "mode": lib_plankton.args.enum_mode.replace, "default": "conf.json", "info": "conf_path", "name": "conf-path", }), "help": lib_plankton.args.class_argument.volatile({ "indicators_long": ["help"], "indicators_short": ["h"], "type": lib_plankton.args.enum_type.boolean, "mode": lib_plankton.args.enum_mode.replace, "default": false, "info": "help", "name": "help", }), }); const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); if (args.help) { process.stdout.write( arg_handler.generate_help( { "programname": "Mimir", "description": "backup tool", "executable": "mimir", } ) + "\n" ); } else { switch (args["action"]) { default: { lib_plankton.log.error( "invalid_action", { "action": args["action"], } ); return Promise.reject("invalid action"); break; } case "conf-schema": { process.stdout.write( JSON.stringify( _mimir.conf.schema, undefined, "\t" ) ); return Promise.resolve(undefined); break; } case "conf-expose": { const conf : _mimir.conf.type_conf = await lib_plankton.conf.load(_mimir.conf.schema, args["conf_path"]); process.stdout.write( JSON.stringify( conf, undefined, "\t" ) ); return Promise.resolve(undefined); break; } case "init": { return Promise.reject(new Error("not implemented")); break; } case "run": { const conf : _mimir.conf.type_conf = await lib_plankton.conf.load(_mimir.conf.schema, args["conf_path"]); const stamp : string = get_stamp(); /** * @todo get from configuration */ const base_directory : string = "/tmp/mimir"; for await (const concern of conf.concerns) { let commands : Array = []; const commands_add : ((command : string) => void) = (command) => { commands.push(command); }; const commands_apply : (() => void) = () => { process.stdout.write(commands.join("\n") + "\n"); }; commands_add( lib_plankton.string.coin( "## {{name}}\n", { "name": concern.name, } ) ); commands_add( lib_plankton.string.coin( "echo '-- {{name}}'", { "name": concern.name, "kind": concern.kind, } ) ); if (! concern.active) { commands_add( "echo '-- (skipping)'" ); } else { const directory : string = lib_plankton.string.coin( "{{base}}/{{stamp}}/{{name}}", { "base": base_directory, "stamp": stamp, "name": concern.name, } ); // preparation { commands_add( lib_plankton.string.coin( "mkdir --parents {{directory}}", { "directory": directory, } ) ); } // serialization { const serialization_logic : _mimir.serialization.type_logic = _mimir.serialization.get_logic(concern); commands = commands.concat( serialization_logic.execute( directory ) ); } // transfer { const target_logic : _mimir.transfer.type_logic = _mimir.transfer.get_logic(conf.target); commands = commands.concat( target_logic.execute( concern.name, stamp, directory ) ); } // cleaning { /** * @todo use shred? */ commands_add( lib_plankton.string.coin( "rm --recursive {{path}}/*", { "path": base_directory, } ) ); } } commands_add( "" ); commands_add( "" ); commands_apply(); } return Promise.resolve(undefined); break; } } } } } ( _mimir.main(process.argv.slice(2)) .then( (result) => { process.exit(0); } ) .catch( (reason) => { process.exit(1); } ) );