1 /** 2 Copyright: Copyright (c) 2019, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module dsnapshot.config; 7 8 import logger = std.experimental.logger; 9 import std.stdio : writeln; 10 11 import colorlog; 12 13 public import dsnapshot.types; 14 15 struct Config { 16 import std.datetime : SysTime, Duration; 17 import std.variant : Algebraic, visit; 18 static import std.getopt; 19 20 struct Help { 21 std.getopt.GetoptResult helpInfo; 22 } 23 24 struct Backup { 25 /// The name of the snapshot to backup. If none is specified then all are backed up. 26 Name name; 27 /// If the user wants to resume an interrupted backup. 28 bool resume; 29 /// Force a backup to be taken even though it isn't time for it 30 bool forceBackup; 31 /// Adjusts the margin used when calculating if a new snapshot should be taken. 32 Duration newSnapshotMargin; 33 /// 34 int[] ignoreRsyncErrorCodes; 35 std.getopt.GetoptResult helpInfo; 36 } 37 38 struct Remotecmd { 39 /// Single path to modify on the remote host. 40 string path; 41 RemoteSubCmd cmd; 42 std.getopt.GetoptResult helpInfo; 43 } 44 45 struct Admin { 46 /// Name of the snapshot to administrate. 47 Name[] names; 48 49 enum Cmd { 50 list, 51 diskusage, 52 } 53 54 Cmd cmd; 55 56 std.getopt.GetoptResult helpInfo; 57 } 58 59 struct Restore { 60 /// The name of the snapshot to restore. 61 Name name; 62 /// The time to restore. 63 SysTime time; 64 /// Path to restore the named snapshot to. 65 string restoreTo; 66 /// Delete files from restoreTo if they have been removed in src 67 bool deleteFromTo; 68 69 std.getopt.GetoptResult helpInfo; 70 } 71 72 struct Verifyconfig { 73 std.getopt.GetoptResult helpInfo; 74 } 75 76 struct Watch { 77 /// The name of the snapshot to backup. 78 Name name; 79 /// Max number of snapshots to create before exiting. 80 ulong maxSnapshots = ulong.max; 81 std.getopt.GetoptResult helpInfo; 82 } 83 84 struct Global { 85 /// Configuration file to read 86 Path confFile; 87 88 VerboseMode verbosity; 89 bool help = true; 90 string progName; 91 } 92 93 alias Type = Algebraic!(Help, Backup, Remotecmd, Restore, Verifyconfig, Admin, Watch); 94 Type data; 95 96 Global global; 97 SnapshotConfig[] snapshots; 98 99 void printHelp() { 100 import std.format : format; 101 import std.getopt : defaultGetoptPrinter; 102 import std.path : baseName; 103 import std.string : toLower; 104 105 static void printGroup(std.getopt.GetoptResult helpInfo, string progName, string name) { 106 defaultGetoptPrinter(format("usage: %s %s <options>\n", progName, 107 name), helpInfo.options); 108 } 109 110 static void printHelpGroup(std.getopt.GetoptResult helpInfo, string progName) { 111 defaultGetoptPrinter(format("usage: %s <command>\n", progName), helpInfo.options); 112 writeln("Command groups:"); 113 static foreach (T; Type.AllowedTypes) { 114 writeln(" ", T.stringof.toLower); 115 } 116 } 117 118 import std.meta : AliasSeq; 119 120 template printers(T...) { 121 static if (T.length == 1) { 122 static if (is(T[0] == Config.Help)) 123 alias printers = (T[0] a) => printHelpGroup(a.helpInfo, global.progName); 124 else 125 alias printers = (T[0] a) => printGroup(a.helpInfo, 126 global.progName, T[0].stringof.toLower); 127 } else { 128 alias printers = AliasSeq!(printers!(T[0]), printers!(T[1 .. $])); 129 } 130 } 131 132 data.visit!(printers!(Type.AllowedTypes)); 133 134 if (data.type == typeid(Verifyconfig)) { 135 writeln("Verify the configuration file without actually executing it"); 136 } 137 } 138 }