1 // Written in D programming language 2 /** 3 * Module describes application startup options. 4 * 5 * Copyright: © 2014 DSoftOut 6 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 7 * Authors: Zaramzan <shamyan.roman@gmail.com> 8 * NCrashed <ncrashed@gmail.com> 9 */ 10 module server.options; 11 12 import std.path; 13 import std.array; 14 import std.getopt; 15 import std.range; 16 17 import server.config; 18 import dlogg.log; 19 import util; 20 21 private enum PGATOR_VERSION = import("current-pgator.version"); 22 private enum PGATOR_BACKEND_VERSION = import("current-pgator-backend.version"); 23 24 /** 25 * Application startup options. The main purpose is 26 * to parse and store options about daemon mode, 27 * configuration file path and some other options that 28 * needed in application startup. 29 * 30 * As the class is immutable, it can be passed between 31 * threads safely. 32 */ 33 immutable class Options 34 { 35 /** 36 * Application $(B args) arguments parsing. 37 * 38 * Options are: daemon or terminal mode, help message 39 * request, configuration file path and request for 40 * default configuration file generation. 41 */ 42 this(string[] args) 43 { 44 bool pDaemon, pHelp, pVersion; 45 string pConfigName, pGenPath; 46 string pPidFile = buildPath("/var/run", APPNAME, APPNAME~".pid"); 47 string pLockFile = buildPath("/var/run", APPNAME, APPNAME~".lock"); 48 49 getopt(args, std.getopt.config.passThrough, 50 "daemon", &pDaemon, 51 "help|h", &pHelp, 52 "config", &pConfigName, 53 "genConfig", &pGenPath, 54 "pidfile", &pPidFile, 55 "lockfile", &pLockFile, 56 "version", &pVersion); 57 58 mDaemon = pDaemon; 59 mHelp = pHelp; 60 mConfigName = pConfigName; 61 mGenPath = pGenPath; 62 mPidFile = pPidFile; 63 mLockFile = pLockFile; 64 mVersion = pVersion; 65 } 66 67 /** 68 * Verbose creation from native D types. 69 * Params: 70 * daemon = is program should start in daemon mode 71 * help = is program should show help message and exit 72 * configName = configuration file name 73 * genPath = is program should generate config at specified path and exit 74 * showVersion = is program should show it version 75 */ 76 this(bool daemon, bool help, string configName, string genPath 77 , string pidFile, string lockFile, bool showVersion) pure nothrow 78 { 79 mDaemon = daemon; 80 mHelp = help; 81 mConfigName = configName; 82 mGenPath = genPath; 83 mPidFile = pidFile; 84 mLockFile = lockFile; 85 mVersion = showVersion; 86 } 87 88 /** 89 * Returns all paths where application should try to find 90 * configuration file. 91 * 92 * Note: Application should use this when and only when 93 * configName is not set. 94 */ 95 InputRange!string configPaths() @property 96 { 97 auto builder = appender!(string[]); 98 builder.put(buildPath("~/.config", APPNAME, DEF_CONF_NAME).expandTilde); 99 100 version(Posix) 101 { 102 builder.put(buildPath("/etc", DEF_CONF_NAME)); 103 } 104 version(Windows) 105 { 106 builder.put(buildPath(".", DEF_CONF_NAME)); 107 } 108 109 return builder.data.inputRangeObject; 110 } 111 112 @property pure nothrow @safe 113 { 114 /// Configuration full file name 115 string configName() 116 { 117 return buildNormalizedPath(mConfigName); 118 } 119 120 /// Path where to generate configuration 121 string genConfigPath() 122 { 123 return buildNormalizedPath(mGenPath); 124 } 125 126 /// Is application should run in daemon mode 127 bool daemon() 128 { 129 return mDaemon; 130 } 131 132 /// Is application should show help message and exit 133 bool help() 134 { 135 return mHelp; 136 } 137 138 /// Path to file where daemon puts it pid 139 string pidFile() 140 { 141 return mPidFile; 142 } 143 144 /// Path to file that checked to no exists in daemon mode 145 string lockFile() 146 { 147 return mLockFile; 148 } 149 150 /// Is program should show it version and exit 151 bool showVersion() 152 { 153 return mVersion; 154 } 155 } 156 157 /// Application help message 158 enum helpMsg = "Server that transforms JSON-RPC calls into SQL queries for PostgreSQL.\n\n" 159 ~ versionMsg ~ "\n" 160 " pgator [arguments]\n" 161 " arguments =\n" 162 " --daemon - runs in daemon mode (detached from tty).\n" 163 " Linux only.\n" 164 " --config=<string> - specifies config file name in\n" 165 " config directory.\n" 166 " --genConfig=<path> - generates default config at the path\n" 167 " --help - prints this message\n" 168 " --pidfile=<path> - specifies path to file where pid is written\n" 169 " to in daemon mode. Default: /var/run/pgator/pgator.pid\n" 170 " --lockfile=<path> - specifies path to file which prevents running\n" 171 " multiple instances in daemon mode.\n" 172 " Default: /var/run/pgator/pgator.lock\n" 173 " --version - shows program version"; 174 175 /// Application version message 176 enum versionMsg = 177 "build-version: " ~ PGATOR_VERSION ~ 178 "backend-version: " ~ PGATOR_BACKEND_VERSION; 179 180 /** 181 * Creates new options with updated configuration $(B path). 182 */ 183 immutable(Options) updateConfigPath(string path) pure nothrow 184 { 185 return new immutable Options(daemon, help, path, genConfigPath, pidFile, lockFile, showVersion); 186 } 187 188 private 189 { 190 enum DEF_CONF_NAME = APPNAME~".conf"; 191 192 bool mDaemon; 193 bool mHelp; 194 bool mVersion; 195 196 string mConfigName; 197 string mGenPath; 198 string mPidFile; 199 string mLockFile; 200 } 201 }