OpenGrok秒搜代碼,誰用誰Happy。支持多OpenGrok多工程,自動配置腳本,自動更新代碼,自動OpenGrok數據庫,也可以定製Opengrok的解析過濾。
本文僅僅在Ubuntu 14.04下面驗證,請他環境可以參考,但是需要修改下python腳本。
Tools:
- apache-tomcat-9.0.8(github下載地址)
- java-8-openjdk-amd64(官網下載地址)
- opengrok-1.1-rc75(github下載地址)
- ctags(github下載地址)
下載1,2,3的工具並解壓:
android@ubuntu:~/OpenGrok2$ tree -L 1
.
├── apache-tomcat-9.0.8
├── apache-tomcat-9.0.8.tar.gz
├── java-8-openjdk-amd64
├── java-8-openjdk-amd64.zip
├── opengrok-1.1-rc75
└── opengrok-1.1-rc75.tar.gz
3 directories, 3 files
安裝步驟:
1 安裝Ctags
需要安裝最新的universal-ctags。
請直接參考:
https://www.cnblogs.com/zjutzz/p/9393397.html
2 安裝OpenGrok:
解壓下載的opengrok-1.1-rc75得到opengrok_tools.tar.gz
執行下面兩條命令,給opengrok新建python3虛擬環境,並且安裝opengrok。
android@ubuntu:~/OpenGrok2$ python3 -m venv opengrok-tools
android@ubuntu:~/OpenGrok2$ ./opengrok-tools/bin/python -m pip install opengrok-1.1-rc75/tools/opengrok-tools.tar.gz
遇到的問題
錯誤1:
android@ubuntu:~/OpenGrok2$ python3 -m venv opengrok-tools
The virtual environment was not created successfully because ensurepip is not
available. On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.
apt-get install python3-venv
You may need to use sudo with that command. After installing the python3-venv
package, recreate your virtual environment.
android@ubuntu:~/OpenGrok2$
參考https://stackoverflow.com/questions/34271982/install-python3-venv-module-on-linux-mint執行下面的命令解決:
android@ubuntu:~/OpenGrok2$ sudo apt-get install python3.4-venv
錯誤2:
android@ubuntu:~/OpenGrok2$ ./opengrok-tools/bin/python -m pip install opengrok-1.1-rc75/tools/opengrok-tools.tar.gz
Unpacking ./opengrok-1.1-rc75/tools/opengrok-tools.tar.gz
......
File "/home/android/OpenGrok2/opengrok-tools/lib/python3.4/site-packages/pkg_resources.py", line 2093, in load
raise ImportError("%r has no %r attribute" % (entry,attr))
ImportError: <module 'setuptools.dist' from '/home/android/OpenGrok2/opengrok-tools/lib/python3.4/site-packages/setuptools/dist.py'> has no 'check_specifier' attribute
----------------------------------------
Cleaning up...
Command python setup.py egg_info failed with error code 1 in /tmp/pip-6aji3xzi-build
Storing debug log for failure in /home/android/.pip/pip.log
android@ubuntu:~/OpenGrok2$
執行下面命令解決:
android@ubuntu:~/OpenGrok2$ ./opengrok-tools/bin/python -m pip install --upgrade setuptools
3 執行python腳本:
if __name__ == '__main__':
_parser = argparse.ArgumentParser(description='Update or Config a Project for Source Search')
_parser.add_argument("-p", "--project_name", help="Project Name")
_parser.add_argument("-s", "--sync_cmd", help="Sync cmd, like git clone xxx.git, repo sync xxx")
_args = _parser.parse_args()
-p 指定項目名稱
-s 設定項目同步命令
android@ubuntu:~/OpenGrok2$ python UpdateProject.py -p MiniControl -s 'git clone https://gitee.com/lookfuyao/minicontrol.git'
如果有過歷史記錄,也可以直接不帶任何參數。記錄保存在Config.ini裏面。
android@ubuntu:~/OpenGrok2$ python UpdateProject.py
0: sc7731e-9
1: MiniControl
Please Select project:1
Cur Project is: MiniControl
Exe cmd: cd Projects/MiniControl; git clone https://gitee.com/lookfuyao/minicontrol.git
fatal: destination path 'minicontrol' already exists and is not an empty directory.
Exe cmd: cd Projects/MiniControl/minicontrol; git pull
Already up-to-date.
Exe cmd: ./opengrok-tools/bin/opengrok-indexer -j=/home/android/OpenGrok2/java-8-openjdk-amd64/bin/java -a=/home/android/OpenGrok2/opengrok-1.1-rc75/lib/opengrok.jar -- -c /usr/bin/ctags -i d:*.git -i d:*.repo -i f:*.jar -H -P -s /home/android/OpenGrok2/Projects/MiniControl -d /home/android/OpenGrok2/Datas/MiniControl -W /home/android/OpenGrok2/Datas/MiniControl/configuration.xml
Update MiniControl config /home/android/OpenGrok2/Datas/MiniControl/configuration.xml success
Exe cmd: export JRE_HOME=./java-8-openjdk-amd64/jre; ./apache-tomcat-9.0.8/bin/shutdown.sh; ./apache-tomcat-9.0.8/bin/startup.sh &
Using CATALINA_BASE: /home/android/OpenGrok2/apache-tomcat-9.0.8
Using CATALINA_HOME: /home/android/OpenGrok2/apache-tomcat-9.0.8
Using CATALINA_TMPDIR: /home/android/OpenGrok2/apache-tomcat-9.0.8/temp
Using JRE_HOME: ./java-8-openjdk-amd64/jre
Using CLASSPATH: /home/android/OpenGrok2/apache-tomcat-9.0.8/bin/bootstrap.jar:/home/android/OpenGrok2/apache-tomcat-9.0.8/bin/tomcat-juli.jar
android@ubuntu:~/OpenGrok2$ Tomcat started.
可以自己修改下面的執行參數(包括過濾不需要的目錄文件、指定ctags的目錄等):
# open grok indexer
_work_path = os.path.abspath(".")
_cmd = "./opengrok-tools/bin/opengrok-indexer \
-j=%s \
-a=%s -- \
-c %s \
-i %s \
-H -P \
-s %s \
-d %s \
-W %s" % (os.path.join(_work_path, "java-8-openjdk-amd64/bin/java"), # -j java path
os.path.join(_work_path, "opengrok-1.1-rc75/lib/opengrok.jar"), # -a opengrok jar path
"/usr/bin/ctags", # -c ctags path
"d:*.git -i d:*.repo -i f:*.jar", # -i filter files and dirs
os.path.join(_work_path, "Projects", _project_name), # -s Project source path
os.path.join(_work_path, "Datas", _project_name), # -d opengrok generate data
os.path.join(_work_path, "Datas", _project_name, "configuration.xml") # -W cfg for apache
)
腳本內容如下,
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import configparser
import os
import subprocess
import shutil
import time
from xml.dom.minidom import parse
import xml.dom.minidom
CONFIG_FILE = 'Config.ini'
def get_all_projects():
cf = configparser.ConfigParser()
cf.read(CONFIG_FILE)
secs = cf.sections()
return secs
def get_project_sync_cmd(project):
cf = configparser.ConfigParser()
cf.read(CONFIG_FILE)
if cf.has_section(project):
cf.has_option(project, 'sync_cmd')
return cf.get(project, 'sync_cmd')
return None
def set_project_sync_cmd(project, sync_cmd):
if _sync_cmd and (_sync_cmd.startswith("git clone") or _sync_cmd.startswith("repo sync")):
cf = configparser.ConfigParser()
cf.read(CONFIG_FILE)
if not cf.has_section(project):
cf.add_section(project)
cf.set(project, 'sync_cmd', sync_cmd)
cf.write(open(CONFIG_FILE, 'w'))
def restart_apache_tomcat():
cmd = "export JRE_HOME=./java-8-openjdk-amd64/jre; \
./apache-tomcat-9.0.8/bin/shutdown.sh; \
./apache-tomcat-9.0.8/bin/startup.sh &"
exe_cmd(cmd)
def exe_cmd(cmd):
print("Exe cmd: %s" % cmd)
# result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# for info in result.communicate():
# print(info)
os.system(cmd)
if __name__ == '__main__':
_parser = argparse.ArgumentParser(description='Update or Config a Project for Source Search')
_parser.add_argument("-p", "--project_name", help="Project Name")
_parser.add_argument("-s", "--sync_cmd", help="Sync cmd, like git clone xxx.git, repo sync xxx")
_args = _parser.parse_args()
_project_name = _args.project_name
if not _project_name:
_projects = get_all_projects()
if len(_projects) <= 0:
print("Pls set project with options -p")
exit(1)
else:
_index = 0
for _project in _projects:
print("%s: %s" % (_index, _project))
_index = _index + 1
_select = int(input("Please Select project:"))
if 0 <= _select < _index:
_project_name = _projects[_select]
else:
print("Project index error")
exit(2)
print("Cur Project is: %s" % _project_name)
_sync_cmd = _args.sync_cmd
set_project_sync_cmd(_project_name, _sync_cmd)
_project_path = os.path.join('Projects', _project_name)
_sync_cmd = get_project_sync_cmd(_project_name)
if not _sync_cmd:
_sync_cmd = input("Please Set %s Sync cmd (only support git clone xxx.git or repo sync xxx):")
if _sync_cmd:
if _sync_cmd.startswith("git clone") or _sync_cmd.startswith("repo sync"):
set_project_sync_cmd(_project_name, _sync_cmd)
else:
print("Sync cmd is Error!")
exit(3)
else:
print("Sync cmd is empty!")
exit(4)
# init code
if not os.path.exists(_project_path):
os.makedirs(_project_path)
if _sync_cmd.startswith("git clone"):
_sync = "git pull"
else:
_sync = "repo sync"
_cmd = "cd %s; %s " % (_project_path, _sync_cmd)
exe_cmd(_cmd)
# sync code
if _sync.startswith("git pull"):
_cmd = os.listdir(_project_path)[0]
_cmd = "cd %s; git pull" % (os.path.join(_project_path, _cmd))
elif _sync.startswith("repo sync"):
_cmd = "cd %s; repo sync" % _project_path
exe_cmd(_cmd)
# open grok indexer
_work_path = os.path.abspath(".")
_cmd = "./opengrok-tools/bin/opengrok-indexer \
-j=%s \
-a=%s -- \
-c %s \
-i %s \
-H -P \
-s %s \
-d %s \
-W %s" % (os.path.join(_work_path, "java-8-openjdk-amd64/bin/java"), # -j java path
os.path.join(_work_path, "opengrok-1.1-rc75/lib/opengrok.jar"), # -a opengrok jar path
"/usr/bin/ctags", # -c ctags path
"d:*.git -i d:*.repo -i f:*.jar", # -i filter files and dirs
os.path.join(_work_path, "Projects", _project_name), # -s Project source path
os.path.join(_work_path, "Datas", _project_name), # -d opengrok generate data
os.path.join(_work_path, "Datas", _project_name, "configuration.xml") # -W cfg for apache
)
exe_cmd(_cmd)
# create project in apache tomcat
_apache_app_path = os.path.join(os.path.abspath("."), "apache-tomcat-9.0.8/webapps", _project_name + ".war")
if not os.path.exists(_apache_app_path):
_war_path = "opengrok-1.1-rc75/lib/source.war"
shutil.copyfile(_war_path, _apache_app_path)
restart_apache_tomcat()
time.sleep(3)
# set the project configuration.xml to apache tomcat
_apache_app_config = os.path.join(os.path.join(os.path.abspath("."), "apache-tomcat-9.0.8/webapps", _project_name),
"WEB-INF", "web.xml")
_wait_time = 0
while not os.path.exists(_apache_app_config):
if _wait_time > 10:
print("Cannot find apache tomcat app=%s config_path=%s error!" % (_project_name, _apache_app_config))
exit(6)
_wait_time = _wait_time + 1
time.sleep(3)
_tree = xml.dom.minidom.parse(_apache_app_config)
_nodes = _tree.documentElement.getElementsByTagName('context-param')
for _node in _nodes:
_cfgNode = _node.getElementsByTagName('param-value')
if _cfgNode:
_value = os.path.join(_work_path, "Datas", _project_name, "configuration.xml")
_cfgNode[0].childNodes[0].data = _value
print("Update %s config %s success" % (_project_name, _value))
with open(_apache_app_config, 'w') as fh:
_tree.writexml(fh)
break
restart_apache_tomcat()
瀏覽器打開下面地址即可搜索代碼(xxx替換爲自己的項目名稱):
局域網的其他人也可以訪問,把localhost換成自己的ip既可。