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