use of org.opensolaris.opengrok.util.OptionParser in project OpenGrok by OpenGrok.
the class Indexer method parseOptions.
/**
* Parse OpenGrok Indexer options
* This method was created so that it would be easier to write unit
* tests against the Indexer option parsing mechanism.
*
* @param argv the command line arguments
* @return array of remaining non option arguments
* @throws ParseException if parsing failed
*/
public static String[] parseOptions(String[] argv) throws ParseException {
String[] usage = { "--help" };
String program = "opengrok.jar";
final String[] ON_OFF = { ON, OFF };
final String[] REMOTE_REPO_CHOICES = { ON, OFF, DIRBASED, UIONLY };
final String[] LUCENE_LOCKS = { ON, OFF, "simple", "native" };
if (argv.length == 0) {
// will force usage output
argv = usage;
status = 1;
}
OptionParser configure = OptionParser.scan(parser -> {
parser.on("-R configPath").Do(cfgFile -> {
try {
cfg = Configuration.read(new File((String) cfgFile));
} catch (IOException e) {
die(e.getMessage());
}
});
});
// An example of how to add a data type for option parsing
OptionParser.accept(WebAddress.class, s -> {
return parseWebAddress(s);
});
openGrok = OptionParser.Do(parser -> {
parser.setPrologue(String.format("\nUsage: java -jar %s [options] [subDir1 [...]]\n", program));
parser.on("-?", "-h", "--help", "Display this usage summary.").Do(v -> {
help = true;
helpUsage = parser.getUsage();
});
parser.on("--detailed", "Display additional help with -h,--help.").Do(v -> {
helpDetailed = true;
});
parser.on("-A (.ext|prefix.):(-|analyzer)", "--analyzer", "/(\\.\\w+|\\w+\\.):(-|[a-zA-Z_0-9.]+)/", "Files with the named prefix/extension should be analyzed", "with the given analyzer, where 'analyzer' may be specified", "using a simple class name (CAnalyzer) or language name (C)", "(Note, analyzer specification is case sensitive)", " Ex: -A .foo:CAnalyzer", " will use the C analyzer for all files ending with .foo", " Ex: -A bar.:C", " will use the C analyzer for all files starting with bar.", " Ex: -A .c:-", " will disable the C analyzer for for all files ending with .c").Do(analyzerSpec -> {
String[] arg = ((String) analyzerSpec).split(":");
String fileSpec = arg[0];
String analyzer = arg[1];
configureFileAnalyzer(fileSpec, analyzer);
});
parser.on("-c", "--ctags", "=/path/to/ctags", "Path to Exuberant or Universal Ctags", "By default takes the Exuberant Ctags in PATH.").Do(ctagsPath -> {
cfg.setCtags((String) ctagsPath);
});
parser.on("-d", "--dataRoot", "=/path/to/data/root", "The directory where OpenGrok stores the generated data.").Do(drPath -> {
File dataRoot = new File((String) drPath);
if (!dataRoot.exists() && !dataRoot.mkdirs()) {
die("Cannot create data root: " + dataRoot);
}
if (!dataRoot.isDirectory()) {
die("Data root must be a directory");
}
try {
cfg.setDataRoot(dataRoot.getCanonicalPath());
} catch (IOException e) {
die(e.getMessage());
}
});
parser.on("--deleteHistory", "=/path/to/repository", "Delete the history cache for the given repository and exit.", "Use '*' to delete the cache for all repositories.").Do(repo -> {
zapCache.add((String) repo);
});
parser.on("--depth", "=number", Integer.class, "Scanning depth for repositories in directory structure relative to", "source root. Default is " + Configuration.defaultScanningDepth + ".").Do(depth -> {
cfg.setScanningDepth((Integer) depth);
});
parser.on("-e", "--economical", "Economical, consumes less disk space.", "It does not generate hyper text cross reference files offline,", "but will do so on demand, which could be sightly slow.").Do(v -> {
cfg.setGenerateHtml(false);
});
parser.on("-G", "--assignTags", "Assign commit tags to all entries in history for all repositories.").Do(v -> {
cfg.setTagsEnabled(true);
});
parser.on("-H", "--history", "=[/path/to/repository]", "Get history for specific repositories (specified as", "absolute path from source root), or ALL repositories", "when none specified.").Do(repo -> {
String repository = (String) repo;
if (repository.equals("")) {
// all repositories
cfg.setHistoryEnabled(true);
} else {
// specific repository
repositories.add((String) repository);
}
});
parser.on("-I", "--include", "=pattern", "Only files matching this pattern will be examined.", "(supports wildcards, example: -I *.java -I *.c)").Do(pattern -> {
cfg.getIncludedNames().add((String) pattern);
});
parser.on("-i", "--ignore", "=pattern", "Ignore the named files (prefixed with 'f:')", "or directories (prefixed with 'd:').", "Supports wildcards (example: -i *.so -i *.dll)").Do(pattern -> {
cfg.getIgnoredNames().add((String) pattern);
});
parser.on("-l", "--lock", "=on|off|simple|native", LUCENE_LOCKS, "Set OpenGrok/Lucene locking mode of the Lucene database", "during index generation. \"on\" is an alias for \"simple\".", "Default is off.").Do(v -> {
try {
if (v != null) {
String vuc = v.toString().toUpperCase(Locale.ROOT);
cfg.setLuceneLocking(LuceneLockName.valueOf(vuc));
}
} catch (IllegalArgumentException e) {
System.err.println(String.format("`--lock %s' is invalid and ignored", v));
}
});
parser.on("--leadingWildCards", "=on|off", ON_OFF, Boolean.class, "Allow or disallow leading wildcards in a search.").Do(v -> {
cfg.setAllowLeadingWildcard((Boolean) v);
});
parser.on("--listRepos", "List all repository paths and exit.").Do(v -> {
listRepos = true;
});
parser.on("-m", "--memory", "=number", Double.class, "Amount of memory that may be used for buffering added documents and", "deletions before they are flushed to the directory (default " + Configuration.defaultRamBufferSize + "MB).", "Please increase JVM heap accordingly, too.").Do(memSize -> {
cfg.setRamBufferSize((Double) memSize);
});
parser.on("--man", "Generate OpenGrok XML manual page.").Do(v -> {
try {
System.out.print(parser.getManPage());
} catch (IOException e) {
System.err.println(e.getMessage());
status = 1;
}
System.exit(status);
});
parser.on("--mandoc", "=/path/to/mandoc", "Path to mandoc(1) binary.").Do(mandocPath -> {
cfg.setMandoc((String) mandocPath);
});
parser.on("-n", "--noIndex", "Do not generate indexes, but process all other command line options.").Do(v -> {
runIndex = false;
});
parser.on("-O", "--optimize", "=on|off", ON_OFF, Boolean.class, "Turn on/off the optimization of the index database", "as part of the indexing step.").Do(v -> {
boolean oldval = cfg.isOptimizeDatabase();
cfg.setOptimizeDatabase((Boolean) v);
if (oldval != cfg.isOptimizeDatabase()) {
optimizedChanged = true;
}
});
parser.on("-o", "--ctagOpts", "=path", "File with extra command line options for ctags.").Do(path -> {
String CTagsExtraOptionsFile = (String) path;
File CTagsFile = new File(CTagsExtraOptionsFile);
if (!(CTagsFile.isFile() && CTagsFile.canRead())) {
die("File '" + CTagsExtraOptionsFile + "' not found for the -o option");
}
System.err.println("INFO: file with extra " + "options for ctags: " + CTagsExtraOptionsFile);
cfg.setCTagsExtraOptionsFile(CTagsExtraOptionsFile);
});
parser.on("-P", "--projects", "Generate a project for each top-level directory in source root.").Do(v -> {
addProjects = true;
cfg.setProjectsEnabled(true);
});
parser.on("-p", "--defaultProject", "=/path/to/default/project", "This is the path to the project that should be selected", "by default in the web application (when no other project", "set either in cookie or in parameter). May be used multiple", "times for several projects. Use \"__all__\" for all projects.", "You should strip off the source root.").Do(v -> {
defaultProjects.add((String) v);
});
parser.on("--profiler", "Pause to await profiler or debugger.").Do(v -> awaitProfiler = true);
parser.on("--progress", "Print per project percentage progress information.", "(I/O extensive, since one read through directory structure is", "made before indexing, needs -v, otherwise it just goes to the log)").Do(v -> {
cfg.setPrintProgress(true);
});
parser.on("-Q", "--quickScan", "=on|off", ON_OFF, Boolean.class, "Turn on/off quick context scan. By default, only the first", "1024k of a file is scanned, and a '[..all..]' link is inserted", "when the file is bigger. Activating this may slow the server down.", "(Note: this is setting only affects the web application)").Do(v -> {
cfg.setQuickContextScan((Boolean) v);
});
parser.on("-q", "--quiet", "Run as quietly as possible.").Do(v -> {
cfg.setVerbose(false);
LoggerUtil.setBaseConsoleLogLevel(Level.WARNING);
});
parser.on("-R /path/to/configuration", "Read configuration from the specified file.").Do(v -> {
// Already handled above. This populates usage.
});
parser.on("-r", "--remote", "=on|off|uionly|dirbased", REMOTE_REPO_CHOICES, "Specify support for remote SCM systems.", " on - allow retrieval for remote SCM systems.", " off - ignore SCM for remote systems.", " uionly - support remote SCM for user interface only.", "dirbased - allow retrieval during history index only for repositories", " which allow getting history for directories.").Do(v -> {
String option = (String) v;
if (option.equalsIgnoreCase(ON)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.ON);
} else if (option.equalsIgnoreCase(OFF)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.OFF);
} else if (option.equalsIgnoreCase(DIRBASED)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.DIRBASED);
} else if (option.equalsIgnoreCase(UIONLY)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.UIONLY);
}
});
parser.on("--renamedHistory", "=on|off", ON_OFF, Boolean.class, "Enable or disable generating history for renamed files.", "If set to on, makes history indexing slower for repositories", "with lots of renamed files.").Do(v -> {
cfg.setHandleHistoryOfRenamedFiles((Boolean) v);
});
parser.on("-S", "--search", "Search for \"external\" source repositories and add them.").Do(v -> {
searchRepositories = true;
});
parser.on("-s", "--source", "=/path/to/source/root", "The root directory of the source tree.").Do(source -> {
File sourceRoot = new File((String) source);
if (!sourceRoot.isDirectory()) {
die("Source root " + sourceRoot + " must be a directory");
}
try {
cfg.setSourceRoot(sourceRoot.getCanonicalPath());
} catch (IOException e) {
die(e.getMessage());
}
});
parser.on("--style", "=path", "Path to the subdirectory in the web-application containing the", "requested stylesheet. The factory-setting is: \"default\".").Do(stylePath -> {
cfg.setWebappLAF((String) stylePath);
});
parser.on("--symlink", "=/path/to/symlink", "Allow this symlink to be followed. Option may be repeated.", "By default only symlinks directly under source root directory", "are allowed.").Do(symlink -> {
allowedSymlinks.add((String) symlink);
});
parser.on("-T", "--threads", "=number", Integer.class, "The number of threads to use for index generation.", "By default the number of threads will be set to the number", "of available CPUs.").Do(threadCount -> {
cfg.setIndexingParallelism((Integer) threadCount);
});
parser.on("-t", "--tabSize", "=number", Integer.class, "Default tab size to use (number of spaces per tab character).").Do(tabSize -> {
cfg.setTabSize((Integer) tabSize);
});
parser.on("-U", "--host", "=host:port", WebAddress.class, "Send the current configuration to the specified address", "(This is most likely the web-app configured with ConfigAddress)").Do(webAddr -> {
WebAddress web = (WebAddress) webAddr;
env = RuntimeEnvironment.getInstance();
host = web.getHost();
port = web.getPort();
env.setConfigHost(host);
env.setConfigPort(port);
});
// For unit test only, will not appear in help
parser.on("---unitTest");
parser.on("--updateConfig", "Populate the webapp with bare configuration and exit.").Do(v -> {
noindex = true;
});
parser.on("--userPage", "=URL", "Base URL of the user Information provider.", "Example: \"http://www.myserver.org/viewProfile.jspa?username=\".", "Use \"none\" to disable link.").Do(v -> {
cfg.setUserPage((String) v);
});
parser.on("--userPageSuffix", "=URL-suffix", "URL Suffix for the user Information provider. Default: \"\".").Do(suffix -> {
cfg.setUserPageSuffix((String) suffix);
});
parser.on("-V", "--version", "Print version and quit.").Do(v -> {
System.out.println(Info.getFullVersion());
System.exit(0);
});
parser.on("-v", "--verbose", "Print progress information as we go along.").Do(v -> {
cfg.setVerbose(true);
LoggerUtil.setBaseConsoleLogLevel(Level.INFO);
});
parser.on("-W", "--writeConfig", "=/path/to/configuration", "Write the current configuration to the specified file", "(so that the web application can use the same configuration)").Do(configFile -> {
configFilename = (String) configFile;
});
parser.on("-w", "--web", "=webapp-context", "Context of webapp. Default is /source. If you specify a different", "name, make sure to rename source.war to that name. Also FULL reindex", "is needed if this is changed.").Do(webContext -> {
String webapp = (String) webContext;
if (webapp.charAt(0) != '/' && !webapp.startsWith("http")) {
webapp = "/" + webapp;
}
if (!webapp.endsWith("/")) {
webapp += "/";
}
cfg.setUrlPrefix(webapp + "s?");
});
});
// Need to read the configuration file first
// so that options may be overwritten later.
configure.parse(argv);
if (cfg == null) {
cfg = new Configuration();
}
// force user to turn on history capture
cfg.setHistoryEnabled(false);
argv = openGrok.parse(argv);
return argv;
}
Aggregations