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 module dextool.plugin.analyze.raw_config; 11 12 import logger = std.experimental.logger; 13 14 /** Handle parsing of user arguments. 15 16 For a simple plugin this is overly complex. But a plugin very seldom stays 17 simple. By keeping the user input parsing and validation separate from the rest 18 of the program it become more robust to future changes. 19 */ 20 struct RawConfiguration { 21 import std.getopt : GetoptResult, getopt, defaultGetoptPrinter; 22 23 bool help; 24 bool errorHelp; 25 bool shortPluginHelp; 26 bool mccabe; 27 bool outputJson; 28 bool outputStdout; 29 int mccabeThreshold = 5; 30 int workerThreads = -1; 31 string outdir = "."; 32 string restrictDir = "."; 33 string[] cflags; 34 string[] compileDb; 35 string[] files; 36 37 private GetoptResult help_info; 38 39 void parse(string[] args) @safe { 40 static import std.getopt; 41 42 try { 43 // getopt is safe in newer versions than 2.071.1 44 // remove this trusted wrapper there. 45 // dfmt off 46 () @trusted { 47 help_info = getopt(args, std.getopt.config.keepEndOfOptions, 48 "short-plugin-help", "short description of the plugin", &shortPluginHelp, 49 "threads", "number of worker threads to use (default: detected CPU cores)", &workerThreads, 50 "compile-db", "Retrieve compilation parameters from the file", &compileDb, 51 "output-json", "Write the analyze result to json file(s)", &outputJson, 52 "output-stdout", "Write the analyze result to stdout", &outputStdout, 53 "restrict", "Restrict analyze of files to those in this directory tree (default: .)", &restrictDir, 54 "mccabe", "Calculate the McCabe complexity of functions and files", &mccabe, 55 "mccabe-threshold", "Threshold that must be reached for the McCabe value to be reported (default: 5)", &mccabeThreshold, 56 "out", "directory to write result files to (default: .)", &outdir, 57 "in", "Input file to parse", &files, 58 ); 59 }(); 60 // dfmt on 61 help = help_info.helpWanted; 62 } catch (std.getopt.GetOptException ex) { 63 logger.error(ex.msg); 64 errorHelp = true; 65 } 66 67 import std.algorithm : find; 68 import std.array : array; 69 import std.range : drop; 70 71 // at this point args contain "what is left". What is interesting then is those after "--". 72 cflags = args.find("--").drop(1).array(); 73 74 if (!shortPluginHelp) { 75 // DMD-2.075.0 76 // workaround because the log is funky. those from 77 // application.plugin.toPlugin aren't "flushed". It think it is 78 // because pipeProcess uses linux pipes and this somehow interacts 79 // badly with std.experimental.logger; 80 debug logger.trace(""); 81 82 debug logger.trace(this); 83 } 84 } 85 86 void printHelp() @trusted { 87 import std.stdio : writeln; 88 89 defaultGetoptPrinter("Usage: dextool analyze [options] [--in=] [-- CFLAGS...]", 90 help_info.options); 91 } 92 }