1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 10 This file contains an optional main function suitable for plugins. 11 12 It takes care of configuring the logging level in std.experimental.logger if 13 the user call the program with "-d|--debug". 14 15 This optional main function requires that: 16 - the module is named dextool.plugin.runner 17 - the module provides a function runPlugin that takes the program arguments. 18 */ 19 module dextool.plugin.main.standard; 20 21 import logger = std.experimental.logger; 22 import std.algorithm : filter, among, findAmong, canFind, sort; 23 import std.array : array, empty, appender; 24 import std.conv : to; 25 import std.stdio : writeln; 26 27 import colorlog : VerboseMode, confLogger, setLogLevel, toLogLevel, RootLogger, 28 SpanMode, getRegisteredLoggers, parseLogNames, NameLevel; 29 30 /** Parse the raw command line. 31 */ 32 VerboseMode parseLogLevel(string[] args) { 33 import std.traits : EnumMembers; 34 35 if (!findAmong(args, ["-d", "--debug"]).empty) 36 return VerboseMode.trace; 37 38 auto verbose = findAmong(args, ["--verbose"]); 39 try { 40 if (verbose.length >= 2) 41 return verbose[1].to!VerboseMode; 42 } catch (Exception e) { 43 logger.warning(e.msg); 44 logger.info("--verbose supports ", [EnumMembers!VerboseMode]); 45 } 46 47 return VerboseMode.info; 48 } 49 50 NameLevel[] parseLogModules(string[] args, logger.LogLevel defaultLogLvl) { 51 auto modules = findAmong(args, ["--verbose-module"]); 52 try { 53 if (modules.length >= 2) 54 return parseLogNames(modules[1], defaultLogLvl); 55 } catch (Exception e) { 56 logger.info(e.msg); 57 } 58 59 return [NameLevel(RootLogger, defaultLogLvl)]; 60 } 61 62 int main(string[] args) { 63 if (canFind(args, "--short-plugin-help")) { 64 confLogger(VerboseMode.warning); 65 setLogLevel(RootLogger, logger.LogLevel.warning, SpanMode.depth); 66 } else { 67 const mode = parseLogLevel(args); 68 confLogger(mode); 69 70 const modules = parseLogModules(args, toLogLevel(mode)); 71 try { 72 if (modules.empty) 73 setLogLevel([RootLogger], toLogLevel(mode), SpanMode.depth); 74 else 75 setLogLevel(modules, SpanMode.depth); 76 } catch (Exception e) { 77 logger.info(e.msg); 78 logger.info("--verbose-module supports ", getRegisteredLoggers.sort); 79 logger.info("Use comma to separate name=logLevel"); 80 } 81 } 82 83 auto remArgs = appender!(string[])(); 84 for (size_t i = 0; i < args.length; ++i) { 85 if (args[i].among("-d", "--debug")) { 86 // skip one 87 } else if (args[i].among("--verbose", "--verbose-module")) { 88 ++i; //skip two 89 } else { 90 remArgs.put(args[i]); 91 } 92 } 93 94 // REQUIRED BY PLUGINS USING THIS MAIN 95 import dextool.plugin.runner : runPlugin; 96 97 return runPlugin(remArgs.data); 98 }