xref: /OpenGrok/tools/src/main/python/opengrok_tools/utils/indexer.py (revision 5fad5acaa3c98b8c1f20cc5fdf3471d32fc65c1c)
1#!/usr/bin/env python3
2
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# See LICENSE.txt included in this distribution for the specific
10# language governing permissions and limitations under the License.
11#
12# When distributing Covered Code, include this CDDL HEADER in each
13# file and include the License file at LICENSE.txt.
14# If applicable, add the following below this CDDL HEADER, with the
15# fields enclosed by brackets "[]" replaced with your own identifying
16# information: Portions Copyright [yyyy] [name of copyright owner]
17#
18# CDDL HEADER END
19
20#
21# Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
22# Portions Copyright (c) 2017-2018, Chris Fraire <cfraire@me.com>.
23#
24
25
26from .utils import get_command
27from .command import Command
28from .java import Java
29import logging
30
31
32"""
33  opengrok.jar wrapper
34
35  This script can be used to run the OpenGrok indexer.
36"""
37
38
39class Indexer(Java):
40    """
41    Wrapper class to make it easier to execute the OpenGrok indexer.
42    """
43
44    def __init__(self, command, logger=None, java=None, jar='opengrok.jar',
45                 java_opts=None, env_vars=None, doprint=False):
46
47        java_options = []
48        if java_opts:
49            java_options.extend(java_opts)
50        java_options = merge_properties(java_options,
51                                        get_SCM_properties(logger))
52        logger.debug("Java options: {}".format(java_options))
53
54        super().__init__(command, jar=jar, java=java, java_opts=java_options,
55                         logger=logger, env_vars=env_vars, doprint=doprint)
56
57
58def get_SCM_properties(logger):
59    """
60    Return list of Java System properties that contain valid paths to
61    SCM commands.
62    """
63    SCM_COMMANDS = {
64        'bk': '-Dorg.opengrok.indexer.history.BitKeeper',
65        'hg': '-Dorg.opengrok.indexer.history.Mercurial',
66        'cvs': '-Dorg.opengrok.indexer.history.cvs',
67        'svn': '-Dorg.opengrok.indexer.history.Subversion',
68        'sccs': '-Dorg.opengrok.indexer.history.SCCS',
69        'cleartool': '-Dorg.opengrok.indexer.history.ClearCase',
70        'p4': '-Dorg.opengrok.indexer.history.Perforce',
71        'mtn': '-Dorg.opengrok.indexer.history.Monotone',
72        'blame': '-Dorg.opengrok.indexer.history.RCS',
73        'bzr': '-Dorg.opengrok.indexer.history.Bazaar'}
74
75    properties = []
76    for cmd in SCM_COMMANDS.keys():
77        executable = get_command(logger, None, cmd, level=logging.INFO)
78        if executable:
79            properties.append("{}={}".
80                              format(SCM_COMMANDS[cmd], executable))
81
82    return properties
83
84
85def merge_properties(base, extra):
86    """
87    Merge two lists of options (strings in the form of name=value).
88    Take everything from base and add properties from extra
89    (according to names) that are not present in the base.
90    :param base: list of properties
91    :param extra: list of properties
92    :return: merged list
93    """
94
95    extra_prop_names = set(map(lambda x: x.split('=')[0], base))
96
97    ret = set(base)
98    for item in extra:
99        nv = item.split("=")
100        if nv[0] not in extra_prop_names:
101            ret.add(item)
102
103    return list(ret)
104
105
106def FindCtags(logger):
107    """
108    Search for Universal ctags intelligently, skipping over other ctags
109    implementations. Return path to the command or None if not found.
110    """
111    binary = None
112    logger.debug("Trying to find ctags binary")
113    for program in ['universal-ctags', 'ctags']:
114        executable = get_command(logger, None, program, level=logging.DEBUG)
115        if executable:
116            # Verify that this executable is or is Universal Ctags
117            # by matching the output when run with --version.
118            logger.debug("Checking ctags command {}".format(executable))
119            cmd = Command([executable, '--version'], logger=logger)
120            cmd.execute()
121
122            output_str = cmd.getoutputstr()
123            if output_str and output_str.find("Universal Ctags") != -1:
124                logger.debug("Got valid ctags binary: {}".format(executable))
125                binary = executable
126                break
127
128    return binary
129