diff --git a/404.html b/404.html new file mode 100644 index 000000000..555099b10 --- /dev/null +++ b/404.html @@ -0,0 +1,33 @@ + + +
+ + + + + +Error Prone是google开源的Java编译时检测工具,将常见的Java错误捕获为编译时错误,增强对java代码的类型分析,从而让开发人员及时发现问题
TCA原有编译时检测工具JavaWarning获取java代码编译时的告警信息,现集成Error Prone规则至JavaWarning工具以增加获取Error Prone的错误告警信息。
',5),m=e("li",null,"在规则包中添加JavaWarning工具的Error Prone规则(可通过规则解决方法进行区分);",-1),p=e("li",null,"客户端启动分析,在TCA Web页面上查看问题。",-1),g=e("h2",{id:"error-prone-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#error-prone-配置","aria-hidden":"true"},"#"),r(" Error Prone 配置")],-1),b=e("h3",{id:"通过bazel构建",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#通过bazel构建","aria-hidden":"true"},"#"),r(" 通过Bazel构建")],-1),h=e("li",null,[r("Bazel在构建java项目时,默认打开了Error Prone,所以在本地配置Bazel环境,编写Bazel构建文件,"),e("code",null,"bazel build :project"),r("构建项目即可。")],-1),_={href:"https://bazel.build/?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"},E=a(`编辑pom.xml文件将设置添加到maven-compiler-plugin,例如:
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ <encoding>UTF-8</encoding>
+ <compilerArgs>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>-Xplugin:ErrorProne</arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>\${error-prone.version}</version>
+ </path>
+ <!-- Other annotation processors go here.
+
+ If 'annotationProcessorPaths' is set, processors will no longer be
+ discovered on the regular -classpath; see also 'Using Error Prone
+ together with other annotation processors' below. -->
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
对于JDK 16
或更高的版本,需要将以下内容--add-exports
和--add-opens
标志添加到.mvn/jvm.config
文件中:
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+
###命令行 Error Prone 支持com.sun.source.util.Plugin
API,并且可以通过将 Error Prone 添加到-processorpath
并设置-Xplugin
标志来与JDK 9
及更高版本一起使用:
wget https://repo1.maven.org/maven2/com/google/errorprone/error_prone_core/\${EP_VERSION?}/error_prone_core-\${EP_VERSION?}-with-dependencies.jar
+wget https://repo1.maven.org/maven2/org/checkerframework/dataflow-errorprone/3.15.0/dataflow-errorprone-3.15.0.jar
+javac \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \\
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \\
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \\
+ -XDcompilePolicy=simple \\
+ -processorpath error_prone_core-\${EP_VERSION?}-with-dependencies.jar:dataflow-errorprone-3.15.0.jar \\
+ '-Xplugin:ErrorProne -XepDisableAllChecks -Xep:CollectionIncompatibleType:ERROR' \\
+ Example.java
+
Error Prone是google开源的Java编译时检测工具,将常见的Java错误捕获为编译时错误,增强对java代码的类型分析,从而让开发人员及时发现问题
TCA原有编译时检测工具JavaWarning获取java代码编译时的告警信息,现集成Error Prone规则至JavaWarning工具以增加获取Error Prone的错误告警信息。
',5),m=e("li",null,"在规则包中添加JavaWarning工具的Error Prone规则(可通过规则解决方法进行区分);",-1),p=e("li",null,"客户端启动分析,在TCA Web页面上查看问题。",-1),g=e("h2",{id:"error-prone-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#error-prone-配置","aria-hidden":"true"},"#"),r(" Error Prone 配置")],-1),b=e("h3",{id:"通过bazel构建",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#通过bazel构建","aria-hidden":"true"},"#"),r(" 通过Bazel构建")],-1),h=e("li",null,[r("Bazel在构建java项目时,默认打开了Error Prone,所以在本地配置Bazel环境,编写Bazel构建文件,"),e("code",null,"bazel build :project"),r("构建项目即可。")],-1),_={href:"https://bazel.build/?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"},E=a(`编辑pom.xml文件将设置添加到maven-compiler-plugin,例如:
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ <encoding>UTF-8</encoding>
+ <compilerArgs>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>-Xplugin:ErrorProne</arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>\${error-prone.version}</version>
+ </path>
+ <!-- Other annotation processors go here.
+
+ If 'annotationProcessorPaths' is set, processors will no longer be
+ discovered on the regular -classpath; see also 'Using Error Prone
+ together with other annotation processors' below. -->
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
对于JDK 16
或更高的版本,需要将以下内容--add-exports
和--add-opens
标志添加到.mvn/jvm.config
文件中:
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+
###命令行 Error Prone 支持com.sun.source.util.Plugin
API,并且可以通过将 Error Prone 添加到-processorpath
并设置-Xplugin
标志来与JDK 9
及更高版本一起使用:
wget https://repo1.maven.org/maven2/com/google/errorprone/error_prone_core/\${EP_VERSION?}/error_prone_core-\${EP_VERSION?}-with-dependencies.jar
+wget https://repo1.maven.org/maven2/org/checkerframework/dataflow-errorprone/3.15.0/dataflow-errorprone-3.15.0.jar
+javac \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \\
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \\
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \\
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \\
+ -XDcompilePolicy=simple \\
+ -processorpath error_prone_core-\${EP_VERSION?}-with-dependencies.jar:dataflow-errorprone-3.15.0.jar \\
+ '-Xplugin:ErrorProne -XepDisableAllChecks -Xep:CollectionIncompatibleType:ERROR' \\
+ Example.java
+
如果在执行pip install
环节出现以下错误,可以调整一下镜像源:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='files.pythonhosted. org', port=443): Read timed out.(read timeout=15)") '
+
该错误是访问官方pypi
下载源时网络不通或者不稳定导致,可以通过以下方式调整:
本地部署时,调整pypi
下载源配置方式:
mkdir ~/.pip/
+echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
Docker-Compose部署时,调整pypi
下载源配置方式:
vi server/dockerconfs/Dockerfile-common
+
调整文件中最后一行 RUN
指令
RUN mkdir -p log/ && \\
+ mkdir ~/.pip/ && \\
+ echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf && \\
+ pip install -U setuptools pip && \\
+ pip install -r requirements.txt
+
注:如果需要指定其他pypi
下载源,可以将https://mirrors.cloud.tencent.com/pypi/simple
进行替换
如果出现以下错误:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f6d4ac24910>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/setuptools/
+
该错误是无法正常解析pypi
访问域名,需要检查一下本地的dns配置是否正常
TCA Server使用Docker-Compose依赖的Docker版本需要是1.13.0
及以上,可以执行以下命令查看Docker版本
$ docker --version
+Docker version 18.09.7, build 2d0083d
+
文档相关:
`,20),f={href:"https://docs.docker.com/compose/compose-file/compose-versioning/",target:"_blank",rel:"noopener noreferrer"},x={href:"https://docs.docker.com/engine/install/centos/",target:"_blank",rel:"noopener noreferrer"},y={href:"https://docs.docker.com/engine/install/ubuntu/",target:"_blank",rel:"noopener noreferrer"},k=c(`如果启动Docker-Compose输出以下错误:
* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+
问题原因:可能镜像构建目录权限不足,导致异常。 解决方案:
docker-compose build
可以通过日志查看是哪个镜像构建异常docker build .
可以看到详细错误信息,结合具体错误信息进行处理文档相关:
`,6),E={href:"https://docs.docker.com/compose/install/",target:"_blank",rel:"noopener noreferrer"},R={href:"https://docs.docker.com/compose/cli-command/",target:"_blank",rel:"noopener noreferrer"},C=c(`目前TCA基础镜像是使用python:3.7.12-slim
,该镜像是基于debian bullseye(debian 11)
版本构建的,对应的源需要选择 bullseye
版本的源。
如果使用默认的下载源会报错或访问速度比较慢,可以调整server/dockerconfs/Dockerfile-common
,指定其他国内下载源:
# FROM python:3.7.12-slim
+
+# 增加一下内容用于指定下载源
+RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \\
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye main non-free contrib' > /etc/apt/sources.list && \\
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list && \\
+ echo 'deb http://mirrors.tencent.com/debian-security bullseye-security main non-free contrib' >> /etc/apt/sources.list
+
+# ARG EXTRA_TOOLS=...
+
如果出现以下错误:E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages
可以做以下检查,确认是什么原因:
使用Python执行时提示ImportError: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory
,该如何处理
在本地安装Python的目录中查找该文件,比如Python的安装目录是/usr/local/python3
,可以执行find /usr/local/python3 -name "libpython3.7m.so.1.0"
,确认本地是否存在该文件
如果本地存在该文件,则执行以下命令:(注:需要将/usr/local/python3
调整为本地实际的Python3安装路径)
# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
如果本地不存在该文件,则可能需要重新安装Python3:(注:以下是将Python安装到/usr/local/python3
,可以根据实际情况进行调整)
# 编译前配置,注意重点:需要加上参数 --enable-shared
+$ ./configure prefix=/usr/local/python3 --enable-shared
+
文档相关:
`,10),T={href:"https://github.com/Tencent/CodeAnalysis/blob/main/doc/references/install_python37_on_centos.md",target:"_blank",rel:"noopener noreferrer"},D={href:"https://github.com/Tencent/CodeAnalysis/blob/main/doc/references/install_python37_on_ubuntu.md",target:"_blank",rel:"noopener noreferrer"},j=c(`compose_init.sh
脚本的pip install
提示sha256
不匹配错误在构建镜像的pip install
步骤提示以下报错时:
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
+ setuptools from https://mirrors.cloud.tencent.com/pypi/packages/fb/58/9efbfe68482dab9557c49d433a60fff9efd7ed8835f829eba8297c2c124a/setuptools-62.1.0-py3-none-any.whl#sha256=26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8:
+ Expected sha256 26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8
+ Got ddaacc49de5c08c09d744573240a9a49f24f65c5c72380e972433784caa68d98
+
可以执行export ORIGIN=normal
,然后再执行./compose_init.sh
注:执行
export
命令的作用是调整为pypi
默认官方下载源进行pip install
在M1机器上使用默认配置启动docker-compose,会出现mysql
和scmproxy
服务启动失败,需要做以下两步调整
调整docker-compose.yml
文件,修改MySQL的镜像版本:
# 默认:
+image: mysql:5.7.24
+
+# 调整后:
+image: mariadb:10.5.8
+
调整server/dockerconfs/Dockerfile-common
文件,修改Python的镜像版本:
# 默认:
+FROM python:3.7.12-slim
+
+# 调整后:
+FROM amd64/python:3.7.12-slim
+
如果启动服务时,提示:celery could not be found
或gunicorn could not be found
,需要做以下检查
python -v
检查输出,确认当前python版本是否为python3.7pip install celery
和pip install gunicorn
检查celery和gunicorn是否已经安装/usr/local/python3
调整为本地实际的Python3安装路径)ln -s /usr/local/python3/bin/gunicorn /usr/local/bin/gunicorn
+ln -s /usr/local/python3/bin/celery /usr/local/bin/celery
+
TCA 本地部署启动后,会监听多个端口:
如果出现端口占用冲突,建议采用以下方式解决:
不推荐调整TCA指定服务的端口号,需要调整多处配置,以及可能会影响到后续服务的升级
本地部署输出的日志位置:
main
服务输出的日志目录:server/projects/main/log
server/projects/main/log/gunicorn_error.log
server/projects/main/log/gunicorn_access.log
server/projects/main/nohup_worker.out
server/projects/main/nohup_beat.out
server/projects/main/log/codedog.log
server/projects/main/log/main_celery.log
server/projects/main/log/main_beat.log
analysis
服务输出的日志目录:server/projects/analysis/log
server/projects/analysis/log/gunicorn_error.log
server/projects/analysis/nohup.out
server/projects/analysis/log/gunicorn_access.log
server/projects/analysis/log/codedog.log
server/projects/analysis/log/celery.log
login
服务输出的日志目录:server/projects/login/log
server/projects/login/log/gunicorn_error.log
server/projects/login/log/gunicorn_access.log
server/projects/login/log/codedog.log
file
服务输出的日志目录:server/projects/file/log
server/projects/file/log/gunicorn_error.log
server/projects/file/log/gunicorn_access.log
server/projects/file/log/codedog_file.log
scmproxy
服务输出的日志目录:server/projects/scmproxy/logs
server/projects/scmproxy/nohup.out
server/projects/scmproxy/logs/scmproxy.log
默认账号: CodeDog
,密码: admin
默认Token是0712b895f30c5e958ec71a7c22e1b1a2ad1d5c6b
如果在平台上刷新了CodeDog
用户的Token,需要将刷新后的Token填写到以下文件中:
server/scripts/config.sh
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)server/dockerconfs/.env.local
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)然后重启服务。
本地部署:
cd server/
+./scripts/deploy.sh start
+
docker-compose部署:
$ docker-compose stop
+# 稍等片刻
+$ docker-compose up -d
+
该错误出现可能有以下几个原因:
`,33),S=e("li",null,"账号密码不准确或登记的代码库地址不存在",-1),N=e("code",null,"github",-1),A={href:"https://github.com/settings/tokens",target:"_blank",rel:"noopener noreferrer"},O=e("code",null,"personal access token",-1),L=c("ps aux | grep proxyserver
看看是否有python proxyserver.py
执行进程,如果不存在可以看一下server/projects/scmproxy/nohup.out
看看启动失败的原因docker-compose ps
看看scmproxy
容器是否正常启动,如果没有启动,可以执行docker-compose logs scmproxy
看看启动失败的原因git clone xxxx
(xxx表示待登记的代码库),检查看看是否能够正常拉取unknown option `local`
错误 1.8.3.1
出现该提示的原因是,代码库偏大或clone
代码库时间较长,可以稍等一会再刷新重试
method(upload_file) call fails on error: Expecting value: line 1 column 1 (char 0)
出现这种错误,可能是本地配置异常或token配置有问题,检查方式如下:
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
如果xxx不一致需要调整为一致
注: xxx地址与在浏览器访问平台的xxx地址是一致的,不需要区分端口
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
检查当前在codedog.ini
-[config]token
与config.ini
文件配置的[FILE_SERVER]TOKEN
是否一致,如果不一致需要调整为一致
检查用户CodeDog
的Token
是否被刷新了然后没有更新到配置文件中
Connection timed out
本地客户端执行过程提示method (upload file) call fails on error: <urlopen error [Errno 110] Connection timed out>
该如何处理? 一般情况下,这个问题是客户端与Server之间网络不通导致,可以检查一下是否有防火墙限制或者配置的URL是内部IP或地址,可以通过以下方式检查
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
出现该错误提示,一般是访问文件器出错或文件服务器本身有问题,可以通过以下方式检查: 需要检查analysis-worker
的日志(本地部署:server/projects/analysis/log/celery.log
,docker-compose部署:docker-compose exec analysis-worker /bin/bash
进入容器后访问log/celery.log
查看具体错误原因
如果提示no route to host
可能是当前机器/容器无法访问当前宿主机的IP,可以检查一下当前防火墙的设置,是否限制了analysis-worker
来源的访问
出现该错误提示,一般是Server未进行初始化,可以通过执行以下命令初始化后再启动测试
cd server && ./scripts/deploy.sh init
./compose_init.sh
为防止国内用户访问CodeAnalysis Github首页时图片资源加载失败,目前各个md文件中的图片资源引用地址调整增加了URL前缀https://tencent.github.io/CodeAnalysis/
。
用户下载代码库到本地后,发现无法访问资源文件时,请检查本地网络是否能够连通外网,如果无法连通外网,可以在文档引入资源地址中进行相对路径替换,调整各个资源文件的链接。
对于根目录下的md文件,直接删除URL前缀即可:
例如在https://tencent.github.io/CodeAnalysis/media/homepage.png
这个链接可以调整为media/homepage.png
对于其他目录下的md文件,删除URL前缀后,需调整文件相对路径链接:
例如对于doc/client.md
, 需将https://tencent.github.io/CodeAnalysis/media/clientConfigIni.png
这个链接调整为../media/clientConfigIni.png
如果在执行pip install
环节出现以下错误,可以调整一下镜像源:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='files.pythonhosted. org', port=443): Read timed out.(read timeout=15)") '
+
该错误是访问官方pypi
下载源时网络不通或者不稳定导致,可以通过以下方式调整:
本地部署时,调整pypi
下载源配置方式:
mkdir ~/.pip/
+echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
Docker-Compose部署时,调整pypi
下载源配置方式:
vi server/dockerconfs/Dockerfile-common
+
调整文件中最后一行 RUN
指令
RUN mkdir -p log/ && \\
+ mkdir ~/.pip/ && \\
+ echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf && \\
+ pip install -U setuptools pip && \\
+ pip install -r requirements.txt
+
注:如果需要指定其他pypi
下载源,可以将https://mirrors.cloud.tencent.com/pypi/simple
进行替换
如果出现以下错误:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f6d4ac24910>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/setuptools/
+
该错误是无法正常解析pypi
访问域名,需要检查一下本地的dns配置是否正常
TCA Server使用Docker-Compose依赖的Docker版本需要是1.13.0
及以上,可以执行以下命令查看Docker版本
$ docker --version
+Docker version 18.09.7, build 2d0083d
+
文档相关:
`,20),f={href:"https://docs.docker.com/compose/compose-file/compose-versioning/",target:"_blank",rel:"noopener noreferrer"},x={href:"https://docs.docker.com/engine/install/centos/",target:"_blank",rel:"noopener noreferrer"},y={href:"https://docs.docker.com/engine/install/ubuntu/",target:"_blank",rel:"noopener noreferrer"},k=c(`如果启动Docker-Compose输出以下错误:
* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+
问题原因:可能镜像构建目录权限不足,导致异常。 解决方案:
docker-compose build
可以通过日志查看是哪个镜像构建异常docker build .
可以看到详细错误信息,结合具体错误信息进行处理文档相关:
`,6),E={href:"https://docs.docker.com/compose/install/",target:"_blank",rel:"noopener noreferrer"},R={href:"https://docs.docker.com/compose/cli-command/",target:"_blank",rel:"noopener noreferrer"},C=c(`目前TCA基础镜像是使用python:3.7.12-slim
,该镜像是基于debian bullseye(debian 11)
版本构建的,对应的源需要选择 bullseye
版本的源。
如果使用默认的下载源会报错或访问速度比较慢,可以调整server/dockerconfs/Dockerfile-common
,指定其他国内下载源:
# FROM python:3.7.12-slim
+
+# 增加一下内容用于指定下载源
+RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \\
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye main non-free contrib' > /etc/apt/sources.list && \\
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list && \\
+ echo 'deb http://mirrors.tencent.com/debian-security bullseye-security main non-free contrib' >> /etc/apt/sources.list
+
+# ARG EXTRA_TOOLS=...
+
如果出现以下错误:E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages
可以做以下检查,确认是什么原因:
使用Python执行时提示ImportError: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory
,该如何处理
在本地安装Python的目录中查找该文件,比如Python的安装目录是/usr/local/python3
,可以执行find /usr/local/python3 -name "libpython3.7m.so.1.0"
,确认本地是否存在该文件
如果本地存在该文件,则执行以下命令:(注:需要将/usr/local/python3
调整为本地实际的Python3安装路径)
# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
如果本地不存在该文件,则可能需要重新安装Python3:(注:以下是将Python安装到/usr/local/python3
,可以根据实际情况进行调整)
# 编译前配置,注意重点:需要加上参数 --enable-shared
+$ ./configure prefix=/usr/local/python3 --enable-shared
+
文档相关:
`,10),L={href:"https://github.com/Tencent/CodeAnalysis/blob/main/doc/references/install_python37_on_centos.md",target:"_blank",rel:"noopener noreferrer"},S={href:"https://github.com/Tencent/CodeAnalysis/blob/main/doc/references/install_python37_on_ubuntu.md",target:"_blank",rel:"noopener noreferrer"},T=c(`compose_init.sh
脚本的pip install
提示sha256
不匹配错误在构建镜像的pip install
步骤提示以下报错时:
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
+ setuptools from https://mirrors.cloud.tencent.com/pypi/packages/fb/58/9efbfe68482dab9557c49d433a60fff9efd7ed8835f829eba8297c2c124a/setuptools-62.1.0-py3-none-any.whl#sha256=26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8:
+ Expected sha256 26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8
+ Got ddaacc49de5c08c09d744573240a9a49f24f65c5c72380e972433784caa68d98
+
可以执行export ORIGIN=normal
,然后再执行./compose_init.sh
注:执行
export
命令的作用是调整为pypi
默认官方下载源进行pip install
在M1机器上使用默认配置启动docker-compose,会出现mysql
和scmproxy
服务启动失败,需要做以下两步调整
调整docker-compose.yml
文件,修改MySQL的镜像版本:
# 默认:
+image: mysql:5.7.24
+
+# 调整后:
+image: mariadb:10.5.8
+
调整server/dockerconfs/Dockerfile-common
文件,修改Python的镜像版本:
# 默认:
+FROM python:3.7.12-slim
+
+# 调整后:
+FROM amd64/python:3.7.12-slim
+
如果启动服务时,提示:celery could not be found
或gunicorn could not be found
,需要做以下检查
python -v
检查输出,确认当前python版本是否为python3.7pip install celery
和pip install gunicorn
检查celery和gunicorn是否已经安装/usr/local/python3
调整为本地实际的Python3安装路径)ln -s /usr/local/python3/bin/gunicorn /usr/local/bin/gunicorn
+ln -s /usr/local/python3/bin/celery /usr/local/bin/celery
+
使用docker方式部署项目时,提示
fatal: 无法访问 'https://git.code.tencent.com/TCA/tca-tools/tca_lib.git/': URL using bad/illegal format or missing URL.
+Download lib failed
+
该如何处理。
出错原因可能是Windows系统、和macOs系统、linux系统的行分隔符不同,可以先查看当前文件的换行符是 CRLF 还是LF, 如果要部署在Windows系统系统上,行分隔符应该为CRLF格式,部署在linux和macOS系统预期是LF格式,如果不一致需要进行手动修改。
修改方式可以选择: 1、使用pycharm打开项目,依次点击”File”->”Settings”->”Editor”->”Code Style”->”General” 在面板中,可以找到”Line separator”选项,根据要部署的系统选择行分隔符格式。 2、也可以使用dos2unix、unix2dos等转换命令,例如从Windows系统打包到Linux系统,当前行分隔符为CRLF,需要对脚本执行 dos2unix fileName
指令进行转换 ,注意使用该指令前需要先进行安装。
完成以上操作之后再对代码进行打包,即可部署运行。
TCA 本地部署启动后,会监听多个端口:
如果出现端口占用冲突,建议采用以下方式解决:
不推荐调整TCA指定服务的端口号,需要调整多处配置,以及可能会影响到后续服务的升级
本地部署输出的日志位置:
main
服务输出的日志目录:server/projects/main/log
server/projects/main/log/gunicorn_error.log
server/projects/main/log/gunicorn_access.log
server/projects/main/nohup_worker.out
server/projects/main/nohup_beat.out
server/projects/main/log/codedog.log
server/projects/main/log/main_celery.log
server/projects/main/log/main_beat.log
analysis
服务输出的日志目录:server/projects/analysis/log
server/projects/analysis/log/gunicorn_error.log
server/projects/analysis/nohup.out
server/projects/analysis/log/gunicorn_access.log
server/projects/analysis/log/codedog.log
server/projects/analysis/log/celery.log
login
服务输出的日志目录:server/projects/login/log
server/projects/login/log/gunicorn_error.log
server/projects/login/log/gunicorn_access.log
server/projects/login/log/codedog.log
file
服务输出的日志目录:server/projects/file/log
server/projects/file/log/gunicorn_error.log
server/projects/file/log/gunicorn_access.log
server/projects/file/log/codedog_file.log
scmproxy
服务输出的日志目录:server/projects/scmproxy/logs
server/projects/scmproxy/nohup.out
server/projects/scmproxy/logs/scmproxy.log
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
config.ini
文件和codedog.ini
文件是否按照json格式正确填写config.ini
文件中的 【SERVER_URL】
已正确填写,则检查codedog.ini
文件中是否有填写codedog_env
配置项。如果有填写,往往因为填写有误(比如URL缺少最后的/
)导致报错。建议直接删除codedog.ini
文件的codedog_env
配置项(config.ini
已配置【SERVER_URL】
,无需重复配置),再尝试重启服务。默认账号: CodeDog
,密码: admin
默认Token是0712b895f30c5e958ec71a7c22e1b1a2ad1d5c6b
如果在平台上刷新了CodeDog
用户的Token,需要将刷新后的Token填写到以下文件中:
server/scripts/config.sh
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)server/dockerconfs/.env.local
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)然后重启服务。
本地部署:
cd server/
+./scripts/deploy.sh start
+
docker-compose部署:
$ docker-compose stop
+# 稍等片刻
+$ docker-compose up -d
+
该错误出现可能有以下几个原因:
`,42),D=e("li",null,"账号密码不准确或登记的代码库地址不存在",-1),j=e("code",null,"github",-1),N={href:"https://github.com/settings/tokens",target:"_blank",rel:"noopener noreferrer"},A=e("code",null,"personal access token",-1),O=c("ps aux | grep proxyserver
看看是否有python proxyserver.py
执行进程,如果不存在可以看一下server/projects/scmproxy/nohup.out
看看启动失败的原因docker-compose ps
看看scmproxy
容器是否正常启动,如果没有启动,可以执行docker-compose logs scmproxy
看看启动失败的原因git clone xxxx
(xxx表示待登记的代码库),检查看看是否能够正常拉取unknown option `local`
错误 1.8.3.1
该错误出现可能有以下几个原因:
.docker_temp/configs/config.sh
, 将HTTPS_CLONE_FLAG调整为false, 然后重启容器docker restart tca-services
出现该提示的原因是,代码库偏大或clone
代码库时间较长,可以稍等一会再刷新重试
method(upload_file) call fails on error: Expecting value: line 1 column 1 (char 0)
出现这种错误,可能是本地配置异常或token配置有问题,检查方式如下:
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
如果xxx不一致需要调整为一致
注: xxx地址与在浏览器访问平台的xxx地址是一致的,不需要区分端口
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
检查当前在codedog.ini
-[config]token
与config.ini
文件配置的[FILE_SERVER]TOKEN
是否一致,如果不一致需要调整为一致
检查用户CodeDog
的Token
是否被刷新了然后没有更新到配置文件中
Connection timed out
本地客户端执行过程提示method (upload file) call fails on error: <urlopen error [Errno 110] Connection timed out>
该如何处理? 一般情况下,这个问题是客户端与Server之间网络不通导致,可以检查一下是否有防火墙限制或者配置的URL是内部IP或地址,可以通过以下方式检查
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
出现该错误提示,一般是访问文件器出错或文件服务器本身有问题,可以通过以下方式检查: 需要检查analysis-worker
的日志(本地部署:server/projects/analysis/log/celery.log
,docker-compose部署:docker-compose exec analysis-worker /bin/bash
进入容器后访问log/celery.log
查看具体错误原因
如果提示no route to host
可能是当前机器/容器无法访问当前宿主机的IP,可以检查一下当前防火墙的设置,是否限制了analysis-worker
来源的访问
出现该错误提示,一般是Server未进行初始化,可以通过执行以下命令初始化后再启动测试
cd server && ./scripts/deploy.sh init
./compose_init.sh
为防止国内用户访问CodeAnalysis Github首页时图片资源加载失败,目前各个md文件中的图片资源引用地址调整增加了URL前缀https://tencent.github.io/CodeAnalysis/
。
用户下载代码库到本地后,发现无法访问资源文件时,请检查本地网络是否能够连通外网,如果无法连通外网,可以在文档引入资源地址中进行相对路径替换,调整各个资源文件的链接。
对于根目录下的md文件,直接删除URL前缀即可:
例如在https://tencent.github.io/CodeAnalysis/media/homepage.png
这个链接可以调整为media/homepage.png
对于其他目录下的md文件,删除URL前缀后,需调整文件相对路径链接:
例如对于doc/client.md
, 需将https://tencent.github.io/CodeAnalysis/media/clientConfigIni.png
这个链接调整为../media/clientConfigIni.png
提示
以下说明以 Jenkins 2.361.2 版本为例。
Jenkins插件有以下两种获取方式:
方式一:在 TCA 源码的plugin/jenkins_plugin
目录下,执行命令mvn package -DskipTests
,打包完成后进入target目录会看到tca_jenkins_plugin.hpi
的安装包。
在Jenkins中通过【Manage Plugin】-> 【Advanced】->【Deploy plugin】的方式选择 Jenkins_plugin.hpi文件上传安装,并重启Jenkins。
最终在【Installed】里搜索出【TCA】代表插件安装成功。
在CodeAnalysis目录下执行代码
bash ./scripts/base/install_bin.sh
+
将client
目录下的config.ini
文件中的<Server IP地址>
替换为部署的开源版TCA的IP地址(可包含端口号)
如已创建后待使用的团队和项目,可跳过此步。
进入已部署好的TCA页面,点击【创建团队】,成功后【创建项目】。
进入Jenkins设置界面,在【Manage Jenkins】->【Configure System】->【Global properties】中添加环境变量:
Name:PYTHONPATH
Value:xxxx(路径不包含python3)
Value:GITPATH
Value:xxxx(路径不包含git)
创建一个构建任务,配置代码库信息,进入Jenkins,通过【New Item】创建一个空白任务,在任务配置中【Source Code Management】配置待分析的代码库地址和凭证。Repository URL
: 填入远端仓库地址Credentials
: 添加仓库的用户名和密码作为凭证,如果是公开仓库,可以不设置仓库凭证
在构建任务的【Build】中选择【TCA】插件并配置以下参数:
CodeAnalysis目录绝对路径
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)团队ID
: 在 TCA 中创建的团队的标识ID,可在TCA【团队概览】中获取“团队唯一标识”项目名称
: 在 TCA 中创建的项目的标识ID,可在TCA【项目概览】中获取“项目唯一标识”Token
: 在 TCA 的【个人中心】->【个人令牌】中获取分支名称
: 需要扫描的代码分支名称语言类别
: 项目需要扫描的语言分析方案模板ID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)分析方案名称
: 指定创建出来的分析方案的名称(选填)全量扫描
: 不勾选默认启动增量扫描质量门禁
: 设置质量门禁值,配置和使用参考 设置质量门禁
配置完成后点击【Save】保存。
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ }
+ }
+ }
+}
+
+
codeAnalysisPath
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)teamId
:团队IDprojectName
: 项目名称token
: 在 TCA 的【个人中心】->【个人令牌】中获取branchName
: 需要扫描的代码分支名称languageType
: 项目需要扫描的语言refSchemeID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)scanPlan
: 指定创建出来的分析方案的名称(选填)threshold
: 设置质量门禁值total
: 是否全量扫描,填ture
为全量扫描,不填或填false
为增量扫描
点击【Build Now】启动构建。
进入构建任务,在【Console Output】中查看执行过程。
执行完成后,可在下方看到代码分析的结果链接,也可在【代码分析报告】中获取代码分析的json报告。
在上述 TCA 插件配置部分填写质量门禁
参数,需要填写一个整数,即当前分支的扫描问题量大于该质量门禁值时,判断为不通过;否则为通过。完成后会将TCA结果状态(success
|failure
)输出到工作空间下的tca_threshold.txt
文件中,供后续步骤判断和终止流水线。
在TCA插件后增加shell命令步骤,输入以下脚本内容:
tca_status=\`cat tca_threshold.txt\`
+if [ "\${tca_status}" == "success" ]; then
+ echo ">> tca scan pass!"
+else
+ echo ">> tca scan fail! exit code 255"
+ exit 255
+fi
+
当质量门禁不通过时,会终止流水线(退出码:255)。
以下是pipeline脚本使用质量门禁进行相应操作的示例,你可以在if和else部分写入你想要运行的脚本
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ script{
+ def tca_status = readFile('tca_threshold.txt')
+ if (tca_status == "success") {
+ echo ">> tca scan pass!"
+ } else {
+ echo ">> tca scan fail! exit code 255"
+ error("TCA scan failed. Terminating pipeline.")
+ }
+ }
+ }
+ }
+ }
+}
+
TIP
以下说明以 Jenkins 2.361.2 版本为例。
Jenkins插件有以下两种获取方式:
方式一:在 TCA 源码的plugin/jenkins_plugin
目录下,执行命令mvn package -DskipTests
,打包完成后进入target目录会看到tca_jenkins_plugin.hpi
的安装包。
在Jenkins中通过【Manage Plugin】-> 【Advanced】->【Deploy plugin】的方式选择 Jenkins_plugin.hpi文件上传安装,并重启Jenkins。
最终在【Installed】里搜索出【TCA】代表插件安装成功。
在CodeAnalysis目录下执行代码
bash ./scripts/base/install_bin.sh
+
将client
目录下的config.ini
文件中的<Server IP地址>
替换为部署的开源版TCA的IP地址(可包含端口号)
如已创建后待使用的团队和项目,可跳过此步。
进入已部署好的TCA页面,点击【创建团队】,成功后【创建项目】。
进入Jenkins设置界面,在【Manage Jenkins】->【Configure System】->【Global properties】中添加环境变量:
Name:PYTHONPATH
Value:xxxx(路径不包含python3)
Value:GITPATH
Value:xxxx(路径不包含git)
创建一个构建任务,配置代码库信息,进入Jenkins,通过【New Item】创建一个空白任务,在任务配置中【Source Code Management】配置待分析的代码库地址和凭证。Repository URL
: 填入远端仓库地址Credentials
: 添加仓库的用户名和密码作为凭证,如果是公开仓库,可以不设置仓库凭证
在构建任务的【Build】中选择【TCA】插件并配置以下参数:
CodeAnalysis目录绝对路径
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)团队ID
: 在 TCA 中创建的团队的标识ID,可在TCA【团队概览】中获取“团队唯一标识”项目名称
: 在 TCA 中创建的项目的标识ID,可在TCA【项目概览】中获取“项目唯一标识”Token
: 在 TCA 的【个人中心】->【个人令牌】中获取分支名称
: 需要扫描的代码分支名称语言类别
: 项目需要扫描的语言分析方案模板ID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)分析方案名称
: 指定创建出来的分析方案的名称(选填)全量扫描
: 不勾选默认启动增量扫描质量门禁
: 设置质量门禁值,配置和使用参考 设置质量门禁
配置完成后点击【Save】保存。
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ }
+ }
+ }
+}
+
+
codeAnalysisPath
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)teamId
:团队IDprojectName
: 项目名称token
: 在 TCA 的【个人中心】->【个人令牌】中获取branchName
: 需要扫描的代码分支名称languageType
: 项目需要扫描的语言refSchemeID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)scanPlan
: 指定创建出来的分析方案的名称(选填)threshold
: 设置质量门禁值total
: 是否全量扫描,填ture
为全量扫描,不填或填false
为增量扫描
点击【Build Now】启动构建。
进入构建任务,在【Console Output】中查看执行过程。
执行完成后,可在下方看到代码分析的结果链接,也可在【代码分析报告】中获取代码分析的json报告。
在上述 TCA 插件配置部分填写质量门禁
参数,需要填写一个整数,即当前分支的扫描问题量大于该质量门禁值时,判断为不通过;否则为通过。完成后会将TCA结果状态(success
|failure
)输出到工作空间下的tca_threshold.txt
文件中,供后续步骤判断和终止流水线。
在TCA插件后增加shell命令步骤,输入以下脚本内容:
tca_status=\`cat tca_threshold.txt\`
+if [ "\${tca_status}" == "success" ]; then
+ echo ">> tca scan pass!"
+else
+ echo ">> tca scan fail! exit code 255"
+ exit 255
+fi
+
当质量门禁不通过时,会终止流水线(退出码:255)。
以下是pipeline脚本使用质量门禁进行相应操作的示例,你可以在if和else部分写入你想要运行的脚本
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ script{
+ def tca_status = readFile('tca_threshold.txt')
+ if (tca_status == "success") {
+ echo ">> tca scan pass!"
+ } else {
+ echo ">> tca scan fail! exit code 255"
+ error("TCA scan failed. Terminating pipeline.")
+ }
+ }
+ }
+ }
+ }
+}
+
pip install requests\n
method | 类型 |
---|---|
create_repository | 创建代码库 |
update_scheme_settings | 设置指定代码库的指定方案的代码度量配置 |
create_project | 创建分析项目 |
create_scans | 启动任务 |
get_scan_cons | 轮询任务结果 |
get_overview | 获取分析概览 |
get_issues | 查看扫描问题列表 |
get_issue_detail | 查看问题详情 |
get_ccissues | 查看指定项目的圈复杂度问题列表 |
get_dupfiles | 查看指定项目的重复文件列表 |
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_repository |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
scm_url | str | 代码库地址 |
scm_type | str | 填git或svn |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_repository --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --scm_url=${TCA_SCM_URL} --scm_type=${TCA_SCM_TYPE}\n
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,update_scheme_settings |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
scheme_id | str | 扫描方案id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=update_scheme_settings --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --scheme_id=${TCA_SCHEME_ID}\n
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_repository |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
scan_scheme_id | int | 和global_scheme_id二选一进行填写,当前代码库的扫描方案编号 |
global_scheme_id | int | 和scan_scheme_id二选一进行填写,扫描方案模板编号 |
branch | str | 分支 |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_project --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --scan_scheme_id=${TCA_SCAN_SCHEME_ID} --branch=${TCA_BRANCH}\n
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_scans |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_scans --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}\n
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_scan_cons |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
sleeptime | int | 轮询间隔的时间 |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_scan_cons --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID} --job_id=${TCA_JOB_ID}\n
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_overview |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_overview --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}\n
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_issues |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_issues --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}\n
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_issue_detail |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
issue_id | str | 问题id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_issue_detail --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID} --issue_id=${TCA_ISSUE_ID}\n
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_ccissues |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_ccissues --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}\n
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/\n
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_dupfiles |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_dupfiles --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}\n
TCA-Armory-C1 属于 TCA 的增强分析模块。
支持的语言:Java
',4),b={href:"https://owasp.org/www-community/attacks/Command_Injection",target:"_blank",rel:"noopener noreferrer"},v=e("code",null,"命令行注入漏洞",-1),p=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String cmd = req.getParameter("cmd");
+ Runtime rt = Runtime.getRuntime();
+ rt.exec(cmd); // 触发规则
+}
+
需要评估 childprocess 等模块执行命令的使用,应限定或校验命令和参数的内容。
支持的语言:Java
`,9),m={href:"https://owasp.org/www-community/attacks/Path_Traversal",target:"_blank",rel:"noopener noreferrer"},g=e("code",null,"路径穿越漏洞",-1),f=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String image = req.getParameter("image");
+ File file = new File("resources/images/", image); // 触发规则
+
+ if (!file.exists()) {
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ return Response.ok().entity(new FileInputStream(file)).build();
+}
+
按业务需求,使用白名单限定后缀范围,校验并限定文件路径范围。
支持的语言:Java
`,9),x={href:"https://en.wikipedia.org/wiki/SQL_injection",target:"_blank",rel:"noopener noreferrer"},C=e("code",null,"SQL注入漏洞",-1),j=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = req.getParameter("id");
+ Connection conn = null;
+ Statement statement = null;
+ ResultSet rs = null;
+
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sec_sql", "root", "admin888");
+ String sql = "select * from userinfo where id = " + id;
+ statement = conn.createStatement();
+ statement.executeUpdate(sql); // 触发规则
+}
+
SQL 语句默认使用预编译并绑定变量,使用安全的ORM操作。
支持的语言:Java
`,9),_={href:"https://en.wikipedia.org/wiki/Server-side_request_forgery",target:"_blank",rel:"noopener noreferrer"},S=e("code",null,"服务端请求伪造漏洞 SSRF(Server-side request forgery)",-1),q=i(`无
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf ->
+ csrf.disable() // 触发规则
+ );
+ }
+}
+
限定访问网络资源地址范围,请求网络资源应加密传输。
支持的语言:Java
`,9),O={href:"https://en.wikipedia.org/wiki/Cross-site_scripting",target:"_blank",rel:"noopener noreferrer"},P=e("code",null,"跨站脚本攻击漏洞 XSS(Cross-site scripting)",-1),y=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = request.getParameter("id") != null ? request.getParameter("id") : "0";
+ Doc doc = getdetailsById(id);
+ byte[] b = doc.getUploaded();
+ try {
+ response.setContentType("APPLICATION/OCTET-STREAM");
+ String disHeader = "Attachment;Filename=" + doc.getName();
+ response.setHeader("Content-Disposition", disHeader);
+ ServletOutputStream out = response.getOutputStream();
+ out.print(b); // 触发规则
+ }
+}
+
在输出所有用户可控的数据时, 对数据做转义或者编码。
检查 Objective-C/C++ 代码文件的copyright信息。
无
// 触发规则
+@interface Test : NSObject
+@end
+
+
在代码文件头部添加 Copyright 信息。比如:
// Copyright (c) xxxx Tencent. All rights reserved.
+//
+
+@interface Test : NSObject
+@end
+
+
检查 Objective-C/C++ 代码文件的缩进。
\\t
,默认是 spaces;参考以下示例:
IndentStyle=spaces
+IndentSize=4
+
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
调整为对应的缩进方式。比如默认是4个空格缩进。
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
检查 Objective-C/C++ 代码中超出行数长度阈值的函数。
参考以下示例:
LineThreshold=100
+
无
可以基于单一职责原则拆分函数,缩减函数长度。
检查 Objective-C/C++ 代码中 interface 是否有注释信息。
无
无
为 inferface 增加注释。
检查 Objective-C/C++ 代码中 Property 是否有注释信息。
无
无
为 Property 增加注释。
检查 Objective-C/C++ 代码中 Protocol 是否有注释信息。
无
无
为 Protocol 增加注释。
检查 Objective-C/C++ 代码中方法的参数个数是否超过阈值。
参考以下示例:
Max=6
+
无。
参数个数越少越好,多于 6 个参数时建议考虑重构。
检查 Objective-C/C++ 代码中 class 名称是否符合命名规范。
参考以下示例:
ClassCase=CamelCase
+
无。
修改 class 名称符合命名规范。
检查 Objective-C/C++ 代码中 Function 名称是否符合命名规范。
参考以下示例:
FunctionCase=camelBack
+
无。
修改 Function 名称符合命名规范。
检查 Objective-C/C++ 代码中 GlobalVariable 名称是否符合命名规范。
g
;参考以下示例:
GlobalVariablePrefix=g
+GlobalVariableCase=camelBack
+
无。
修改 GlobalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 LocalVariable 名称是否符合命名规范。
参考以下示例:
LocalVariableCase=camelBack
+
无。
修改 LocalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 Macro 名称是否符合命名规范。
参考以下示例:
MacroCase=UPPER_CASE
+
无。
修改 Macro 名称符合命名规范。
检查 Objective-C/C++ 代码中 Method 名称是否符合命名规范。
参考以下示例:
MethodCase=camelBack
+
无。
修改 Method 名称符合命名规范。
检查 Objective-C/C++ 代码中 Parameter 名称是否符合命名规范。
参考以下示例:
ParameterCase=camelBack
+
无。
修改 Parameter 名称符合命名规范。
检查 Objective-C/C++ 代码中一行长度是否超过阈值。
参考以下示例:
tabWidth=4
+MaxLineLength=150
+
无。
通过换行、优化逻辑等方式,缩减一行长度。
`,165);function k(E,R){const n=s("ExternalLinkIcon");return t(),h("div",null,[l,e("ul",null,[e("li",null,[a("需要事先部署好 "),e("a",o,[a("CLS 微服务"),r(n)])])]),u,e("p",null,[a("CmdInject 规则用于检查代码中是否存在"),e("a",b,[v,r(n)]),a("。 当使用 childprocess 等模块执行命令时,拼接了用户可控的输入,会导致命令执行漏洞。攻击者利用漏洞可以控制目标主机或者容器。")]),p,e("p",null,[a("PathTraversal 规则用于检查代码中是否存在"),e("a",m,[g,r(n)]),a("。 操作文件时,应该限定文件的路径范围,如果拼接用户输入到文件路径,可能导致路径穿越漏洞。攻击者利用漏洞可以访问到文件系统上的任意文件,这可能导致信息泄漏等问题。")]),f,e("p",null,[a("SQLInject 规则用于检查代码中是否存在"),e("a",x,[C,r(n)]),a("。 错误的拼接用户可控的值到 sql 语句,可能导致 sql 注入漏洞。攻击者可以修改 sql 语法来更改查询的目标或结果,泄露数据库敏感信息,也可以使用SQL文件操作攻击底层Web服务器。如果使用该 sql 查询进行授权认证,攻击者还可以用于提权。")]),j,e("p",null,[a("SSRF 规则用于检查代码中是否存在"),e("a",_,[S,r(n)]),a("。 攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。")]),q,e("p",null,[a("XSS 规则用于检查代码中是否存在"),e("a",O,[P,r(n)]),a("。 如果 web 页面在动态展示数据时使用了用户的输入内容,没有对输入的内容过滤或者进行转义,黑客可以通过参数传入恶意代码,当用户浏览该页面时恶意代码会被执行。")]),y])}const L=d(c,[["render",k],["__file","TCA-Armory-C1.html.vue"]]);export{L as default}; diff --git a/assets/TCA-Armory-C1.html-5177716b.js b/assets/TCA-Armory-C1.html-5177716b.js new file mode 100644 index 000000000..9426295ab --- /dev/null +++ b/assets/TCA-Armory-C1.html-5177716b.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1cf92e76","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html","title":"TCA-Armory-C1 使用手册","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"功能","slug":"功能","link":"#功能","children":[]},{"level":2,"title":"准备","slug":"准备","link":"#准备","children":[]},{"level":2,"title":"规则介绍","slug":"规则介绍","link":"#规则介绍","children":[{"level":3,"title":"CmdInject","slug":"cmdinject","link":"#cmdinject","children":[]},{"level":3,"title":"PathTraversal","slug":"pathtraversal","link":"#pathtraversal","children":[]},{"level":3,"title":"SQLInject","slug":"sqlinject","link":"#sqlinject","children":[]},{"level":3,"title":"SSRF","slug":"ssrf","link":"#ssrf","children":[]},{"level":3,"title":"XSS","slug":"xss","link":"#xss","children":[]},{"level":3,"title":"ObjectiveC/Copyright","slug":"objectivec-copyright","link":"#objectivec-copyright","children":[]},{"level":3,"title":"ObjectiveC/Indent","slug":"objectivec-indent","link":"#objectivec-indent","children":[]},{"level":3,"title":"ObjectiveC/MaxLinesPerFunction","slug":"objectivec-maxlinesperfunction","link":"#objectivec-maxlinesperfunction","children":[]},{"level":3,"title":"ObjectiveC/MissingDocInterface","slug":"objectivec-missingdocinterface","link":"#objectivec-missingdocinterface","children":[]},{"level":3,"title":"ObjectiveC/MissingDocProperty","slug":"objectivec-missingdocproperty","link":"#objectivec-missingdocproperty","children":[]},{"level":3,"title":"ObjectiveC/MissingDocProtocol","slug":"objectivec-missingdocprotocol","link":"#objectivec-missingdocprotocol","children":[]},{"level":3,"title":"ObjectiveC/ParameterCount","slug":"objectivec-parametercount","link":"#objectivec-parametercount","children":[]},{"level":3,"title":"ObjectiveC/ClassNaming","slug":"objectivec-classnaming","link":"#objectivec-classnaming","children":[]},{"level":3,"title":"ObjectiveC/FunctionNaming","slug":"objectivec-functionnaming","link":"#objectivec-functionnaming","children":[]},{"level":3,"title":"ObjectiveC/GlobalVariableNaming","slug":"objectivec-globalvariablenaming","link":"#objectivec-globalvariablenaming","children":[]},{"level":3,"title":"ObjectiveC/LocalVariableNaming","slug":"objectivec-localvariablenaming","link":"#objectivec-localvariablenaming","children":[]},{"level":3,"title":"ObjectiveC/MacroNaming","slug":"objectivec-macronaming","link":"#objectivec-macronaming","children":[]},{"level":3,"title":"ObjectiveC/MethodNaming","slug":"objectivec-methodnaming","link":"#objectivec-methodnaming","children":[]},{"level":3,"title":"ObjectiveC/ParameterNaming","slug":"objectivec-parameternaming","link":"#objectivec-parameternaming","children":[]},{"level":3,"title":"ObjectiveC/MaxLineLength","slug":"objectivec-maxlinelength","link":"#objectivec-maxlinelength","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/工具/TCA-Armory-C1.md"}');export{e as data}; diff --git a/assets/TCA-Armory-C1.html-9ef6db9a.js b/assets/TCA-Armory-C1.html-9ef6db9a.js new file mode 100644 index 000000000..49875d89b --- /dev/null +++ b/assets/TCA-Armory-C1.html-9ef6db9a.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7c0ce2de","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html","title":"TCA-Armory-C1 使用手册","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"功能","slug":"功能","link":"#功能","children":[]},{"level":2,"title":"准备","slug":"准备","link":"#准备","children":[]},{"level":2,"title":"规则介绍","slug":"规则介绍","link":"#规则介绍","children":[{"level":3,"title":"CmdInject","slug":"cmdinject","link":"#cmdinject","children":[]},{"level":3,"title":"PathTraversal","slug":"pathtraversal","link":"#pathtraversal","children":[]},{"level":3,"title":"SQLInject","slug":"sqlinject","link":"#sqlinject","children":[]},{"level":3,"title":"SSRF","slug":"ssrf","link":"#ssrf","children":[]},{"level":3,"title":"XSS","slug":"xss","link":"#xss","children":[]},{"level":3,"title":"ObjectiveC/Copyright","slug":"objectivec-copyright","link":"#objectivec-copyright","children":[]},{"level":3,"title":"ObjectiveC/Indent","slug":"objectivec-indent","link":"#objectivec-indent","children":[]},{"level":3,"title":"ObjectiveC/MaxLinesPerFunction","slug":"objectivec-maxlinesperfunction","link":"#objectivec-maxlinesperfunction","children":[]},{"level":3,"title":"ObjectiveC/MissingDocInterface","slug":"objectivec-missingdocinterface","link":"#objectivec-missingdocinterface","children":[]},{"level":3,"title":"ObjectiveC/MissingDocProperty","slug":"objectivec-missingdocproperty","link":"#objectivec-missingdocproperty","children":[]},{"level":3,"title":"ObjectiveC/MissingDocProtocol","slug":"objectivec-missingdocprotocol","link":"#objectivec-missingdocprotocol","children":[]},{"level":3,"title":"ObjectiveC/ParameterCount","slug":"objectivec-parametercount","link":"#objectivec-parametercount","children":[]},{"level":3,"title":"ObjectiveC/ClassNaming","slug":"objectivec-classnaming","link":"#objectivec-classnaming","children":[]},{"level":3,"title":"ObjectiveC/FunctionNaming","slug":"objectivec-functionnaming","link":"#objectivec-functionnaming","children":[]},{"level":3,"title":"ObjectiveC/GlobalVariableNaming","slug":"objectivec-globalvariablenaming","link":"#objectivec-globalvariablenaming","children":[]},{"level":3,"title":"ObjectiveC/LocalVariableNaming","slug":"objectivec-localvariablenaming","link":"#objectivec-localvariablenaming","children":[]},{"level":3,"title":"ObjectiveC/MacroNaming","slug":"objectivec-macronaming","link":"#objectivec-macronaming","children":[]},{"level":3,"title":"ObjectiveC/MethodNaming","slug":"objectivec-methodnaming","link":"#objectivec-methodnaming","children":[]},{"level":3,"title":"ObjectiveC/ParameterNaming","slug":"objectivec-parameternaming","link":"#objectivec-parameternaming","children":[]},{"level":3,"title":"ObjectiveC/MaxLineLength","slug":"objectivec-maxlinelength","link":"#objectivec-maxlinelength","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/工具/TCA-Armory-C1.md"}');export{e as data}; diff --git a/assets/TCA-Armory-C1.html-f73f9e95.js b/assets/TCA-Armory-C1.html-f73f9e95.js new file mode 100644 index 000000000..6b546b096 --- /dev/null +++ b/assets/TCA-Armory-C1.html-f73f9e95.js @@ -0,0 +1,86 @@ +import{_ as d,r as s,o as t,c as h,a as e,b as a,d as r,e as i}from"./app-2a91d8ab.js";const c={},l=i('TCA-Armory-C1 属于 TCA 的增强分析模块。
支持的语言:Java
',4),b={href:"https://owasp.org/www-community/attacks/Command_Injection",target:"_blank",rel:"noopener noreferrer"},v=e("code",null,"命令行注入漏洞",-1),p=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String cmd = req.getParameter("cmd");
+ Runtime rt = Runtime.getRuntime();
+ rt.exec(cmd); // 触发规则
+}
+
需要评估 childprocess 等模块执行命令的使用,应限定或校验命令和参数的内容。
支持的语言:Java
`,9),m={href:"https://owasp.org/www-community/attacks/Path_Traversal",target:"_blank",rel:"noopener noreferrer"},g=e("code",null,"路径穿越漏洞",-1),f=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String image = req.getParameter("image");
+ File file = new File("resources/images/", image); // 触发规则
+
+ if (!file.exists()) {
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ return Response.ok().entity(new FileInputStream(file)).build();
+}
+
按业务需求,使用白名单限定后缀范围,校验并限定文件路径范围。
支持的语言:Java
`,9),x={href:"https://en.wikipedia.org/wiki/SQL_injection",target:"_blank",rel:"noopener noreferrer"},C=e("code",null,"SQL注入漏洞",-1),j=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = req.getParameter("id");
+ Connection conn = null;
+ Statement statement = null;
+ ResultSet rs = null;
+
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sec_sql", "root", "admin888");
+ String sql = "select * from userinfo where id = " + id;
+ statement = conn.createStatement();
+ statement.executeUpdate(sql); // 触发规则
+}
+
SQL 语句默认使用预编译并绑定变量,使用安全的ORM操作。
支持的语言:Java
`,9),_={href:"https://en.wikipedia.org/wiki/Server-side_request_forgery",target:"_blank",rel:"noopener noreferrer"},S=e("code",null,"服务端请求伪造漏洞 SSRF(Server-side request forgery)",-1),q=i(`无
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf ->
+ csrf.disable() // 触发规则
+ );
+ }
+}
+
限定访问网络资源地址范围,请求网络资源应加密传输。
支持的语言:Java
`,9),O={href:"https://en.wikipedia.org/wiki/Cross-site_scripting",target:"_blank",rel:"noopener noreferrer"},P=e("code",null,"跨站脚本攻击漏洞 XSS(Cross-site scripting)",-1),y=i(`无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = request.getParameter("id") != null ? request.getParameter("id") : "0";
+ Doc doc = getdetailsById(id);
+ byte[] b = doc.getUploaded();
+ try {
+ response.setContentType("APPLICATION/OCTET-STREAM");
+ String disHeader = "Attachment;Filename=" + doc.getName();
+ response.setHeader("Content-Disposition", disHeader);
+ ServletOutputStream out = response.getOutputStream();
+ out.print(b); // 触发规则
+ }
+}
+
在输出所有用户可控的数据时, 对数据做转义或者编码。
检查 Objective-C/C++ 代码文件的copyright信息。
无
// 触发规则
+@interface Test : NSObject
+@end
+
+
在代码文件头部添加 Copyright 信息。比如:
// Copyright (c) xxxx Tencent. All rights reserved.
+//
+
+@interface Test : NSObject
+@end
+
+
检查 Objective-C/C++ 代码文件的缩进。
\\t
,默认是 spaces;参考以下示例:
IndentStyle=spaces
+IndentSize=4
+
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
调整为对应的缩进方式。比如默认是4个空格缩进。
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
检查 Objective-C/C++ 代码中超出行数长度阈值的函数。
参考以下示例:
LineThreshold=100
+
无
可以基于单一职责原则拆分函数,缩减函数长度。
检查 Objective-C/C++ 代码中 interface 是否有注释信息。
无
无
为 inferface 增加注释。
检查 Objective-C/C++ 代码中 Property 是否有注释信息。
无
无
为 Property 增加注释。
检查 Objective-C/C++ 代码中 Protocol 是否有注释信息。
无
无
为 Protocol 增加注释。
检查 Objective-C/C++ 代码中方法的参数个数是否超过阈值。
参考以下示例:
Max=6
+
无。
参数个数越少越好,多于 6 个参数时建议考虑重构。
检查 Objective-C/C++ 代码中 class 名称是否符合命名规范。
参考以下示例:
ClassCase=CamelCase
+
无。
修改 class 名称符合命名规范。
检查 Objective-C/C++ 代码中 Function 名称是否符合命名规范。
参考以下示例:
FunctionCase=camelBack
+
无。
修改 Function 名称符合命名规范。
检查 Objective-C/C++ 代码中 GlobalVariable 名称是否符合命名规范。
g
;参考以下示例:
GlobalVariablePrefix=g
+GlobalVariableCase=camelBack
+
无。
修改 GlobalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 LocalVariable 名称是否符合命名规范。
参考以下示例:
LocalVariableCase=camelBack
+
无。
修改 LocalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 Macro 名称是否符合命名规范。
参考以下示例:
MacroCase=UPPER_CASE
+
无。
修改 Macro 名称符合命名规范。
检查 Objective-C/C++ 代码中 Method 名称是否符合命名规范。
参考以下示例:
MethodCase=camelBack
+
无。
修改 Method 名称符合命名规范。
检查 Objective-C/C++ 代码中 Parameter 名称是否符合命名规范。
参考以下示例:
ParameterCase=camelBack
+
无。
修改 Parameter 名称符合命名规范。
检查 Objective-C/C++ 代码中一行长度是否超过阈值。
参考以下示例:
tabWidth=4
+MaxLineLength=150
+
无。
通过换行、优化逻辑等方式,缩减一行长度。
`,165);function k(E,R){const n=s("ExternalLinkIcon");return t(),h("div",null,[l,e("ul",null,[e("li",null,[a("需要事先部署好 "),e("a",o,[a("CLS 微服务"),r(n)])])]),u,e("p",null,[a("CmdInject 规则用于检查代码中是否存在"),e("a",b,[v,r(n)]),a("。 当使用 childprocess 等模块执行命令时,拼接了用户可控的输入,会导致命令执行漏洞。攻击者利用漏洞可以控制目标主机或者容器。")]),p,e("p",null,[a("PathTraversal 规则用于检查代码中是否存在"),e("a",m,[g,r(n)]),a("。 操作文件时,应该限定文件的路径范围,如果拼接用户输入到文件路径,可能导致路径穿越漏洞。攻击者利用漏洞可以访问到文件系统上的任意文件,这可能导致信息泄漏等问题。")]),f,e("p",null,[a("SQLInject 规则用于检查代码中是否存在"),e("a",x,[C,r(n)]),a("。 错误的拼接用户可控的值到 sql 语句,可能导致 sql 注入漏洞。攻击者可以修改 sql 语法来更改查询的目标或结果,泄露数据库敏感信息,也可以使用SQL文件操作攻击底层Web服务器。如果使用该 sql 查询进行授权认证,攻击者还可以用于提权。")]),j,e("p",null,[a("SSRF 规则用于检查代码中是否存在"),e("a",_,[S,r(n)]),a("。 攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。")]),q,e("p",null,[a("XSS 规则用于检查代码中是否存在"),e("a",O,[P,r(n)]),a("。 如果 web 页面在动态展示数据时使用了用户的输入内容,没有对输入的内容过滤或者进行转义,黑客可以通过参数传入恶意代码,当用户浏览该页面时恶意代码会被执行。")]),y])}const L=d(c,[["render",k],["__file","TCA-Armory-C1.html.vue"]]);export{L as default}; diff --git a/assets/TCA-Armory-Q1.html-08aa80f4.js b/assets/TCA-Armory-Q1.html-08aa80f4.js new file mode 100644 index 000000000..f651d0f0f --- /dev/null +++ b/assets/TCA-Armory-Q1.html-08aa80f4.js @@ -0,0 +1,367 @@ +import{_ as e,o as i,c as n,e as d}from"./app-2a91d8ab.js";const l={},a=d(`TCA-Armory-Q1, 又名 tca_ql_cpp 主要用于分析Cpp质量问题。
包含规则:
在使用多线程对文件全局变量或类成员在进行读写时,工具会对未正确的进行上锁操作和上锁异常而引发死锁的情况进行检查。
支持的多线程标准库库包括(若有其他库需求可提issue):
missing_lock 如果发现多线程中某个全局变量在未持有锁便更新时,则会上报错误。
以下提供一个或多个 missing_loc 案例 在下面代码中,函数 increase1, increase2 皆以将 counter 加到 1000 为目的。如果使用 increase1 函数则有可能多个线程皆在 1000 时进入循环导致最后 counter结果大于 1000
int counter = 0;
+std::mutex mtx; // 保护counter
+void increase1() {
+ while (1) {
+ if (counter <= 1000)
+ counter++; // defect: missing_lock
+ else
+ break;
+ }
+}
+void increase2() {
+ while (1) {
+ mtx.lock(); // example_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx.unlock(); // example_release
+ }
+}
+
dead_lock 如果发现文件内存在 mtx1 -> mtx2 的上锁顺序时,另存在mtx2 -> mtx1 的上锁顺序,视为死锁或存在死锁的可能,则会上报错误。 死锁发生时程序将会卡死无法正常执行。
以下提供一个或多个 dead_lock 案例
在下面代码中,函数 increase 以将 counter 加到 1000 为目的。但在线程 1 中第一次释放 mtx 后,线程 2 的 mtx 上锁,此时线程1等待线程2释放mtx,线程2等待线程1释放mtx2,形成死锁,程序卡死。
int counter = 0;
+std::mutex mtx;
+std::mutex mtx2;
+void increase() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ mtx.unlock();
+ mtx.lock(); // defect: dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
在下面代码中 线程函数increase1存在mtx -> mtx2 的顺序,increase2顺序为 mtx2 -> mtx;视为出现死锁。
void increase1() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+void increase2() {
+ while (1) {
+ mtx2.lock();
+ mtx.lock(); // defect: dead_lock;
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
以下案例在better-lock
参数为True
时将会生效 使用better-lock
规则会检查在上锁期间若调用其他函数时将视为可能会出现预期之外的异常,且上锁期间应只做对全局变量操作以提升性能
void increase1() {
+ while (1) {
+ mtx.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter); // defect: dead_lock
+ mtx.unlock()
+ }
+}
+void read_counter(counter){
+ std::cout << counter << std::endl;
+ do_something_more();
+}
+void increase1() {
+ while (1) {
+ std::lock_guard<std::mutex> lk(mtx); // good: 使用lock_guard会自动上锁解锁将不会检查dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter);
+ }
+}
+
包含规则
resource_leak 在程序申请了资源但并未按时释放时上报错误 目前场景包括:句柄打开时未关闭,指针分配内存后没有及时释放
以下将提供一个或多个resource_leak案例
int leak_example1(int c) {
+ void *p = malloc(10);
+ if(c)
+ return -1; // defect: if c "p" is leaked
+ free(p);
+ return 0;
+}
+
+int leak_example2() {
+ void *p = malloc(10);
+ void *q = malloc(20);
+ if(!p || !q)
+ return -1; // defect: "p" or "q" may be leaked if the other is NULL
+ /*...*/
+ free(q);
+ free(p);
+ return 0;
+}
+
+void leak_example3(int c) {
+ FILE *p = fopen("starwar.anakin", "rb");
+ if(c)
+ return; // defect: leaking file pointer "p"
+ fclose(p);
+}
+
包含规则
unused_value 检查那些赋予给变量的值是否正确被使用,存在连续两次赋予变量值的情况,视为第一次赋予的值未被正确使用,报出错误。 两次连续赋值可能存在条件控制语句出现错误、变量名拼写错误等情况。
以下提供一个或多个unused_value案例
以下函数会因为key的不同去不一样的神明,但实际上 Zeus Hades却永远不会使用到。
const char* key_value(const int key) {
+ const char * value = 0;
+ if (key != 0) {
+ value = "Zeus";
+ } else if (key != 1) {
+ value = "Hades";
+ }
+ if (key != 2) { // Should be 'else if' here.
+ value = "Poseidon"; // defect: unused_value Zeus Hades never used
+ }
+ else {
+ value = "Unknow
+ }
+ return result;
+}
+
以下继续提供几个unused_value代码
const char* key_value1(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // defect: Zeus never used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ } else { // May else need not be here
+ value = "Unknow";
+ }
+ return value
+}
+
+const char* key_value2(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // better Zeus used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ }
+ return value
+}
+
+const char* key_value3(const int key) {
+ const char * value = 0;
+ if (key == 1) {
+ value = "Hades;
+ } else {
+ value = "Poseidon";
+ }
+ value = "Zeus"; // defect: Hades Poseidon never used
+ return value
+}
+
包含规则
array_overflow 检查数组越界的情况。不正确的缓存区访问可能损坏内存,导致程序崩溃或读取到权限外的内存。
以下提供一个或多个array_overflow案例
void foo() {
+ int array[10];
+ int i = get();
+ // i = 9;
+ if (i > 8 && i <= length(array)) { // Shoud be i < length(array)
+ array[i] = 1; // defect: array[10] overflow
+ }
+ array[i] = 1; // defect: array[10] overflow
+}
+
+
+void test(int i) {
+ int n= 10;
+ char *p = malloc(sizeof(int) * 10);
+ int y = n;
+ p[y] = 'a'; // defect: writing to buffer[y] overflow
+}
+
buff_overflow 检查strcpy
,strcat
字符串复制/拼接过程中长度不当导致的溢出, 同样gets
scanf
函数也视为不安全
以下提供一个或多个buff_overflow案例
void overflow1() {
+
+ char a[4]={0};
+ strcpy(a, "Poseidon"); // defect: len("Poseidon") > 4 strncpy is better
+ return;
+}
+
+void overflow2() {
+ char s1[10] = "1";
+ char s2[] = "1234567890";
+ strcat(s1, s2); // defect: len(s1 + s2) > 10
+ // strncat(s1, s2, 6) // strncat is better
+ return 0;
+}
+
+
包含规则
func_ret_null 函数返回值可能为nullpointer,但是调用该函数时指针未经判空便进行使用
在选用func_ret_null_full 时, 检查器会在项目内全局搜索空指针函数的调用情况,否则只会在相关文件内进行检查。
以下提供一个或多个func_ret_null代码案例
在下面代码中test
函数中调用get_name
可能返回空指针,在后续使用name
指针前应该判断是否为空指针
// name.hpp
+
+char* get_name(int id) {
+ char* name = 0;
+ if (id == 1) {
+ name = "Zeus";
+ } else if (id == 2) {
+ name = "Hades"
+ } else {
+ return nullpointer;
+ }
+ return name;
+}
+
+void test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect: name may nullpointer should check it
+ if (name != nullpointer) {
+ dosomething(name); // good
+ }
+}
+
+
在选用full_ret_null_full时,将会全局分析函数get_name
调用情况
// third.cpp
+# include "name.h"
+
+void name_test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect
+}
+
use_after_free 检查当指针已经被释放但在后续仍然使用该指针的情况。
以下提供一个或多个use_after_free代码案例
通常情况下已经释放的指针只允许置空或重新指向新的值,不允许存在读取或作为函数参数使用。
+void UAR() {
+ int* p = new int[];
+ p = get_array();
+ dosomething(p);
+ delete p;
+ p = NULL; // allow
+ p = get_array(); // allow: get array again
+ delete p;
+ dosomething(p); // defect: use as param
+ std::cout << "p[0] = " << p[0] << std::endl; // defect: read p
+}
+
forward_null 检查可能导致程序终止或运行时异常的错误。它查找指针或引用被检查是否为 null 或被赋值为 null,且之后被解引用的很多情况。
以下提供一个或多个forward_null代码案例
指针曾经有过检查null的操作则会视为有可能为空指针,之后在未被确认为非空指针情况下直接使用。将会视为forward_null
错误
void forward_null_1() {
+ int * p;
+ p = get_int_pointer();
+ dosomething(p);
+ if (p == NULL) {
+ std::cout << "Null Pointer Find" << srd::endl;
+ // return; // prefer: if return here
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // defect forward_null: p may NULL
+}
+
+
+void forward_null_2(int *p) {
+ dosomething(p);
+ if (p == NULL) {
+ return;
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // good
+ ...
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
以下案例在设置trust_param
为False
时将会生效,其将会默认认为函数参数存在空指针可能,必须确认无空指针可能时方可使用
void forward_null_2(int *p) {
+ dosomething(p); // defect: param p may NULL
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
reverse_null 检查已经使用过指针,但在后续又对指针进行了判空操作;会被认为之前使用指针也有可能是空指针。
以下将提供一个或多个reverse_null案例
void reverse_null(int *p) {
+ dosomething(p); // use p
+ if (p != NULL) { // defect reverse_null: It means p may NULL
+ dosomething(p);
+ }
+ ...
+
glob_null_pointer 检查文件内全局指针是否为空,指针赋值将会被认为不为空指针,但检测到空指针判断则视为指针此时可能为空,如果在可能为空时使用则会报错
以下将提供一个或多个glob_null_pointer案例
int *p;
+
+
+void thread1() {
+ p = get_int_pointer(); // p is not NULL
+ dosomething(p); // good
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL, because check p before
+}
+
+
+void thread2() {
+ *p = 6; // defect: p may NULL
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL
+}
+
包含规则
仅类虚拟函数允许重写。
function_override 检查非虚拟函数重写的情况。
以下提供一个或多个function_override代码案例
+
+class father{
+ public:
+ father(){};
+ ~father(){};
+
+ private:
+ virtual void test(){};
+ void test2(){ std::cout<<"hello";};
+};
+
+class man{};
+
+
+class son: public father, public man{
+ public:
+ son(){};
+ ~son(){};
+ private:
+ void test(){ std::cout<<"hello";}; // allow: virtual function override
+ void test2(){ std::cout<<"hello";}; // defect: bad override
+};
+
dead_code 检查永远不会执行到的代码,主要为在同一作用域内 return, break 后的代码
以下提供一个或多个dead_code代码案例
// C/Cpp
+void dead_code(int t) {
+ int sum = 0;
+ for (int i = 1; i <= 100; i++) {
+ if (i == t) {
+ break;
+ sum = t; // Defect: dead_code
+ }
+ sum += i;
+ }
+}
+
dead_branch 检查永远不会被执行到的分支代码,其原因可能是具有相同效果的控制语句或某些条件在特定情况下永远不会执行。
以下提供一个或多个dead_branch代码案例
+void dead_branch(int i) {
+ if (i < 100) {
+ if ( i > 100) { // Defect: dead_branch, i 属于 (-inf, 100) 不存在 (100, inf)的可能
+ dosomething() ;
+ }
+ return;
+ } else if (i >= 100) {
+ if ( i < 99 ) { // Defect: dead_branch, i 属于[100, inf) 不存在 (-inf, 99)的可能
+ dosomething();
+ }
+ return;
+ } else if (i < 10){ // Defect: dead_branch, 在前面分支中已经包含了所有i的可能,这里已经不存在 (-inf, 10)的可能
+ dosomething();
+ }
+ else { // Defect: dead_branch, 在前面分支中已经包含了所有i的可能
+ dosomething();
+ }
+ return;
+}
+
+
包含规则
uinit 检查变量在定义后直接使用,却没有初始化的场景;使用未初始化的变量 可能导致无法预测的行为、崩溃和安全漏洞。
以下提供一个或多个 uinit 代码案例
+void test(char* t) {
+ std::cout<< t << std::endl; // Defect: p 作为函数参数,此处未初始化。
+ return;
+}
+
+
+int uinit(int i) {
+ int a;
+ char * p;
+ test(p); // deep_level = true
+ if (i < 10)
+ a = 1;
+ else
+ i = 1;
+ return a; // Defect: i大于10时,a并未赋值
+}
+
TCA-Armory-Q1, 又名 tca_ql_cpp 主要用于分析Cpp质量问题。
包含规则:
在使用多线程对文件全局变量或类成员在进行读写时,工具会对未正确的进行上锁操作和上锁异常而引发死锁的情况进行检查。
支持的多线程标准库库包括(若有其他库需求可提issue):
missing_lock 如果发现多线程中某个全局变量在未持有锁便更新时,则会上报错误。
以下提供一个或多个 missing_loc 案例 在下面代码中,函数 increase1, increase2 皆以将 counter 加到 1000 为目的。如果使用 increase1 函数则有可能多个线程皆在 1000 时进入循环导致最后 counter结果大于 1000
int counter = 0;
+std::mutex mtx; // 保护counter
+void increase1() {
+ while (1) {
+ if (counter <= 1000)
+ counter++; // defect: missing_lock
+ else
+ break;
+ }
+}
+void increase2() {
+ while (1) {
+ mtx.lock(); // example_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx.unlock(); // example_release
+ }
+}
+
dead_lock 如果发现文件内存在 mtx1 -> mtx2 的上锁顺序时,另存在mtx2 -> mtx1 的上锁顺序,视为死锁或存在死锁的可能,则会上报错误。 死锁发生时程序将会卡死无法正常执行。
以下提供一个或多个 dead_lock 案例
在下面代码中,函数 increase 以将 counter 加到 1000 为目的。但在线程 1 中第一次释放 mtx 后,线程 2 的 mtx 上锁,此时线程1等待线程2释放mtx,线程2等待线程1释放mtx2,形成死锁,程序卡死。
int counter = 0;
+std::mutex mtx;
+std::mutex mtx2;
+void increase() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ mtx.unlock();
+ mtx.lock(); // defect: dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
在下面代码中 线程函数increase1存在mtx -> mtx2 的顺序,increase2顺序为 mtx2 -> mtx;视为出现死锁。
void increase1() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+void increase2() {
+ while (1) {
+ mtx2.lock();
+ mtx.lock(); // defect: dead_lock;
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
以下案例在better-lock
参数为True
时将会生效 使用better-lock
规则会检查在上锁期间若调用其他函数时将视为可能会出现预期之外的异常,且上锁期间应只做对全局变量操作以提升性能
void increase1() {
+ while (1) {
+ mtx.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter); // defect: dead_lock
+ mtx.unlock()
+ }
+}
+void read_counter(counter){
+ std::cout << counter << std::endl;
+ do_something_more();
+}
+void increase1() {
+ while (1) {
+ std::lock_guard<std::mutex> lk(mtx); // good: 使用lock_guard会自动上锁解锁将不会检查dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter);
+ }
+}
+
包含规则
resource_leak 在程序申请了资源但并未按时释放时上报错误 目前场景包括:句柄打开时未关闭,指针分配内存后没有及时释放
以下将提供一个或多个resource_leak案例
int leak_example1(int c) {
+ void *p = malloc(10);
+ if(c)
+ return -1; // defect: if c "p" is leaked
+ free(p);
+ return 0;
+}
+
+int leak_example2() {
+ void *p = malloc(10);
+ void *q = malloc(20);
+ if(!p || !q)
+ return -1; // defect: "p" or "q" may be leaked if the other is NULL
+ /*...*/
+ free(q);
+ free(p);
+ return 0;
+}
+
+void leak_example3(int c) {
+ FILE *p = fopen("starwar.anakin", "rb");
+ if(c)
+ return; // defect: leaking file pointer "p"
+ fclose(p);
+}
+
指针为返回值目前不会进行上报与检查,需要后期增加对返回值是否释放的检查
包含规则
unused_value 检查那些赋予给变量的值是否正确被使用,存在连续两次赋予变量值的情况,视为第一次赋予的值未被正确使用,报出错误。 两次连续赋值可能存在条件控制语句出现错误、变量名拼写错误等情况。
以下提供一个或多个unused_value案例
以下函数会因为key的不同去不一样的神明,但实际上 Zeus Hades却永远不会使用到。
const char* key_value(const int key) {
+ const char * value = 0;
+ if (key != 0) {
+ value = "Zeus";
+ } else if (key != 1) {
+ value = "Hades";
+ }
+ if (key != 2) { // Should be 'else if' here.
+ value = "Poseidon"; // defect: unused_value Zeus Hades never used
+ }
+ else {
+ value = "Unknow
+ }
+ return result;
+}
+
以下继续提供几个unused_value代码
const char* key_value1(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // defect: Zeus never used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ } else { // May else need not be here
+ value = "Unknow";
+ }
+ return value
+}
+
+const char* key_value2(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // better Zeus used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ }
+ return value
+}
+
+const char* key_value3(const int key) {
+ const char * value = 0;
+ if (key == 1) {
+ value = "Hades;
+ } else {
+ value = "Poseidon";
+ }
+ value = "Zeus"; // defect: Hades Poseidon never used
+ return value
+}
+
包含规则
array_overflow 检查数组越界的情况。不正确的缓存区访问可能损坏内存,导致程序崩溃或读取到权限外的内存。
以下提供一个或多个array_overflow案例
void foo() {
+ int array[10];
+ int i = get();
+ // i = 9;
+ if (i > 8 && i <= length(array)) { // Shoud be i < length(array)
+ array[i] = 1; // defect: array[10] overflow
+ }
+ array[i] = 1; // defect: array[10] overflow
+}
+
+
+void test(int i) {
+ int n= 10;
+ char *p = malloc(sizeof(int) * 10);
+ int y = n;
+ p[y] = 'a'; // defect: writing to buffer[y] overflow
+}
+
buff_overflow 检查strcpy
,strcat
字符串复制/拼接过程中长度不当导致的溢出, 同样gets
scanf
函数也视为不安全
以下提供一个或多个buff_overflow案例
void overflow1() {
+
+ char a[4]={0};
+ strcpy(a, "Poseidon"); // defect: len("Poseidon") > 4 strncpy is better
+ return;
+}
+
+void overflow2() {
+ char s1[10] = "1";
+ char s2[] = "1234567890";
+ strcat(s1, s2); // defect: len(s1 + s2) > 10
+ // strncat(s1, s2, 6) // strncat is better
+ return 0;
+}
+
+
包含规则
func_ret_null 函数返回值可能为nullpointer,但是调用该函数时指针未经判空便进行使用
在选用func_ret_null_full 时, 检查器会在项目内全局搜索空指针函数的调用情况,否则只会在相关文件内进行检查。
以下提供一个或多个func_ret_null代码案例
在下面代码中test
函数中调用get_name
可能返回空指针,在后续使用name
指针前应该判断是否为空指针
// name.hpp
+
+char* get_name(int id) {
+ char* name = 0;
+ if (id == 1) {
+ name = "Zeus";
+ } else if (id == 2) {
+ name = "Hades"
+ } else {
+ return nullpointer;
+ }
+ return name;
+}
+
+void test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect: name may nullpointer should check it
+ if (name != nullpointer) {
+ dosomething(name); // good
+ }
+}
+
+
在选用full_ret_null_full时,将会全局分析函数get_name
调用情况
// third.cpp
+# include "name.h"
+
+void name_test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect
+}
+
use_after_free 检查当指针已经被释放但在后续仍然使用该指针的情况。
以下提供一个或多个use_after_free代码案例
通常情况下已经释放的指针只允许置空或重新指向新的值,不允许存在读取或作为函数参数使用。
+void UAR() {
+ int* p = new int[];
+ p = get_array();
+ dosomething(p);
+ delete p;
+ p = NULL; // allow
+ p = get_array(); // allow: get array again
+ delete p;
+ dosomething(p); // defect: use as param
+ std::cout << "p[0] = " << p[0] << std::endl; // defect: read p
+}
+
forward_null 检查可能导致程序终止或运行时异常的错误。它查找指针或引用被检查是否为 null 或被赋值为 null,且之后被解引用的很多情况。
以下提供一个或多个forward_null代码案例
指针曾经有过检查null的操作则会视为有可能为空指针,之后在未被确认为非空指针情况下直接使用。将会视为forward_null
错误
void forward_null_1() {
+ int * p;
+ p = get_int_pointer();
+ dosomething(p);
+ if (p == NULL) {
+ std::cout << "Null Pointer Find" << srd::endl;
+ // return; // prefer: if return here
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // defect forward_null: p may NULL
+}
+
+
+void forward_null_2(int *p) {
+ dosomething(p);
+ if (p == NULL) {
+ return;
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // good
+ ...
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
以下案例在设置trust_param
为False
时将会生效,其将会默认认为函数参数存在空指针可能,必须确认无空指针可能时方可使用
void forward_null_2(int *p) {
+ dosomething(p); // defect: param p may NULL
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
reverse_null 检查已经使用过指针,但在后续又对指针进行了判空操作;会被认为之前使用指针也有可能是空指针。
以下将提供一个或多个reverse_null案例
void reverse_null(int *p) {
+ dosomething(p); // use p
+ if (p != NULL) { // defect reverse_null: It means p may NULL
+ dosomething(p);
+ }
+ ...
+
glob_null_pointer 检查文件内全局指针是否为空,指针赋值将会被认为不为空指针,但检测到空指针判断则视为指针此时可能为空,如果在可能为空时使用则会报错
以下将提供一个或多个glob_null_pointer案例
int *p;
+
+
+void thread1() {
+ p = get_int_pointer(); // p is not NULL
+ dosomething(p); // good
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL, because check p before
+}
+
+
+void thread2() {
+ *p = 6; // defect: p may NULL
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL
+}
+
包含规则
仅类虚拟函数允许重写。
function_override 检查非虚拟函数重写的情况。
以下提供一个或多个function_override代码案例
+
+class father{
+ public:
+ father(){};
+ ~father(){};
+
+ private:
+ virtual void test(){};
+ void test2(){ std::cout<<"hello";};
+};
+
+class man{};
+
+
+class son: public father, public man{
+ public:
+ son(){};
+ ~son(){};
+ private:
+ void test(){ std::cout<<"hello";}; // allow: virtual function override
+ void test2(){ std::cout<<"hello";}; // defect: bad override
+};
+
TCA独立工具TCA-Armory-R,别名RegexScanner,正则匹配工具,支持扫描文件名称和文本内容,支持页面直接自定义创建规则。
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到TCA-Armory-R工具,并将其权限状态调整为支持自定义规则。
',3),B=l('进入工具管理入口,进入TCA-Armory-R工具页面,选择上方的“自定义规则”,然后点击“添加规则”:
进入“创建规则”页面,按照需求填写相关信息,完成后,点击页面最后的“确定”按钮提交。
规则扫描场景:扫描代码中的 github token,如果token以明文形式写在源码文件中,会造成隐私泄露,可能造成严重的安全事故。
正则表达式:匹配 github token 字符串,根据github token的一般形式,可以推断出正则表达式 ((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})。
',8),N={class:"custom-container tip"},z=e("p",{class:"custom-container-title"},"提示",-1),F={href:"https://pkg.go.dev/regexp/syntax",target:"_blank",rel:"noopener noreferrer"},S=l('建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则名称、前端展示名称:建议使用单词首字母大写的格式,如 DetectedGithubToken
规则简述:作为扫描出来到问题标题
规则参数:
提示
规则参数中的(3)(4)(5)属于新功能,需要将客户端client和工具库TCA-Armory更新到最新版本
(3) [可选] regex{N}
参数,只有在已有regex
参数情况下生效,用于扩展扫描的正则表达式,其中 N 从1开始计数,例如: regex1=EAAAACZAVC6ygB[0-9A-Za-z]+
, regex2=EAAAAZAw4[0-9A-Za-z]+
。regex{N}
和regex
的表达式均为或关系,每一个匹配结果上报一个问题。
(4) [可选] regex_not
参数,用于指定正则过滤表达式,例如: regex_not=(?i)example
。可以对(2)(3)中regex匹配的字符串进行筛选,如果匹配则过滤该结果,不予上报。
(5) [可选] regex_not{N}
参数,只有在已有regex_not
参数情况下生效,用于扩展正则过滤表达式,其中 N 从1开始计数,例如: regex_not1=(?i)test
, regex_not2=(?i)fake
。regex_not{N}
和regex_not
的表达式均为或关系。
(6) [必选] msg
参数,用于展现issue说明, 例如: msg=检测到高危函数%s,建议替换。
msg中的“%s”使用regex中的group(用“()"括起来的部分)一一匹配,单个%s默认为整个regex匹配的字符串
如果regex没有定义group,则msg最多有一个%s, 并由整个regex匹配的字符串替代
如果msg里没有包含“%s”,则直接显示msg
如果msg没有提供,则会给出默认信息
(7) [可选] ignore_comment
参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如: ignore_comment=True
, 默认是False
(8) [可选] file_scan
参数,用于指定是否扫描文件名称,可选值:True、true、False、false 。例如: file_scan=True
, 默认是False
(9) [可选] include
参数,用于指定只扫描的文件匹配范围,基于相对路径,使用通配符格式,多项使用英文分号(;)隔开。例如: include=src/test;src/main.*;*.cpp
",1),O=e("li",null,[e("p",null,[o("(11)[可选] "),e("code",null,"match_group"),o(" 参数,用于指定正则匹配的分组,数值不能大于正则匹配分组数,例如: "),e("code",null,"regex=(aws_account_id)\\s{0,50}(:|=>|=)\\s{0,50}([0-9]{12})"),e("code",null,"match_group=3"),o(",匹配到第3个分组"),e("code",null,"([0-9]{12})")])],-1),P=e("p",null,[o("(12)[可选] "),e("code",null,"entropy"),o(" 参数,用于指定正则匹配结果的最小信息熵,例如:"),e("code",null,"entropy=3"),o(",熵不大于3的匹配结果将被过滤")],-1),Q={href:"https://zh.wikipedia.org/wiki/%E7%86%B5_(%E4%BF%A1%E6%81%AF%E8%AE%BA)",target:"_blank",rel:"noopener noreferrer"},U=e("h3",{id:"_4-将自定义规则添加到项目分析方案中",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-将自定义规则添加到项目分析方案中","aria-hidden":"true"},"#"),o(" 4. 将自定义规则添加到项目分析方案中")],-1),W=e("p",null,"进入 代码分析 - 分析方案 - 代码检查 - 自定义规则包 - 查看详细规则,添加规则。",-1),X=e("p",null,[e("img",{src:d,alt:"点击自定义规则包"})],-1),Y=e("p",null,[e("img",{src:h,alt:"添加规则"})],-1);function $(ee,oe){const n=s("ExternalLinkIcon"),r=s("RouterLink");return p(),u("div",null,[x,e("ul",null,[m,f,A,k,b,e("li",null,[e("em",null,[o("只支持"),e("a",y,[o("go的正则语法"),t(n)])])])]),E,T,e("ol",null,[e("li",null,[o("属于增强分析模块,需要先"),t(r,{to:"/zh/quickStarted/enhanceDeploy.html"},{default:c(()=>[o("部署CLS")]),_:1})]),C,v]),R,e("p",null,[o("规则权限详见"),t(r,{to:"/zh/guide/%E5%B7%A5%E5%85%B7%E7%AE%A1%E7%90%86/%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99.html"},{default:c(()=>[o("自定义规则权限说明")]),_:1})]),B,e("div",N,[z,e("p",null,[e("strong",null,[o("只支持go正则语法: "),e("a",F,[o("regexp"),t(n)])])])]),S,e("ul",null,[j,e("li",null,[e("p",null,[o("(2) [必选] "),q,o(" 参数,用于指定扫描的正则表达式,例如: "),w,o("。"),e("strong",null,[o("只支持go正则语法: "),e("a",Z,[o("regexp"),t(n)])]),o("。建议先测试好正则表达式是否正确,正则表达式测试网站推荐:"),e("a",L,[o("http://tool.oschina.net/regex"),t(n)])])]),V,e("li",null,[G,e("blockquote",null,[e("p",null,[o("路径过滤("),D,o(", "),I,o(")采用Glob-Style的匹配模式,详见 "),e("a",M,[o("Go-filepath-Match"),t(n)]),o(", 除了 "),H,o(" 用来匹配零或多个目录,本工具会"),J,o("。举例:")]),K])]),O,e("li",null,[P,e("blockquote",null,[e("p",null,[o("信息熵:"),e("a",Q,[o("熵(信息论)"),t(n)]),o(" 可用于敏感信息(密钥、token)的检测 含义:可以理解为字符串的混乱程度,字符越随机,熵越大。因此,设置合适的熵,可以过滤掉一些误报或者人为测试用例。")])])])]),U,W,X,Y])}const re=_(g,[["render",$],["__file","TCA-Armory-R.html.vue"]]);export{re as default}; diff --git a/assets/TCA-Armory-R.html-0470623e.js b/assets/TCA-Armory-R.html-0470623e.js new file mode 100644 index 000000000..f786690b9 --- /dev/null +++ b/assets/TCA-Armory-R.html-0470623e.js @@ -0,0 +1 @@ +import{_ as i,a}from"./createcustomrule-3919c596.js";import{_ as d,a as h}from"./scheme_codelint_03-5bcd9286.js";import{_,r as s,o as p,c as u,a as e,b as o,d as t,w as c,e as l}from"./app-2a91d8ab.js";const g={},x=l('
exclude=*.py
会忽略以下文件: main.py, src/main.py, main.py/install.shexclude=tests
会忽略以下文件: tests/test.py, a/tests/b/test.pyinclude=main.*
会只扫描以下文件: src/main.py, app/main.goinclude=src
且exclude=src/lib
会只扫描以下文件: src/main.py, src/project/proj.py; 忽略以下文件: src/lib/lib.py, src/lib/package/pack.js
TCA独立工具TCA-Armory-R,别名RegexScanner,正则匹配工具,支持扫描文件名称和文本内容,支持页面直接自定义创建规则。
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到TCA-Armory-R工具,并将其权限状态调整为支持自定义规则。
',3),B=l('进入工具管理入口,进入TCA-Armory-R工具页面,选择上方的“自定义规则”,然后点击“添加规则”:
进入“创建规则”页面,按照需求填写相关信息,完成后,点击页面最后的“确定”按钮提交。
规则扫描场景:扫描代码中的 github token,如果token以明文形式写在源码文件中,会造成隐私泄露,可能造成严重的安全事故。
正则表达式:匹配 github token 字符串,根据github token的一般形式,可以推断出正则表达式 ((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})。
',8),N={class:"custom-container tip"},F=e("p",{class:"custom-container-title"},"TIP",-1),S={href:"https://pkg.go.dev/regexp/syntax",target:"_blank",rel:"noopener noreferrer"},j=l('建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则名称、前端展示名称:建议使用单词首字母大写的格式,如 DetectedGithubToken
规则简述:作为扫描出来到问题标题
规则参数:
TIP
规则参数中的(3)(4)(5)属于新功能,需要将客户端client和工具库TCA-Armory更新到最新版本
(3) [可选] regex{N}
参数,只有在已有regex
参数情况下生效,用于扩展扫描的正则表达式,其中 N 从1开始计数,例如: regex1=EAAAACZAVC6ygB[0-9A-Za-z]+
, regex2=EAAAAZAw4[0-9A-Za-z]+
。regex{N}
和regex
的表达式均为或关系,每一个匹配结果上报一个问题。
(4) [可选] regex_not
参数,用于指定正则过滤表达式,例如: regex_not=(?i)example
。可以对(2)(3)中regex匹配的字符串进行筛选,如果匹配则过滤该结果,不予上报。
(5) [可选] regex_not{N}
参数,只有在已有regex_not
参数情况下生效,用于扩展正则过滤表达式,其中 N 从1开始计数,例如: regex_not1=(?i)test
, regex_not2=(?i)fake
。regex_not{N}
和regex_not
的表达式均为或关系。
(6) [必选] msg
参数,用于展现issue说明, 例如: msg=检测到高危函数%s,建议替换。
msg中的“%s”使用regex中的group(用“()"括起来的部分)一一匹配,单个%s默认为整个regex匹配的字符串
如果regex没有定义group,则msg最多有一个%s, 并由整个regex匹配的字符串替代
如果msg里没有包含“%s”,则直接显示msg
如果msg没有提供,则会给出默认信息
(7) [可选] ignore_comment
参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如: ignore_comment=True
, 默认是False
(8) [可选] file_scan
参数,用于指定是否扫描文件名称,可选值:True、true、False、false 。例如: file_scan=True
, 默认是False
(9) [可选] include
参数,用于指定只扫描的文件匹配范围,基于相对路径,使用通配符格式,多项使用英文分号(;)隔开。例如: include=src/test;src/main.*;*.cpp
",1),K=e("li",null,[e("p",null,[o("(11)[可选] "),e("code",null,"match_group"),o(" 参数,用于指定正则匹配的分组,数值不能大于正则匹配分组数,例如: "),e("code",null,"regex=(aws_account_id)\\s{0,50}(:|=>|=)\\s{0,50}([0-9]{12})"),e("code",null,"match_group=3"),o(",匹配到第3个分组"),e("code",null,"([0-9]{12})")])],-1),O=e("p",null,[o("(12)[可选] "),e("code",null,"entropy"),o(" 参数,用于指定正则匹配结果的最小信息熵,例如:"),e("code",null,"entropy=3"),o(",熵不大于3的匹配结果将被过滤")],-1),Q={href:"https://zh.wikipedia.org/wiki/%E7%86%B5_(%E4%BF%A1%E6%81%AF%E8%AE%BA)",target:"_blank",rel:"noopener noreferrer"},U=e("h3",{id:"_4-将自定义规则添加到项目分析方案中",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-将自定义规则添加到项目分析方案中","aria-hidden":"true"},"#"),o(" 4. 将自定义规则添加到项目分析方案中")],-1),W=e("p",null,"进入 代码分析 - 分析方案 - 代码检查 - 自定义规则包 - 查看详细规则,添加规则。",-1),X=e("p",null,[e("img",{src:d,alt:"点击自定义规则包"})],-1),Y=e("p",null,[e("img",{src:h,alt:"添加规则"})],-1);function $(ee,oe){const n=s("ExternalLinkIcon"),r=s("RouterLink");return p(),u("div",null,[x,e("ul",null,[m,f,A,k,b,e("li",null,[e("em",null,[o("只支持"),e("a",y,[o("go的正则语法"),t(n)])])])]),E,T,e("ol",null,[e("li",null,[o("属于增强分析模块,需要先"),t(r,{to:"/en/quickStarted/enhanceDeploy.html"},{default:c(()=>[o("部署CLS")]),_:1})]),C,v]),R,e("p",null,[o("规则权限详见"),t(r,{to:"/en/guide/%E5%B7%A5%E5%85%B7%E7%AE%A1%E7%90%86/%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99.html"},{default:c(()=>[o("自定义规则权限说明")]),_:1})]),B,e("div",N,[F,e("p",null,[e("strong",null,[o("只支持go正则语法: "),e("a",S,[o("regexp"),t(n)])])])]),j,e("ul",null,[q,e("li",null,[e("p",null,[o("(2) [必选] "),w,o(" 参数,用于指定扫描的正则表达式,例如: "),Z,o("。"),e("strong",null,[o("只支持go正则语法: "),e("a",z,[o("regexp"),t(n)])]),o("。建议先测试好正则表达式是否正确,正则表达式测试网站推荐:"),e("a",L,[o("http://tool.oschina.net/regex"),t(n)])])]),V,e("li",null,[I,e("blockquote",null,[e("p",null,[o("路径过滤("),G,o(", "),D,o(")采用Glob-Style的匹配模式,详见 "),e("a",M,[o("Go-filepath-Match"),t(n)]),o(", 除了 "),P,o(" 用来匹配零或多个目录,本工具会"),H,o("。举例:")]),J])]),K,e("li",null,[O,e("blockquote",null,[e("p",null,[o("信息熵:"),e("a",Q,[o("熵(信息论)"),t(n)]),o(" 可用于敏感信息(密钥、token)的检测 含义:可以理解为字符串的混乱程度,字符越随机,熵越大。因此,设置合适的熵,可以过滤掉一些误报或者人为测试用例。")])])])]),U,W,X,Y])}const re=_(g,[["render",$],["__file","TCA-Armory-R.html.vue"]]);export{re as default}; diff --git a/assets/TCA-Armory-R.html-a4907275.js b/assets/TCA-Armory-R.html-a4907275.js new file mode 100644 index 000000000..9835a9293 --- /dev/null +++ b/assets/TCA-Armory-R.html-a4907275.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-6d0cdd3c","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-R.html","title":"TCA-Armory-R 使用手册","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"适用场景","slug":"适用场景","link":"#适用场景","children":[]},{"level":2,"title":"对比RegexScan、RegexFileScan","slug":"对比regexscan、regexfilescan","link":"#对比regexscan、regexfilescan","children":[]},{"level":2,"title":"快速接入","slug":"快速接入","link":"#快速接入","children":[]},{"level":2,"title":"自定义规则","slug":"自定义规则","link":"#自定义规则","children":[{"level":3,"title":"1. 开放支持自定义规则权限","slug":"_1-开放支持自定义规则权限","link":"#_1-开放支持自定义规则权限","children":[]},{"level":3,"title":"2. 添加规则","slug":"_2-添加规则","link":"#_2-添加规则","children":[]},{"level":3,"title":"3. 填写规则信息","slug":"_3-填写规则信息","link":"#_3-填写规则信息","children":[]},{"level":3,"title":"规则示例:","slug":"规则示例","link":"#规则示例","children":[]},{"level":3,"title":"字段解释","slug":"字段解释","link":"#字段解释","children":[]},{"level":3,"title":"4. 将自定义规则添加到项目分析方案中","slug":"_4-将自定义规则添加到项目分析方案中","link":"#_4-将自定义规则添加到项目分析方案中","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/工具/TCA-Armory-R.md"}');export{e as data}; diff --git a/assets/TCA-Armory-R.html-d83fb336.js b/assets/TCA-Armory-R.html-d83fb336.js new file mode 100644 index 000000000..5deb050b4 --- /dev/null +++ b/assets/TCA-Armory-R.html-d83fb336.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-027ae47e","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-R.html","title":"TCA-Armory-R 使用手册","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"适用场景","slug":"适用场景","link":"#适用场景","children":[]},{"level":2,"title":"对比RegexScan、RegexFileScan","slug":"对比regexscan、regexfilescan","link":"#对比regexscan、regexfilescan","children":[]},{"level":2,"title":"快速接入","slug":"快速接入","link":"#快速接入","children":[]},{"level":2,"title":"自定义规则","slug":"自定义规则","link":"#自定义规则","children":[{"level":3,"title":"1. 开放支持自定义规则权限","slug":"_1-开放支持自定义规则权限","link":"#_1-开放支持自定义规则权限","children":[]},{"level":3,"title":"2. 添加规则","slug":"_2-添加规则","link":"#_2-添加规则","children":[]},{"level":3,"title":"3. 填写规则信息","slug":"_3-填写规则信息","link":"#_3-填写规则信息","children":[]},{"level":3,"title":"规则示例:","slug":"规则示例","link":"#规则示例","children":[]},{"level":3,"title":"字段解释","slug":"字段解释","link":"#字段解释","children":[]},{"level":3,"title":"4. 将自定义规则添加到项目分析方案中","slug":"_4-将自定义规则添加到项目分析方案中","link":"#_4-将自定义规则添加到项目分析方案中","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/工具/TCA-Armory-R.md"}');export{e as data}; diff --git a/assets/Welcome-e497e1a9.png b/assets/Welcome-e497e1a9.png new file mode 100644 index 000000000..0184d09b4 Binary files /dev/null and b/assets/Welcome-e497e1a9.png differ diff --git a/assets/addcustomrules-220aab00.png b/assets/addcustomrules-220aab00.png new file mode 100644 index 000000000..a6749e7c8 Binary files /dev/null and b/assets/addcustomrules-220aab00.png differ diff --git a/assets/app-2a91d8ab.js b/assets/app-2a91d8ab.js new file mode 100644 index 000000000..bb09ddd32 --- /dev/null +++ b/assets/app-2a91d8ab.js @@ -0,0 +1,10 @@ +const Ys="modulepreload",Xs=function(e){return"/CodeAnalysis/"+e},Jn={},u=function(t,l,i){if(!l||l.length===0)return t();const n=document.getElementsByTagName("link");return Promise.all(l.map(r=>{if(r=Xs(r),r in Jn)return;Jn[r]=!0;const o=r.endsWith(".css"),s=o?'[rel="stylesheet"]':"";if(!!i)for(let d=n.length-1;d>=0;d--){const E=n[d];if(E.href===r&&(!o||E.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${r}"]${s}`))return;const c=document.createElement("link");if(c.rel=o?"stylesheet":Ys,o||(c.as="script",c.crossOrigin=""),c.href=r,document.head.appendChild(c),o)return new Promise((d,E)=>{c.addEventListener("load",d),c.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())};function vn(e,t){const l=Object.create(null),i=e.split(",");for(let n=0;n
exclude=*.py
会忽略以下文件: main.py, src/main.py, main.py/install.shexclude=tests
会忽略以下文件: tests/test.py, a/tests/b/test.pyinclude=main.*
会只扫描以下文件: src/main.py, app/main.goinclude=src
且exclude=src/lib
会只扫描以下文件: src/main.py, src/project/proj.py; 忽略以下文件: src/lib/lib.py, src/lib/package/pack.js
初始发布
',74),d=[h];function s(c,n){return i(),a("div",null,d)}const u=e(r,[["render",s],["__file","changelog.html.vue"]]);export{u as default}; diff --git a/assets/changelog.html-55c50323.js b/assets/changelog.html-55c50323.js new file mode 100644 index 000000000..81cec38ee --- /dev/null +++ b/assets/changelog.html-55c50323.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3179abd3","path":"/zh/community/changelog.html","title":"更新日志","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"V1.4.1 (2022-7-28)","slug":"v1-4-1-2022-7-28","link":"#v1-4-1-2022-7-28","children":[{"level":3,"title":"Features","slug":"features","link":"#features","children":[]},{"level":3,"title":"Docs","slug":"docs","link":"#docs","children":[]}]},{"level":2,"title":"V1.4.0 (2022-7-18)","slug":"v1-4-0-2022-7-18","link":"#v1-4-0-2022-7-18","children":[{"level":3,"title":"Features","slug":"features-1","link":"#features-1","children":[]},{"level":3,"title":"Docs","slug":"docs-1","link":"#docs-1","children":[]}]},{"level":2,"title":"V1.3.3 (2022-6-29)","slug":"v1-3-3-2022-6-29","link":"#v1-3-3-2022-6-29","children":[{"level":3,"title":"Features","slug":"features-2","link":"#features-2","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes","link":"#bugfixes","children":[]},{"level":3,"title":"Docs","slug":"docs-2","link":"#docs-2","children":[]}]},{"level":2,"title":"V1.3.2 (2022-6-16)","slug":"v1-3-2-2022-6-16","link":"#v1-3-2-2022-6-16","children":[{"level":3,"title":"Features","slug":"features-3","link":"#features-3","children":[]},{"level":3,"title":"Docs","slug":"docs-3","link":"#docs-3","children":[]}]},{"level":2,"title":"V1.3.1 (2022-6-14)","slug":"v1-3-1-2022-6-14","link":"#v1-3-1-2022-6-14","children":[{"level":3,"title":"Features","slug":"features-4","link":"#features-4","children":[]}]},{"level":2,"title":"V1.3.0 (2022-6-7)","slug":"v1-3-0-2022-6-7","link":"#v1-3-0-2022-6-7","children":[{"level":3,"title":"Features","slug":"features-5","link":"#features-5","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-1","link":"#bugfixes-1","children":[]},{"level":3,"title":"Docs","slug":"docs-4","link":"#docs-4","children":[]}]},{"level":2,"title":"V1.2.1 (2022-5-24)","slug":"v1-2-1-2022-5-24","link":"#v1-2-1-2022-5-24","children":[{"level":3,"title":"Features","slug":"features-6","link":"#features-6","children":[]},{"level":3,"title":"Docs","slug":"docs-5","link":"#docs-5","children":[]}]},{"level":2,"title":"V1.2.0 (2022-4-27)","slug":"v1-2-0-2022-4-27","link":"#v1-2-0-2022-4-27","children":[{"level":3,"title":"Features","slug":"features-7","link":"#features-7","children":[]},{"level":3,"title":"Docs","slug":"docs-6","link":"#docs-6","children":[]}]},{"level":2,"title":"V1.1.3 (2022-4-18)","slug":"v1-1-3-2022-4-18","link":"#v1-1-3-2022-4-18","children":[{"level":3,"title":"Features","slug":"features-8","link":"#features-8","children":[]},{"level":3,"title":"Docs","slug":"docs-7","link":"#docs-7","children":[]}]},{"level":2,"title":"V1.1.2 (2022-4-2)","slug":"v1-1-2-2022-4-2","link":"#v1-1-2-2022-4-2","children":[{"level":3,"title":"Features","slug":"features-9","link":"#features-9","children":[]},{"level":3,"title":"Docs","slug":"docs-8","link":"#docs-8","children":[]}]},{"level":2,"title":"V1.1.1 (2022-3-31)","slug":"v1-1-1-2022-3-31","link":"#v1-1-1-2022-3-31","children":[{"level":3,"title":"Features","slug":"features-10","link":"#features-10","children":[]},{"level":3,"title":"Docs","slug":"docs-9","link":"#docs-9","children":[]}]},{"level":2,"title":"V1.1.0 (2022-3-29)","slug":"v1-1-0-2022-3-29","link":"#v1-1-0-2022-3-29","children":[{"level":3,"title":"Features","slug":"features-11","link":"#features-11","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-2","link":"#bugfixes-2","children":[]},{"level":3,"title":"Docs","slug":"docs-10","link":"#docs-10","children":[]}]},{"level":2,"title":"V1.0.1 (2022-03-01)","slug":"v1-0-1-2022-03-01","link":"#v1-0-1-2022-03-01","children":[{"level":3,"title":"Features","slug":"features-12","link":"#features-12","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-3","link":"#bugfixes-3","children":[]},{"level":3,"title":"Docs","slug":"docs-11","link":"#docs-11","children":[]}]},{"level":2,"title":"V1.0.0","slug":"v1-0-0","link":"#v1-0-0","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/community/changelog.md"}');export{e as data}; diff --git a/assets/changelog.html-c22ca463.js b/assets/changelog.html-c22ca463.js new file mode 100644 index 000000000..618238893 --- /dev/null +++ b/assets/changelog.html-c22ca463.js @@ -0,0 +1 @@ +import{_ as e,o as i,c as a,e as l}from"./app-2a91d8ab.js";const r={},h=l('初始发布
',74),d=[h];function s(c,n){return i(),a("div",null,d)}const u=e(r,[["render",s],["__file","changelog.html.vue"]]);export{u as default}; diff --git a/assets/changelog.html-c4b08e96.js b/assets/changelog.html-c4b08e96.js new file mode 100644 index 000000000..e22c446ca --- /dev/null +++ b/assets/changelog.html-c4b08e96.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ee298290","path":"/en/community/changelog.html","title":"更新日志","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"V1.4.1 (2022-7-28)","slug":"v1-4-1-2022-7-28","link":"#v1-4-1-2022-7-28","children":[{"level":3,"title":"Features","slug":"features","link":"#features","children":[]},{"level":3,"title":"Docs","slug":"docs","link":"#docs","children":[]}]},{"level":2,"title":"V1.4.0 (2022-7-18)","slug":"v1-4-0-2022-7-18","link":"#v1-4-0-2022-7-18","children":[{"level":3,"title":"Features","slug":"features-1","link":"#features-1","children":[]},{"level":3,"title":"Docs","slug":"docs-1","link":"#docs-1","children":[]}]},{"level":2,"title":"V1.3.3 (2022-6-29)","slug":"v1-3-3-2022-6-29","link":"#v1-3-3-2022-6-29","children":[{"level":3,"title":"Features","slug":"features-2","link":"#features-2","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes","link":"#bugfixes","children":[]},{"level":3,"title":"Docs","slug":"docs-2","link":"#docs-2","children":[]}]},{"level":2,"title":"V1.3.2 (2022-6-16)","slug":"v1-3-2-2022-6-16","link":"#v1-3-2-2022-6-16","children":[{"level":3,"title":"Features","slug":"features-3","link":"#features-3","children":[]},{"level":3,"title":"Docs","slug":"docs-3","link":"#docs-3","children":[]}]},{"level":2,"title":"V1.3.1 (2022-6-14)","slug":"v1-3-1-2022-6-14","link":"#v1-3-1-2022-6-14","children":[{"level":3,"title":"Features","slug":"features-4","link":"#features-4","children":[]}]},{"level":2,"title":"V1.3.0 (2022-6-7)","slug":"v1-3-0-2022-6-7","link":"#v1-3-0-2022-6-7","children":[{"level":3,"title":"Features","slug":"features-5","link":"#features-5","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-1","link":"#bugfixes-1","children":[]},{"level":3,"title":"Docs","slug":"docs-4","link":"#docs-4","children":[]}]},{"level":2,"title":"V1.2.1 (2022-5-24)","slug":"v1-2-1-2022-5-24","link":"#v1-2-1-2022-5-24","children":[{"level":3,"title":"Features","slug":"features-6","link":"#features-6","children":[]},{"level":3,"title":"Docs","slug":"docs-5","link":"#docs-5","children":[]}]},{"level":2,"title":"V1.2.0 (2022-4-27)","slug":"v1-2-0-2022-4-27","link":"#v1-2-0-2022-4-27","children":[{"level":3,"title":"Features","slug":"features-7","link":"#features-7","children":[]},{"level":3,"title":"Docs","slug":"docs-6","link":"#docs-6","children":[]}]},{"level":2,"title":"V1.1.3 (2022-4-18)","slug":"v1-1-3-2022-4-18","link":"#v1-1-3-2022-4-18","children":[{"level":3,"title":"Features","slug":"features-8","link":"#features-8","children":[]},{"level":3,"title":"Docs","slug":"docs-7","link":"#docs-7","children":[]}]},{"level":2,"title":"V1.1.2 (2022-4-2)","slug":"v1-1-2-2022-4-2","link":"#v1-1-2-2022-4-2","children":[{"level":3,"title":"Features","slug":"features-9","link":"#features-9","children":[]},{"level":3,"title":"Docs","slug":"docs-8","link":"#docs-8","children":[]}]},{"level":2,"title":"V1.1.1 (2022-3-31)","slug":"v1-1-1-2022-3-31","link":"#v1-1-1-2022-3-31","children":[{"level":3,"title":"Features","slug":"features-10","link":"#features-10","children":[]},{"level":3,"title":"Docs","slug":"docs-9","link":"#docs-9","children":[]}]},{"level":2,"title":"V1.1.0 (2022-3-29)","slug":"v1-1-0-2022-3-29","link":"#v1-1-0-2022-3-29","children":[{"level":3,"title":"Features","slug":"features-11","link":"#features-11","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-2","link":"#bugfixes-2","children":[]},{"level":3,"title":"Docs","slug":"docs-10","link":"#docs-10","children":[]}]},{"level":2,"title":"V1.0.1 (2022-03-01)","slug":"v1-0-1-2022-03-01","link":"#v1-0-1-2022-03-01","children":[{"level":3,"title":"Features","slug":"features-12","link":"#features-12","children":[]},{"level":3,"title":"Bugfixes","slug":"bugfixes-3","link":"#bugfixes-3","children":[]},{"level":3,"title":"Docs","slug":"docs-11","link":"#docs-11","children":[]}]},{"level":2,"title":"V1.0.0","slug":"v1-0-0","link":"#v1-0-0","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/community/changelog.md"}');export{e as data}; diff --git a/assets/codeDeploy.html-0291e9cf.js b/assets/codeDeploy.html-0291e9cf.js new file mode 100644 index 000000000..53d61c013 --- /dev/null +++ b/assets/codeDeploy.html-0291e9cf.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-64f30f77","path":"/en/quickStarted/codeDeploy.html","title":"源代码快速部署","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/quickStarted/codeDeploy.md"}');export{e as data}; diff --git a/assets/codeDeploy.html-319b644b.js b/assets/codeDeploy.html-319b644b.js new file mode 100644 index 000000000..1a74b461d --- /dev/null +++ b/assets/codeDeploy.html-319b644b.js @@ -0,0 +1,7 @@ +import{_ as d,r as c,o as n,c as t,a as l,b as e,d as a,w as o,e as s}from"./app-2a91d8ab.js";const r={},h=l("h1",{id:"源代码快速部署",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#源代码快速部署","aria-hidden":"true"},"#"),e(" 源代码快速部署")],-1),p=l("br",null,null,-1),u=s(`系统环境
环境准备
提示
TCA 一键部署脚本已封装好 Python、Mariadb、Redis 与 Nginx 安装步骤,无需自行安装,本地部署体验可按 操作说明 内容直接进行部署操作。
注意:生产环境建议使用专业的 MySQL、Redis 等服务
Python 3.7
MySQL 服务(MySQL5.7.8 以上版本或 Mariadb 10.5 以上版本)
Redis 服务(4.0版本以上)
Nginx 服务
权限准备
CREATE、ALTER、INDEX、DELETE、LOCK TABLES、SELECT、INSERT、REFERENCES、UPDATE
权限端口使用:需要开放80端口的访问权限(80为TCA平台默认访问端口),或调整 Web 服务默认的访问端口地址
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
安装基础软件与部署 TCA(可根据脚本选项确定是否要安装 Python、MySQL、Redis、Nginx 相关基础软件),执行
$ bash ./quick_install.sh local deploy
+
执行该命令会做以下四个步骤:
Install
:检测本地 Python3.7、Mariadb/MySQL、Redis 与 Nginx,如果不存在会提示安装Init
:部署 TCA Server、Web与Client,并进行初始化Start
:启动 TCA Server、Web与ClientCheck
:检测 TCA 的运行状态注意:在运行过程中,脚本会检测本地是否安装了相关基础软件(Python3.7、MySQL/Mariadb、Redis、Nignx),如果未安装会输出以下类似提示语:
Do you want to install [Redis] by this script?
+Please enter:[Y/N]
+
如果确定通过脚本安装可以输入Y
。
1. 更新代码
2. 执行以下命令
bash ./quick_install.sh local install tca #更新相关配置
+bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+bash ./quick_install.sh local check #检查服务是否启动失败
+
注意:local install
命令行参数说明:
- base
:安装 Python、Mariadb/MySQL、Redis 与 Nginx
- tca
:初始化或更新 TCA Server、Web、Client 相关配置和数据
- server
:初始化或更新 TCA Server 相关配置和数据
- web
:初始化或更新 TCA Web 相关配置和数据
- client
:初始化或更新 TCA Client 相关配置和数据
- 不填参数,默认会执行base
、tca
相关操作
启动所有服务:bash ./quick_install.sh local start
启动Main相关服务:bash ./quick_install.sh local start main
local start
支持启动指定服务,如上述的启动Main服务,还支持mysql/redis/analysis/file/login/scmproxy/nginx/client/all
停止所有服务:bash ./quick_install.sh local stop
停止Main相关服务:bash ./quick_install.sh local stop main
local stop
支持停止指定服务,如上述的停止Main服务,还支持analysis/file/login/scmproxy/nginx/client/all
注意:
启动时会自动关闭之前已经运行的服务
mysql
和redis
默认会使用systemctl
进行启动,如果systemctl
无法使用,则会直接使用nohup
方式运行相关服务
检查服务运行状态:bash ./quick_install.sh local check
打印 TCA Server 各个服务的日志路径: bash ./quick_install.sh local log
系统环境
环境准备
TIP
TCA 一键部署脚本已封装好 Python、Mariadb、Redis 与 Nginx 安装步骤,无需自行安装,本地部署体验可按 操作说明 内容直接进行部署操作。
注意:生产环境建议使用专业的 MySQL、Redis 等服务
Python 3.7
MySQL 服务(MySQL5.7.8 以上版本或 Mariadb 10.5 以上版本)
Redis 服务(4.0版本以上)
Nginx 服务
权限准备
CREATE、ALTER、INDEX、DELETE、LOCK TABLES、SELECT、INSERT、REFERENCES、UPDATE
权限端口使用:需要开放80端口的访问权限(80为TCA平台默认访问端口),或调整 Web 服务默认的访问端口地址
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
安装基础软件与部署 TCA(可根据脚本选项确定是否要安装 Python、MySQL、Redis、Nginx 相关基础软件),执行
$ bash ./quick_install.sh local deploy
+
执行该命令会做以下四个步骤:
Install
:检测本地 Python3.7、Mariadb/MySQL、Redis 与 Nginx,如果不存在会提示安装Init
:部署 TCA Server、Web与Client,并进行初始化Start
:启动 TCA Server、Web与ClientCheck
:检测 TCA 的运行状态注意:在运行过程中,脚本会检测本地是否安装了相关基础软件(Python3.7、MySQL/Mariadb、Redis、Nignx),如果未安装会输出以下类似提示语:
Do you want to install [Redis] by this script?
+Please enter:[Y/N]
+
如果确定通过脚本安装可以输入Y
。
1. 更新代码
2. 执行以下命令
bash ./quick_install.sh local install tca #更新相关配置
+bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+bash ./quick_install.sh local check #检查服务是否启动失败
+
注意:local install
命令行参数说明:
- base
:安装 Python、Mariadb/MySQL、Redis 与 Nginx
- tca
:初始化或更新 TCA Server、Web、Client 相关配置和数据
- server
:初始化或更新 TCA Server 相关配置和数据
- web
:初始化或更新 TCA Web 相关配置和数据
- client
:初始化或更新 TCA Client 相关配置和数据
- 不填参数,默认会执行base
、tca
相关操作
启动所有服务:bash ./quick_install.sh local start
启动Main相关服务:bash ./quick_install.sh local start main
local start
支持启动指定服务,如上述的启动Main服务,还支持mysql/redis/analysis/file/login/scmproxy/nginx/client/all
停止所有服务:bash ./quick_install.sh local stop
停止Main相关服务:bash ./quick_install.sh local stop main
local stop
支持停止指定服务,如上述的停止Main服务,还支持analysis/file/login/scmproxy/nginx/client/all
注意:
启动时会自动关闭之前已经运行的服务
mysql
和redis
默认会使用systemctl
进行启动,如果systemctl
无法使用,则会直接使用nohup
方式运行相关服务
检查服务运行状态:bash ./quick_install.sh local check
打印 TCA Server 各个服务的日志路径: bash ./quick_install.sh local log
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
为了帮助你正确地格式化代码,我们建议你使用clang-format进行代码自动格式化。工具可直接通过 Homebrew 进行安装:
brew install clang-format
+
安装完成后将 .clang-format 配置文件置于工程根目录,执行 clang-format -i FILE.m 即可完成自动格式化。目前格式化工具配置仅支持11.0版本。
`,6);function N(T,x){const n=o("ExternalLinkIcon");return a(),l("div",null,[h,A,d,e("ul",null,[e("li",null,[e("a",E,[t("ObjectiveC/Copyright"),r(n)])]),e("li",null,[e("a",C,[t("ObjectiveC/Indent"),r(n)])]),e("li",null,[e("a",b,[t("ObjectiveC/MaxLinesPerFunction"),r(n)])]),e("li",null,[e("a",g,[t("ObjectiveC/MissingDocInterface"),r(n)])]),e("li",null,[e("a",_,[t("ObjectiveC/MissingDocProperty"),r(n)])]),e("li",null,[e("a",u,[t("ObjectiveC/MissingDocProtocol"),r(n)])]),e("li",null,[e("a",m,[t("ObjectiveC/ParameterCount"),r(n)])]),e("li",null,[e("a",B,[t("ObjectiveC/ClassNaming"),r(n)])]),e("li",null,[e("a",p,[t("ObjectiveC/FunctionNaming"),r(n)])]),e("li",null,[e("a",f,[t("ObjectiveC/GlobalVariableNaming"),r(n)])]),e("li",null,[e("a",v,[t("ObjectiveC/LocalVariableNaming"),r(n)])]),e("li",null,[e("a",j,[t("ObjectiveC/MacroNaming"),r(n)])]),e("li",null,[e("a",y,[t("ObjectiveC/MethodNaming"),r(n)])]),e("li",null,[e("a",O,[t("ObjectiveC/ParameterNaming"),r(n)])]),e("li",null,[e("a",F,[t("ObjectiveC/MaxLineLength"),r(n)])])]),k])}const M=i(c,[["render",N],["__file","code_spec_oc.html.vue"]]);export{M as default}; diff --git a/assets/code_spec_oc.html-9d084275.js b/assets/code_spec_oc.html-9d084275.js new file mode 100644 index 000000000..4219451ec --- /dev/null +++ b/assets/code_spec_oc.html-9d084275.js @@ -0,0 +1,2 @@ +import{_ as i,r as o,o as a,c as l,a as e,b as t,d as r,e as s}from"./app-2a91d8ab.js";const c={},A=e("h1",{id:"【objective-c】代码规范规则包",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【objective-c】代码规范规则包","aria-hidden":"true"},"#"),t(" 【Objective-C】代码规范规则包")],-1),h=e("p",null,"该规则包针对 Objective-C/C++ 语言进行代码规范相关检查。",-1),d=e("h2",{id:"规则列表",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#规则列表","aria-hidden":"true"},"#"),t(" 规则列表")],-1),E={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/Copyright",target:"_blank",rel:"noopener noreferrer"},C={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/Indent",target:"_blank",rel:"noopener noreferrer"},b={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MaxLinesPerFunction",target:"_blank",rel:"noopener noreferrer"},g={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MissingDocInterface",target:"_blank",rel:"noopener noreferrer"},_={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MissingDocProperty",target:"_blank",rel:"noopener noreferrer"},u={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MissingDocProtocol",target:"_blank",rel:"noopener noreferrer"},m={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/ParameterCount",target:"_blank",rel:"noopener noreferrer"},B={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/ClassNaming",target:"_blank",rel:"noopener noreferrer"},p={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/FunctionNaming",target:"_blank",rel:"noopener noreferrer"},f={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/GlobalVariableNaming",target:"_blank",rel:"noopener noreferrer"},v={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/LocalVariableNaming",target:"_blank",rel:"noopener noreferrer"},j={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MacroNaming",target:"_blank",rel:"noopener noreferrer"},y={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MethodNaming",target:"_blank",rel:"noopener noreferrer"},O={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/ParameterNaming",target:"_blank",rel:"noopener noreferrer"},F={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-C1.html#ObjectiveC/MaxLineLength",target:"_blank",rel:"noopener noreferrer"},k=s(`分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
为了帮助你正确地格式化代码,我们建议你使用clang-format进行代码自动格式化。工具可直接通过 Homebrew 进行安装:
brew install clang-format
+
安装完成后将 .clang-format 配置文件置于工程根目录,执行 clang-format -i FILE.m 即可完成自动格式化。目前格式化工具配置仅支持11.0版本。
`,6);function N(T,x){const n=o("ExternalLinkIcon");return a(),l("div",null,[A,h,d,e("ul",null,[e("li",null,[e("a",E,[t("ObjectiveC/Copyright"),r(n)])]),e("li",null,[e("a",C,[t("ObjectiveC/Indent"),r(n)])]),e("li",null,[e("a",b,[t("ObjectiveC/MaxLinesPerFunction"),r(n)])]),e("li",null,[e("a",g,[t("ObjectiveC/MissingDocInterface"),r(n)])]),e("li",null,[e("a",_,[t("ObjectiveC/MissingDocProperty"),r(n)])]),e("li",null,[e("a",u,[t("ObjectiveC/MissingDocProtocol"),r(n)])]),e("li",null,[e("a",m,[t("ObjectiveC/ParameterCount"),r(n)])]),e("li",null,[e("a",B,[t("ObjectiveC/ClassNaming"),r(n)])]),e("li",null,[e("a",p,[t("ObjectiveC/FunctionNaming"),r(n)])]),e("li",null,[e("a",f,[t("ObjectiveC/GlobalVariableNaming"),r(n)])]),e("li",null,[e("a",v,[t("ObjectiveC/LocalVariableNaming"),r(n)])]),e("li",null,[e("a",j,[t("ObjectiveC/MacroNaming"),r(n)])]),e("li",null,[e("a",y,[t("ObjectiveC/MethodNaming"),r(n)])]),e("li",null,[e("a",O,[t("ObjectiveC/ParameterNaming"),r(n)])]),e("li",null,[e("a",F,[t("ObjectiveC/MaxLineLength"),r(n)])])]),k])}const L=i(c,[["render",N],["__file","code_spec_oc.html.vue"]]);export{L as default}; diff --git a/assets/code_spec_oc.html-b745b523.js b/assets/code_spec_oc.html-b745b523.js new file mode 100644 index 000000000..edda42440 --- /dev/null +++ b/assets/code_spec_oc.html-b745b523.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1f200688","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/code_spec_oc.html","title":"【Objective-C】代码规范规则包","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"规则列表","slug":"规则列表","link":"#规则列表","children":[]},{"level":2,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":2,"title":"格式化工具","slug":"格式化工具","link":"#格式化工具","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/规则包/code_spec_oc.md"}');export{e as data}; diff --git a/assets/code_spec_oc.html-c551e928.js b/assets/code_spec_oc.html-c551e928.js new file mode 100644 index 000000000..5958fdb21 --- /dev/null +++ b/assets/code_spec_oc.html-c551e928.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-02d030be","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/code_spec_oc.html","title":"【Objective-C】代码规范规则包","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"规则列表","slug":"规则列表","link":"#规则列表","children":[]},{"level":2,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":2,"title":"格式化工具","slug":"格式化工具","link":"#格式化工具","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/规则包/code_spec_oc.md"}');export{e as data}; diff --git a/assets/codelint_01-16d22a72.png b/assets/codelint_01-16d22a72.png new file mode 100644 index 000000000..ce5098c2c Binary files /dev/null and b/assets/codelint_01-16d22a72.png differ diff --git a/assets/codelint_02-f10f8b1f.png b/assets/codelint_02-f10f8b1f.png new file mode 100644 index 000000000..406a93799 Binary files /dev/null and b/assets/codelint_02-f10f8b1f.png differ diff --git a/assets/codelint_03-2a32e4e0.png b/assets/codelint_03-2a32e4e0.png new file mode 100644 index 000000000..d013b2511 Binary files /dev/null and b/assets/codelint_03-2a32e4e0.png differ diff --git a/assets/codelint_03-8fa68424.js b/assets/codelint_03-8fa68424.js new file mode 100644 index 000000000..3f4ba18a4 --- /dev/null +++ b/assets/codelint_03-8fa68424.js @@ -0,0 +1 @@ +const s="/CodeAnalysis/assets/codelint_01-16d22a72.png",o="/CodeAnalysis/assets/codelint_02-f10f8b1f.png",t="/CodeAnalysis/assets/codelint_03-2a32e4e0.png";export{s as _,o as a,t as b}; diff --git a/assets/codelint_04-0c416697.png b/assets/codelint_04-0c416697.png new file mode 100644 index 000000000..b315bc7bf Binary files /dev/null and b/assets/codelint_04-0c416697.png differ diff --git a/assets/contribute.html-50405d2a.js b/assets/contribute.html-50405d2a.js new file mode 100644 index 000000000..44bc04e9a --- /dev/null +++ b/assets/contribute.html-50405d2a.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5b86903e","path":"/zh/community/contribute.html","title":"贡献指南","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"报告问题","slug":"报告问题","link":"#报告问题","children":[{"level":3,"title":"搜索已知issue","slug":"搜索已知issue","link":"#搜索已知issue","children":[]},{"level":3,"title":"报告新issue","slug":"报告新issue","link":"#报告新issue","children":[]}]},{"level":2,"title":"Pull Request","slug":"pull-request","link":"#pull-request","children":[{"level":3,"title":"分支管理","slug":"分支管理","link":"#分支管理","children":[]},{"level":3,"title":"提交Pull Request","slug":"提交pull-request","link":"#提交pull-request","children":[]}]},{"level":2,"title":"许可","slug":"许可","link":"#许可","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/community/contribute.md"}');export{e as data}; diff --git a/assets/contribute.html-58671db5.js b/assets/contribute.html-58671db5.js new file mode 100644 index 000000000..a955f967f --- /dev/null +++ b/assets/contribute.html-58671db5.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1b714c0e","path":"/en/community/contribute.html","title":"贡献指南","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"报告问题","slug":"报告问题","link":"#报告问题","children":[{"level":3,"title":"搜索已知issue","slug":"搜索已知issue","link":"#搜索已知issue","children":[]},{"level":3,"title":"报告新issue","slug":"报告新issue","link":"#报告新issue","children":[]}]},{"level":2,"title":"Pull Request","slug":"pull-request","link":"#pull-request","children":[{"level":3,"title":"分支管理","slug":"分支管理","link":"#分支管理","children":[]},{"level":3,"title":"提交Pull Request","slug":"提交pull-request","link":"#提交pull-request","children":[]}]},{"level":2,"title":"许可","slug":"许可","link":"#许可","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/community/contribute.md"}');export{e as data}; diff --git a/assets/contribute.html-bb8c692b.js b/assets/contribute.html-bb8c692b.js new file mode 100644 index 000000000..5ac3e4ddf --- /dev/null +++ b/assets/contribute.html-bb8c692b.js @@ -0,0 +1 @@ +import{_ as l,r as n,o as r,c as d,a as e,b as o,d as t,w as c,e as a}from"./app-2a91d8ab.js";const h={},u=e("h1",{id:"贡献指南",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#贡献指南","aria-hidden":"true"},"#"),o(" 贡献指南")],-1),_=e("p",null,"欢迎报告Issue或提交Pull Request。建议在贡献代码前先阅读以下贡献指南。",-1),p=e("h2",{id:"报告问题",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#报告问题","aria-hidden":"true"},"#"),o(" 报告问题")],-1),m={href:"https://github.com/Tencent/CodeAnalysis/issues",target:"_blank",rel:"noopener noreferrer"},b=a('在您提交新的issue前,请搜索现有issue以查看是否已有人提交任何类似问题或功能请求,确认不存在重复的issue。
当您提交新的issue时,请尽量提供更多的信息,例如与问题相关的详细描述、屏幕截图、视频、logcat和导致崩溃的代码块。
TCA有两个主要分支:
main
分支: main
作为标签, 带有版本号 v1.0.1
, v1.0.2
...main
分支提交任何PR.dev
分支: dev
分支将合并到 main
分支的下一个版本。dev
分支。代码团队将监控所有拉取请求,我们对其进行一些代码检查和测试。在所有测试通过后,我们将接受此PR。但它不会立即合并到 main
分支,这有一些延迟。
在提交拉取请求之前,请确保完成以下工作:
',6),x={href:"https://github.com/Tencent/CodeAnalysis/blob/main/CONTRIBUTING.md",target:"_blank",rel:"noopener noreferrer"},C=e("code",null,"main",-1),R=e("li",null,"如果您更改了API,请更新代码或文档。",-1),g=e("li",null,"将版权声明添加到您添加的任何新文件的顶部。",-1),T=e("li",null,"检查您的代码样式。",-1),k=e("li",null,"测试您的代码,确保其可以正常运行。",-1),q=e("li",null,[o("现在,您可以向 "),e("code",null,"dev"),o(" 分支提交Pull Request。")],-1),I=e("h2",{id:"许可",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#许可","aria-hidden":"true"},"#"),o(" 许可")],-1),P={href:"https://github.com/Tencent/CodeAnalysis/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"};function v(A,N){const s=n("ExternalLinkIcon"),i=n("RouterLink");return r(),d("div",null,[u,_,p,e("p",null,[o("我们使用"),e("a",m,[o("Github Issues"),t(s)]),o("来跟踪漏洞和功能请求。")]),b,e("p",null,[o("我们非常欢迎您提出Pull Request来帮助TCA变得更好,操作流程详见"),t(i,{to:"/en/community/pr.html"},{default:c(()=>[o("PullRequests操作流程")]),_:1}),o("。")]),f,e("ol",null,[e("li",null,[o("Fork "),e("a",x,[o("TCA仓库"),t(s)]),o(",并从 "),C,o(" 创建分支。")]),R,g,T,k,q]),I,e("p",null,[e("a",P,[o("MIT LICENSE"),t(s)]),o(" 是 TCA 的开源许可证。任何人贡献的代码都受此许可证保护。在贡献代码之前,请确保您可以接受许可。")])])}const L=l(h,[["render",v],["__file","contribute.html.vue"]]);export{L as default}; diff --git a/assets/contribute.html-e2151c44.js b/assets/contribute.html-e2151c44.js new file mode 100644 index 000000000..9d264e458 --- /dev/null +++ b/assets/contribute.html-e2151c44.js @@ -0,0 +1 @@ +import{_ as l,r as n,o as r,c as d,a as e,b as o,d as t,w as c,e as a}from"./app-2a91d8ab.js";const h={},u=e("h1",{id:"贡献指南",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#贡献指南","aria-hidden":"true"},"#"),o(" 贡献指南")],-1),_=e("p",null,"欢迎报告Issue或提交Pull Request。建议在贡献代码前先阅读以下贡献指南。",-1),p=e("h2",{id:"报告问题",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#报告问题","aria-hidden":"true"},"#"),o(" 报告问题")],-1),m={href:"https://github.com/Tencent/CodeAnalysis/issues",target:"_blank",rel:"noopener noreferrer"},b=a('在您提交新的issue前,请搜索现有issue以查看是否已有人提交任何类似问题或功能请求,确认不存在重复的issue。
当您提交新的issue时,请尽量提供更多的信息,例如与问题相关的详细描述、屏幕截图、视频、logcat和导致崩溃的代码块。
TCA有两个主要分支:
main
分支: main
作为标签, 带有版本号 v1.0.1
, v1.0.2
...main
分支提交任何PR.dev
分支: dev
分支将合并到 main
分支的下一个版本。dev
分支。代码团队将监控所有拉取请求,我们对其进行一些代码检查和测试。在所有测试通过后,我们将接受此PR。但它不会立即合并到 main
分支,这有一些延迟。
在提交拉取请求之前,请确保完成以下工作:
',6),x={href:"https://github.com/Tencent/CodeAnalysis/blob/main/CONTRIBUTING.md",target:"_blank",rel:"noopener noreferrer"},C=e("code",null,"main",-1),R=e("li",null,"如果您更改了API,请更新代码或文档。",-1),g=e("li",null,"将版权声明添加到您添加的任何新文件的顶部。",-1),T=e("li",null,"检查您的代码样式。",-1),k=e("li",null,"测试您的代码,确保其可以正常运行。",-1),q=e("li",null,[o("现在,您可以向 "),e("code",null,"dev"),o(" 分支提交Pull Request。")],-1),I=e("h2",{id:"许可",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#许可","aria-hidden":"true"},"#"),o(" 许可")],-1),P={href:"https://github.com/Tencent/CodeAnalysis/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"};function v(A,N){const s=n("ExternalLinkIcon"),i=n("RouterLink");return r(),d("div",null,[u,_,p,e("p",null,[o("我们使用"),e("a",m,[o("Github Issues"),t(s)]),o("来跟踪漏洞和功能请求。")]),b,e("p",null,[o("我们非常欢迎您提出Pull Request来帮助TCA变得更好,操作流程详见"),t(i,{to:"/zh/community/pr.html"},{default:c(()=>[o("PullRequests操作流程")]),_:1}),o("。")]),f,e("ol",null,[e("li",null,[o("Fork "),e("a",x,[o("TCA仓库"),t(s)]),o(",并从 "),C,o(" 创建分支。")]),R,g,T,k,q]),I,e("p",null,[e("a",P,[o("MIT LICENSE"),t(s)]),o(" 是 TCA 的开源许可证。任何人贡献的代码都受此许可证保护。在贡献代码之前,请确保您可以接受许可。")])])}const L=l(h,[["render",v],["__file","contribute.html.vue"]]);export{L as default}; diff --git a/assets/cpp_doc.html-2bc2277b.js b/assets/cpp_doc.html-2bc2277b.js new file mode 100644 index 000000000..da5a78745 --- /dev/null +++ b/assets/cpp_doc.html-2bc2277b.js @@ -0,0 +1 @@ +import{_ as o,r as l,o as a,c as s,a as e,b as n,d as t}from"./app-2a91d8ab.js";const i={},c=e("h1",{id:"【c-c-】代码质量缺陷规则包",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【c-c-】代码质量缺陷规则包","aria-hidden":"true"},"#"),n(" 【C/C++】代码质量缺陷规则包")],-1),_={href:"https://tencent.github.io/CodeAnalysis/zh/quickStarted/enhanceDeploy.html",target:"_blank",rel:"noopener noreferrer"},A=e("h2",{id:"规则列表",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#规则列表","aria-hidden":"true"},"#"),n(" 规则列表")],-1),h={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#array_overflow",target:"_blank",rel:"noopener noreferrer"},d={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#buff_overflow",target:"_blank",rel:"noopener noreferrer"},u={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#dead_lock",target:"_blank",rel:"noopener noreferrer"},E={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#func_ret_null",target:"_blank",rel:"noopener noreferrer"},f={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#missing_lock",target:"_blank",rel:"noopener noreferrer"},B={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#resource_leak",target:"_blank",rel:"noopener noreferrer"},p={href:"https://tencent.github.io/CodeAnalysis/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#unused_value",target:"_blank",rel:"noopener noreferrer"};function g(m,b){const r=l("ExternalLinkIcon");return a(),s("div",null,[c,e("p",null,[n("采用自研工具检查Cpp代码缺陷,需要使用license;属于 TCA 增强分析模块的能力之一,请参考"),e("a",_,[n("增强分析模块部署"),t(r)]),n("文档进行部署。")]),A,e("ul",null,[e("li",null,[e("a",h,[n("array_overflow"),t(r)])]),e("li",null,[e("a",d,[n("buff_overflow"),t(r)])]),e("li",null,[e("a",u,[n("dead_lock"),t(r)])]),e("li",null,[e("a",E,[n("func_ret_null"),t(r)])]),e("li",null,[e("a",f,[n("missing_lock"),t(r)])]),e("li",null,[e("a",B,[n("resource_leak"),t(r)])]),e("li",null,[e("a",p,[n("unused_value"),t(r)])])])])}const k=o(i,[["render",g],["__file","cpp_doc.html.vue"]]);export{k as default}; diff --git a/assets/cpp_doc.html-bf6ce6bb.js b/assets/cpp_doc.html-bf6ce6bb.js new file mode 100644 index 000000000..31d926e5f --- /dev/null +++ b/assets/cpp_doc.html-bf6ce6bb.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-218b1d6f","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/cpp_doc.html","title":"【C/C++】代码质量缺陷规则包","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"规则列表","slug":"规则列表","link":"#规则列表","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/规则包/cpp_doc.md"}');export{e as data}; diff --git a/assets/cpp_doc.html-c7d5253e.js b/assets/cpp_doc.html-c7d5253e.js new file mode 100644 index 000000000..866cb275a --- /dev/null +++ b/assets/cpp_doc.html-c7d5253e.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ef89f918","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/cpp_doc.html","title":"【C/C++】代码质量缺陷规则包","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"规则列表","slug":"规则列表","link":"#规则列表","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/规则包/cpp_doc.md"}');export{e as data}; diff --git a/assets/cpp_doc.html-e71f1648.js b/assets/cpp_doc.html-e71f1648.js new file mode 100644 index 000000000..cb8dce0b6 --- /dev/null +++ b/assets/cpp_doc.html-e71f1648.js @@ -0,0 +1 @@ +import{_ as o,r as l,o as a,c as i,a as e,b as r,d as t}from"./app-2a91d8ab.js";const s={},A=e("h1",{id:"【c-c-】代码质量缺陷规则包",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【c-c-】代码质量缺陷规则包","aria-hidden":"true"},"#"),r(" 【C/C++】代码质量缺陷规则包")],-1),h={href:"https://tencent.github.io/CodeAnalysis/zh/quickStarted/enhanceDeploy.html",target:"_blank",rel:"noopener noreferrer"},_=e("h2",{id:"规则列表",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#规则列表","aria-hidden":"true"},"#"),r(" 规则列表")],-1),d={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#array_overflow",target:"_blank",rel:"noopener noreferrer"},c={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#buff_overflow",target:"_blank",rel:"noopener noreferrer"},E={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#dead_lock",target:"_blank",rel:"noopener noreferrer"},u={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#func_ret_null",target:"_blank",rel:"noopener noreferrer"},B={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#missing_lock",target:"_blank",rel:"noopener noreferrer"},f={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#resource_leak",target:"_blank",rel:"noopener noreferrer"},g={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#unused_value",target:"_blank",rel:"noopener noreferrer"},p={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#dead_branch",target:"_blank",rel:"noopener noreferrer"},m={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#forward_null",target:"_blank",rel:"noopener noreferrer"},b={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#reverse_null",target:"_blank",rel:"noopener noreferrer"},C={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#dead_code",target:"_blank",rel:"noopener noreferrer"},y={href:"https://tencent.github.io/CodeAnalysis/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%B7%A5%E5%85%B7/TCA-Armory-Q1.html#uinit",target:"_blank",rel:"noopener noreferrer"};function k(T,z){const n=l("ExternalLinkIcon");return a(),i("div",null,[A,e("p",null,[r("采用自研工具检查Cpp代码缺陷,需要使用license;属于 TCA 增强分析模块的能力之一,请参考"),e("a",h,[r("增强分析模块部署"),t(n)]),r("文档进行部署。")]),_,e("ul",null,[e("li",null,[e("a",d,[r("array_overflow"),t(n)])]),e("li",null,[e("a",c,[r("buff_overflow"),t(n)])]),e("li",null,[e("a",E,[r("dead_lock"),t(n)])]),e("li",null,[e("a",u,[r("func_ret_null"),t(n)])]),e("li",null,[e("a",B,[r("missing_lock"),t(n)])]),e("li",null,[e("a",f,[r("resource_leak"),t(n)])]),e("li",null,[e("a",g,[r("unused_value"),t(n)])]),e("li",null,[e("a",p,[r("dead_branch"),t(n)])]),e("li",null,[e("a",m,[r("forward_null"),t(n)])]),e("li",null,[e("a",b,[r("reverse_null"),t(n)])]),e("li",null,[e("a",C,[r("dead_code"),t(n)])]),e("li",null,[e("a",y,[r("uinit"),t(n)])])])])}const Q=o(s,[["render",k],["__file","cpp_doc.html.vue"]]);export{Q as default}; diff --git a/assets/creataAnalysePlan-cef75d2f.png b/assets/creataAnalysePlan-cef75d2f.png new file mode 100644 index 000000000..82cdbeeb9 Binary files /dev/null and b/assets/creataAnalysePlan-cef75d2f.png differ diff --git a/assets/create_repo-d6d12fcc.png b/assets/create_repo-d6d12fcc.png new file mode 100644 index 000000000..2dab3e3cf Binary files /dev/null and b/assets/create_repo-d6d12fcc.png differ diff --git a/assets/create_team-e3e2cf05.png b/assets/create_team-e3e2cf05.png new file mode 100644 index 000000000..05fca9102 Binary files /dev/null and b/assets/create_team-e3e2cf05.png differ diff --git a/assets/create_team_group-a704de08.png b/assets/create_team_group-a704de08.png new file mode 100644 index 000000000..41c0fc4d9 Binary files /dev/null and b/assets/create_team_group-a704de08.png differ diff --git a/assets/createcustomrule-3919c596.js b/assets/createcustomrule-3919c596.js new file mode 100644 index 000000000..0b52b6b85 --- /dev/null +++ b/assets/createcustomrule-3919c596.js @@ -0,0 +1 @@ +const s="/CodeAnalysis/assets/addcustomrules-220aab00.png",a="/CodeAnalysis/assets/createcustomrule-54c07258.png";export{s as _,a}; diff --git a/assets/createcustomrule-54c07258.png b/assets/createcustomrule-54c07258.png new file mode 100644 index 000000000..faad029e5 Binary files /dev/null and b/assets/createcustomrule-54c07258.png differ diff --git a/assets/customtool_01-9e3e2bf5.png b/assets/customtool_01-9e3e2bf5.png new file mode 100644 index 000000000..80d9364f2 Binary files /dev/null and b/assets/customtool_01-9e3e2bf5.png differ diff --git a/assets/customtool_02-59fa95a2.png b/assets/customtool_02-59fa95a2.png new file mode 100644 index 000000000..6e5d788ac Binary files /dev/null and b/assets/customtool_02-59fa95a2.png differ diff --git a/assets/customtool_03-b18281ea.png b/assets/customtool_03-b18281ea.png new file mode 100644 index 000000000..eca12883a Binary files /dev/null and b/assets/customtool_03-b18281ea.png differ diff --git a/assets/customtool_04-9b94978f.png b/assets/customtool_04-9b94978f.png new file mode 100644 index 000000000..47f34630e Binary files /dev/null and b/assets/customtool_04-9b94978f.png differ diff --git a/assets/customtool_05-8d60b225.png b/assets/customtool_05-8d60b225.png new file mode 100644 index 000000000..25bd2c203 Binary files /dev/null and b/assets/customtool_05-8d60b225.png differ diff --git a/assets/customtool_06-8ec07c7b.js b/assets/customtool_06-8ec07c7b.js new file mode 100644 index 000000000..a3f3b1e68 --- /dev/null +++ b/assets/customtool_06-8ec07c7b.js @@ -0,0 +1 @@ +const s="/CodeAnalysis/assets/customtool_01-9e3e2bf5.png",o="/CodeAnalysis/assets/customtool_02-59fa95a2.png",t="/CodeAnalysis/assets/customtool_03-b18281ea.png",a="/CodeAnalysis/assets/customtool_04-9b94978f.png",_="/CodeAnalysis/assets/customtool_05-8d60b225.png",n="/CodeAnalysis/assets/customtool_06-cd5acb80.png";export{s as _,o as a,t as b,a as c,_ as d,n as e}; diff --git a/assets/customtool_06-cd5acb80.png b/assets/customtool_06-cd5acb80.png new file mode 100644 index 000000000..af530ad1b Binary files /dev/null and b/assets/customtool_06-cd5acb80.png differ diff --git a/assets/dependency_vul.html-387d064d.js b/assets/dependency_vul.html-387d064d.js new file mode 100644 index 000000000..5a2dd82c1 --- /dev/null +++ b/assets/dependency_vul.html-387d064d.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7981d049","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/dependency_vul.html","title":"依赖漏洞扫描规则包","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"概述","slug":"概述","link":"#概述","children":[]},{"level":2,"title":"示例","slug":"示例","link":"#示例","children":[]},{"level":2,"title":"快速体验","slug":"快速体验","link":"#快速体验","children":[{"level":3,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":3,"title":"更多","slug":"更多","link":"#更多","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/规则包/dependency_vul.md"}');export{e as data}; diff --git a/assets/dependency_vul.html-6e099c3e.js b/assets/dependency_vul.html-6e099c3e.js new file mode 100644 index 000000000..88a633909 --- /dev/null +++ b/assets/dependency_vul.html-6e099c3e.js @@ -0,0 +1,39 @@ +import{_ as e,o as n,c as i,e as t}from"./app-2a91d8ab.js";const l={},a=t(`该规则包可分析项目依赖组件,以及依赖组件中是否存在漏洞等问题。辅助开发者准确分析到依赖组件的安全性,选用安全可靠的依赖组件。
规则包中将漏洞规则分为“低危漏洞”、“中危漏洞”、“高危漏洞”三个等级,扫描出有漏洞的组件,TCA会提供问题组件名称和版本、漏洞情况介绍,以及可用的修复版本(如获取到)。
已支持语言:C/C++、C#、Go、Java、JavaScript、PHP、Python、Ruby、Scala、TypeScript等。
<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.javaweb.vuln</groupId>
+ <artifactId>javaweb-vuln</artifactId>
+ <version>3.0.3</version>
+ </parent>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <!-- 触发规则 -->
+ <version>2.1.8</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+</project>
+
TCA 现已支持依赖漏洞扫描规则包,可以在 TCA 分析方案中搜索勾选该规则包,快速体验。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
更多场景支持,欢迎提 issue 进行咨询扩展。
`,13),d=[a];function s(r,c){return n(),i("div",null,d)}const u=e(l,[["render",s],["__file","dependency_vul.html.vue"]]);export{u as default}; diff --git a/assets/dependency_vul.html-da9f0e2b.js b/assets/dependency_vul.html-da9f0e2b.js new file mode 100644 index 000000000..88a633909 --- /dev/null +++ b/assets/dependency_vul.html-da9f0e2b.js @@ -0,0 +1,39 @@ +import{_ as e,o as n,c as i,e as t}from"./app-2a91d8ab.js";const l={},a=t(`该规则包可分析项目依赖组件,以及依赖组件中是否存在漏洞等问题。辅助开发者准确分析到依赖组件的安全性,选用安全可靠的依赖组件。
规则包中将漏洞规则分为“低危漏洞”、“中危漏洞”、“高危漏洞”三个等级,扫描出有漏洞的组件,TCA会提供问题组件名称和版本、漏洞情况介绍,以及可用的修复版本(如获取到)。
已支持语言:C/C++、C#、Go、Java、JavaScript、PHP、Python、Ruby、Scala、TypeScript等。
<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.javaweb.vuln</groupId>
+ <artifactId>javaweb-vuln</artifactId>
+ <version>3.0.3</version>
+ </parent>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <!-- 触发规则 -->
+ <version>2.1.8</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+</project>
+
TCA 现已支持依赖漏洞扫描规则包,可以在 TCA 分析方案中搜索勾选该规则包,快速体验。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
更多场景支持,欢迎提 issue 进行咨询扩展。
`,13),d=[a];function s(r,c){return n(),i("div",null,d)}const u=e(l,[["render",s],["__file","dependency_vul.html.vue"]]);export{u as default}; diff --git a/assets/dependency_vul.html-f875aa89.js b/assets/dependency_vul.html-f875aa89.js new file mode 100644 index 000000000..06ffd310b --- /dev/null +++ b/assets/dependency_vul.html-f875aa89.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-c54ad424","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/dependency_vul.html","title":"依赖漏洞扫描规则包","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"概述","slug":"概述","link":"#概述","children":[]},{"level":2,"title":"示例","slug":"示例","link":"#示例","children":[]},{"level":2,"title":"快速体验","slug":"快速体验","link":"#快速体验","children":[{"level":3,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":3,"title":"更多","slug":"更多","link":"#更多","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/规则包/dependency_vul.md"}');export{e as data}; diff --git a/assets/deployClient.html-26310b53.js b/assets/deployClient.html-26310b53.js new file mode 100644 index 000000000..1053a7b88 --- /dev/null +++ b/assets/deployClient.html-26310b53.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-2af89834","path":"/zh/quickStarted/deployClient.html","title":"部署与配置客户端","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"通过源代码","slug":"通过源代码","link":"#通过源代码","children":[{"level":3,"title":"依赖环境","slug":"依赖环境","link":"#依赖环境","children":[]},{"level":3,"title":"使用步骤","slug":"使用步骤","link":"#使用步骤","children":[]}]},{"level":2,"title":"通过Docker-Compose","slug":"通过docker-compose","link":"#通过docker-compose","children":[{"level":3,"title":"使用步骤","slug":"使用步骤-1","link":"#使用步骤-1","children":[]}]},{"level":2,"title":"通过可执行文件","slug":"通过可执行文件","link":"#通过可执行文件","children":[{"level":3,"title":"依赖环境","slug":"依赖环境-1","link":"#依赖环境-1","children":[]},{"level":3,"title":"使用步骤","slug":"使用步骤-2","link":"#使用步骤-2","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/quickStarted/deployClient.md"}');export{l as data}; diff --git a/assets/deployClient.html-9dc0de26.js b/assets/deployClient.html-9dc0de26.js new file mode 100644 index 000000000..238868ae7 --- /dev/null +++ b/assets/deployClient.html-9dc0de26.js @@ -0,0 +1,25 @@ +import{_ as o}from"./personalToken-2ae175b9.js";import{_ as t,r as c,o as r,c as h,a as e,b as n,d as i,w as l,e as a}from"./app-2a91d8ab.js";const u={},p=a('# 源码根目录下执行
+pip3 install -r client/requirements/app_reqs.pip
+
# 源码根目录
+cd client/requirements
+
+# 执行安装脚本
+# Linux/macOS环境
+./install.sh
+# Windows环境
+./install.bat
+
配置 client/config.ini
文件
将 <Server IP地址>
替换成实际的serve ip(可包含端口号)。
配置 client/codedog.ini
文件
必填项:token
、org_sid
、team_name
、source_dir
个人令牌 - token
:从 TCA 页面获取,前往[个人中心]-[个人令牌]-复制Token
团队编号 - org_sid
:进入 TCA 项目概览页,从 URL 中获取
项目名称 - team_name
::进入 TCA 项目概览页,从 URL 中获取
TIP
项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
分析路径 - source_dir
: 本地代码目录路径
TIP
如果项目代码为编译型语言(比如:C/C++,C#,Go,Java,Kotlin,Objective-C等),且使用的分析方案中配置了编译型工具(如图,使用了OC推荐规则包),需要填写build_cmd
编译命令。
其他可选项按需填写,不填写时按默认配置执行
# 源码根目录
+cd client
+
+# 执行客户端脚本
+python3 codepuppy.py localscan
+
WARNING
Client 的实现及启动脚本均依赖 Python3 版本为 3.7,可执行 python3 --version
查看版本。若版本有误,可安装版本为3.7的python并软链接到python3命令。
TIP
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
docker build -t tca-client .
+
进入client
目录,执行以下命令
# 按照实际情况填写\`SOURCE_DIR\`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
进入docker容器内的bash终端
# 按照实际情况填写\`SOURCE_DIR\`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+
通过命令行启动client代码
python3 codepuppy.py localscan
+
系统环境
进入到client
目录下,执行客户端
./codepuppy localscan
+
# 源码根目录下执行
+pip3 install -r client/requirements/app_reqs.pip
+
# 源码根目录
+cd client/requirements
+
+# 执行安装脚本
+# Linux/macOS环境
+./install.sh
+# Windows环境
+./install.bat
+
配置 client/config.ini
文件
将 <Server IP地址>
替换成实际的serve ip(可包含端口号)。
配置 client/codedog.ini
文件
必填项:token
、org_sid
、team_name
、source_dir
个人令牌 - token
:从 TCA 页面获取,前往[个人中心]-[个人令牌]-复制Token
团队编号 - org_sid
:进入 TCA 项目概览页,从 URL 中获取
项目名称 - team_name
::进入 TCA 项目概览页,从 URL 中获取
提示
项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
分析路径 - source_dir
: 本地代码目录路径
提示
如果项目代码为编译型语言(比如:C/C++,C#,Go,Java,Kotlin,Objective-C等),且使用的分析方案中配置了编译型工具(如图,使用了OC推荐规则包),需要填写build_cmd
编译命令。
其他可选项按需填写,不填写时按默认配置执行
# 源码根目录
+cd client
+
+# 执行客户端脚本
+python3 codepuppy.py localscan
+
注意
Client 的实现及启动脚本均依赖 Python3 版本为 3.7,可执行 python3 --version
查看版本。若版本有误,可安装版本为3.7的python并软链接到python3命令。
提示
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
docker build -t tca-client .
+
进入client
目录,执行以下命令
# 按照实际情况填写\`SOURCE_DIR\`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
进入docker容器内的bash终端
# 按照实际情况填写\`SOURCE_DIR\`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+
通过命令行启动client代码
python3 codepuppy.py localscan
+
系统环境
进入到client
目录下,执行客户端
./codepuppy localscan
+
WARNING
仅适用于Docker部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
TIP
通过Docker部署默认会在当前根目录下的挂载三个路径:
.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy
:重新构建并启动tca容器TIP
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
成功部署TCA后,请开始您的代码分析。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
TIP
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
TIP
分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
注意
仅适用于Docker部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
提示
tencenttca/tca:latest
镜像.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy
:重新构建并启动tca容器提示
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
成功部署TCA后,请开始您的代码分析。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
提示
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
提示
分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
Linux 环境
系统已安装 nginx
TCA Server 服务已部署完毕,具备后端服务地址
进入前端部署源码目录
进入web服务目录,并切换至tca-deploy-source
目录,将其视为工作目录(假设工作目录为 /data/CodeAnalysis/web/tca-deploy-source
)
部署/更新前端服务
# 部署、更新都使用此命令
+sh ./scripts/deploy.sh init -d
+
具体请查阅部署脚本内容,可根据业务调整配置。
额外说明
tca-deploy-source/scripts/config.sh
已配置默认环境变量,用户可根据需要调整环境变量再部署前端服务,具体可查阅脚本内容。
Linux 环境
系统已安装 nginx
TCA Server 服务已部署完毕,具备后端服务地址
进入前端部署源码目录
进入web服务目录,并切换至tca-deploy-source
目录,将其视为工作目录(假设工作目录为 /data/CodeAnalysis/web/tca-deploy-source
)
部署/更新前端服务
# 部署、更新都使用此命令
+sh ./scripts/deploy.sh init -d
+
具体请查阅部署脚本内容,可根据业务调整配置。
额外说明
tca-deploy-source/scripts/config.sh
已配置默认环境变量,用户可根据需要调整环境变量再部署前端服务,具体可查阅脚本内容。
TCA的file
服务支持对接MinIO
作为底层存储,将文件转发到已部署的MinIO平台上进行持久化存储
注意:如果之前已经使用本地进行存储,切换为MinIO后,之前已经上传的文件只能到服务部署的目录
server/projects/file/data
查看,不支持通过页面进行下载
获取MinIO平台登录的账号密码,用于上传文件
file
服务的配置修改server/configs/django/local_file.py
文件,取消以下代码的注释
# MINIO
+STORAGE = {
+ "CLIENT": os.environ.get("FILE_STORAGE_CLIENT", "MINIO"), # 存储方式
+ "OPTIONS": {
+ "MINIO_ENTRYPOINT": os.environ.get("FILE_MINIO_ENTRYPOINT"),
+ "MINIO_ACCESS_KEY": os.environ.get("FILE_MINIO_ACCESS_KEY"),
+ "MINIO_SECRET_KEY": os.environ.get("FILE_MINIO_SECRET_KEY"),
+ }
+}
+
修改server/scripts/config.sh
文件,填写MinIO的信息
export FILE_MINIO_ENTRYPOINT=<MinIO平台的地址>
+export FILE_MINIO_ACCESS_KEY=<MinIO平台的登录账号>
+export FILE_MINIO_SECRET_KEY=<MinIO平台的登录密码>
+
修改完配置后,如果服务已经正在运行,则执行以下命令重启服务
$ cd server
+$ ./scripts/deploy.sh start
+
删除nginx已有的文件服务器配置文件/etc/nginx/conf.d/tca_file_local.conf
文件,然后执行
rm /etc/nginx/conf.d/tca_file_local.conf
+ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf
+
也可以修改
server/scripts/init_config.sh
# 注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_local.conf /etc/nginx/conf.d/tca_file_local.conf +# 取消注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf +
修改完配置后,如果nginx已经正在运行,则执行nginx -s reload
以上两个步骤操作完成后,就可以通过MinIO
存储文件了~
TCA的file
服务支持对接MinIO
作为底层存储,将文件转发到已部署的MinIO平台上进行持久化存储
注意:如果之前已经使用本地进行存储,切换为MinIO后,之前已经上传的文件只能到服务部署的目录
server/projects/file/data
查看,不支持通过页面进行下载
获取MinIO平台登录的账号密码,用于上传文件
file
服务的配置修改server/configs/django/local_file.py
文件,取消以下代码的注释
# MINIO
+STORAGE = {
+ "CLIENT": os.environ.get("FILE_STORAGE_CLIENT", "MINIO"), # 存储方式
+ "OPTIONS": {
+ "MINIO_ENTRYPOINT": os.environ.get("FILE_MINIO_ENTRYPOINT"),
+ "MINIO_ACCESS_KEY": os.environ.get("FILE_MINIO_ACCESS_KEY"),
+ "MINIO_SECRET_KEY": os.environ.get("FILE_MINIO_SECRET_KEY"),
+ }
+}
+
修改server/scripts/config.sh
文件,填写MinIO的信息
export FILE_MINIO_ENTRYPOINT=<MinIO平台的地址>
+export FILE_MINIO_ACCESS_KEY=<MinIO平台的登录账号>
+export FILE_MINIO_SECRET_KEY=<MinIO平台的登录密码>
+
修改完配置后,如果服务已经正在运行,则执行以下命令重启服务
$ cd server
+$ ./scripts/deploy.sh start
+
删除nginx已有的文件服务器配置文件/etc/nginx/conf.d/tca_file_local.conf
文件,然后执行
rm /etc/nginx/conf.d/tca_file_local.conf
+ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf
+
也可以修改
server/scripts/init_config.sh
# 注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_local.conf /etc/nginx/conf.d/tca_file_local.conf +# 取消注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf +
修改完配置后,如果nginx已经正在运行,则执行nginx -s reload
以上两个步骤操作完成后,就可以通过MinIO
存储文件了~
server/sql/init.sql
SET SESSION FOREIGN_KEY_CHECKS=0
,否则会因为数据中有外键关联导致导入失败source /youdir/codedog_all.sql;
SET SESSION FOREIGN_KEY_CHECKS=1
bash ./scripts/deploy.sh start
,无需执行 init
方法,否则会导致数据重复写入server/sql/init.sql
SET SESSION FOREIGN_KEY_CHECKS=0
,否则会因为数据中有外键关联导致导入失败source /youdir/codedog_all.sql;
SET SESSION FOREIGN_KEY_CHECKS=1
bash ./scripts/deploy.sh start
,无需执行 init
方法,否则会导致数据重复写入WARNING
Docker deployment include Mariadb and Redis. Configuration file can be modified to indicate a MySQL/Mariadb and Redis, which satisfied operation and maintenance specification for extensive use.
Server, Web and Client
~/CodeAnalysis
), the following paths are relative paths within the directory.bash ./quick_install.sh docker deploy
+
TIP
tencenttca/tca:latest
image will be pulled from dockerhub by default..docker_temp/logs
:/var/log/tca/
in container,TCA daily log output;.docker_temp/data
:/var/opt/tca/
in container, TCA service data, mainly about Mariadb,Redis;.docker_temp/configs
:/etc/tca
in container,TCA configuration file,mainly config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy # Re-build and start TCA Container
+
TIP
TCA_IMAGE_BUILD=true
Indicates that the TCA image is built locally to run
If docker deploy
has been executed on the machine and the container data is retained, you can execute the following command to start the container and continue to run TCA
bash ./quick_install.sh docker start
+
If a container is running and you want to stop it, you can run command
bash ./quick_install.sh docker stop
+
注意
Docker部署会包含Mariadb和Redis,如果需要更大规模使用,可以调整配置文件使用运维规范的 MySQL/Mariadb 和 Redis。
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
提示
tencenttca/tca:latest
镜像.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy #重新构建并启动tca容器
+
提示
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
Server、Web 与 Client
注意
仅适用于 Docker-Compose 部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
执行命令:
bash ./quick_install.sh docker-compose deploy #启动tca_server容器
+
注意:通过 Docker-Compose 部署默认会在当前根目录下的挂载三个路径:
.docker_data/logs
:存放 TCA 平台的各个服务日志输出目录;.docker_data/mysql
:存放 TCA 平台的 MySQL 数据.docker_data/redis
:存放 TCA 平台的 Redis 数据.docker_data/filedata
:存放 TCA 平台文件服务器的文件更新代码
执行以下命令:
bash ./quick_install.sh docker-compose build #重新构建TCA相关镜像
+bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
如果已经在机器上执行过docker-compose deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行 TCA
bash ./quick_install.sh docker-compose start
+
如果容器正在运行,希望停止容器,可以执行以下命令
bash ./quick_install.sh docker-compose stop
+
如果希望构建镜像,可以执行以下命令
bash ./quick_install.sh docker-compose build
+
Server、Web 与 Client
WARNING
仅适用于 Docker-Compose 部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
执行命令:
bash ./quick_install.sh docker-compose deploy #启动tca_server容器
+
注意:通过 Docker-Compose 部署默认会在当前根目录下的挂载三个路径:
.docker_data/logs
:存放 TCA 平台的各个服务日志输出目录;.docker_data/mysql
:存放 TCA 平台的 MySQL 数据.docker_data/redis
:存放 TCA 平台的 Redis 数据.docker_data/filedata
:存放 TCA 平台文件服务器的文件更新代码
执行以下命令:
bash ./quick_install.sh docker-compose build #重新构建TCA相关镜像
+bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
如果已经在机器上执行过docker-compose deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行 TCA
bash ./quick_install.sh docker-compose start
+
如果容器正在运行,希望停止容器,可以执行以下命令
bash ./quick_install.sh docker-compose stop
+
如果希望构建镜像,可以执行以下命令
bash ./quick_install.sh docker-compose build
+
TCA 除开集成业界知名的分析工具之外,也有自主研发的独立工具,作为 TCA 的增强分析模块。
TCA 增强分析模块,需要用户额外部署 License 鉴权微服务,并邮件申请 License 。
提示
1. License申请完全免费! 2. 优先企业或高校申请License。
持续更新中……
如果用户是在企业内网环境内使用 TCA,并想在内网体验 TCA 的增强分析模块能力,可以参考下面步骤申请。
注意
注意:不能随意删除CLS目录
注意
注意:需要在 CLS 目录下执行命令
# 安装 Git LFS
+$ bash ./scripts/base/install_git_lfs.sh
+# 如果在该目录下没有找到 cls 二进制文件,可以执行以下命令进行同步
+$ bash ./scripts/base/install_bin.sh
+$ cd server/cls
+$ ./cls server
+2022-04-13 18:35:29.356510559 +0800 CST [INFO] Version: 20220328.1
+2022-04-13 18:35:29.44083463 +0800 CST [INFO] The client license is:
+xxx
+2022-04-13 18:35:29.454552966 +0800 CST [INFO] License Server ID: xxx
+
Server ID
: 机器码,用于向 TCA 团队申请 License 授权Client License
: 提供给 TCA Client,方便 TCA Client 进行工具鉴权(重要,建议备份留底)[LICENSE_CONFIG]
+; [可选]使用独立工具时,需要填写,默认不需要
+; License服务的域名和端口
+URL=http://<IP或者域名>:<port>
+BASE_PATH=
+LICENSE=<Client License>
+
注意
注意:URL对应值的最后不需要跟斜杆/
.
注意
不同的部署方式可以根据下面方法修改config.ini
配置
client/config.ini
./quick_install.sh local start client
.docker_temp/configs/client/config.ini
,并重启tca-services
容器tca-service
容器后,修改/CodeAnalysis/client/config.ini
,并退出重启tca-services
容器docker restart tca-service
client/config.ini
,并重启client
容器docker-compose restart client
Server ID
,首次登记的机器码Client License
注意
注意:遵从 yaml 格式,比如:
:
后面跟一个空白字符,示例 key: value
。./cls server -d
+
# 查找是否存在CLS进程
+ps aux|grep cls
+
# 查找CLS进程ID
+ps aux|grep cls
+# 重启微服务
+kill -USR2 <pid>
+
如果以上部署步骤已经完成,但是增强功能还是出现 License check failed! Please check the license. License Server is not available!
异常。可以按照以下步骤进行排查:
method(head) call fails on error: <urlopen error [Errno 111] Connection refused>
+
ping <config.ini中填写的 CLS IP或者域名>
+telnet <config.ini中填写的 CLS IP或者域名> <对应端口>
+
背景: 小明以 Docker 方式部署 TCA,并在相同宿主机上部署 CLS 服务,然后在 config.ini 中设置的 URL 中的 IP 为 127.0.0.1
, 重启后启动增强功能任务遇到上述网络不通异常。
原因: 原因是此时的 127.0.0.1
指向的是 TCA Client 容器自身,而不是部署在宿主机上的 CLS 服务。
解决方案: 将 127.0.0.1
改成宿主机自身IP即可。
# 查找CLS进程ID
+ps aux|grep cls
+# 重启微服务
+kill -9 <pid>
+
注意
注意:不能删除原来的 cls 目录,只需要替换其中的 cls 二进制文件即可。
./cls server -d
+
In addition to integrating well-known analysis tools in the industry, TCA also has its own independently developed tools, which serve as the enhanced analysis module of TCA.
The TCA enhanced analysis module requires users to additionally deploy the License authentication microservice and apply for a License by email.
TIP
1. License application is completely free! 2. Enterprises or universities are given priority in applying for a License.
Continuously updating...
If you are using TCA in an enterprise intranet environment and want to experience the enhanced analysis module capabilities of TCA on the intranet, you can apply as follows.
WARNING
Note: The CLS directory cannot be deleted at will
server/cls
directory of the TCA source code to obtain the Server ID
and Client License
WARNING
Note: The command needs to be executed in the CLS directory
# install Git LFS
+$ bash ./scripts/base/install_git_lfs.sh
+# If the cls binary is not found in this directory, you can execute the following command to synchronize.
+$ bash ./scripts/base/install_bin.sh
+$ cd server/cls
+$ ./cls server
+2022-04-13 18:35:29.356510559 +0800 CST [INFO] Version: 20220328.1
+2022-04-13 18:35:29.44083463 +0800 CST [INFO] The client license is:
+xxx
+2022-04-13 18:35:29.454552966 +0800 CST [INFO] License Server ID: xxx
+
Server ID
: Machine code, used to apply for License authorization from the TCA teamClient License
: Provided to the TCA Client to facilitate tool authentication (important, it is recommended to back up)config.ini
of the TCA Client directory, for example[LICENSE_CONFIG]
+; [optional] Fill in when using independent tools, no need by default
+; Domain name and port of the License service
+URL=http://<IP or domain name>:<port>
+BASE_PATH=
+LICENSE=<Client License>
+
WARNING
Note: The URL corresponding value does not need to follow the slash /
at the end.
WARNING
Different deployment methods can modify the config.ini
configuration according to the following methods:
client/config.ini
in the source code directory./quick_install.sh local start client
.docker_temp/configs/client/config.ini
in the source code directory and restart the tca-services
containertca-service
container, modify /CodeAnalysis/client/config.ini
, and exit and restart the tca-services
containerdocker restart tca-service
client/config.ini
in the source code directory and restart the client
containerdocker-compose restart client
Server ID
output in step 1, the machine code for the first registrationClient License
output in step 1config.yaml
file in the CLS directoryWARNING
Note: Follow the yaml format, for example:
:
, for example key: value
../cls server -d
+
# Find if there is a CLS process
+ps aux|grep cls
+
WARNING
Note: If the above command does not find the CLS process, it means that CLS did not start normally.
Please try to change the port in the config.yaml
file to another port, such as 8080, the default is port 80, and then re-execute the command in step 5.
# Find the CLS process ID
+ps aux|grep cls
+# Restart the microservice
+kill -USR2 <pid>
+
If the above deployment steps have been completed, but the enhanced function still encounters the License check failed! Please check the license. License Server is not available!
exception. You can troubleshoot as follows:
method(head) call fails on error: <urlopen error [Errno 111] Connection refused>
+
ping <CLS IP or domain name filled in config.ini>
+telnet <CLS IP or domain name filled in config.ini> <corresponding port>
+
Background: Xiao Ming deployed TCA in Docker mode and deployed the CLS service on the same host. Then he set the IP in the URL in config.ini to 127.0.0.1
, restarted and started the enhanced function task and encountered the above network disconnection exception.
Reason: The reason is that the 127.0.0.1
at this time points to the TCA Client container itself, not the CLS service deployed on the host.
Solution: Change 127.0.0.1
to the host's own IP.
# Find the CLS process ID
+ps aux|grep cls
+# Restart the microservice
+kill -9 <pid>
+
WARNING
Note: You cannot delete the original cls directory, you only need to replace the cls binary file in it.
./cls server -d
+
代码分析支持 Eslint 分析,并支持用户自由扩展配置。
目前 TCA-Eslint 的适用场景很广,灵活扩展:
以下是接入步骤:
在进行高级配置之前,这里先普及下代码分析这边的基础概念——Eslint 类型。 由于 JavaScript 语法、 Vue 语法和 TypeScript 语法之间的区别,三者使用的语法解析器也是不一样的,这里基于其使用的语法解析器的不同,从 Eslint 中拆分出来了 Eslint_vue 和 Eslint_typescript 工具。可以根据需要选择对应工具下的规则进行分析。而配置也会基于类型的不同匹配到对应的工具中。 目前代码分析上 Eslint 类型有:
因为项目会用到各式各样的框架,其中会有全局变量是 Eslint 无法识别到的,比如 _
或者 jtest,从而导致分析出不少误报。这里支持使用下面环境变量设置这些全局变量,减少误报。可以在代码分析项目中设置对应的环境变量。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_GLOBALS | 字符串,以分号分割 |
ESLINT_VUE_GLOBALS | 字符串,以分号分割 |
ESLINT_TYPESCRIPT_GLOBALS | 字符串,以分号分割 |
比如:
ESLINT_JAVASCRIPT_GLOBALS=_:readonly;jtest:readonly
+
其中,
代码分析执行 Eslint 分析,默认会使用 Alloy Team 的 Eslint 配置来分析,但是也支持修改配置。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_VUE_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
代码分析也支持用户指定自己维护的 Eslint 配置文件进行分析。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_VUE_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
代码分析自带支持 Google 代码规范,可以在代码分析项目设置对应环境变量,使用对应的配置文件。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG_TYPE | 字符串, google,default,custom |
ESLINT_VUE_CONFIG_TYPE | 字符串, 可选:default,custom |
ESLINT_TYPESCRIPT_CONFIG_TYPE | 字符串, 可选:default,custom |
其中:
这里介绍 TCA-Eslint 的配置使用顺序:
可以在代码分析页面上设置分析路径设置,这里建议多使用 Exclude 设置,因为 Eslint 工具本身对 include 支持不友好。
Q:JavaScript 内存溢出
A:Eslint 执行可能会出现 Js 内存溢出,以下有三种方案可以解决:
NODE_OPTIONS="--max-old-space-size=4096"
+
ESLINT_MAX_OLD_SPACE_SIZE=4096
+
Q:一个配置同时分析 JS 和 TS
A:若代码库中既有 JavaScript 代码,又有 TypeScript 代码,并且共用一个配置文件。 若规则集中既有 Eslint 规则又有 Eslint_typescript 规则,为了避免执行两次 Eslint 以及可能出现重复单的情况,并且因为 Eslint_typescript 的语法解析器也能够解析 JavaScript 代码,所以这里将这样的项目当作 TypeScript 项目。
Q:找不到依赖
A:用户自己配置的配置文件中,可能会用到代码分析没有管理到的规则插件,导致分析时候找不到对应的依赖,这里有两个方案提供解决:
Q:custom 与指定配置文件的区别
A:- custom 模式,会检测代码库中的 Eslint 配置文件进行分析,包括子目录和代码注释中设置的配置,都是可以生效的。
代码分析支持 Eslint 分析,并支持用户自由扩展配置。
目前 TCA-Eslint 的适用场景很广,灵活扩展:
以下是接入步骤:
在进行高级配置之前,这里先普及下代码分析这边的基础概念——Eslint 类型。 由于 JavaScript 语法、 Vue 语法和 TypeScript 语法之间的区别,三者使用的语法解析器也是不一样的,这里基于其使用的语法解析器的不同,从 Eslint 中拆分出来了 Eslint_vue 和 Eslint_typescript 工具。可以根据需要选择对应工具下的规则进行分析。而配置也会基于类型的不同匹配到对应的工具中。 目前代码分析上 Eslint 类型有:
因为项目会用到各式各样的框架,其中会有全局变量是 Eslint 无法识别到的,比如 _
或者 jtest,从而导致分析出不少误报。这里支持使用下面环境变量设置这些全局变量,减少误报。可以在代码分析项目中设置对应的环境变量。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_GLOBALS | 字符串,以分号分割 |
ESLINT_VUE_GLOBALS | 字符串,以分号分割 |
ESLINT_TYPESCRIPT_GLOBALS | 字符串,以分号分割 |
比如:
ESLINT_JAVASCRIPT_GLOBALS=_:readonly;jtest:readonly
+
其中,
代码分析执行 Eslint 分析,默认会使用 Alloy Team 的 Eslint 配置来分析,但是也支持修改配置。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_VUE_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
代码分析也支持用户指定自己维护的 Eslint 配置文件进行分析。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_VUE_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
代码分析自带支持 Google 代码规范,可以在代码分析项目设置对应环境变量,使用对应的配置文件。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG_TYPE | 字符串, google,default,custom |
ESLINT_VUE_CONFIG_TYPE | 字符串, 可选:default,custom |
ESLINT_TYPESCRIPT_CONFIG_TYPE | 字符串, 可选:default,custom |
其中:
这里介绍 TCA-Eslint 的配置使用顺序:
可以在代码分析页面上设置分析路径设置,这里建议多使用 Exclude 设置,因为 Eslint 工具本身对 include 支持不友好。
Q:JavaScript 内存溢出
A:Eslint 执行可能会出现 Js 内存溢出,以下有三种方案可以解决:
NODE_OPTIONS="--max-old-space-size=4096"
+
ESLINT_MAX_OLD_SPACE_SIZE=4096
+
Q:一个配置同时分析 JS 和 TS
A:若代码库中既有 JavaScript 代码,又有 TypeScript 代码,并且共用一个配置文件。 若规则集中既有 Eslint 规则又有 Eslint_typescript 规则,为了避免执行两次 Eslint 以及可能出现重复单的情况,并且因为 Eslint_typescript 的语法解析器也能够解析 JavaScript 代码,所以这里将这样的项目当作 TypeScript 项目。
Q:找不到依赖
A:用户自己配置的配置文件中,可能会用到代码分析没有管理到的规则插件,导致分析时候找不到对应的依赖,这里有两个方案提供解决:
Q:custom 与指定配置文件的区别
A:- custom 模式,会检测代码库中的 Eslint 配置文件进行分析,包括子目录和代码注释中设置的配置,都是可以生效的。
前端项目在长期发展过程中,由于框架开源许可证变更、框架性能外观等不适用等因素,需要对前端框架进行平滑切换,而这就需要腾讯云代码分析 TCA 的介入,方便对企业内所有前端项目进行批量分析统计,方便管理。
{
+ "name": "framework",
+ "version": "1.0.0",
+ "dependencies": {
+ "react": "^17.0.2", // 触发规则
+ "react-dom": "^17.0.2", // 触发规则
+ "react-hotkeys-hook": "^3.4.3", // 触发规则
+ "react-redux": "^7.2.5", // 触发规则
+ "single-spa": "^5.9.3",
+ "universal-cookie": "^4.0.4"
+ },
+}
+
TCA 现已支持前端框架检查规则包,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 前端框架检查规则包 -> 启用/查看规则
更多框架支持,欢迎提 issue 进行咨询扩展。
`,15),t=[r];function o(s,u){return a(),i("div",null,t)}const c=e(d,[["render",o],["__file","front_end_framework_check.html.vue"]]);export{c as default}; diff --git a/assets/front_end_framework_check.html-2b5efba2.js b/assets/front_end_framework_check.html-2b5efba2.js new file mode 100644 index 000000000..46a550cf4 --- /dev/null +++ b/assets/front_end_framework_check.html-2b5efba2.js @@ -0,0 +1,13 @@ +import{_ as e,o as a,c as i,e as n}from"./app-2a91d8ab.js";const d={},r=n(`前端项目在长期发展过程中,由于框架开源许可证变更、框架性能外观等不适用等因素,需要对前端框架进行平滑切换,而这就需要腾讯云代码分析 TCA 的介入,方便对企业内所有前端项目进行批量分析统计,方便管理。
{
+ "name": "framework",
+ "version": "1.0.0",
+ "dependencies": {
+ "react": "^17.0.2", // 触发规则
+ "react-dom": "^17.0.2", // 触发规则
+ "react-hotkeys-hook": "^3.4.3", // 触发规则
+ "react-redux": "^7.2.5", // 触发规则
+ "single-spa": "^5.9.3",
+ "universal-cookie": "^4.0.4"
+ },
+}
+
TCA 现已支持前端框架检查规则包,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 前端框架检查规则包 -> 启用/查看规则
更多框架支持,欢迎提 issue 进行咨询扩展。
`,15),t=[r];function o(s,u){return a(),i("div",null,t)}const c=e(d,[["render",o],["__file","front_end_framework_check.html.vue"]]);export{c as default}; diff --git a/assets/front_end_framework_check.html-755e8478.js b/assets/front_end_framework_check.html-755e8478.js new file mode 100644 index 000000000..e42be40ec --- /dev/null +++ b/assets/front_end_framework_check.html-755e8478.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-6908b43a","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/front_end_framework_check.html","title":"前端框架检查规则包","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"背景","slug":"背景","link":"#背景","children":[]},{"level":2,"title":"需求","slug":"需求","link":"#需求","children":[{"level":3,"title":"示例","slug":"示例","link":"#示例","children":[]}]},{"level":2,"title":"快速体验","slug":"快速体验","link":"#快速体验","children":[{"level":3,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":3,"title":"支持框架","slug":"支持框架","link":"#支持框架","children":[]},{"level":3,"title":"更多","slug":"更多","link":"#更多","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/规则包/front_end_framework_check.md"}');export{e as data}; diff --git a/assets/front_end_framework_check.html-bc39db93.js b/assets/front_end_framework_check.html-bc39db93.js new file mode 100644 index 000000000..f0da00e0d --- /dev/null +++ b/assets/front_end_framework_check.html-bc39db93.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0b3551c4","path":"/en/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E8%A7%84%E5%88%99%E5%8C%85/front_end_framework_check.html","title":"前端框架检查规则包","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"背景","slug":"背景","link":"#背景","children":[]},{"level":2,"title":"需求","slug":"需求","link":"#需求","children":[{"level":3,"title":"示例","slug":"示例","link":"#示例","children":[]}]},{"level":2,"title":"快速体验","slug":"快速体验","link":"#快速体验","children":[{"level":3,"title":"启用规则包","slug":"启用规则包","link":"#启用规则包","children":[]},{"level":3,"title":"支持框架","slug":"支持框架","link":"#支持框架","children":[]},{"level":3,"title":"更多","slug":"更多","link":"#更多","children":[]}]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/代码检查/规则包/front_end_framework_check.md"}');export{e as data}; diff --git a/assets/gitlab_application_01-7866c7ca.png b/assets/gitlab_application_01-7866c7ca.png new file mode 100644 index 000000000..dc85658ba Binary files /dev/null and b/assets/gitlab_application_01-7866c7ca.png differ diff --git a/assets/gitlab_application_02-6f821932.png b/assets/gitlab_application_02-6f821932.png new file mode 100644 index 000000000..89942faf9 Binary files /dev/null and b/assets/gitlab_application_02-6f821932.png differ diff --git a/assets/gitlab_application_03-41a33813.png b/assets/gitlab_application_03-41a33813.png new file mode 100644 index 000000000..09e999b89 Binary files /dev/null and b/assets/gitlab_application_03-41a33813.png differ diff --git a/assets/gitlab_application_04-01ff3c53.png b/assets/gitlab_application_04-01ff3c53.png new file mode 100644 index 000000000..d18799d31 Binary files /dev/null and b/assets/gitlab_application_04-01ff3c53.png differ diff --git a/assets/gitlab_oauth_QA_01-00f480f3.png b/assets/gitlab_oauth_QA_01-00f480f3.png new file mode 100644 index 000000000..f0e51e148 Binary files /dev/null and b/assets/gitlab_oauth_QA_01-00f480f3.png differ diff --git a/assets/gitlab_oauth_QA_02-02424dd0.png b/assets/gitlab_oauth_QA_02-02424dd0.png new file mode 100644 index 000000000..a6b8b478e Binary files /dev/null and b/assets/gitlab_oauth_QA_02-02424dd0.png differ diff --git a/assets/gitlab_oauth_QA_03-f1493e02.png b/assets/gitlab_oauth_QA_03-f1493e02.png new file mode 100644 index 000000000..35673c555 Binary files /dev/null and b/assets/gitlab_oauth_QA_03-f1493e02.png differ diff --git a/assets/gitlab_oauth_QA_05-8d166cf1.png b/assets/gitlab_oauth_QA_05-8d166cf1.png new file mode 100644 index 000000000..197ebdc24 Binary files /dev/null and b/assets/gitlab_oauth_QA_05-8d166cf1.png differ diff --git a/assets/gitlab_oauth_QA_06-3f3cc486.png b/assets/gitlab_oauth_QA_06-3f3cc486.png new file mode 100644 index 000000000..88a141aa0 Binary files /dev/null and b/assets/gitlab_oauth_QA_06-3f3cc486.png differ diff --git a/assets/gitlab_oauth_QA_07-d3997b70.png b/assets/gitlab_oauth_QA_07-d3997b70.png new file mode 100644 index 000000000..92d330d3a Binary files /dev/null and b/assets/gitlab_oauth_QA_07-d3997b70.png differ diff --git a/assets/gitlab_oauth_disposition_01-aa54e072.png b/assets/gitlab_oauth_disposition_01-aa54e072.png new file mode 100644 index 000000000..d57ad0fb2 Binary files /dev/null and b/assets/gitlab_oauth_disposition_01-aa54e072.png differ diff --git a/assets/gitlab_oauth_disposition_02-2679e831.png b/assets/gitlab_oauth_disposition_02-2679e831.png new file mode 100644 index 000000000..36bc7afe8 Binary files /dev/null and b/assets/gitlab_oauth_disposition_02-2679e831.png differ diff --git a/assets/gitlab_oauth_disposition_03-07d21c14.png b/assets/gitlab_oauth_disposition_03-07d21c14.png new file mode 100644 index 000000000..88e929ccd Binary files /dev/null and b/assets/gitlab_oauth_disposition_03-07d21c14.png differ diff --git a/assets/gitlab_oauth_disposition_04-4506c3a9.png b/assets/gitlab_oauth_disposition_04-4506c3a9.png new file mode 100644 index 000000000..e46ec0306 Binary files /dev/null and b/assets/gitlab_oauth_disposition_04-4506c3a9.png differ diff --git a/assets/gitlab_oauth_disposition_05-983333e5.png b/assets/gitlab_oauth_disposition_05-983333e5.png new file mode 100644 index 000000000..18c0fc327 Binary files /dev/null and b/assets/gitlab_oauth_disposition_05-983333e5.png differ diff --git a/assets/gitlab_oauth_disposition_06-21fa11a0.png b/assets/gitlab_oauth_disposition_06-21fa11a0.png new file mode 100644 index 000000000..36ebbb5a9 Binary files /dev/null and b/assets/gitlab_oauth_disposition_06-21fa11a0.png differ diff --git a/assets/gitlab_oauth_disposition_07-935997e9.png b/assets/gitlab_oauth_disposition_07-935997e9.png new file mode 100644 index 000000000..b84264219 Binary files /dev/null and b/assets/gitlab_oauth_disposition_07-935997e9.png differ diff --git a/assets/gitlab_oauth_guide.html-04a9d45f.js b/assets/gitlab_oauth_guide.html-04a9d45f.js new file mode 100644 index 000000000..4e6431be9 --- /dev/null +++ b/assets/gitlab_oauth_guide.html-04a9d45f.js @@ -0,0 +1,34 @@ +import{_ as a,o as e,c as i,e as t}from"./app-2a91d8ab.js";const s="/CodeAnalysis/assets/gitlab_application_01-7866c7ca.png",d="/CodeAnalysis/assets/gitlab_application_02-6f821932.png",r="/CodeAnalysis/assets/gitlab_application_03-41a33813.png",n="/CodeAnalysis/assets/gitlab_application_04-01ff3c53.png",l="/CodeAnalysis/assets/gitlab_oauth_disposition_01-aa54e072.png",h="/CodeAnalysis/assets/gitlab_oauth_disposition_02-2679e831.png",o="/CodeAnalysis/assets/gitlab_oauth_disposition_03-07d21c14.png",c="/CodeAnalysis/assets/gitlab_oauth_disposition_04-4506c3a9.png",p="/CodeAnalysis/assets/gitlab_oauth_disposition_05-983333e5.png",u="/CodeAnalysis/assets/gitlab_oauth_disposition_06-21fa11a0.png",b="/CodeAnalysis/assets/gitlab_oauth_disposition_07-935997e9.png",A="/CodeAnalysis/assets/gitlab_oauth_QA_01-00f480f3.png",g="/CodeAnalysis/assets/gitlab_oauth_QA_02-02424dd0.png",_="/CodeAnalysis/assets/gitlab_oauth_QA_03-f1493e02.png",m="data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIADoB8QMBIgACEQEDEQH/xAAvAAEAAwEBAQEAAAAAAAAAAAAAAwQFAgEGBwEBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAD8z5l+h1PmW31GE0b9fPteWXDbfCY7erLlPsKNnzr6LWPh299Ufm7rmAAAAAAAAAAAAAAAAAAAAAAqzez/AA0vcwXO6AsK40uKAvxVRtVc8WNr50XtDBEfMwhTCFMIUwhWfSqsCutelRbiIlr0qLArrIrLIrLYqeXOSqmEKYQpuysmEKYQphCsckKbRMhMLuphWq0OsyFLe9g112saTyNPQ+er1q2sTg2MviSNiTEhJ6lqkamWG9zjd1rTY09k+dPHm2rGb4T+0BsTYfta+dDEbveIi/1memmzFanWUjc6w1bMWaTTs4/q2NDE6LvlBG3Qr8G3FlxWasFavLo2KPFl3b+Vvy4wIee+AIAAAAAAAAAAAA9eK9eD14PfACAAAAAAAAAAAAAr/8QALBAAAgICAgIABAUFAQAAAAAAAgMBBAAFEhMRFBAVMkAhIzEzUCAiJTQ1Qv/aAAgBAQABCACfoH+fCBKQgrOu1osUpNtFRiCYl+lJU1fHpLFRsOzS1wbGqlNqnXreXpuqrsOiitGtQLa8ha1RpaITY0ZoKvlmghAQYW9dTpm+GTRCdkfRd1B1a0gFTW6o1VFH1V0fKWOJCE1lsIxgTIY/jKzyrNQ4bG6u2JrSZ7QIJfQ7ahIQCbl9dhUrSewSbqtjG3Oyu1WMvETqbgPZq5K6T2ZnC5lmwRL0OUV8+owBe3UoWwNq3UtWzskdhdoJmwjeUlOqTL30bUVZk7mnK0+wJwEGUB9j4zxnjPGeM8Z4zx9pxjjGcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRziOcRzoLq7MiuZL7IlDInxkIbM+I9V+RTsThVHjHmeo8GpYKImJqWBjzPruz13Z6zs9Z2es7Iqvn8M9OznpWcmnYj9eguvsziOcRziOcRziOdBdXZnEc4jnEc4jnEc4jhKkOPLiOcRzX60b/u5xHKQCduoB32tbWls7S7cIqElsbdpx68GXwJm1uCN5U+5rDzbN76pTFEBO7VA7Zuu1mSy6qfc1Z40zVTeQPt2nXNODL4oGg7p1/wDv08R+gZsmwakedn/0buKGCaAzfqoQsJXhbKdhf13m3FWVnYDbWEe2EReKvY2dVM3U1ZrGxLzSfV1X/wAlNOpDohK6tXC+rF/XHwH6Yx/7RfCv+yGN/bn4R+kf0B9UfCMbPhc45USzWa+W1q9gIlDaNEpqGBJQmu1mWnKPb0hG+FdiGuXYWX+OoC2jRKahgSUJrtZlpyj29IRbWq2yAgYio2ANd6aAE5atjK5miY2EVCbRqxsk0Fr/ACKGynYfNPORMjxmH37VmQ7bN6zcgIcb2slckza3WmJmu09UcRbsLFiQhzrKTiIUeyusNRnFhwgS4s3rVuBh02XyxJTFpnjibrKTiIU3Y3HEuTm0+QIJs7CzbiYb8VsNTBISsONZLl1yw9a1sXsXS2pL7l59uZgjtMcxMvbZ77ZvY+0x9hz8lzJnIe2J/D2X5FuxH4YVp5R4ntPBtPCIGJt2CjxPe7O9+d787353vyLFiM9qznt2si0ySiGWLBvstfLthceQSb9jcsDAMs3rVuBhxX7RwmCGyc/2G6011pljH7G5YGAZZvWrcDDiv2jhMFNl8jIY7YW3yEslpk6Wk3Z3HdcHYv2bMxLLF61biIbprdep8z7sn6B+8855nPM55nPM/f8A/iP5/wD/xAA1EAACAQMCBgADBQcFAAAAAAABAgMAERIEIRMiMUFRoVBhcQUQIzJyFCBCUoGisjBTVFWR/9oACAEBAAk/APJ+PsQpexIFyBt0G1SyZya0QbpawSytvkfNQiApq+AeZmBBFwTe+9SShJtQIbyQmMgnuAeoqYhF1XBayXNrE5dRTyMHeAPGyYjFwCTlkacTxLqGjeNlKgEb2uDcitFFE88cTZBnO79uZjtU/HiOrWCQFCm9Xjlm1BSKFhvhewYk08oWTUCAmSEx2J7qD1FaoyRicwykR2Kkd1BO9RRKUTRqDqFkRbtG2VuATckrWmkeFYIWIggadbyxg9HKkA1DrHICylzpMRYqDZnyNsagQ6qaJGXlfcOE3sJRcDI1Fpon4mcil2cPGFR0LgZkZ1oIrK5LloCOVN97abob0wYAkBhex+YvY/Db3jky2NjtUjkwycSzMWBbK4rSiMLqRqGDPnk4/oLCtOyFdSJ8nkMhyH9BWn4StMZXu+d2PjYWFaZhPE0Rc8TlcRgDYW26VHbPU8a9+mxFqTFtPHGo3vcx960vDVdSJ3BfLJh4NthUf4kWpMsTk3xBNyh8i9aQoUnErXlLXIN7DwKUox1XHVw26mv2tS6aRQYZRCfwIijXNmoTtaOEKj75lECnNwRVxKoODog38Iw22HYjoK0jtwUgDPaG941AJF0Le64sbhAkzBQ+yRqiBQWH8tPqw8z6ok8Fek6lQPz/AMNElbnEkWJHzG/w3yaFChQoUKFChQoUKFChQoUKFChQoUKFIcMscvn1tUZwL4X+dr2pPdJSexUfsUlh9RS0m31FR+xS+xSexSexSexSexSexUfsVH7FR7fUUhwzxy+fW1ChQoUKQ4ZY5fPrahQoUKFCkIyFxfa48ihQqTD9n0kk/S+WHahQBVp0BHkEitUztHqyoUpYodzZWv02rUykrponByOzea1EjoYIXKsxILea3ZtU4H1LVhaLUjTjFlbkQgrfGp3nw1bKXkFmS42UbnagCrTICPIJo5yDX8KO/YMDyisMYtUNOMXVuRCCt8aYq6/aVww2IIU1PI6FdM5DMSC1+tSu99ecskwscT8zX+/H/lX/AHCVPLqC+rYh5BYx4GxQbmv+RJ/lQuCwBFwvs7ComUlrb6mKb0n3RYYTr3v1YVpVBTWNGylmIkHXetFFskLE5PzDAcp5q0ka5HTBmDPcqyrtuag4Rj1Rh2YtkLXBN6g4eMYDcxbJh1bfpeuqR8R/1y7+hauscXEf9cu/oW/f+f8Apm1yrSfJpyD6Fq03DYawQYhycwfm17GlhsdasLrE7sCp8lwN6hDFNbhYlrFQCbbGtNGjB9KcwWJIKrtuSKh4brq2iNmJyBF7m9KS1lZ1Btd5t7f+WpYbHWrC6xO7AqfJcDeoQxTW4WJaxUAm2xrTRowfSnMFiSCq7bkiouEx1/AYhicg3c371p+EF1ogIDMclPm/etNhJFqSoGTEOg81EAraZW4eTsuzEWGRJArTJDO8i8bBnIQOdl5yd6aISLKVKxtI118tmBvUWGH2Tqu9+uP3Egg3BFSBsGyAxUC/kgDc0UIQWXGNEsPHKBTXMaqq7DYL0pos1kEgYQxqch3uFp7DirL0B516GsHRXyKBRGpPzwtWjjgcMCHRnJ/uY1KMo3zWyKObyQBuachTIJD+pehqTIAk2Chdz1JsBc0/NCFCGw2CdKs8Zl4rIdgzfUWNaOOBgwOaM5P9zGpd43zWyqObybDc0/KZeLaw/P5oxm7ZEiJFJP1UA/uGzIwZT4Ip7q0nEIsPzeaZWCAAHBQ1gLAFgLmiGSCRG2Rc7J2y6mnvGHZlGIXr3Nupo8RYlVAuy8i9qS4eXNlvba/StmkYtTU1P6FP6FPt9BRp7D6Cn9Cm9U3oU3oU3oU3oU/oU/oVJ6FHNAwLLsLgdr1s7uX27VNujZriAvN/NsBc1KLB8wFVU5vPKBUmQUkgBQu56k2AuadSYSpRsFyGPS5tc1zxGYSumwyNEq7SZi38JvcWqUWD5gKqpzeeUCpMgpJAChdz1JsBc06kwlSjYLkMelza5p9jLxfHP5qW5Rs1sqrzeTYbmiC5fMkgEE3v0povwyCloY1tbcdBRjyDZZLGiNfzdQKkuASbBQu57mwFzT48b7OmiTYm7taw+7yfj/k/H//EACwRAAECBAQEBQUAAAAAAAAAAAEAESExQWECElFxEIGhsSJAgsHRIFCR4fD/2gAIAQIBAT8AaV5IRZCLNYIRZtQOa0v5zSyk1kISshBmt+QGUmsm4f0PbzJkNy6E/W6wwyWPVYfCQsMGsY7rDDK9CG5CSw+Eg7dAhDLb2b4WGAFuFA1Hf3CDONM3RYZB7dl8l99OBQVfpFN+UKIU3WGDPQhtIIQyv+oU4aWJ7haKvqPeX2P/xAAoEQABAwIEBQUBAAAAAAAAAAABABEhYaECEFFxEkBBgtEwMVCBwdL/2gAIAQMBAT8AdGL2Rh6PZGH2JWtOc1rkZRm9553qUfbsZYp4qrFII3Rl9jdGXqDcusUgje6M8VXu/lGScupRdu1kerVXj0ddkfwoy9Qboy/3fLwFqv5b4P8A/9k=",v="/CodeAnalysis/assets/gitlab_oauth_QA_05-8d166cf1.png",x="/CodeAnalysis/assets/gitlab_oauth_QA_06-3f3cc486.png",f="/CodeAnalysis/assets/gitlab_oauth_QA_07-d3997b70.png",B={},C=t(`以下三种部署方式选择其中一项即可。
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息。
#Oauth认证相关配置
+GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker deploy
+
在/scripts/config.sh 中添加以下配置
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行重新启动操作
bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+
填写重定向url,“http://<部署gitlab的ip地址>/cb_git_auth/gitlab”
scopes尽量都勾选,以开启对私有化代码库的访问权限
保存application 这里的Application ID、Secret 和 Callback URL 之后需要填写到代码分析服务中。
以下三种部署方式选择其中一项即可。
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息。
#Oauth认证相关配置
+GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker deploy
+
在/scripts/config.sh 中添加以下配置
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行重新启动操作
bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+
将application中的Application ID、Secret 和 Callback URL分别填入
An error has occurred
Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
如图,GITLAB_OAUTH_URL没有配置,默认使用 https://gitlab.com/oauth/authorize 。
需要根据项目部署方式,修改配置信息。
(1)docker-compose 部署方式
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息
GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
(2)docker 部署方式
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
(3)源代码部署方式
在/scripts/config.sh 中添加以下配置
export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
此站点的连接不安全,发送了无效的响应。
ERR_SSL_PROTOCOL_ERROR
配置的url存在问题,可能使用了https协议,访问本地ip不能用https协议,修改成http。
(1)检查配置url是否加端口号,默认80端口可能已经被占用,或已经分配给代码分析平台。
(2)检查回调地址是否填写端口号
oauth failed, err: 未知错误: <class 'Exception'>:{method: git_oauth, error_message: [400] 授权异常,请稍后再试,异常原因:{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}}
client.py 中存在默认的GITLAB_URL,如果在配置文件中没有设置GITLAB_URL,那么TCA将默认访问https://gitlab.com
GITLAB_URL = os.environ.get("GITLAB_URL") or "https://gitlab.com"
+
客户端调用的API都需要使用到GITLAB_URL作为前缀的路径,会发送post请求到 https://gitlab.com 路径下,因此需要对路径进行修改。
要连接私有化的gitlab,需要根据项目部署方式,修改配置信息。
(1)docker-compose 部署方式
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息
GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
(2)docker 部署方式
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
(3)源代码部署方式
在/scripts/config.sh 中添加以下配置
export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
Golangci-lint 是为了解决 GoMetalinter 的弊端而改版升级的。
比 GoMetaliner 快个 2 到 7 倍
共享代码缓存,消耗内存比 Gometaliner 少 26%
更精准的 issue,会内置一些 exclude 列表过滤掉误报 issue
支持增量分析
在 CI 系统上选用 TCA 插件,或者下载 TCA 客户端到本地机器上
因为 GolangCiLint 要求找寻到项目需要的全部依赖,否则就会执行失败。所以这里需要在 Ci 系统或者本地机器上配置好项目的依赖,并确保能够编译通过
检查是否设置了 GOPATH 和 GOROOT,在分析方案的环境变量中设置 GOPATH=$GOPATH
在 代码分析 页面上关联待分析的代码库并创建分析方案,并在代码检查-规则设置的自定义规则包里面添加 GolangCiLint 工具规则
在分析方案中增加编译命令
然后在 CI 系统上或者本地启动代码分析即可
若项目目录结构如下图,需要设置 include 执行 myproj,比如 src/myproj/*
这是因为 GolangCiLint 分析前会优先检查所有代码文件的依赖是否齐全,所以需要设置 include,让工具只关注 include 下面的代码文件的依赖。
在分析方案的过滤配置,路径过滤中添加 include 路径。
Q:出现 no go files to analyze 问题
A:这里可能为以下原因:
机器环境没有项目的完整依赖,使用以下命令查找对应依赖在 GOPATH 下是否存在或者 GOPATH 设置是否完整(有的项目有多个 GOPATH 内容),或者对应依赖是否存在,需要用户部署好机器环境
grep -nr "path/to/GOPATH" .
+
没有指定 include 分析路径过滤,这样才不会检查依赖中的依赖,而是关注源码文件的依赖完整性
也可能是某 go 文件中使用到该依赖,但是 GOPATH 没有设置正确的依赖搜索路径导致。需要找到依赖相对的当前目录:
grep -nr "path/to/GOPATH" .
+
然后设置到 GOPATH 中,比如
GOPATH=$GOPATH:$SOURCE_DIR/test
+
还有可能是部分依赖是需要编译之后生成的,需要正确填写好编译命令,使得项目编译成功。
Q:could not determine GOARCH and Go compiler 问题
A:跟问题 1 是一样的问题。解决方案也是一样。
Q:failed to run 'go env': exit status 1 问题
A:原因是找不到正确的 GOPATH。解决方案是设置 GOPATH 环境变量。
Q:GO 版本限制
A:因为 golangci-lint 用到了 go mod 特性,该特性是在 1.11 之后才有的。所以要求 go 版本在 1.11 版本以上。
Golangci-lint 是为了解决 GoMetalinter 的弊端而改版升级的。
比 GoMetaliner 快个 2 到 7 倍
共享代码缓存,消耗内存比 Gometaliner 少 26%
更精准的 issue,会内置一些 exclude 列表过滤掉误报 issue
支持增量分析
在 CI 系统上选用 TCA 插件,或者下载 TCA 客户端到本地机器上
因为 GolangCiLint 要求找寻到项目需要的全部依赖,否则就会执行失败。所以这里需要在 Ci 系统或者本地机器上配置好项目的依赖,并确保能够编译通过
检查是否设置了 GOPATH 和 GOROOT,在分析方案的环境变量中设置 GOPATH=$GOPATH
在 代码分析 页面上关联待分析的代码库并创建分析方案,并在代码检查-规则设置的自定义规则包里面添加 GolangCiLint 工具规则
在分析方案中增加编译命令
然后在 CI 系统上或者本地启动代码分析即可
若项目目录结构如下图,需要设置 include 执行 myproj,比如 src/myproj/*
这是因为 GolangCiLint 分析前会优先检查所有代码文件的依赖是否齐全,所以需要设置 include,让工具只关注 include 下面的代码文件的依赖。
在分析方案的过滤配置,路径过滤中添加 include 路径。
Q:出现 no go files to analyze 问题
A:这里可能为以下原因:
机器环境没有项目的完整依赖,使用以下命令查找对应依赖在 GOPATH 下是否存在或者 GOPATH 设置是否完整(有的项目有多个 GOPATH 内容),或者对应依赖是否存在,需要用户部署好机器环境
grep -nr "path/to/GOPATH" .
+
没有指定 include 分析路径过滤,这样才不会检查依赖中的依赖,而是关注源码文件的依赖完整性
也可能是某 go 文件中使用到该依赖,但是 GOPATH 没有设置正确的依赖搜索路径导致。需要找到依赖相对的当前目录:
grep -nr "path/to/GOPATH" .
+
然后设置到 GOPATH 中,比如
GOPATH=$GOPATH:$SOURCE_DIR/test
+
还有可能是部分依赖是需要编译之后生成的,需要正确填写好编译命令,使得项目编译成功。
Q:could not determine GOARCH and Go compiler 问题
A:跟问题 1 是一样的问题。解决方案也是一样。
Q:failed to run 'go env': exit status 1 问题
A:原因是找不到正确的 GOPATH。解决方案是设置 GOPATH 环境变量。
Q:GO 版本限制
A:因为 golangci-lint 用到了 go mod 特性,该特性是在 1.11 之后才有的。所以要求 go 版本在 1.11 版本以上。
腾讯云代码分析(Tencent Cloud Code Analysis, TCA)起步于 2012 年(内部代号CodeDog),是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是精准跟踪管理代码分析发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码,以及度量代码复杂度、重复代码、代码统计。持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
用心关注每行代码迭代,助力传承卓越代码文化!
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
通过代码检查精准跟踪管理发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码等。
目前已集成众多自研、知名开源分析工具,并采用了分层分离架构,可以满足团队快速自助管理工具。
包含代码圈复杂度、代码重复率和代码统计等度量信息。
圈复杂度也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度。圈复杂度大说明程序代码的判断逻辑复杂,可能造成代码质量低下且难于测试和维护。
定期分析工程项目中代码的圈复杂度,可以有效地帮助开发与测试逐步优化代码质量。
定期分析工程项目中的重复代码,可以有效地帮助开发发现冗余代码,进行代码抽象和重构,降低代码风险,以便于更好的管理和维护代码。
支持全量增量展示代码行数统计,包含代码行、注释行和空白行,可以有效地跟踪了解工程项目中代码量持续变化,并可以查看各个语言的占比情况。
',17),t=[n];function i(s,o){return a(),r("div",null,t)}const p=e(h,[["render",i],["__file","index.html.vue"]]);export{p as default}; diff --git a/assets/index.html-8632c13c.js b/assets/index.html-8632c13c.js new file mode 100644 index 000000000..12d12a83d --- /dev/null +++ b/assets/index.html-8632c13c.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-075401e2","path":"/en/api/","title":"接口调用说明","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"接口地址","slug":"接口地址","link":"#接口地址","children":[]},{"level":2,"title":"接口鉴权方式","slug":"接口鉴权方式","link":"#接口鉴权方式","children":[]},{"level":2,"title":"获取 org_sid 和 project_team 信息","slug":"获取-org-sid-和-project-team-信息","link":"#获取-org-sid-和-project-team-信息","children":[]},{"level":2,"title":"Example","slug":"example","link":"#example","children":[]},{"level":2,"title":"分页方式","slug":"分页方式","link":"#分页方式","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/api/README.md"}');export{e as data}; diff --git a/assets/index.html-892823d8.js b/assets/index.html-892823d8.js new file mode 100644 index 000000000..ec13f2c44 --- /dev/null +++ b/assets/index.html-892823d8.js @@ -0,0 +1,87 @@ +import{_ as e}from"./API的个人令牌-d33dd7b6.js";import{_ as n,o as i,c as t,e as u}from"./app-2a91d8ab.js";const s={},o=u(`http://{host}/server/
注:host 指当前浏览器访问该文档的 URL 域名部分。
发起请求时,需要在头部中添加以下格式形式,对应的 value 请看下面获取方式
{
+ "Authorization": "Token 当前user的token"
+}
+
获取 token 位置(个人中心-个人令牌):
通过平台访问具体代码库扫描情况时,可从 URL 中获取对应 org_sid 和 project_team 字段,查看方式如下例子:
代码库扫描地址:http://{host}/t/xxx/p/yyy/code-analysis/repos/1/projects?limit=10&offset=0
其中,org_sid 为xxx
字段,project_team 为 yyy
字段
import requests
+# 假设:
+# 当前域名为http://tca.com/,当前org_sid为helloworld
+# 获取helloworld团队下的hellotca项目下登记的代码库
+url="http://tca.com/server/main/api/orgs/helloworld/teams/hellotca/repos/?limit=12&offset=0"
+headers = {
+ "Authorization": "Token %s" % token,
+}
+
+response = requests.get(url, headers=headers)
+print(response.json())
+# 结果如下:
+{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 23,
+ "name": "repo_name",
+ "scm_url": "http://git.repo.com/group/repo_name",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-05-14 02:34:44.509118+00:00",
+ "recent_active": {
+ "id": 27,
+ "branch_name": "master",
+ "active_time": "2021-05-14 02:34:44.509118+00:00",
+ "total_line_num": 1,
+ "code_line_num": 1
+ },
+ "created_from": "tca",
+ "creator": {
+ "username": "author",
+ "nickname": "author",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ },
+ "symbol": null,
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "test",
+ "scm_platform": 2,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-05-14T10:34:44.552859+08:00",
+ "modified_time": "2021-05-14T10:34:44.552887+08:00"
+ },
+ "project_team": {
+ "name": "test",
+ "display_name": "测试",
+ "status": 1,
+ "org_sid": "test"
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
平台返回的数据分页格式是使用limit
和offset
参数进行分页处理
比如:server/main/api/orgs/<org_sid>/teams/?limit=12&offset=12
获取得到的数据是从第 13 条开始获取
平台返回的响应格式如下:
{
+ "data": {...}, # 详细数据
+ "code": 0, # 请求结果码,为0表示正常
+ "msg": "xxx" , # 请求结果信息
+ "status_code": 200 # 请求响应码
+}
+
腾讯云代码分析(Tencent Cloud Code Analysis, TCA)起步于 2012 年(内部代号CodeDog),是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是精准跟踪管理代码分析发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码,以及度量代码复杂度、重复代码、代码统计。持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
用心关注每行代码迭代,助力传承卓越代码文化!
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
通过代码检查精准跟踪管理发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码等。
目前已集成众多自研、知名开源分析工具,并采用了分层分离架构,可以满足团队快速自助管理工具。
包含代码圈复杂度、代码重复率和代码统计等度量信息。
圈复杂度也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度。圈复杂度大说明程序代码的判断逻辑复杂,可能造成代码质量低下且难于测试和维护。
定期分析工程项目中代码的圈复杂度,可以有效地帮助开发与测试逐步优化代码质量。
定期分析工程项目中的重复代码,可以有效地帮助开发发现冗余代码,进行代码抽象和重构,降低代码风险,以便于更好的管理和维护代码。
支持全量增量展示代码行数统计,包含代码行、注释行和空白行,可以有效地跟踪了解工程项目中代码量持续变化,并可以查看各个语言的占比情况。
',17),t=[n];function i(s,o){return a(),r("div",null,t)}const p=e(h,[["render",i],["__file","index.html.vue"]]);export{p as default}; diff --git a/assets/index.html-984e57d5.js b/assets/index.html-984e57d5.js new file mode 100644 index 000000000..668f749ac --- /dev/null +++ b/assets/index.html-984e57d5.js @@ -0,0 +1 @@ +import{_ as a,r as i,o as l,c as r,a as t,b as e,d as n,w as s,e as c}from"./app-2a91d8ab.js";const d={},u=c('Tencent Cloud Code Analysis (TCA for short, code-named CodeDog inside the company early) is a comprehensive platform for code analysis and issue tracking. TCA consist of three components, server, web and client. It integrates of a number of self-developed tools, and also supports dynamic integration of code analysis tools in various programming languages.
Code analysis is a technology, using lexical analysis, syntax analysis, control-flow analysis, data-flow analysis to make a comprehensive analysis of the code, so as to verify whether the code meets the requirements of normative, security, reliability, maintainability and other indicators.
Using TCA can help team find normative, structural, security vulnerabilities and other issues in the code, continuously monitor the quality of the project code and issue alerts. At the same time, TCA opens up APIs to support connection with upstream and downstream systems, so as to integrate code analysis capabilities, ensure code quality, and be more conducive to inheriting an excellent team code culture.
http://{host}/server/
注:host 指当前浏览器访问该文档的 URL 域名部分。
发起请求时,需要在头部中添加以下格式形式,对应的 value 请看下面获取方式
{
+ "Authorization": "当前user的token"
+}
+
获取 token 位置(个人中心-个人令牌):
通过平台访问具体代码库扫描情况时,可从 URL 中获取对应 org_sid 和 project_team 字段,查看方式如下例子:
代码库扫描地址:http://{host}/t/xxx/p/yyy/code-analysis/repos/1/projects?limit=10&offset=0
其中,org_sid 为xxx
字段,project_team 为 yyy
字段
import requests
+# 假设:
+# 当前域名为http://tca.com/,当前org_sid为helloworld
+# 获取helloworld团队下的hellotca项目下登记的代码库
+url="http://tca.com/server/main/api/orgs/helloworld/teams/hellotca/repos/?limit=12&offset=0"
+headers = {
+ "Authorization": token,
+}
+
+response = requests.get(url, headers=headers)
+print(response.json())
+# 结果如下:
+{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 23,
+ "name": "repo_name",
+ "scm_url": "http://git.repo.com/group/repo_name",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-05-14 02:34:44.509118+00:00",
+ "recent_active": {
+ "id": 27,
+ "branch_name": "master",
+ "active_time": "2021-05-14 02:34:44.509118+00:00",
+ "total_line_num": 1,
+ "code_line_num": 1
+ },
+ "created_from": "tca",
+ "creator": {
+ "username": "author",
+ "nickname": "author",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ },
+ "symbol": null,
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "test",
+ "scm_platform": 2,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-05-14T10:34:44.552859+08:00",
+ "modified_time": "2021-05-14T10:34:44.552887+08:00"
+ },
+ "project_team": {
+ "name": "test",
+ "display_name": "测试",
+ "status": 1,
+ "org_sid": "test"
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
平台返回的数据分页格式是使用limit
和offset
参数进行分页处理
比如:server/main/api/orgs/<org_sid>/teams/?limit=12&offset=12
获取得到的数据是从第 13 条开始获取
腾讯云代码分析(Tencent Cloud Code Analysis,简称TCA,内部曾用研发代号 CodeDog )是集众多分析工具的云原生、分布式、高性能的代码综合分析跟踪平台,包含服务端、Web端、客户端三个组件,已集成一批自研工具,同时也支持动态集成业界各编程语言的分析工具。
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
使用TCA可以帮助团队用代码分析技术查找代码中的规范性、结构性、安全漏洞等问题,持续监控项目代码质量并进行告警。同时TCA开放API,支持与上下游系统对接,从而集成代码分析能力,为代码质量提供保障,更有益于传承优良的团队代码文化。
成功部署并启动 Server 与 Web 服务后,通过以下步骤创建您的第一个代码分析项目。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
提示
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
提示
成功部署并启动 Server 与 Web 服务后,通过以下步骤创建您的第一个代码分析项目。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
TIP
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
TIP
CentOS 7.3 版本
wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm
+yum localinstall mysql57-community-release-el7-11.noarch.rpm
+
安装成功后,查看MySQL版本:
yum repolist all | grep mysql
+
输出结果:
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community 禁用
+mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community - 禁用
+mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community 禁用
+mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community - 禁用
+!mysql-connectors-community/x86_64 MySQL Connectors Community 启用: 221
+mysql-connectors-community-source MySQL Connectors Community - S 禁用
+!mysql-tools-community/x86_64 MySQL Tools Community 启用: 135
+mysql-tools-community-source MySQL Tools Community - Source 禁用
+mysql-tools-preview/x86_64 MySQL Tools Preview 禁用
+mysql-tools-preview-source MySQL Tools Preview - Source 禁用
+mysql55-community/x86_64 MySQL 5.5 Community Server 禁用
+mysql55-community-source MySQL 5.5 Community Server - S 禁用
+mysql56-community/x86_64 MySQL 5.6 Community Server 禁用
+mysql56-community-source MySQL 5.6 Community Server - S 禁用
+!mysql57-community/x86_64 MySQL 5.7 Community Server 启用: 544
+mysql57-community-source MySQL 5.7 Community Server - S 禁用
+mysql80-community/x86_64 MySQL 8.0 Community Server 禁用
+mysql80-community-source MySQL 8.0 Community Server - S 禁用
+
yum install mysql-community-server
+
1.如遇以下报错,可尝试运行
yum install mysql-community-server --nogpgcheck
安装
Public key for mysql-community-libs-compat-5.7.37-1.el7.x86_64.rpm is not installed
Failing package is: mysql-community-libs-compat-5.7.37-1.el7.x86_64 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
2.如遇以下报错,可执行yum module disable mysql
后重试安装
All matches were filtered out by modular filtering for argument: mysql-community-serve
Error: Unable to find a match: mysql-community-server
安装好的MySQL配置文件路径是/etc/my.cnf
,这里可以根据需要调整,比如可以调整:
systemctl start mysqld
+
确认MySQL正常启动
systemctl status mysqld
+
查看生成 MySQL root用户临时密码:
grep 'temporary password' /var/log/mysqld.log
+
连接MySQL服务
$ mysql -uroot -p
+# 输出上述查询到的临时密码
+
修改root用户的密码(下面是改成 Password@2021
,这里根据自行需要进行调整):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Password@2021';
+
CentOS 7.3 版本
wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm
+yum localinstall mysql57-community-release-el7-11.noarch.rpm
+
安装成功后,查看MySQL版本:
yum repolist all | grep mysql
+
输出结果:
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community 禁用
+mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community - 禁用
+mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community 禁用
+mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community - 禁用
+!mysql-connectors-community/x86_64 MySQL Connectors Community 启用: 221
+mysql-connectors-community-source MySQL Connectors Community - S 禁用
+!mysql-tools-community/x86_64 MySQL Tools Community 启用: 135
+mysql-tools-community-source MySQL Tools Community - Source 禁用
+mysql-tools-preview/x86_64 MySQL Tools Preview 禁用
+mysql-tools-preview-source MySQL Tools Preview - Source 禁用
+mysql55-community/x86_64 MySQL 5.5 Community Server 禁用
+mysql55-community-source MySQL 5.5 Community Server - S 禁用
+mysql56-community/x86_64 MySQL 5.6 Community Server 禁用
+mysql56-community-source MySQL 5.6 Community Server - S 禁用
+!mysql57-community/x86_64 MySQL 5.7 Community Server 启用: 544
+mysql57-community-source MySQL 5.7 Community Server - S 禁用
+mysql80-community/x86_64 MySQL 8.0 Community Server 禁用
+mysql80-community-source MySQL 8.0 Community Server - S 禁用
+
yum install mysql-community-server
+
1.如遇以下报错,可尝试运行
yum install mysql-community-server --nogpgcheck
安装
Public key for mysql-community-libs-compat-5.7.37-1.el7.x86_64.rpm is not installed
Failing package is: mysql-community-libs-compat-5.7.37-1.el7.x86_64 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
2.如遇以下报错,可执行yum module disable mysql
后重试安装
All matches were filtered out by modular filtering for argument: mysql-community-serve
Error: Unable to find a match: mysql-community-server
安装好的MySQL配置文件路径是/etc/my.cnf
,这里可以根据需要调整,比如可以调整:
systemctl start mysqld
+
确认MySQL正常启动
systemctl status mysqld
+
查看生成 MySQL root用户临时密码:
grep 'temporary password' /var/log/mysqld.log
+
连接MySQL服务
$ mysql -uroot -p
+# 输出上述查询到的临时密码
+
修改root用户的密码(下面是改成 Password@2021
,这里根据自行需要进行调整):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Password@2021';
+
安装编译打包需要的工具
yum -y install gcc zlib-devel pcre-devel bzip2-devel openssl-devel readline-devel
+
Ubuntu:
apt install gcc libssl-dev zlib1g-dev libpcre3-dev libbz2-dev libreadline-dev
wget http://nginx.org/download/nginx-1.20.2.tar.gz
+
# 解压
+$ tar zvxf nginx-1.20.2.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/nginx-1.20.2
+
+# 配置
+$ ./configure \\
+--sbin-path=/usr/local/nginx/nginx \\
+--conf-path=/etc/nginx/nginx.conf \\
+--pid-path=/run/nginx.pid \\
+--with-stream \\
+--with-http_ssl_module --with-http_v2_module --with-http_auth_request_module
+
+# 构建nginx
+$ make -j4
+$ make install
+$ make clean
+
+# 建立软链
+$ ln -s /usr/local/nginx/nginx /usr/local/bin/nginx
+
mkdir /etc/nginx/conf.d/
+vi /etc/nginx/nginx.conf
+
检查nginx.conf
配置文件:
pid /run/nginx.pid
,如果缺失或被注释则加上,加上位置如下所示:include conf.d/*.conf;
,如果缺失则加上,加上位置如下所示:# ...省略内容
+#pid logs/nginx.pid; # 默认有的
+pid /run/nginx.pid;
+
+events {
+ # ...省略内容
+}
+
+# ...省略内容
+
+http {
+ # ...省略内容
+ #
+ include conf.d/*.conf;
+ server {
+ # ...省略内容
+ }
+}
+
+
后续可以将nginx配置文件放置到/etc/nginx/conf.d/
目录下
vim /usr/lib/systemd/system/nginx.service
+
输入以下内容:
[Unit]
+Description=The nginx HTTP and reverse proxy server
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/run/nginx.pid
+# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
+# SELinux context. This might happen when running \`nginx -t\` from the cmdline.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
+ExecStartPre=/bin/rm -f /run/nginx.pid
+ExecStartPre=/usr/local/bin/nginx -t
+ExecStart=/usr/local/bin/nginx
+ExecReload=/usr/local/bin/nginx -s reload
+ExecStop=/usr/local/bin/nginx -s stop
+KillSignal=SIGQUIT
+TimeoutStopSec=5
+KillMode=process
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动nginx:
systemctl start nginx
+
开机自动启动nginx:
systemctl enable nginx
+
安装编译打包需要的工具
yum -y install gcc zlib-devel pcre-devel bzip2-devel openssl-devel readline-devel
+
Ubuntu:
apt install gcc libssl-dev zlib1g-dev libpcre3-dev libbz2-dev libreadline-dev
wget http://nginx.org/download/nginx-1.20.2.tar.gz
+
# 解压
+$ tar zvxf nginx-1.20.2.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/nginx-1.20.2
+
+# 配置
+$ ./configure \\
+--sbin-path=/usr/local/nginx/nginx \\
+--conf-path=/etc/nginx/nginx.conf \\
+--pid-path=/run/nginx.pid \\
+--with-stream \\
+--with-http_ssl_module --with-http_v2_module --with-http_auth_request_module
+
+# 构建nginx
+$ make -j4
+$ make install
+$ make clean
+
+# 建立软链
+$ ln -s /usr/local/nginx/nginx /usr/local/bin/nginx
+
mkdir /etc/nginx/conf.d/
+vi /etc/nginx/nginx.conf
+
检查nginx.conf
配置文件:
pid /run/nginx.pid
,如果缺失或被注释则加上,加上位置如下所示:include conf.d/*.conf;
,如果缺失则加上,加上位置如下所示:# ...省略内容
+#pid logs/nginx.pid; # 默认有的
+pid /run/nginx.pid;
+
+events {
+ # ...省略内容
+}
+
+# ...省略内容
+
+http {
+ # ...省略内容
+ #
+ include conf.d/*.conf;
+ server {
+ # ...省略内容
+ }
+}
+
+
后续可以将nginx配置文件放置到/etc/nginx/conf.d/
目录下
vim /usr/lib/systemd/system/nginx.service
+
输入以下内容:
[Unit]
+Description=The nginx HTTP and reverse proxy server
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/run/nginx.pid
+# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
+# SELinux context. This might happen when running \`nginx -t\` from the cmdline.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
+ExecStartPre=/bin/rm -f /run/nginx.pid
+ExecStartPre=/usr/local/bin/nginx -t
+ExecStart=/usr/local/bin/nginx
+ExecReload=/usr/local/bin/nginx -s reload
+ExecStop=/usr/local/bin/nginx -s stop
+KillSignal=SIGQUIT
+TimeoutStopSec=5
+KillMode=process
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动nginx:
systemctl start nginx
+
开机自动启动nginx:
systemctl enable nginx
+
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/bin/python
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
以下脚本内容是上面的步骤集合,省去了复制粘贴的重复动作。
install_py37.sh
,写入以下 shell 脚本chmox +x install_py37.sh
./install_py37.sh
#!/bin/env bash
+
+## 下载 Python 源码,如果已下载源码在脚本当前目录下,可注释跳过下载步骤
+wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
+## 安装编译依赖组件
+yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
+## 解压安装
+# 解压到/usr/local/src目录
+tar zvxf Python-3.7.12.tgz -C /usr/local/src
+cd /usr/local/src/Python-3.7.12
+# 编译前配置
+./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+make -j8
+# 安装Python
+make install
+# 清理编译产出的中间文件
+make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+ldconfig
+
+## 检查Python版本是否安装成功
+echo -e "\\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\\033[0m"
+python --version
+echo -e "\\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\\033[0m"
+
+## pypi下载源配置
+mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/bin/python
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
以下脚本内容是上面的步骤集合,省去了复制粘贴的重复动作。
install_py37.sh
,写入以下 shell 脚本chmox +x install_py37.sh
./install_py37.sh
#!/bin/env bash
+
+## 下载 Python 源码,如果已下载源码在脚本当前目录下,可注释跳过下载步骤
+wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
+## 安装编译依赖组件
+yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
+## 解压安装
+# 解压到/usr/local/src目录
+tar zvxf Python-3.7.12.tgz -C /usr/local/src
+cd /usr/local/src/Python-3.7.12
+# 编译前配置
+./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+make -j8
+# 安装Python
+make install
+# 清理编译产出的中间文件
+make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+ldconfig
+
+## 检查Python版本是否安装成功
+echo -e "\\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\\033[0m"
+python --version
+echo -e "\\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\\033[0m"
+
+## pypi下载源配置
+mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
注:当前Ubuntu版本为18.04
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
apt-get update
+apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev wget libbz2-dev tk-dev gcc make
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
注:当前Ubuntu版本为18.04
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
apt-get update
+apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev wget libbz2-dev tk-dev gcc make
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "[global]\\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
安装编译打包需要的工具
yum install -y gcc make tcl wget
+
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
+
# 解压
+$ tar zvxf redis-5.0.4.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/redis-5.0.4
+
+# 构建redis依赖库
+$ cd deps; make -j4 hiredis jemalloc linenoise lua
+$ cd ..
+
+# 构建redis
+$ make -j4
+$ make install
+$ make clean
+
安装后,可以在/usr/local/src/redis-5.0.4/src
目录和/usr/local/bin/
目录下找到redis-server
与redis-cli
两个文件
cp /usr/local/src/redis/redis.conf /etc/redis.conf
+vim /usr/local/src/redis/redis.conf
+
# 设置Redis密码
+requirepass 123456
+
+# 将 daemonize no 调整为 daemonize yes,将redis-server调整为默认后台启动
+daemonize yes
+
+# 配置日志
+logfile '/var/log/redis/redis-server.log'
+
redis-server /etc/redis.conf
+
vim /etc/systemd/system/redis.service
+
输入以下内容:
[Unit]
+Description=redis-server
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/local/bin/redis-server /etc/redis.conf
+ExecStop=/usr/local/bin/redis-cli shutdown
+Restart=always
+
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动redis-server:
systemctl start redis
+
开机自动启动redis:
systemctl enable redis
+
安装编译打包需要的工具
yum install -y gcc make tcl wget
+
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
+
# 解压
+$ tar zvxf redis-5.0.4.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/redis-5.0.4
+
+# 构建redis依赖库
+$ cd deps; make -j4 hiredis jemalloc linenoise lua
+$ cd ..
+
+# 构建redis
+$ make -j4
+$ make install
+$ make clean
+
安装后,可以在/usr/local/src/redis-5.0.4/src
目录和/usr/local/bin/
目录下找到redis-server
与redis-cli
两个文件
cp /usr/local/src/redis/redis.conf /etc/redis.conf
+vim /usr/local/src/redis/redis.conf
+
# 设置Redis密码
+requirepass 123456
+
+# 将 daemonize no 调整为 daemonize yes,将redis-server调整为默认后台启动
+daemonize yes
+
+# 配置日志
+logfile '/var/log/redis/redis-server.log'
+
redis-server /etc/redis.conf
+
vim /etc/systemd/system/redis.service
+
输入以下内容:
[Unit]
+Description=redis-server
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/local/bin/redis-server /etc/redis.conf
+ExecStop=/usr/local/bin/redis-cli shutdown
+Restart=always
+
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动redis-server:
systemctl start redis
+
开机自动启动redis:
systemctl enable redis
+
CentOS 7.3 版本
yum install redis
+
注:安装redis可能会出现"no package redis available"的错误提示,请执行yum install epel-release
后重试redis安装命令。
$ vi /etc/redis.conf
+
+# 找到 requirepass foobared
+# 复制一行并根据自己需要调整密码,比如
+requirepass tca123
+
systemctl start redis
+
查看redis运行状态
systemctl status redis
+
$ redis-cli
+
+127.0.0.1:6379> auth tca123
+OK # 鉴权通过
+
CentOS 7.3 版本
yum install redis
+
注:安装redis可能会出现"no package redis available"的错误提示,请执行yum install epel-release
后重试redis安装命令。
$ vi /etc/redis.conf
+
+# 找到 requirepass foobared
+# 复制一行并根据自己需要调整密码,比如
+requirepass tca123
+
systemctl start redis
+
查看redis运行状态
systemctl status redis
+
$ redis-cli
+
+127.0.0.1:6379> auth tca123
+OK # 鉴权通过
+
PR全称为Pull Request,它是一种代码库的协作方式。开发者可以通过PR将自己在代码库的修改通知到代码库负责人,由原作者评审代码并决定是否能合入。
提示
Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.
在本地克隆Fork的代码库并创建分支
git clone https://github.com/Lingghh/CodeAnalysis
+git checkout -b dev/add_qa_20220301
+
注:也可以在自己Fork的代码库GitHub页面上创建分支。
接下来就可以在本地修改代码,修改完成后先push到Fork的代码库中.
点击compare across forks 。
点击head repository 。
选择自己Fork的代码库和比较的分支,比如我这里选择Lingghh/CodeAnalysis和待合入的分支dev/add_arm64_file 。
最后确认commits和changed files是否准确,如果没有问题就可以点击Create pull request 。
PR创建后,代码库管理员会评审你提交的代码,并决定是否接受该PR。
',12),f={id:"更多信息请参阅github-pullrequest官方文档",tabindex:"-1"},k=e("a",{class:"header-anchor",href:"#更多信息请参阅github-pullrequest官方文档","aria-hidden":"true"},"#",-1),q={href:"https://docs.github.com/cn/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests/",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"tca团队诚邀您的加入",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#tca团队诚邀您的加入","aria-hidden":"true"},"#"),a(" TCA团队诚邀您的加入")],-1);function x(y,P){const r=c("ExternalLinkIcon");return p(),u("div",null,[b,e("p",null,[a("点击Fork后,会在自己名下产生一个相同代码库,比如我Fork CodeAnalysis项目后,会在我名下多出一个CodeAnalysis代码库,地址为"),e("a",m,[a("https://github.com/Lingghh/CodeAnalysis"),s(r)])]),g,e("h2",f,[k,a(" 更多信息请参阅"),e("a",q,[a("GitHub PullRequest官方文档"),s(r)])]),v])}const C=d(_,[["render",x],["__file","pr.html.vue"]]);export{C as default}; diff --git a/assets/pr.html-d341e50b.js b/assets/pr.html-d341e50b.js new file mode 100644 index 000000000..19586c595 --- /dev/null +++ b/assets/pr.html-d341e50b.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-78c226f8","path":"/en/community/pr.html","title":"PR操作流程","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"一、Fork目标代码库","slug":"一、fork目标代码库","link":"#一、fork目标代码库","children":[]},{"level":2,"title":"二、克隆Fork的代码库并创建分支","slug":"二、克隆fork的代码库并创建分支","link":"#二、克隆fork的代码库并创建分支","children":[]},{"level":2,"title":"三、在目标项目中提交PR","slug":"三、在目标项目中提交pr","link":"#三、在目标项目中提交pr","children":[{"level":3,"title":"1.进入到目标项目中,点击Pull requests Tab,再点击New pull request就会进入到创建PR的页面","slug":"_1-进入到目标项目中-点击pull-requests-tab-再点击new-pull-request就会进入到创建pr的页面","link":"#_1-进入到目标项目中-点击pull-requests-tab-再点击new-pull-request就会进入到创建pr的页面","children":[]},{"level":3,"title":"2.进入PR页面后","slug":"_2-进入pr页面后","link":"#_2-进入pr页面后","children":[]}]},{"level":2,"title":"更多信息请参阅GitHub PullRequest官方文档","slug":"更多信息请参阅github-pullrequest官方文档","link":"#更多信息请参阅github-pullrequest官方文档","children":[]},{"level":2,"title":"TCA团队诚邀您的加入","slug":"tca团队诚邀您的加入","link":"#tca团队诚邀您的加入","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/community/pr.md"}');export{l as data}; diff --git a/assets/pr.html-d355a211.js b/assets/pr.html-d355a211.js new file mode 100644 index 000000000..5b0c1df38 --- /dev/null +++ b/assets/pr.html-d355a211.js @@ -0,0 +1,3 @@ +import{_ as o,a as i,b as l,c as n,d as h}from"./PR-48d0e900.js";import{_ as d,r as c,o as p,c as u,a as e,b as a,d as s,e as t}from"./app-2a91d8ab.js";const _={},b=t('PR全称为Pull Request,它是一种代码库的协作方式。开发者可以通过PR将自己在代码库的修改通知到代码库负责人,由原作者评审代码并决定是否能合入。
TIP
Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.
在本地克隆Fork的代码库并创建分支
git clone https://github.com/Lingghh/CodeAnalysis
+git checkout -b dev/add_qa_20220301
+
注:也可以在自己Fork的代码库GitHub页面上创建分支。
接下来就可以在本地修改代码,修改完成后先push到Fork的代码库中.
点击compare across forks 。
点击head repository 。
选择自己Fork的代码库和比较的分支,比如我这里选择Lingghh/CodeAnalysis和待合入的分支dev/add_arm64_file 。
最后确认commits和changed files是否准确,如果没有问题就可以点击Create pull request 。
PR创建后,代码库管理员会评审你提交的代码,并决定是否接受该PR。
',12),f={id:"更多信息请参阅github-pullrequest官方文档",tabindex:"-1"},k=e("a",{class:"header-anchor",href:"#更多信息请参阅github-pullrequest官方文档","aria-hidden":"true"},"#",-1),q={href:"https://docs.github.com/cn/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests/",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"tca团队诚邀您的加入",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#tca团队诚邀您的加入","aria-hidden":"true"},"#"),a(" TCA团队诚邀您的加入")],-1);function x(P,y){const r=c("ExternalLinkIcon");return p(),u("div",null,[b,e("p",null,[a("点击Fork后,会在自己名下产生一个相同代码库,比如我Fork CodeAnalysis项目后,会在我名下多出一个CodeAnalysis代码库,地址为"),e("a",m,[a("https://github.com/Lingghh/CodeAnalysis"),s(r)])]),g,e("h2",f,[k,a(" 更多信息请参阅"),e("a",q,[a("GitHub PullRequest官方文档"),s(r)])]),v])}const C=d(_,[["render",x],["__file","pr.html.vue"]]);export{C as default}; diff --git a/assets/registerCodeRepo-637a4b5b.png b/assets/registerCodeRepo-637a4b5b.png new file mode 100644 index 000000000..647cdb287 Binary files /dev/null and b/assets/registerCodeRepo-637a4b5b.png differ diff --git a/assets/runProject.html-083184d0.js b/assets/runProject.html-083184d0.js new file mode 100644 index 000000000..e8669832b --- /dev/null +++ b/assets/runProject.html-083184d0.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1b6d66dd","path":"/en/quickStarted/runProject.html","title":"启动代码分析","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"执行代码分析","slug":"执行代码分析","link":"#执行代码分析","children":[]},{"level":2,"title":"查看分析历史","slug":"查看分析历史","link":"#查看分析历史","children":[]},{"level":2,"title":"查看分析概览","slug":"查看分析概览","link":"#查看分析概览","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/quickStarted/runProject.md"}');export{e as data}; diff --git a/assets/runProject.html-2ddb4214.js b/assets/runProject.html-2ddb4214.js new file mode 100644 index 000000000..df93b89f3 --- /dev/null +++ b/assets/runProject.html-2ddb4214.js @@ -0,0 +1 @@ +import{_ as c,a as d,b as s}from"./start_scan_04-65ab4d48.js";import{_ as l,r as i,o as h,c as _,a as e,b as t,d as o,w as r,e as n}from"./app-2a91d8ab.js";const u={},E=n('在完成 Server、Web 和 Client 相关部署和配置后,可通过平台执行代码分析。
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
注:
',6),p=e("li",null,[t("TCA推荐使用"),e("code",null,"在线分析"),t(",您可根据具体使用场景选择其一。")],-1),A=e("li",null,[e("code",null,"在线分析"),t("表示配置代码库链接后,TCA客户端拉取代码后进行分析;"),e("code",null,"客户端分析"),t("在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。")],-1),m=e("code",null,"在线分析",-1),f=e("code",null,"客户端分析",-1),B=n('分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
在完成 Server、Web 和 Client 相关部署和配置后,可通过平台执行代码分析。
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
注:
',6),p=e("li",null,[t("TCA推荐使用"),e("code",null,"在线分析"),t(",您可根据具体使用场景选择其一。")],-1),A=e("li",null,[e("code",null,"在线分析"),t("表示配置代码库链接后,TCA客户端拉取代码后进行分析;"),e("code",null,"客户端分析"),t("在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。")],-1),m=e("code",null,"在线分析",-1),f=e("code",null,"客户端分析",-1),B=r('分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
TCA Server由Main、Analysis、Login、File、ScmProxy五个微服务组成,主要技术栈为Django+uwsgi+nginx
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Main服务DB配置:
Main服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Analysis服务DB配置:
Analysis服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Login服务DB配置:
服务交互配置:
注:配置文件中的pub_key与private_key生成方式可以参考以下方法:
$ ssh-keygen -t rsa -b 1024 -m PEM -f tca_login.key
+$ openssl rsa -in tca_login.key -pubout -outform PEM -out tca_login.key.pub
+$ cat tca_login.key # 作为private_key的内容
+$ cat tca_login.key.pub # 作为pub_key的内容
+
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取File服务DB配置:
服务交互配置:
File存储引擎配置
LOCAL
/MINIO
/COS
LOCAL
,可以指定FILE_STORAGE_DIR
文件存放的路径MINIO
,可以指定以下变量: COS
,可以指定以下变量 服务配置:
0.0.0.0
8009
127.0.0.1:8009
TCA Server由Main、Analysis、Login、File、ScmProxy五个微服务组成,主要技术栈为Django+uwsgi+nginx
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Main服务DB配置:
Main服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Analysis服务DB配置:
Analysis服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Login服务DB配置:
服务交互配置:
注:配置文件中的pub_key与private_key生成方式可以参考以下方法:
$ ssh-keygen -t rsa -b 1024 -m PEM -f tca_login.key
+$ openssl rsa -in tca_login.key -pubout -outform PEM -out tca_login.key.pub
+$ cat tca_login.key # 作为private_key的内容
+$ cat tca_login.key.pub # 作为pub_key的内容
+
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取File服务DB配置:
服务交互配置:
File存储引擎配置
LOCAL
/MINIO
/COS
LOCAL
,可以指定FILE_STORAGE_DIR
文件存放的路径MINIO
,可以指定以下变量: COS
,可以指定以下变量 服务配置:
0.0.0.0
8009
127.0.0.1:8009
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。也是提升现网质量的最广泛最简单有效的方式。
但是在实际开发工作中,由于工作繁忙而遗漏或缺乏对单元测试的正确认识,有些开发盲目追求高覆盖率,没有对单元测试做断言,这样的单元测试用例属于无效用例。 为了检测此类无效用例,业务侧找来了代码分析介入,进行单元测试有效性验证。
// Bad case
+func Test_Demo1(t *testing.T) {
+}
+
+
+// Good case
+func Test_Demo2(t *testing.T) {
+ assert.NoError(t, err)
+}
+
TCA 现已支持 Go 语言的单元测试有效行验证,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 单元测试有效性验证 -> 启用/查看规则
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。也是提升现网质量的最广泛最简单有效的方式。
但是在实际开发工作中,由于工作繁忙而遗漏或缺乏对单元测试的正确认识,有些开发盲目追求高覆盖率,没有对单元测试做断言,这样的单元测试用例属于无效用例。 为了检测此类无效用例,业务侧找来了代码分析介入,进行单元测试有效性验证。
// Bad case
+func Test_Demo1(t *testing.T) {
+}
+
+
+// Good case
+func Test_Demo2(t *testing.T) {
+ assert.NoError(t, err)
+}
+
TCA 现已支持 Go 语言的单元测试有效行验证,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 单元测试有效性验证 -> 启用/查看规则
由 framework
、login
、tca-layout
、tca-analysis
、tca-manage
微前端以及tca-document
前端帮助文档组成。
shared
: 公共模块
framework
: 微前端基座
login
: 登录微前端
tca-layout
: 腾讯云代码分析layout微前端
tca-analysis
: 腾讯云代码分析analysis微前端
tca-manage
: 腾讯云代码分析后台管理微前端
tca-document
: 腾讯云代码分析帮助文档
已将当前版本各个微前端构建打包到此目录,可通过阅读该目录下的 README 直接进行前端部署。
按上一节完成一套 TCA Web 部署
根据要调整的内容,启动对应的微前端(login、tca-layout、tca-analysis),具体可进入不同 package
参考阅读其目录下的 README
进行开发。
其他:
根目录下启动单个项目
# framework
+yarn dev --scope framework
+# login
+PUBLIC_PATH=http://127.0.0.1:5055/ yarn dev --scope login
+# tca-layout
+PUBLIC_PATH=http://127.0.0.1:5056/ yarn dev --scope tca-layout
+# tca-analysis
+PUBLIC_PATH=http://127.0.0.1:5057/ yarn dev --scope tca-analysis
+# tca-manage
+PUBLIC_PATH=http://127.0.0.1:5058/ yarn dev --scope tca-manage
+# tca-document
+yarn dev --scope tca-document
+# 或进入对应项目内,查阅对应README
+
如对项目进行变更,本地开发结束后,需要部署最新资源可通过执行 sh build-source.sh
将构建后资源更新到tca-deploy-source 目录内,再参考该目录下的 README 直接进行前端更新/重新部署操作。
可通过阅读 build-source.sh
内容,以及 tca-deploy-source 目录下的 README,用户可根据需要自行进行前端部署。
由 framework
、login
、tca-layout
、tca-analysis
、tca-manage
微前端以及tca-document
前端帮助文档组成。
shared
: 公共模块
framework
: 微前端基座
login
: 登录微前端
tca-layout
: 腾讯云代码分析layout微前端
tca-analysis
: 腾讯云代码分析analysis微前端
tca-manage
: 腾讯云代码分析后台管理微前端
tca-document
: 腾讯云代码分析帮助文档
已将当前版本各个微前端构建打包到此目录,可通过阅读该目录下的 README 直接进行前端部署。
按上一节完成一套 TCA Web 部署
根据要调整的内容,启动对应的微前端(login、tca-layout、tca-analysis),具体可进入不同 package
参考阅读其目录下的 README
进行开发。
其他:
根目录下启动单个项目
# framework
+yarn dev --scope framework
+# login
+PUBLIC_PATH=http://127.0.0.1:5055/ yarn dev --scope login
+# tca-layout
+PUBLIC_PATH=http://127.0.0.1:5056/ yarn dev --scope tca-layout
+# tca-analysis
+PUBLIC_PATH=http://127.0.0.1:5057/ yarn dev --scope tca-analysis
+# tca-manage
+PUBLIC_PATH=http://127.0.0.1:5058/ yarn dev --scope tca-manage
+# tca-document
+yarn dev --scope tca-document
+# 或进入对应项目内,查阅对应README
+
如对项目进行变更,本地开发结束后,需要部署最新资源可通过执行 sh build-source.sh
将构建后资源更新到tca-deploy-source 目录内,再参考该目录下的 README 直接进行前端更新/重新部署操作。
可通过阅读 build-source.sh
内容,以及 tca-deploy-source 目录下的 README,用户可根据需要自行进行前端部署。
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
scan_open | int | 选填,发现问题的扫描编号 |
scan_close | int | 选填,修复问题的扫描编号 |
worse | boolean | 选填,圈复杂度是否恶化 |
over_cc_sum_gte | int | 选填, 圈复杂度总和最小值 |
over_cc_sum_lte | int | 选填,圈复杂度总和最大值 |
over_cc_avg_gte | int | 选填,平均圈复杂度最小值 |
over_cc_avg_lte | int | 选填,平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 选填,超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 选填,超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_close_id | int | 选填,修复问题的扫描编号 |
worse | boolean | 选填,圈复杂度是否恶化 |
over_cc_sum_gte | int | 选填,圈复杂度总和最小值 |
over_cc_sum_lte | int | 选填,圈复杂度总和最大值 |
over_cc_avg_gte | int | 选填,平均圈复杂度最小值 |
over_cc_avg_lte | int | 选填,平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 选填,超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 选填,超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 32,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "tapd_url": null,
+ "created_time": "2020-06-02T10:59:09.418250+08:00",
+ "creator": null,
+ "modified_time": "2020-06-03T16:17:40.892224+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "over_func_cc": 0,
+ "over_cc_sum": 0,
+ "over_cc_avg": 0,
+ "over_cc_func_count": 0,
+ "diff_over_func_cc": 0,
+ "diff_over_cc_sum": 0,
+ "diff_over_cc_avg": 0,
+ "diff_over_cc_func_count": 0,
+ "worse": false,
+ "file_path": "test/demo.py",
+ "state": 3,
+ "change_type": 0,
+ "last_modifier": "author1",
+ "author": null,
+ "related_modifiers": "author1;author2",
+ "file_owners": null,
+ "language": "python",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "revision": null,
+ "ci_time": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": 2
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/
+
参数 | 类型 | 描述 |
---|---|---|
issue__state | str | 选填,问题状态, 1为未处理,2为可忽略,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,重复文件更改类型,add为新增,del为删除,mod为删除,可多选,格式为add,del,mod |
issue__owner | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
duplicate_rate_gte | int | 选填,重复率最小值 |
duplicate_rate_lte | int | 选填,重复率最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "project_id": 1,
+ "scan_id": 1,
+ "issue_id": 1,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "12345678abc",
+ "is_latest": true
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/
+
{
+ "data": {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "blocks": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ],
+ "duplicate_rate_trend": 0.0,
+ "project_id": 1815,
+ "scan_id": 488,
+ "issue_id": 3,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "xxx",
+ "is_latest": true
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/blocks/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/clocfiles/
+
参数 | 类型 | 描述 |
---|---|---|
change_type | str | 选填,改变类型(add、mod、del),支持多值,使用英文逗号','分隔 |
file_path | str | 选填,文件路径 |
{
+ "data": {
+ "count": 1,
+ "next": "",
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 108587,
+ "comment_line_num": 0,
+ "blank_line_num": 0,
+ "total_line_num": 108587,
+ "add_code_line_num": 108587,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 0,
+ "add_total_line_num": 108587,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1,
+ "scan_id": 1,
+ "is_latest": true,
+ "dir_path": "test",
+ "file_name": "test.json",
+ "language": "JSON",
+ "change_type": "add"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/cloclangs/
+
{
+ "data": {
+ "count": 2,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 9753,
+ "comment_line_num": 4220,
+ "blank_line_num": 2454,
+ "total_line_num": 16427,
+ "add_code_line_num": 9753,
+ "add_comment_line_num": 4220,
+ "add_blank_line_num": 2454,
+ "add_total_line_num": 16427,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Python",
+ "file_num": 165
+ },
+ {
+ "id": 2,
+ "code_line_num": 379,
+ "comment_line_num": 0,
+ "blank_line_num": 153,
+ "total_line_num": 532,
+ "add_code_line_num": 379,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 153,
+ "add_total_line_num": 532,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Markdown",
+ "file_num": 7
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
scan_open | int | 发现问题的扫描编号 |
scan_close | int | 修复问题的扫描编号 |
worse | boolean | 圈复杂度是否恶化 |
over_cc_sum_gte | int | 圈复杂度总和最小值 |
over_cc_sum_lte | int | 圈复杂度总和最大值 |
over_cc_avg_gte | int | 平均圈复杂度最小值 |
over_cc_avg_lte | int | 平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
scan_open_id | int | 发现问题的扫描编号 |
scan_close_id | int | 修复问题的扫描编号 |
worse | boolean | 圈复杂度是否恶化 |
over_cc_sum_gte | int | 圈复杂度总和最小值 |
over_cc_sum_lte | int | 圈复杂度总和最大值 |
over_cc_avg_gte | int | 平均圈复杂度最小值 |
over_cc_avg_lte | int | 平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 32,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "tapd_url": null,
+ "created_time": "2020-06-02T10:59:09.418250+08:00",
+ "creator": null,
+ "modified_time": "2020-06-03T16:17:40.892224+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "over_func_cc": 0,
+ "over_cc_sum": 0,
+ "over_cc_avg": 0,
+ "over_cc_func_count": 0,
+ "diff_over_func_cc": 0,
+ "diff_over_cc_sum": 0,
+ "diff_over_cc_avg": 0,
+ "diff_over_cc_func_count": 0,
+ "worse": false,
+ "file_path": "test/demo.py",
+ "state": 3,
+ "change_type": 0,
+ "last_modifier": "author1",
+ "author": null,
+ "related_modifiers": "author1;author2",
+ "file_owners": null,
+ "language": "python",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "revision": null,
+ "ci_time": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": 2
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/
+
参数 | 类型 | 描述 |
---|---|---|
issue__state | str | 问题状态, 1为未处理,2为可忽略,3为关闭,可多选,格式为1,2,3 |
change_type | str | 重复文件更改类型,add为新增,del为删除,mod为删除,可多选,格式为add,del,mod |
issue__owner | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
duplicate_rate_gte | int | 重复率最小值 |
duplicate_rate_lte | int | 重复率最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "project_id": 1,
+ "scan_id": 1,
+ "issue_id": 1,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "12345678abc",
+ "is_latest": true
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/
+
{
+ "data": {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "blocks": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ],
+ "duplicate_rate_trend": 0.0,
+ "project_id": 1815,
+ "scan_id": 488,
+ "issue_id": 3,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "xxx",
+ "is_latest": true
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/blocks/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/clocfiles/
+
参数 | 类型 | 描述 |
---|---|---|
change_type | str | 改变类型(add、mod、del),支持多值,使用英文逗号','分隔 |
file_path | str | 文件路径 |
{
+ "data": {
+ "count": 1,
+ "next": "",
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 108587,
+ "comment_line_num": 0,
+ "blank_line_num": 0,
+ "total_line_num": 108587,
+ "add_code_line_num": 108587,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 0,
+ "add_total_line_num": 108587,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1,
+ "scan_id": 1,
+ "is_latest": true,
+ "dir_path": "test",
+ "file_name": "test.json",
+ "language": "JSON",
+ "change_type": "add"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/cloclangs/
+
{
+ "data": {
+ "count": 2,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 9753,
+ "comment_line_num": 4220,
+ "blank_line_num": 2454,
+ "total_line_num": 16427,
+ "add_code_line_num": 9753,
+ "add_comment_line_num": 4220,
+ "add_blank_line_num": 2454,
+ "add_total_line_num": 16427,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Python",
+ "file_num": 165
+ },
+ {
+ "id": 2,
+ "code_line_num": 379,
+ "comment_line_num": 0,
+ "blank_line_num": 153,
+ "total_line_num": 532,
+ "add_code_line_num": 379,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 153,
+ "add_total_line_num": 532,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Markdown",
+ "file_num": 7
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
可以发现执行路径较多的方法,降低代码的圈复杂度,可测性更高
检测阈值
默认为 20,表示当一个方法的圈复杂度超过 20 时则认为该方法为超标方法,需要被关注修改。
可以根据需要调整
可以发现重复的代码,避免重复代码可以让代码更简洁,更易维护
长度区间
是一个区间值,默认代码中一个单词(变量/操作符)长度为 1。
重复次数
是一个区间值,当一段代码重复次数达到指定区间才认为是有风险的。
上报限制
限制上报的重复代码块数,可以减少开发的压力,提高修复积极性。
从目录和业务纬度统计代码行数,也可以获取提交记录便于代码 Review
',9),s=[n];function h(o,p){return a(),r("div",null,s)}const c=e(i,[["render",h],["__file","代码度量配置.html.vue"]]);export{c as default}; diff --git "a/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-6e7a8634.js" "b/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-6e7a8634.js" new file mode 100644 index 000000000..bd7a7e522 --- /dev/null +++ "b/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-6e7a8634.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4b5d7d25","path":"/en/guide/%E5%88%86%E6%9E%90%E6%96%B9%E6%A1%88/%E4%BB%A3%E7%A0%81%E5%BA%A6%E9%87%8F%E9%85%8D%E7%BD%AE.html","title":"代码度量配置","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"圈复杂度","slug":"圈复杂度","link":"#圈复杂度","children":[]},{"level":2,"title":"重复代码","slug":"重复代码","link":"#重复代码","children":[]},{"level":2,"title":"代码统计","slug":"代码统计","link":"#代码统计","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/分析方案/代码度量配置.md"}');export{e as data}; diff --git "a/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-a0b512c6.js" "b/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-a0b512c6.js" new file mode 100644 index 000000000..3726c2e34 --- /dev/null +++ "b/assets/\344\273\243\347\240\201\345\272\246\351\207\217\351\205\215\347\275\256.html-a0b512c6.js" @@ -0,0 +1 @@ +import{_ as e,o as a,c as r,e as t}from"./app-2a91d8ab.js";const i={},n=t('可以发现执行路径较多的方法,降低代码的圈复杂度,可测性更高
检测阈值
默认为 20,表示当一个方法的圈复杂度超过 20 时则认为该方法为超标方法,需要被关注修改。
可以根据需要调整
可以发现重复的代码,避免重复代码可以让代码更简洁,更易维护
长度区间
是一个区间值,默认代码中一个单词(变量/操作符)长度为 1。
重复次数
是一个区间值,当一段代码重复次数达到指定区间才认为是有风险的。
上报限制
限制上报的重复代码块数,可以减少开发的压力,提高修复积极性。
从目录和业务纬度统计代码行数,也可以获取提交记录便于代码 Review
',9),s=[n];function h(o,p){return a(),r("div",null,s)}const c=e(i,[["render",h],["__file","代码度量配置.html.vue"]]);export{c as default}; diff --git "a/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-4ed0e1d6.js" "b/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-4ed0e1d6.js" new file mode 100644 index 000000000..3a1f73ce1 --- /dev/null +++ "b/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-4ed0e1d6.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-d1cb31be","path":"/en/api/%E4%BB%A3%E7%A0%81%E6%89%AB%E6%8F%8F%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9D%97%E6%8E%A5%E5%8F%A3.html","title":"代码扫描数据管理","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"查看扫描问题列表","slug":"查看扫描问题列表","link":"#查看扫描问题列表","children":[]},{"level":2,"title":"查看问题详情","slug":"查看问题详情","link":"#查看问题详情","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/api/代码扫描数据模块接口.md"}');export{e as data}; diff --git "a/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-9e291d69.js" "b/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-9e291d69.js" new file mode 100644 index 000000000..d57be7118 --- /dev/null +++ "b/assets/\344\273\243\347\240\201\346\211\253\346\217\217\346\225\260\346\215\256\346\250\241\345\235\227\346\216\245\345\217\243.html-9e291d69.js" @@ -0,0 +1,197 @@ +import{_ as t,o as e,c as i,e as u}from"./app-2a91d8ab.js";const n={},d=u(`GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open | int | 选填,发现问题的扫描编号 |
scan_fix | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间,格式为"2021-01-01 00:00:00" |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "file_path": "test/demo.py",
+ "project": 1,
+ "repo": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checktool_name": "xxx",
+ "msg": "xxx",
+ "state": 3,
+ "resolution": 1,
+ "author": "author",
+ "author_email": null,
+ "severity": 2,
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "is_external": false,
+ "scm_url": "",
+ "real_file_path": "",
+ "scan_open": 1,
+ "scan_fix": 2,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/
+
{
+ "data": {
+ "id": 1,
+ "issue_details": [
+ {
+ "id": 1,
+ "issue_refers": [],
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "issuedetail_uuid": "0fcc376e-7283-11eb-bd53-5254005e71ca",
+ "checkrule_real_name": "xxx",
+ "checktool_name": "xxx",
+ "author": "author",
+ "author_email": null,
+ "line": 1809,
+ "column": 15,
+ "scan_revision": "scan_revision",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "real_revision": "",
+ "created_time": "2021-02-19T15:21:19.625658+08:00",
+ "modified_time": "2021-02-19T15:21:19.625662+08:00",
+ "issue": null,
+ "project": 1
+ }
+ ],
+ "is_external": false,
+ "repo": 1,
+ "author": "author",
+ "created_time": "2021-02-19T15:21:19.625685+08:00",
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "file_path": "test/demo.py",
+ "file_hash": "xxx",
+ "scm_url": "",
+ "real_file_path": "",
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "state": 3,
+ "resolution": 1,
+ "scan_revision": null,
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "modified_time": "2021-02-19T15:25:17.807478+08:00",
+ "project": 1,
+ "scan_open": 1,
+ "scan_fix": 2
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/scans/<scan_id>/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_fix_id | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间 |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo_id": 1,
+ "project_id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "file_path": "test/demo.py",
+ "scm_url": "",
+ "real_file_path": "",
+ "line": 21,
+ "column": 68,
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "msg": "xxx",
+ "state": 1,
+ "resolution": null,
+ "author": "author",
+ "scan_open_id": 1,
+ "scan_fix_id": null,
+ "issuedetail_uuid": "26d7ba88-8268-11eb-a304-5254005e71ca",
+ "scan_revision": "scan_revision",
+ "real_revision": "",
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2019-07-01T10:28:19+08:00",
+ "file_owners": null,
+ "created_time": "2021-03-11T20:49:00.539537+08:00",
+ "fixed_time": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/crscans/<scan_id>/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_fix_id | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间 |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo_id": 1,
+ "project_id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "file_path": "test/demo.py",
+ "scm_url": "",
+ "real_file_path": "",
+ "line": 21,
+ "column": 68,
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "msg": "xxx",
+ "state": 1,
+ "resolution": null,
+ "author": "author",
+ "scan_open_id": 1,
+ "scan_fix_id": null,
+ "issuedetail_uuid": "26d7ba88-8268-11eb-a304-5254005e71ca",
+ "scan_revision": "scan_revision",
+ "real_revision": "",
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2019-07-01T10:28:19+08:00",
+ "file_owners": null,
+ "created_time": "2021-03-11T20:49:00.539537+08:00",
+ "fixed_time": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 问题责任人 |
scan_open | int | 发现问题的扫描编号 |
scan_fix | int | 修复问题的扫描编号 |
ci_time_gte | str | 修复问题的起始时间,格式为"2021-01-01 00:00:00" |
ci_time_lte | str | 修复问题的结束时间 |
file_path | str | 文件路径 |
checkrule_display_name | str | 检查规则名 |
checkpackage | int | 问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "file_path": "test/demo.py",
+ "project": 1,
+ "repo": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checktool_name": "xxx",
+ "msg": "xxx",
+ "state": 3,
+ "resolution": 1,
+ "author": "author",
+ "author_email": null,
+ "severity": 2,
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "is_external": false,
+ "scm_url": "",
+ "real_file_path": "",
+ "scan_open": 1,
+ "scan_fix": 2,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/
+
{
+ "data": {
+ "id": 1,
+ "issue_details": [
+ {
+ "id": 1,
+ "issue_refers": [],
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "issuedetail_uuid": "0fcc376e-7283-11eb-bd53-5254005e71ca",
+ "checkrule_real_name": "xxx",
+ "checktool_name": "xxx",
+ "author": "author",
+ "author_email": null,
+ "line": 1809,
+ "column": 15,
+ "scan_revision": "scan_revision",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "real_revision": "",
+ "created_time": "2021-02-19T15:21:19.625658+08:00",
+ "modified_time": "2021-02-19T15:21:19.625662+08:00",
+ "issue": null,
+ "project": 1
+ }
+ ],
+ "is_external": false,
+ "repo": 1,
+ "author": "author",
+ "created_time": "2021-02-19T15:21:19.625685+08:00",
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "file_path": "test/demo.py",
+ "file_hash": "xxx",
+ "scm_url": "",
+ "real_file_path": "",
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "state": 3,
+ "resolution": 1,
+ "scan_revision": null,
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "modified_time": "2021-02-19T15:25:17.807478+08:00",
+ "project": 1,
+ "scan_open": 1,
+ "scan_fix": 2
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
腾讯云代码分析平台支持给编译类的工具或编译型项目配置相关命令。
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描,申购完成后可联系平台管理员进行相关配置。
TIP
对于编译型语言,有些分析工具是可以通过分析编译产出的中间文件,更为准确地发现代码质量问题。
WARNING
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描(私有化版由客户自行评估即可)。
如果配置了编译命令,则需要在具有代码执行所需的编译环境的节点上执行代码分析。即需要用户在专机上提供编译环境(针对私有化版,客户可根据业务情况选择在公共节点机、用户专机、本地节点机提供编译环境即可)。
如以下一些编译环境:
JDK 环境及版本
gradle 环境
cmake & make 环境
visual studio 环境
...
WARNING
如果机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本,可以在分析方案的基础属性当中设定相应环境变量。
前置命令:
通常是项目编译前需要执行的命令,或用于清理之前编译过程的命令,如:make clean
, xcodebuild clean [-optionName]
。如无需要,可以不填。
编译命令:
项目的编译命令,具体可以咨询该代码库所属项目的开发
能够使项目编译成功的编译命令,可以填写多行或用 && 连接命令。
TIP
前置命令与编译命令是隔离的,即在前置命令中的操作不会对编译命令产生影响。
如在前置命令中 cd src && export TEST=src
,在执行编译命令时并不会跳到src
目录和获取TEST
环境变量。
TIP
咨询该代码库所属项目的开发,先确保先在本地工程根目录调试通过
编译命令:
android-studio 项目编译命令示例
gradle compileDebugSources --no-daemon -Dorg.gradle.jvmargs=
+
ant 项目编译命令示例
ant build
+
编译命令:
xcodebuild 命令(确保先在本地工程根目录调试通过)
xcodebuild -target dailybuildipa -configuration DailyBuild -sdk iphonesimulator
+
环境变量(分析方案-基础属性中配置):
XCODE_VERISON=10.1
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=DebugCopy
+
make 项目编译命令示例
make all
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=Debug
+
腾讯云代码分析平台支持给编译类的工具或编译型项目配置相关命令。
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描,申购完成后可联系平台管理员进行相关配置。
提示
对于编译型语言,有些分析工具是可以通过分析编译产出的中间文件,更为准确地发现代码质量问题。
注意
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描(私有化版由客户自行评估即可)。
如果配置了编译命令,则需要在具有代码执行所需的编译环境的节点上执行代码分析。即需要用户在专机上提供编译环境(针对私有化版,客户可根据业务情况选择在公共节点机、用户专机、本地节点机提供编译环境即可)。
如以下一些编译环境:
JDK 环境及版本
gradle 环境
cmake & make 环境
visual studio 环境
...
注意
如果机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本,可以在分析方案的基础属性当中设定相应环境变量。
前置命令:
通常是项目编译前需要执行的命令,或用于清理之前编译过程的命令,如:make clean
, xcodebuild clean [-optionName]
。如无需要,可以不填。
编译命令:
项目的编译命令,具体可以咨询该代码库所属项目的开发
能够使项目编译成功的编译命令,可以填写多行或用 && 连接命令。
提示
前置命令与编译命令是隔离的,即在前置命令中的操作不会对编译命令产生影响。
如在前置命令中 cd src && export TEST=src
,在执行编译命令时并不会跳到src
目录和获取TEST
环境变量。
提示
咨询该代码库所属项目的开发,先确保先在本地工程根目录调试通过
编译命令:
android-studio 项目编译命令示例
gradle compileDebugSources --no-daemon -Dorg.gradle.jvmargs=
+
ant 项目编译命令示例
ant build
+
编译命令:
xcodebuild 命令(确保先在本地工程根目录调试通过)
xcodebuild -target dailybuildipa -configuration DailyBuild -sdk iphonesimulator
+
环境变量(分析方案-基础属性中配置):
XCODE_VERISON=10.1
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=DebugCopy
+
make 项目编译命令示例
make all
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=Debug
+
在上一节文档代码检查配置中我们大致已经了解规则配置主要由官方规则包和自定义规则包构成,本节将详细描述规则配置。
官方规则包是由腾讯云代码分析平台经过多年深耕,在业务中不断实践整理而出的规则集合包,然而平台有超过**10000+**的规则,有些规则并未放到官方规则包中,甚至有些规则是由用户自定义的规则。此外,有些官方规则包中的规则,对于不同的团队所需可能存在差异,因此产生了如下几种问题:
在规则配置中,如何添加规则?
在规则配置中,如果将官方规则包中的规则进行调整?
添加规则存在两种入口:
TIP
无论何种,最终都是将规则添加到自定义规则包中
用户可直接点击页面中的添加规则
用户可点击自定义规则,进入自定义规则包后,再点击添加规则
在添加规则过程中,可以单选或者批量多选规则,可以根据搜索栏进行多维度查询规则
用户可以点击进入官方规则包,进入官方规则包中,对已存在的规则进行编辑。
WARNING
在官方规则包中对规则的任意操作,实质上是将对应规则增加到自定义规则包中进行了相关操作。
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置。
在上一节文档代码检查配置中我们大致已经了解规则配置主要由官方规则包和自定义规则包构成,本节将详细描述规则配置。
官方规则包是由腾讯云代码分析平台经过多年深耕,在业务中不断实践整理而出的规则集合包,然而平台有超过**10000+**的规则,有些规则并未放到官方规则包中,甚至有些规则是由用户自定义的规则。此外,有些官方规则包中的规则,对于不同的团队所需可能存在差异,因此产生了如下几种问题:
在规则配置中,如何添加规则?
在规则配置中,如果将官方规则包中的规则进行调整?
添加规则存在两种入口:
提示
无论何种,最终都是将规则添加到自定义规则包中
用户可直接点击页面中的添加规则
用户可点击自定义规则,进入自定义规则包后,再点击添加规则
在添加规则过程中,可以单选或者批量多选规则,可以根据搜索栏进行多维度查询规则
用户可以点击进入官方规则包,进入官方规则包中,对已存在的规则进行编辑。
注意
在官方规则包中对规则的任意操作,实质上是将对应规则增加到自定义规则包中进行了相关操作。
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置。
腾讯云代码分析采用业界/自研的 80+ 款工具,配置代码检查项能够有效地发现代码中存在的异味代码
规则配置主要是以规则包为元素,由官方规则包和自定义规则包两部分组成。平台提供一些系列的官方规则包,覆盖规范、安全、推荐等方面。
用户可根据项目语言、规则包类型筛选不同的规则包,并启用/关闭规则包。
提示
用户可以根据需要选择官方规则包进行扫描,并可以在官方规则包的基础上屏蔽某些规则或者调整默认的优先级,设置指定参数。这些操作都会记录在自定义规则包中。
自定义规则包是提供给用户自由选择工具规则的包。官方规则包上的调整实质上会记录到自定义规则包中,当自定义规则包中的规则和官方规则包的规则发生冲突,则自定义规则包优先级更高。
通过编译(代码解析和翻译过程)分析中间代码进行辅助分析,能更精准地发现更多潜在的代码问题。
',9),o=[n];function i(_,d){return t(),r("div",null,o)}const l=a(c,[["render",i],["__file","代码检查配置.html.vue"]]);export{l as default}; diff --git "a/assets/\344\273\243\347\240\201\346\243\200\346\237\245\351\205\215\347\275\256.html-daa38911.js" "b/assets/\344\273\243\347\240\201\346\243\200\346\237\245\351\205\215\347\275\256.html-daa38911.js" new file mode 100644 index 000000000..b5bc480ef --- /dev/null +++ "b/assets/\344\273\243\347\240\201\346\243\200\346\237\245\351\205\215\347\275\256.html-daa38911.js" @@ -0,0 +1 @@ +import{_ as e}from"./scheme_codelint_01-9eec47a6.js";import{_ as a,o as t,c as r,e as s}from"./app-2a91d8ab.js";const c={},n=s('腾讯云代码分析采用业界/自研的 80+ 款工具,配置代码检查项能够有效地发现代码中存在的异味代码
规则配置主要是以规则包为元素,由官方规则包和自定义规则包两部分组成。平台提供一些系列的官方规则包,覆盖规范、安全、推荐等方面。
用户可根据项目语言、规则包类型筛选不同的规则包,并启用/关闭规则包。
TIP
用户可以根据需要选择官方规则包进行扫描,并可以在官方规则包的基础上屏蔽某些规则或者调整默认的优先级,设置指定参数。这些操作都会记录在自定义规则包中。
自定义规则包是提供给用户自由选择工具规则的包。官方规则包上的调整实质上会记录到自定义规则包中,当自定义规则包中的规则和官方规则包的规则发生冲突,则自定义规则包优先级更高。
通过编译(代码解析和翻译过程)分析中间代码进行辅助分析,能更精准地发现更多潜在的代码问题。
',9),o=[n];function i(_,d){return t(),r("div",null,o)}const l=a(c,[["render",i],["__file","代码检查配置.html.vue"]]);export{l as default}; diff --git "a/assets/\344\273\273\345\212\241\345\210\206\345\270\203\345\274\217\346\211\247\350\241\214.html-6ed77c45.js" "b/assets/\344\273\273\345\212\241\345\210\206\345\270\203\345\274\217\346\211\247\350\241\214.html-6ed77c45.js" new file mode 100644 index 000000000..10d6c9311 --- /dev/null +++ "b/assets/\344\273\273\345\212\241\345\210\206\345\270\203\345\274\217\346\211\247\350\241\214.html-6ed77c45.js" @@ -0,0 +1 @@ +import{_ as t,r as i,o as l,c as r,a as n,b as e,d as o,w as c,e as s}from"./app-2a91d8ab.js";const d={},p=s('以往的单机器单进程,性能比较低,工具排队等待时间过长。希望通过并行执行分析来提高分析效率。
希望尽量使用公共资源或使用专机资源。
为了满足以上需求,TCA已经进行如下支持:
支持工具在多台机器上并行执行。
支持指定工具在指定的机器上运行。
支持与本地启动的任务衔接,加速本地任务扫描。
配套任务状态监控能力,及时重置初始化超时或机器掉线的任务。
TIP
TCA 客户端除了通过 localscan 命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
以往的单机器单进程,性能比较低,工具排队等待时间过长。希望通过并行执行分析来提高分析效率。
希望尽量使用公共资源或使用专机资源。
为了满足以上需求,TCA已经进行如下支持:
支持工具在多台机器上并行执行。
支持指定工具在指定的机器上运行。
支持与本地启动的任务衔接,加速本地任务扫描。
配套任务状态监控能力,及时重置初始化超时或机器掉线的任务。
提示
TCA客户端除了通过localscan命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/
+
参数 | 类型 | 描述 |
---|---|---|
incr_scan | bool | 增量扫描标志,true表示增量,false表示全量 |
async_flag | bool | 异步启动标志,true表示异步,false表示同步,建议选择异步 |
force_create | bool | 强制启动标志,true表示强制启动,不等待上一个任务结束 |
{
+ "job": {
+ "id": 7974
+ },
+ "scan": {
+ "id": 5528
+ }
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/
+
参数 | 类型 | 描述 |
---|---|---|
create_time_gte | datetime | 最小任务启动时间 |
create_time_lte | datetime | 最大任务启动时间 |
result_code_gte | int | 最小错误码值 |
result_code_lte | int | 最大错误码值 |
result_msg | str | 结果信息 |
state | int | 任务状态, 0为等待中,1为执行中,2为关闭,3为入库中,可多选,格式为1,2,3 |
created_from | str | 创建来源 |
creator | str | 创建用户 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/
+
{
+ "data": {
+ "id": 1,
+ "scan_id": 1,
+ "create_time": "2021-01-28T10:27:26.442961+08:00",
+ "waiting_time": "1",
+ "start_time": "2021-01-28T11:14:56.760427+08:00",
+ "execute_time": "3",
+ "project": {
+ "id": 1,
+ "branch": "master",
+ "repo_id": 1,
+ "scan_scheme": 1,
+ "repo_scm_url": "http://github.com/xxx/test_demo.git"
+ },
+ "end_time": "2021-01-28T11:14:59.760427+08:00",
+ "expire_time": "2021-01-28T14:07:52.968932+08:00",
+ "task_num": 1,
+ "task_done": 1,
+ "tasks": [
+ {
+ "id": 1,
+ "module": "codelint",
+ "task_name": "pylint",
+ "progress_rate": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "result_path": null
+ }
+ ],
+ "co_jobs": [],
+ "state": 2,
+ "result_code": 0,
+ "result_code_msg": null,
+ "result_msg": "success",
+ "result_path": null,
+ "remarks": null,
+ "remarked_by": null,
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400,
+ "created_from": "codedog_web",
+ "creator": "creator"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/
+
参数 | 类型 | 描述 |
---|---|---|
incr_scan | bool | 选填,增量扫描标志,true表示增量,false表示全量 |
async_flag | bool | 选填,异步启动标志,true表示异步,false表示同步,建议选择异步 |
force_create | bool | 选填,强制启动标志,true表示强制启动,不等待上一个任务结束 |
{
+ "job": {
+ "id": 7974
+ },
+ "scan": {
+ "id": 5528
+ }
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/
+
参数 | 类型 | 描述 |
---|---|---|
create_time_gte | datetime | 选填,最小任务启动时间 |
create_time_lte | datetime | 选填,最大任务启动时间 |
result_code_gte | int | 选填,最小错误码值 |
result_code_lte | int | 选填,最大错误码值 |
result_msg | str | 选填,结果信息 |
state | int | 选填,任务状态, 0为等待中,1为执行中,2为关闭,3为入库中,可多选,格式为1,2,3 |
created_from | str | 选填,创建来源 |
creator | str | 选填,创建用户 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/
+
{
+ "data": {
+ "id": 1,
+ "scan_id": 1,
+ "create_time": "2021-01-28T10:27:26.442961+08:00",
+ "waiting_time": "1",
+ "start_time": "2021-01-28T11:14:56.760427+08:00",
+ "execute_time": "3",
+ "project": {
+ "id": 1,
+ "branch": "master",
+ "repo_id": 1,
+ "scan_scheme": 1,
+ "repo_scm_url": "http://github.com/xxx/test_demo.git"
+ },
+ "end_time": "2021-01-28T11:14:59.760427+08:00",
+ "expire_time": "2021-01-28T14:07:52.968932+08:00",
+ "task_num": 1,
+ "task_done": 1,
+ "tasks": [
+ {
+ "id": 1,
+ "module": "codelint",
+ "task_name": "pylint",
+ "progress_rate": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "result_path": null
+ }
+ ],
+ "co_jobs": [],
+ "state": 2,
+ "result_code": 0,
+ "result_code_msg": null,
+ "result_msg": "success",
+ "result_path": null,
+ "remarks": null,
+ "remarked_by": null,
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400,
+ "created_from": "codedog_web",
+ "creator": "creator"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
client/config.ini
中的字段指定puppy-tools-config,如下[COMMON]
+; [必填]工具配置库git地址
+; 如果github网络慢,建议修改为腾讯工蜂地址:https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
+; 这里可以修改为自己维护的puppy-tools-config
+TOOL_CONFIG_URL=
+PASSWORD_KEY=
+; [可选]日志级别,默认为info级别,设置为True则调整为debug级别
+DEBUG=
+; [可选]是否使用本地工具目录,默认为False,如果设置为True,不从git拉取(需要事先准备好工具,存放到tools目录下)
+USE_LOCAL_TOOL=
+
+[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果TOOL_CONFIG_URL使用的是腾讯工蜂,账号密码必填(如果没有,可以先去https://git.code.tencent.com注册)
+USERNAME=
+PASSWORD=
+
; ---------------------------------------------------------------------------------------------------------------------
+; 配置文件填写说明:
+; 填写过程中,如果有多个值,用英文分号分隔
+; [env_path] - 环境变量路径定义,基于tools目录的相对路径,比如:PYLINT_HOME : puppy_tools_common/pylint-1.4.5
+; [env_value] - 环境变量值定义,比如:GIT_SSL_NO_VERIFY : 1
+; [tool_url] - 工具库地址定义,格式:工具名:url,比如 CHECKSTYLE : http://xxxxxx.git
+; [common] - 公共环境配置,比如git环境变量等, 包含以下4个字段
+; env_path - 需要的环境变量路径,填写[env_path]中的KEY值,比如 env_path : ANDROID_HOME;CHECKSTYLE_HOME
+; env_value - 需要的环境变量值,填写[env_value]中的KEY值,比如 env_value : GIT_SSL_NO_VERIFY
+; path - 需要加到path环境变量中的路径,基于tools目录的相对路径,推荐使用变量格式,比如 path : \${env_path:PYLINT_HOME}/bin
+; tool_url - 需要拉取的工具库,多个地址用英文分号分隔,推荐使用变量格式,比如 tool_url : \${tool_url:PYLINT}
+; [工具名] - 各工具配置,工具名需要与tool目录下的模块名匹配,字段格式参考[common]
+; ---------------------------------------------------------------------------------------------------------------------
+[base_value]
+git_url=https://github.com/TCATools
+
+;------------------
+; 1.环境变量路径定义
+;------------------
+; 用来记录工具路径,会在工具执行时写入到环境变量中
+[env_path]
+CPPLINT_HOME : cpplint
+
+;------------------
+; 2.环境变量值定义
+;------------------
+; 记录部分环境变量并在执行时写入环境变量
+[env_value]
+PYTHON_VERSION : 3
+
+
+;------------------
+; 3.工具git库定义
+;------------------
+; 拉工具的仓库地址
+[tool_url]
+CPPLINT : \${base_value:git_url}/cpplint.git
+
+;------------------
+; 5.各个工具配置
+;------------------
+; 整合工具配置
+[cpplint]
+env_path : CPPLINT_HOME
+env_value : PYTHON_VERSION
+path : \${env_path:CPPLINT_HOME}
+tool_url : \${tool_url:CPPLINT}
+
client/config.ini
中指定[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果使用的工具仓库必须账号密码才能拉取则必须填写
+USERNAME=
+PASSWORD=
+
client/config.ini
中的字段指定puppy-tools-config,如下[COMMON]
+; [必填]工具配置库git地址
+; 如果github网络慢,建议修改为腾讯工蜂地址:https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
+; 这里可以修改为自己维护的puppy-tools-config
+TOOL_CONFIG_URL=
+PASSWORD_KEY=
+; [可选]日志级别,默认为info级别,设置为True则调整为debug级别
+DEBUG=
+; [可选]是否使用本地工具目录,默认为False,如果设置为True,不从git拉取(需要事先准备好工具,存放到tools目录下)
+USE_LOCAL_TOOL=
+
+[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果TOOL_CONFIG_URL使用的是腾讯工蜂,账号密码必填(如果没有,可以先去https://git.code.tencent.com注册)
+USERNAME=
+PASSWORD=
+
; ---------------------------------------------------------------------------------------------------------------------
+; 配置文件填写说明:
+; 填写过程中,如果有多个值,用英文分号分隔
+; [env_path] - 环境变量路径定义,基于tools目录的相对路径,比如:PYLINT_HOME : puppy_tools_common/pylint-1.4.5
+; [env_value] - 环境变量值定义,比如:GIT_SSL_NO_VERIFY : 1
+; [tool_url] - 工具库地址定义,格式:工具名:url,比如 CHECKSTYLE : http://xxxxxx.git
+; [common] - 公共环境配置,比如git环境变量等, 包含以下4个字段
+; env_path - 需要的环境变量路径,填写[env_path]中的KEY值,比如 env_path : ANDROID_HOME;CHECKSTYLE_HOME
+; env_value - 需要的环境变量值,填写[env_value]中的KEY值,比如 env_value : GIT_SSL_NO_VERIFY
+; path - 需要加到path环境变量中的路径,基于tools目录的相对路径,推荐使用变量格式,比如 path : \${env_path:PYLINT_HOME}/bin
+; tool_url - 需要拉取的工具库,多个地址用英文分号分隔,推荐使用变量格式,比如 tool_url : \${tool_url:PYLINT}
+; [工具名] - 各工具配置,工具名需要与tool目录下的模块名匹配,字段格式参考[common]
+; ---------------------------------------------------------------------------------------------------------------------
+[base_value]
+git_url=https://github.com/TCATools
+
+;------------------
+; 1.环境变量路径定义
+;------------------
+; 用来记录工具路径,会在工具执行时写入到环境变量中
+[env_path]
+CPPLINT_HOME : cpplint
+
+;------------------
+; 2.环境变量值定义
+;------------------
+; 记录部分环境变量并在执行时写入环境变量
+[env_value]
+PYTHON_VERSION : 3
+
+
+;------------------
+; 3.工具git库定义
+;------------------
+; 拉工具的仓库地址
+[tool_url]
+CPPLINT : \${base_value:git_url}/cpplint.git
+
+;------------------
+; 5.各个工具配置
+;------------------
+; 整合工具配置
+[cpplint]
+env_path : CPPLINT_HOME
+env_value : PYTHON_VERSION
+path : \${env_path:CPPLINT_HOME}
+tool_url : \${tool_url:CPPLINT}
+
client/config.ini
中指定[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果使用的工具仓库必须账号密码才能拉取则必须填写
+USERNAME=
+PASSWORD=
+
注意
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。注意
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。WARNING
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。WARNING
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。为便于用户快速创建代码库进行分析,复用同类型的分析配置,平台提供了分析方案模板功能。
分析方案模板分为系统方案模板和个人自定义方案模板。
系统方案模板
全局可用。但是用户无法变更系统方案模板内容。如系统方案模板产生变更,需用户自行拉取最新模板内容。
个人自定义方案模板
自定义方案模板与团队挂钩,用户可自行创建、更新、同步方案模板,以及可进行权限控制。默认自定义方案模板团队内都可见。
分析方案模版用于在创建分析方案时作为模版参考。分析方案模版全局可用,不用和某个代码库关联。
创建分析项目时,可选择使用分析方案模板创建。默认会根据该分析方案模板创建出一个新的分析方案,并用该方案配置进行分析项目创建。
创建分析方案时,可选择使用分析方案模板创建。
用模版生成的分析方案和模版建立关联关系,当模版和生成的方案由差异时,可以由用户选择是否同步模版的内容到方案。并可以选择拉群哪些功能模块的配置。
为便于用户快速创建代码库进行分析,复用同类型的分析配置,平台提供了分析方案模板功能。
分析方案模板分为系统方案模板和个人自定义方案模板。
系统方案模板
全局可用。但是用户无法变更系统方案模板内容。如系统方案模板产生变更,需用户自行拉取最新模板内容。
个人自定义方案模板
自定义方案模板与团队挂钩,用户可自行创建、更新、同步方案模板,以及可进行权限控制。默认自定义方案模板团队内都可见。
分析方案模版用于在创建分析方案时作为模版参考。分析方案模版全局可用,不用和某个代码库关联。
创建分析项目时,可选择使用分析方案模板创建。默认会根据该分析方案模板创建出一个新的分析方案,并用该方案配置进行分析项目创建。
创建分析方案时,可选择使用分析方案模板创建。
用模版生成的分析方案和模版建立关联关系,当模版和生成的方案由差异时,可以由用户选择是否同步模版的内容到方案。并可以选择拉群哪些功能模块的配置。
客户端分析完毕后,如果分析方案含有代码检查功能,则代码分析结束后会上报结果信息到腾讯云代码分析平台,用户可在平台上查看问题列表及详情。
进入代码检查问题列表页面后,默认展示**当前分支 + 当前分析方案(即分析项目)**发现的全部未处理问题。
如果仅希望查看增量问题,可以进入分析历史页面,指定查看某一次的扫描结果即可。也可以在过滤筛选项中填入发现问题的扫描 id
进行筛选查看结果(该id
为扫描任务 ID,需要到扫描任务列表中查询)。
责任人说明
责任人为 git blame
操作得到的代码提交人。
问题级别说明
代码检查的问题级别是根据对应分析方案中规则设置的严重级别定义的,从高到低分为 致命、错误、警告、提示
。如果调整问题级别,则需要进入分析方案中调整这个规则的严重级别,调整后需要进行全量扫描使得调整生效。
批量处理说明
问题列表支持批量修改问题状态。
点击规则信息可以查看规则说明。
',10),d=[p];function n(_,l){return o(),s("div",null,d)}const g=t(c,[["render",n],["__file","分析结果查看.html.vue"]]);export{g as default}; diff --git "a/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-effefb84.js" "b/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-effefb84.js" new file mode 100644 index 000000000..382cabf07 --- /dev/null +++ "b/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-effefb84.js" @@ -0,0 +1 @@ +import{_ as e,a as o,b as t}from"./codelint_03-8fa68424.js";import{_ as a,o as r,c as s,e as c}from"./app-2a91d8ab.js";const i="/CodeAnalysis/assets/codelint_04-0c416697.png",d={},p=c('代码分析完毕后,可在分支概览
页面查看分析结果概览。如果分析方案含有代码检查功能,则会上报代码检查结果信息到腾讯云代码分析平台,用户可在平台上查看问题列表及问题详情。
进入代码检查问题列表页面后,默认展示当前分析项目发现的全部未处理问题。
如果仅希望查看增量问题,可以进入分析历史
页面,指定查看某一次的扫描结果即可。也可以在过滤筛选项中填入发现问题的扫描 id
进行筛选查看结果(该id
为扫描任务 ID,需要到扫描任务列表中查询)。
责任人说明
责任人为 git blame
操作得到的代码提交人。
问题级别说明
代码检查的问题级别是根据对应分析方案中规则设置的严重级别定义的,从高到低分为 致命、错误、警告、提示
。如果调整问题级别,则需要进入分析方案中调整这个规则的严重级别,调整后需要进行全量扫描使得调整生效。
批量处理说明
问题列表支持批量修改问题状态。
点击规则信息可以查看规则说明。
',10),n=[p];function _(l,h){return r(),s("div",null,n)}const f=a(d,[["render",_],["__file","分析结果查看.html.vue"]]);export{f as default}; diff --git "a/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-f1a2e8c4.js" "b/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-f1a2e8c4.js" new file mode 100644 index 000000000..512b03a92 --- /dev/null +++ "b/assets/\345\210\206\346\236\220\347\273\223\346\236\234\346\237\245\347\234\213.html-f1a2e8c4.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3c5ef996","path":"/zh/guide/%E4%BB%A3%E7%A0%81%E6%A3%80%E6%9F%A5/%E5%88%86%E6%9E%90%E7%BB%93%E6%9E%9C%E6%9F%A5%E7%9C%8B.html","title":"代码检查结果查看","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"问题列表","slug":"问题列表","link":"#问题列表","children":[]},{"level":2,"title":"问题详情","slug":"问题详情","link":"#问题详情","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/代码检查/分析结果查看.md"}');export{e as data}; diff --git "a/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-130acaf2.js" "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-130acaf2.js" new file mode 100644 index 000000000..f4f859e4b --- /dev/null +++ "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-130acaf2.js" @@ -0,0 +1 @@ +import{_ as l}from"./manage_job_01-8f68e1e2.js";import{_,o as n,c as o,a as e,b as t}from"./app-2a91d8ab.js";const s={},r=e("h1",{id:"分析记录管理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#分析记录管理","aria-hidden":"true"},"#"),t(" 分析记录管理")],-1),a=e("ul",null,[e("li",null,[e("p",null,[t("可查看平台"),e("strong",null,"全部分析记录"),t("。")])]),e("li",null,[e("p",null,[t("可点击查阅"),e("strong",null,"分析记录详情"),t("。")])])],-1),c=e("p",null,[e("img",{src:l,alt:"分析记录列表"})],-1),i=[r,a,c];function d(u,h){return n(),o("div",null,i)}const p=_(s,[["render",d],["__file","分析记录管理.html.vue"]]);export{p as default}; diff --git "a/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-560b2bd2.js" "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-560b2bd2.js" new file mode 100644 index 000000000..4fcb6f1cd --- /dev/null +++ "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-560b2bd2.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-46f099d9","path":"/en/guide/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86/%E5%88%86%E6%9E%90%E8%AE%B0%E5%BD%95%E7%AE%A1%E7%90%86.html","title":"分析记录管理","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/后台管理/分析记录管理.md"}');export{e as data}; diff --git "a/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-613c8218.js" "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-613c8218.js" new file mode 100644 index 000000000..f4f859e4b --- /dev/null +++ "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-613c8218.js" @@ -0,0 +1 @@ +import{_ as l}from"./manage_job_01-8f68e1e2.js";import{_,o as n,c as o,a as e,b as t}from"./app-2a91d8ab.js";const s={},r=e("h1",{id:"分析记录管理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#分析记录管理","aria-hidden":"true"},"#"),t(" 分析记录管理")],-1),a=e("ul",null,[e("li",null,[e("p",null,[t("可查看平台"),e("strong",null,"全部分析记录"),t("。")])]),e("li",null,[e("p",null,[t("可点击查阅"),e("strong",null,"分析记录详情"),t("。")])])],-1),c=e("p",null,[e("img",{src:l,alt:"分析记录列表"})],-1),i=[r,a,c];function d(u,h){return n(),o("div",null,i)}const p=_(s,[["render",d],["__file","分析记录管理.html.vue"]]);export{p as default}; diff --git "a/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-94fd5a90.js" "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-94fd5a90.js" new file mode 100644 index 000000000..c626889a4 --- /dev/null +++ "b/assets/\345\210\206\346\236\220\350\256\260\345\275\225\347\256\241\347\220\206.html-94fd5a90.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ceb7b898","path":"/zh/guide/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86/%E5%88%86%E6%9E%90%E8%AE%B0%E5%BD%95%E7%AE%A1%E7%90%86.html","title":"分析记录管理","lang":"zh-CN","frontmatter":{},"headers":[],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/后台管理/分析记录管理.md"}');export{e as data}; diff --git "a/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-2e60458d.js" "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-2e60458d.js" new file mode 100644 index 000000000..28c4aa01a --- /dev/null +++ "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-2e60458d.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-e38c74ec","path":"/en/guide/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86/%E5%9B%A2%E9%98%9F%E7%AE%A1%E7%90%86.html","title":"团队管理","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/后台管理/团队管理.md"}');export{e as data}; diff --git "a/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-4a60f4f5.js" "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-4a60f4f5.js" new file mode 100644 index 000000000..8a0f98005 --- /dev/null +++ "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-4a60f4f5.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-04f2bfb6","path":"/zh/guide/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86/%E5%9B%A2%E9%98%9F%E7%AE%A1%E7%90%86.html","title":"团队管理","lang":"zh-CN","frontmatter":{},"headers":[],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/guide/后台管理/团队管理.md"}');export{t as data}; diff --git "a/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-5ebf6b40.js" "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-5ebf6b40.js" new file mode 100644 index 000000000..7bc80b49e --- /dev/null +++ "b/assets/\345\233\242\351\230\237\347\256\241\347\220\206.html-5ebf6b40.js" @@ -0,0 +1 @@ +import{_ as t,a as e}from"./manage_org_02-ce951ef7.js";import{_ as r,o as s,c as o,e as _}from"./app-2a91d8ab.js";const a={},c=_('可查看平台创建的团队列表,并提供了相应筛选
可禁用、恢复团队
可查看平台创建的团队列表,并提供了相应筛选
可禁用、恢复团队
团队 > 项目 > 代码库 > 分析项目
您可以创建一个团队,并可以在团队中创建多个项目来进行项目区分和项目管理。可以在一个项目中创建多个代码库进行代码分析。
团队成员分为管理员和普通成员两类。团队管理员具备团队全部权限。
项目成员分为管理员和普通成员两类。项目管理员具备项目全部权限。
团队 > 项目 > 代码库 > 分析项目
您可以创建一个团队,并可以在团队中创建多个项目来进行项目区分和项目管理。可以在一个项目中创建多个代码库进行代码分析。
团队成员分为管理员和普通成员两类。团队管理员具备团队全部权限。
项目成员分为管理员和普通成员两类。项目管理员具备项目全部权限。
方案名称
用于标示一个方案,每个方案名称都是唯一的。
分析语言
用于指明该方案是针对代码库何种语言进行分析。初次创建分析方案时会根据语言初始化分析方案相关配置。
运行环境
用于将任务分配到指定的环境节点机器上执行代码分析,需考虑项目在对应环境的节点机器上能否正常执行。
环境变量
每行 key-value 形式,非必填项。
可用于指定特殊编译环境:如机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本的可以设定相应环境变量。
可用于工具传递参数: 如ESLINT_MAX_OLD_SPACE_SIZE=4096
配置 Js 内存大小
可用于指定项目配置,如PYTHON_VERSION=2
指定为 python2 项目
TIP
对 Python 的分析默认采用 Python3,如果需要分析 Python2 请在环境变量中设置:PYTHON_VERSION=2
方案名称
用于标示一个方案,每个方案名称都是唯一的。
分析语言
用于指明该方案是针对代码库何种语言进行分析。初次创建分析方案时会根据语言初始化分析方案相关配置。
运行环境
用于将任务分配到指定的环境节点机器上执行代码分析,需考虑项目在对应环境的节点机器上能否正常执行。
环境变量
每行 key-value 形式,非必填项。
可用于指定特殊编译环境:如机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本的可以设定相应环境变量。
可用于工具传递参数: 如ESLINT_MAX_OLD_SPACE_SIZE=4096
配置 Js 内存大小
可用于指定项目配置,如PYTHON_VERSION=2
指定为 python2 项目
提示
对 Python 的分析默认采用 Python3,如果需要分析 Python2 请在环境变量中设置:PYTHON_VERSION=2
注:以下字段用于参考,具体字段格式需要以具体接口返回为准
org_sid: str,团队编号
+name: str,团队名称
+description: str,团队描述
+certificated: boolean,团队认证标志位
+created_time: datetime,团队创建时间
+updated_time: datetime,团队更新时间
+admins: list,管理员列表
+project_count: int,分析任务数量
+team_count: int,项目组数量
+user_count: int,成员数量
+owner: str,负责人名称
+tel_number: str,负责人电话
+address: str,办公地址
+
name: str,项目组名称
+display_name: str,项目组展示名称
+description: str,项目组描述信息
+
name: str,代码库名称
+scm_url: str,代码库地址
+scm_type: int,代码库类型
+created_from: str,创建来源
+state:str,代码库状态,1表示活跃,2表示失活,3表示暂停使用
+labels:list,标签
+project_team: 项目
+organization: 团队
+
name: str,扫描方案名称
+repo:关联的代码库
+refer_scheme: 参照的扫描方案
+description: str,描述
+tag: 执行标签
+languages: 包含语言
+default_flag: boolean,默认方案标志
+created_from: str,创建来源
+ignore_merged_issue: boolean,过滤其他分支引入的问题,默认False,不过滤
+ignore_branch_issue: str,过滤指定分支引入的问题
+ignore_submodule_clone: boolean,不拉取子模块,默认False
+ignore_submodule_issue: boolean,忽略子模块问题,默认False
+issue_global_ignore: boolean,开启问题全局忽略,默认False
+daily_save: boolean,日常扫描记录保存7天开关,默认False
+lfs_flag: boolean,自动拉取lfs文件,默认True
+status: int,扫描方案状态,1为活跃,2为废弃
+
注:以下字段用于参考,具体字段格式需要以具体接口返回为准
org_sid: str,团队编号
+name: str,团队名称
+description: str,团队描述
+certificated: boolean,团队认证标志位
+created_time: datetime,团队创建时间
+updated_time: datetime,团队更新时间
+admins: list,管理员列表
+project_count: int,分析任务数量
+team_count: int,项目组数量
+user_count: int,成员数量
+owner: str,负责人名称
+tel_number: str,负责人电话
+address: str,办公地址
+
name: str,项目组名称
+display_name: str,项目组展示名称
+description: str,项目组描述信息
+
name: str,代码库名称
+scm_url: str,代码库地址
+scm_type: int,代码库类型
+created_from: str,创建来源
+state:str,代码库状态,1表示活跃,2表示失活,3表示暂停使用
+labels:list,标签
+project_team: 项目
+organization: 团队
+
name: str,扫描方案名称
+repo:关联的代码库
+refer_scheme: 参照的扫描方案
+description: str,描述
+tag: 执行标签
+languages: 包含语言
+default_flag: boolean,默认方案标志
+created_from: str,创建来源
+ignore_merged_issue: boolean,过滤其他分支引入的问题,默认False,不过滤
+ignore_branch_issue: str,过滤指定分支引入的问题
+ignore_submodule_clone: boolean,不拉取子模块,默认False
+ignore_submodule_issue: boolean,忽略子模块问题,默认False
+issue_global_ignore: boolean,开启问题全局忽略,默认False
+daily_save: boolean,日常扫描记录保存7天开关,默认False
+lfs_flag: boolean,自动拉取lfs文件,默认True
+status: int,扫描方案状态,1为活跃,2为废弃
+
可查看全部工具(包含平台提供工具、团队自定义工具)。
可查看、编辑工具。
可变更工具权限状态。
提示
工具的权限状态仅能由平台管理员进行变更调整,需谨慎调整
团队内可用:即工具配置了可用团队白名单的团队可以使用该工具,默认创建工具的团队已在白名单内
全平台可用:即不同团队都可见可用该工具
支持自定义规则,全平台可用:即该工具不同团队都可见可用,且支持用户添加团队所需的自定义规则,该自定义规则存在团队隔离,仅团队内可以,其他团队不可使用
可查看全部工具(包含平台提供工具、团队自定义工具)。
可查看、编辑工具。
可变更工具权限状态。
TIP
工具的权限状态仅能由平台管理员进行变更调整,需谨慎调整
团队内可用:即工具配置了可用团队白名单的团队可以使用该工具,默认创建工具的团队已在白名单内
全平台可用:即不同团队都可见可用该工具
支持自定义规则,全平台可用:即该工具不同团队都可见可用,且支持用户添加团队所需的自定义规则,该自定义规则存在团队隔离,仅团队内可以,其他团队不可使用
腾讯云代码分析平台目前已集成众多自研、知名开源工具,并采用分层分离的架构,可以快速对接企业内部团队研发的工具,并将其集成到平台内供企业内部团队使用,满足快速自助的管理工具。
按工具来源划分,工具包含平台提供的工具,以及团队接入的工具。
平台提供工具:由腾讯云代码分析平台提供的一系列自研、知名开源工具,此类工具都为公开工具,任何团队都可以使用此工具及工具规则进行代码分析。
团队接入:由团队自行接入的工具,默认该工具仅能在团队内使用,如需跨团队使用或任何团队都可以使用需联系平台管理员进行配置。
按工具使用划分,工具包含可自定义规则工具、可使用工具两种。
可自定义规则工具:该工具任何团队都可以使用,且该工具可以支持添加团队所需的自定义规则。如RegexScan
工具,各个团队都可以使用该工具提供的规则,也可以自定义规则,此自定义规则团队隔离。
可使用工具:该工具团队内可使用,但不能添加自定义规则
默认自定义工具只能当前团队内使用,添加 工具白名单
后可以让其他团队使用。
TIP
添加工具、添加工具规则、添加自定义规则等均需团队内管理员可操作。分析。
【用户 A1】【用户 A2】为【团队 O1】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 B1】【用户 B2】为【团队 O2】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 A1】在工具管理页面添加了【工具 T1】,该工具为团队内工具; -【用户 A1】【用户 A2】均可操作该工具,如修改工具信息、添加工具规则等,【用户 A3】仅可以使用该工具,如在规则配置页面添加该工具规则;
由于【工具 T1】目前仅【团队 O1】可用,【团队 O2】中无法看到此工具,即【团队 O2】内的成员无法使用该工具。
如需【工具 T1】也让【团队 O2】使用有两种解决方法:1. 【工具 T1】将【团队 O2】加入使用白名单;2. 向平台发起申请,由平台管理员将【工具 T1】调整为全部团队都可使用。
正则工具 RegexScan
,进入工具-自定义规则栏,发现没有添加规则的入口;腾讯云代码分析平台目前已集成众多自研、知名开源工具,并采用分层分离的架构,可以快速对接企业内部团队研发的工具,并将其集成到平台内供企业内部团队使用,满足快速自助的管理工具。
按工具来源划分,工具包含平台提供的工具,以及团队接入的工具。
平台提供工具:由腾讯云代码分析平台提供的一系列自研、知名开源工具,此类工具都为公开工具,任何团队都可以使用此工具及工具规则进行代码分析。
团队接入:由团队自行接入的工具,默认该工具仅能在团队内使用,如需跨团队使用或任何团队都可以使用需联系平台管理员进行配置。
按工具使用划分,工具包含可自定义规则工具、可使用工具两种。
可自定义规则工具:该工具任何团队都可以使用,且该工具可以支持添加团队所需的自定义规则。如RegexScan
工具,各个团队都可以使用该工具提供的规则,也可以自定义规则,此自定义规则团队隔离。
可使用工具:该工具团队内可使用,但不能添加自定义规则
默认自定义工具只能当前团队内使用,添加 工具白名单
后可以让其他团队使用。
提示
添加工具、添加工具规则、添加自定义规则等均需团队内管理员可操作。分析。
【用户 A1】【用户 A2】为【团队 O1】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 B1】【用户 B2】为【团队 O2】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 A1】在工具管理页面添加了【工具 T1】,该工具为团队内工具; -【用户 A1】【用户 A2】均可操作该工具,如修改工具信息、添加工具规则等,【用户 A3】仅可以使用该工具,如在规则配置页面添加该工具规则;
由于【工具 T1】目前仅【团队 O1】可用,【团队 O2】中无法看到此工具,即【团队 O2】内的成员无法使用该工具。
如需【工具 T1】也让【团队 O2】使用有两种解决方法:1. 【工具 T1】将【团队 O2】加入使用白名单;2. 向平台发起申请,由平台管理员将【工具 T1】调整为全部团队都可使用。
正则工具 RegexScan
,进入工具-自定义规则栏,发现没有添加规则的入口;提示
TCA 客户端除了通过localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。
和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
希望通过并行执行分析来提高分析效率
希望尽量使用公共资源或使用专机资源
config.ini
文件将<Server IP地址>
替换成实际的 TCA 平台 IP(可包含端口号)。
国内使用 github 拉取网络较慢,推荐使用腾讯工蜂拉取,需要修改以下配置:
两种方式可选启动客户端:
client
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
+
python3 codepuppy.py -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
client
目录下,执行命令:./codepuppy -l codepuppy.log start -t <token>
+
./codepuppy -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
常驻节点首次启动后,需要到节点管理页面管理节点状态:
设置节点状态: 进入 TCA 节点管理页面。管理入口
-节点管理
,可以看到当前在线的节点,节点状态默认为不可用
,需将其设置为**活跃
**才可用于接收和执行任务。 也可以按需修改节点名称、标签、负责人等信息。
(按需可选)配置节点工具进程: 进入工具进程配置页面,对节点支持的工具进程进行管理(默认会全部勾选),未勾选的工具进程,将不会在该节点上执行。
(按需可选)设置节点标签: 节点标签会与分析方案中的运行环境标签进行匹配,只有相同标签的任务才会下发到该机器节点上。
TIP
TCA 客户端除了通过localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。
和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
希望通过并行执行分析来提高分析效率
希望尽量使用公共资源或使用专机资源
config.ini
文件将<Server IP地址>
替换成实际的 TCA 平台 IP(可包含端口号)。
国内使用 github 拉取网络较慢,推荐使用腾讯工蜂拉取,需要修改以下配置:
两种方式可选启动客户端:
client
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
+
python3 codepuppy.py -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
client
目录下,执行命令:./codepuppy -l codepuppy.log start -t <token>
+
./codepuppy -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
常驻节点首次启动后,需要到节点管理页面管理节点状态:
设置节点状态: 进入 TCA 节点管理页面。管理入口
-节点管理
,可以看到当前在线的节点,节点状态默认为不可用
,需将其设置为**活跃
**才可用于接收和执行任务。 也可以按需修改节点名称、标签、负责人等信息。
(按需可选)配置节点工具进程: 进入工具进程配置页面,对节点支持的工具进程进行管理(默认会全部勾选),未勾选的工具进程,将不会在该节点上执行。
(按需可选)设置节点标签: 节点标签会与分析方案中的运行环境标签进行匹配,只有相同标签的任务才会下发到该机器节点上。
完成代码库登记,并点击进入代码分析
提示
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
在线分析即是通过Server端将分析任务注册到执行队列中,并将任务分配到平台配置的常驻分析节点上进行,分析完毕后将分析结果上报入库。
',11),k={class:"custom-container tip"},z=e("p",{class:"custom-container-title"},"提示",-1),N=e("p",null,"使用在线分析要求平台具有常驻分析节点:",-1),V=e("p",null,[e("strong",null,"如无分析节点,在线分析任务将无法完成分配,未分配任务将于超时后自动注销"),t("。")],-1),w=e("h4",{id:"客户端分析",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#客户端分析","aria-hidden":"true"},"#"),t(" 客户端分析")],-1),D=e("code",null,"codedog.ini",-1),L=o('分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
Register your repository and go to code analysis
TIP
After initialization, you can use Online analysis
or Client analysis
to start a code analysis。
Online analysis means that the analysis task is registered to the execution queue in the server, and the task is assigned to the resident analysis node configured in the TCA. After the analysis is completed, the analysis result will upload to the TCA.
',11),x={class:"custom-container tip"},k=e("p",{class:"custom-container-title"},"TIP",-1),T=e("p",null,"Use online analysis, the TCA must have at least resident analysis node:",-1),j=e("p",null,[e("strong",null,"If there is no node avaliable, online analysis tasks cannot be assigned. Unassigned tasks will be automatically cancelled after timeout"),a("。")],-1),F=e("h4",{id:"client-analysis",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#client-analysis","aria-hidden":"true"},"#"),a(" Client analysis")],-1),R=e("code",null," codelog.ini",-1),q=i('After the analysis, the data will be reported to the server. You can enter the analysis history page to check the analysis records and results.
对本地代码目录下的临时代码(未关联scm仓库或未提交到scm仓库的本地代码)进行扫描,对某个目录或某些文件进行快速扫描,产出本地扫描结果。
该模式不与scm代码仓库关联,只对给定的目录或文件进行扫描,不依据提交版本号做增量分析,也不定位问题责任人。
由于该模式不与scm代码仓库绑定,因此不能直接使用分析方案(分析方案上归属于某个代码仓库下的),需要使用分析方案模板的配置来扫描。
目前快速扫描模式只支持代码检查,暂不支持代码度量,请勿开启代码度量配置项(无法展示结果)。
配置好方案模板后,从页面URL中获取到分析方案模板ID,分析方案模板页面URL格式:http://{域名}/t/{org_sid}/p/{team_name}/template/{分析方案模板ID}
,template
后面的数字即分析方案模板ID。
client
目录下,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
TOKEN
: 必选,从TCA平台页面获取,前往[个人中心]
-[个人令牌]
-复制TokenSCHEME_TEMPLATE_ID
: 必选,分析方案模板ID,从步骤1中获取ORG_SID
: 必选,团队编号,从TCA平台团队概览URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/profile
client
目录下,执行命令:python3 codepuppy.py quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
参数说明:
SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
对本地代码目录下的临时代码(未关联scm仓库或未提交到scm仓库的本地代码)进行扫描,对某个目录或某些文件进行快速扫描,产出本地扫描结果。
该模式不与scm代码仓库关联,只对给定的目录或文件进行扫描,不依据提交版本号做增量分析,也不定位问题责任人。
提示
客户端快扫模式已内置open_source_check
(开源)、safety
(基础安全)、sensitive
(敏感信息)三种常用分析方案,快速启动内置方案:
client
目录下,运行codepuppy.py或codepuppy二进制,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -l LABEL_NAME
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickinit -l LABEL_NAME
+
LABEL_NAME
: 必选,内置分析方案标签名,从open_source_check
、safety
、sensitive
三者中选一。client
目录下,执行命令:python3 codepuppy.py quickscan -l LABEL_NAME -s SOURCE_DIR --file FILE
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickscan -l LABEL_NAME -s SOURCE_DIR --file FILE
+
参数说明:
LABEL_NAME
: 必选,内置分析方案标签名,从open_source_check
、safety
、sensitive
三者中选一。SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
如需自行创建分析方案,参考以下步骤:
由于该模式不与scm代码仓库绑定,因此不能直接使用分析方案(分析方案上归属于某个代码仓库下的),需要使用分析方案模板的配置来扫描。
目前快速扫描模式只支持代码检查,暂不支持代码度量,请勿开启代码度量配置项(无法展示结果)。
配置好方案模板后,从页面URL中获取到分析方案模板ID,分析方案模板页面URL格式:http://{域名}/t/{org_sid}/p/{team_name}/template/{分析方案模板ID}
,template
后面的数字即分析方案模板ID。
client
目录下,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
TOKEN
: 必选,从TCA平台页面获取,前往[个人中心]
-[个人令牌]
-复制TokenSCHEME_TEMPLATE_ID
: 必选,分析方案模板ID,从步骤1中获取ORG_SID
: 必选,团队编号,从TCA平台团队概览中获取“团队唯一标识”client
目录下,执行命令:python3 codepuppy.py quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
参数说明:
SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
团队成员分为团队管理员和团队普通成员两类。
团队管理员:可以邀请其他成员加入团队,具备团队内所有权限。
团队普通成员:可以创建项目,可以访问自己有权限的项目。创建项目的人会自动成为这个项目的项目管理员。
项目成员分为项目管理员和项目普通成员。
项目管理员:具备项目内全部权限。
项目普通成员:可以查看项目内的配置信息和分析结果等各项信息,并且可以启动分析,但是无其他操作权限。
',10),c=[a];function h(i,_){return e(),s("div",null,c)}const g=t(o,[["render",h],["__file","成员权限.html.vue"]]);export{g as default}; diff --git "a/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-7a01de0b.js" "b/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-7a01de0b.js" new file mode 100644 index 000000000..a3f130c43 --- /dev/null +++ "b/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-7a01de0b.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-53d9da54","path":"/en/guide/%E5%9B%A2%E9%98%9F%E7%AE%A1%E7%90%86/%E6%88%90%E5%91%98%E6%9D%83%E9%99%90.html","title":"成员权限","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"团队成员","slug":"团队成员","link":"#团队成员","children":[]},{"level":2,"title":"项目成员","slug":"项目成员","link":"#项目成员","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/guide/团队管理/成员权限.md"}');export{e as data}; diff --git "a/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-9077d3da.js" "b/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-9077d3da.js" new file mode 100644 index 000000000..48794d4ee --- /dev/null +++ "b/assets/\346\210\220\345\221\230\346\235\203\351\231\220.html-9077d3da.js" @@ -0,0 +1 @@ +import{_ as r}from"./team_member-8942b2d5.js";import{_ as t,o as e,c as s,e as n}from"./app-2a91d8ab.js";const o={},a=n('团队成员分为团队管理员和团队普通成员两类。
团队管理员:可以邀请其他成员加入团队,具备团队内所有权限。
团队普通成员:可以创建项目,可以访问自己有权限的项目。创建项目的人会自动成为这个项目的项目管理员。
项目成员分为项目管理员和项目普通成员。
项目管理员:具备项目内全部权限。
项目普通成员:可以查看项目内的配置信息和分析结果等各项信息,并且可以启动分析,但是无其他操作权限。
',10),c=[a];function h(i,_){return e(),s("div",null,c)}const g=t(o,[["render",h],["__file","成员权限.html.vue"]]);export{g as default}; diff --git "a/assets/\346\234\254\345\234\260\345\210\206\346\236\220.html-28645990.js" "b/assets/\346\234\254\345\234\260\345\210\206\346\236\220.html-28645990.js" new file mode 100644 index 000000000..96b43a45d --- /dev/null +++ "b/assets/\346\234\254\345\234\260\345\210\206\346\236\220.html-28645990.js" @@ -0,0 +1,8 @@ +import{_ as n}from"./start_scan_03-f1dea0e4.js";import{_ as r,r as l,o as c,c as o,a as e,b as t,d,e as i}from"./app-2a91d8ab.js";const s={},h=i('希望在本地随时分析。
接入持续集成系统实现自动化分析。
1. 客户端运行环境机器配置推荐
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
2. 本地需具备客户端
',8),p={href:"https://github.com/Tencent/CodeAnalysis",target:"_blank",rel:"noopener noreferrer"},u={href:"https://github.com/Tencent/CodeAnalysis/releases",target:"_blank",rel:"noopener noreferrer"},g=i(`3. 安装Python环境和第三方库(仅客户端源码启动分析需要)
python3
和 pip3
命令pip3 install -r CodeAnalysis/client/requirements/app_reqs.pip
4. 安装第三方工具(docker下启动分析可跳过)
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)config.ini
文件<Server IP地址>
替换成实际的TCA平台IP(可包含端口号)codedog.ini
文件codedog.ini
获取方法:
codedog.ini
中以下字段为必填项:
字段名 | 填写说明 |
---|---|
token | 从TCA平台页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从TCA平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他字段按需填写。
启动客户端分析有三种方式可选:客户端源码下启动分析、客户端二进制启动分析、docker下启动分析
进入到客户端client
目录下
执行命令: 客户端源码:python3 codepuppy.py localscan
进入到客户端client
目录下
执行命令: 客户端源码:./codepuppy localscan
在client目录下,执行以下命令:docker build -t tca-client .
(需已安装Docker)
注意
注意:因为以下步骤会将代码目录挂载到容器中,需要先将codedog.ini里面的source_dir修改为/workspace/src,其他参数保持不变。
执行Docker容器有以下两种方式:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
通过以下方式,进入容器内的bash终端后,通过命令行启动client代码:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
希望在本地随时分析。
接入持续集成系统实现自动化分析。
1. 客户端运行环境机器配置推荐
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
2. 本地需具备客户端
',8),p={href:"https://github.com/Tencent/CodeAnalysis",target:"_blank",rel:"noopener noreferrer"},u={href:"https://github.com/Tencent/CodeAnalysis/releases",target:"_blank",rel:"noopener noreferrer"},g=i(`3. 安装Python环境和第三方库(仅客户端源码启动分析需要)
python3
和 pip3
命令pip3 install -r CodeAnalysis/client/requirements/app_reqs.pip
4. 安装第三方工具(docker下启动分析可跳过)
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)config.ini
文件<Server IP地址>
替换成实际的TCA平台IP(可包含端口号)codedog.ini
文件codedog.ini
获取方法:
codedog.ini
中以下字段为必填项:
字段名 | 填写说明 |
---|---|
token | 从TCA平台页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从TCA平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他字段按需填写。
启动客户端分析有三种方式可选:客户端源码下启动分析、客户端二进制启动分析、docker下启动分析
进入到客户端client
目录下
执行命令: 客户端源码:python3 codepuppy.py localscan
进入到客户端client
目录下
执行命令: 客户端源码:./codepuppy localscan
在client目录下,执行以下命令:docker build -t tca-client .
(需已安装Docker)
WARNING
注意:因为以下步骤会将代码目录挂载到容器中,需要先将codedog.ini里面的source_dir修改为/workspace/src,其他参数保持不变。
执行Docker容器有以下两种方式:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
通过以下方式,进入容器内的bash终端后,通过命令行启动client代码:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
规则配置是代码检查应用的规则集合,用于指定用哪些工具和规则进行代码分析扫描。目前,TCA 提供了覆盖代码规范、安全扫描、风格检查等方面的官方推荐规则包。
官方推荐规则包是TCA长期以来在业务中实践的经验结果,将相关的有效性高的工具和规则打包在一起。业务可以根据需要选择官方推荐规则包。也可以在自定义规则包中添加希望的工具和规则。
提示
规则配置 = 自定义规则包 + 官方规则包
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置
可以单选或者批量多选规则
也可以根据搜索框进行多维度查询
',7),i=[n];function p(l,m){return e(),a("div",null,i)}const h=o(c,[["render",p],["__file","添加规则配置.html.vue"]]);export{h as default}; diff --git "a/assets/\346\267\273\345\212\240\350\247\204\345\210\231\351\205\215\347\275\256.html-86efce15.js" "b/assets/\346\267\273\345\212\240\350\247\204\345\210\231\351\205\215\347\275\256.html-86efce15.js" new file mode 100644 index 000000000..d78f4a111 --- /dev/null +++ "b/assets/\346\267\273\345\212\240\350\247\204\345\210\231\351\205\215\347\275\256.html-86efce15.js" @@ -0,0 +1 @@ +import{_ as t,a as s,b as r}from"./AddRule3-9d6ed3bf.js";import{_ as o,o as e,c as a,e as _}from"./app-2a91d8ab.js";const c={},n=_('规则配置是代码检查应用的规则集合,用于指定用哪些工具和规则进行代码分析扫描。目前,TCA 提供了覆盖代码规范、安全扫描、风格检查等方面的官方推荐规则包。
官方推荐规则包是TCA长期以来在业务中实践的经验结果,将相关的有效性高的工具和规则打包在一起。业务可以根据需要选择官方推荐规则包。也可以在自定义规则包中添加希望的工具和规则。
TIP
规则配置 = 自定义规则包 + 官方规则包
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置
可以单选或者批量多选规则
也可以根据搜索框进行多维度查询
',7),i=[n];function p(l,m){return e(),a("div",null,i)}const h=o(c,[["render",p],["__file","添加规则配置.html.vue"]]);export{h as default}; diff --git "a/assets/\347\224\250\346\210\267\347\256\241\347\220\206.html-01a71e5a.js" "b/assets/\347\224\250\346\210\267\347\256\241\347\220\206.html-01a71e5a.js" new file mode 100644 index 000000000..7b58e4b96 --- /dev/null +++ "b/assets/\347\224\250\346\210\267\347\256\241\347\220\206.html-01a71e5a.js" @@ -0,0 +1 @@ +import{_ as t,a as r}from"./manage_user_02-e4d7abc6.js";import{_ as s,o,c as e,e as n}from"./app-2a91d8ab.js";const _={},a=n('可查看、编辑、创建平台用户。
可配置用户的登录密码、用户级别、超级管理员等。
可查看、编辑、创建平台用户。
可配置用户的登录密码、用户级别、超级管理员等。
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/
+
{
+ "lintscan": {
+ "issue_open_num": 74,
+ "issue_fix_num": 439,
+ "issue_detail_num": 310,
+ "scan": {
+ "id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "execute_time": "00:02:17.844712"
+ },
+ "current_scan": {
+ "active_category_detail": {
+ "convention": 70,
+ "other": 4
+ },
+ "active_severity_detail": {
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 74,
+ "issue_fix_num": 439
+ },
+ "total": {
+ "state_detail": {
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": {
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": {
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0,
+ "text": "成功",
+ "description": null,
+ "scan_summary": {
+ "convention": {
+ "error": {
+ "rule_count": 7,
+ "active": 65
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ },
+ "cyclomaticcomplexityscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ },
+ "duplicatescan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/latestscan/
+
参数 | 类型 | 描述 |
---|---|---|
scan_revision | str | 指定查询的扫描版本号,如不指定则为当前项目最新的一次扫描 |
{
+ "data": {
+ "id": 1, # 扫描编号
+ "repo_id": 1, # 代码库编号
+ "project_id": 1, # 项目编号
+ "job_gid": 1, # 关联任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "current_revision": "current_revision", # 扫描版本号
+ "result_code": 0, # 扫描任务结果码,0表示正常
+ "result_code_msg": "成功",
+ "result_msg": null,
+ "lintscan": { # 代码扫描结果信息
+ "current_scan": { # 本次扫描信息
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ }
+ },
+ "duplicatescan": { # 重复代码扫描结果信息
+ "id": 1, # 扫描任务编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "default_summary": { # 默认概览
+ "exhi_risk": { # 极高风险
+ "range": [ # 重复率范围: 0.2-1
+ 0.2,
+ 1
+ ],
+ "file_count": 1, # 文件数量
+ "diff": { # 增量数据
+ "diff_file_count": 0 # 增量文件数量
+ }
+ },
+ "high_risk": { # 高风险
+ "range": [ # 重复率范围:0.11-0.2
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": { # 中风险
+ "range": [ # 重复率范围:0.05-0.11
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": { # 低风险
+ "range": [ # 重复率范围:0-0.05
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null, # 自定义概览数据
+ "last_revision": "2010ef28ff3a26424d4e8f32df022f90cd682eda", # 上次扫描版本号
+ "duplicate_file_count": 8, # 重复文件数量
+ "duplicate_block_count": 55, # 重复代码块数量
+ "duplicate_line_count": 1177, # 重复代码行数
+ "diff_duplicate_block_count": 0, # 增量重复代码块数量
+ "diff_duplicate_line_count": 0, # 增量重复代码行数
+ "close_issue_count": 0, # 关闭问题数
+ "new_issue_count": 0, # 新增问题数
+ "reopen_issue_count": 5, # 重新打开问题数
+ "ignored_issue_count": 0, # 忽略问题数
+ "duplicate_rate": 4.98, # 重复率
+ "unique_duplicate_line_count": 1083, # 去重后的重复代码行数
+ "total_duplicate_line_count": 1083, # 项目总的去重后的重复代码行数
+ "total_line_count": 21745, # 项目总行书
+ "scan": 1 # 关联扫描任务编号
+ },
+ "cyclomaticcomplexityscan": { # 圈复杂度扫描数据
+ "id": 1, # 圈复杂度扫描编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": { # 默认概览数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "over_cc_func_count": 6, # 超标函数数量
+ "under_cc_func_count": 796, # 未超标函数数量
+ "diff_over_cc_func_count": 0, # 增量超标函数数据
+ "over_cc_func_average": 22.333333333333332, # 平均超标圈复杂度
+ "cc_func_average": 2.5099750623441395, # 平均圈复杂度
+ "over_cc_sum": 14, # 文件超标方法圈复杂度超过阈值的差值之和
+ "cc_average_of_lines": 1.0422094841063054 # 千行代码平均圈复杂度
+ },
+ "custom_summary": null, # 自定义概览数据
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "diff_cc_num": 0, # 增量超标函数数量
+ "cc_open_num": 6, # 超标函数量
+ "cc_average_of_lines": 1.0422094841063054, # 千行代码平均圈复杂度
+ "cc_fix_num": 0, # 修复数量
+ "worse_cc_file_num": 0, # 圈复杂度恶化的文件数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "code_line_num": 13433, # 代码行数
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "code_line_num": 140490, # 代码行数
+ "comment_line_num": 5410, # 注释行数
+ "blank_line_num": 3408, # 空白行数
+ "total_line_num": 149308, # 总行数
+ "add_code_line_num": 6673, # 增加的代码行数
+ "add_comment_line_num": 2309, # 增加的注释行数
+ "add_blank_line_num": 1289, # 增加的空白行数
+ "add_total_line_num": 10271, # 增加的总行数
+ "mod_code_line_num": 965, # 修改的代码行数
+ "mod_comment_line_num": 297, # 修改的注释行数
+ "mod_blank_line_num": 0, # 修改的空白行数
+ "mod_total_line_num": 1262, # 修改的总行数
+ "del_code_line_num": 35844, # 删除的代码行数
+ "del_comment_line_num": 2117, # 删除的注释行数
+ "del_blank_line_num": 1794, # 删除的空白行数
+ "del_total_line_num": 39755, # 删除的总行数
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/lintscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2, # 本次扫描关闭存量问题数
+ "issue_detail_num": 310, # 本次扫描上报原始问题数(问题展示会进行聚合)
+ "scan": { # 扫描信息
+ "id": 1, # 扫描任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描开始时间
+ "execute_time": "00:02:17.844712" # 扫描执行耗时
+ },
+ "current_scan": { # 本次扫描信息
+ "active_category_detail": { # 活跃问题分类,包含 CORRECTNESS(1-功能)、SECURITY(2-安全)、PERFORMANCE(3-性能)、USABILITY(4-可用性)、ACCESSIBILITY(5-无障碍化)、I18N(6-国际化)、CONVENTION(7-代码风格)、OTHER(8-其他)
+ "convention": 70, # 代码风格类型问题
+ "other": 4 # 其他类型问题
+ },
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": { # 不同分类下不同处理状态的问题量
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0, # 扫描状态,0表示成功
+ "text": "成功",
+ "description": null,
+ "scan_summary": { # 扫描概览
+ "convention": {
+ "error": {
+ "rule_count": 7, # 规则数
+ "active": 65 # 活跃问题数
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/cycscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/dupscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/clocscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/
+
{
+ "data": {
+ "lintscan": {
+ "issue_open_num": 74,
+ "issue_fix_num": 439,
+ "issue_detail_num": 310,
+ "scan": {
+ "id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "execute_time": "00:02:17.844712"
+ },
+ "current_scan": {
+ "active_category_detail": {
+ "convention": 70,
+ "other": 4
+ },
+ "active_severity_detail": {
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 74,
+ "issue_fix_num": 439
+ },
+ "total": {
+ "state_detail": {
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": {
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": {
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0,
+ "text": "成功",
+ "description": null,
+ "scan_summary": {
+ "convention": {
+ "error": {
+ "rule_count": 7,
+ "active": 65
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ },
+ "cyclomaticcomplexityscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ },
+ "duplicatescan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/latestscan/
+
参数 | 类型 | 描述 |
---|---|---|
scan_revision | str | 选填,指定查询的扫描版本号,如不指定则为当前项目最新的一次扫描 |
{
+ "data": {
+ "id": 1, # 扫描编号
+ "repo_id": 1, # 代码库编号
+ "project_id": 1, # 项目编号
+ "job_gid": 1, # 关联任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "current_revision": "current_revision", # 扫描版本号
+ "result_code": 0, # 扫描任务结果码,0表示正常
+ "result_code_msg": "成功",
+ "result_msg": null,
+ "lintscan": { # 代码扫描结果信息
+ "current_scan": { # 本次扫描信息
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ }
+ },
+ "duplicatescan": { # 重复代码扫描结果信息
+ "id": 1, # 扫描任务编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "default_summary": { # 默认概览
+ "exhi_risk": { # 极高风险
+ "range": [ # 重复率范围: 0.2-1
+ 0.2,
+ 1
+ ],
+ "file_count": 1, # 文件数量
+ "diff": { # 增量数据
+ "diff_file_count": 0 # 增量文件数量
+ }
+ },
+ "high_risk": { # 高风险
+ "range": [ # 重复率范围:0.11-0.2
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": { # 中风险
+ "range": [ # 重复率范围:0.05-0.11
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": { # 低风险
+ "range": [ # 重复率范围:0-0.05
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null, # 自定义概览数据
+ "last_revision": "2010ef28ff3a26424d4e8f32df022f90cd682eda", # 上次扫描版本号
+ "duplicate_file_count": 8, # 重复文件数量
+ "duplicate_block_count": 55, # 重复代码块数量
+ "duplicate_line_count": 1177, # 重复代码行数
+ "diff_duplicate_block_count": 0, # 增量重复代码块数量
+ "diff_duplicate_line_count": 0, # 增量重复代码行数
+ "close_issue_count": 0, # 关闭问题数
+ "new_issue_count": 0, # 新增问题数
+ "reopen_issue_count": 5, # 重新打开问题数
+ "ignored_issue_count": 0, # 忽略问题数
+ "duplicate_rate": 4.98, # 重复率
+ "unique_duplicate_line_count": 1083, # 去重后的重复代码行数
+ "total_duplicate_line_count": 1083, # 项目总的去重后的重复代码行数
+ "total_line_count": 21745, # 项目总行书
+ "scan": 1 # 关联扫描任务编号
+ },
+ "cyclomaticcomplexityscan": { # 圈复杂度扫描数据
+ "id": 1, # 圈复杂度扫描编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": { # 默认概览数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "over_cc_func_count": 6, # 超标函数数量
+ "under_cc_func_count": 796, # 未超标函数数量
+ "diff_over_cc_func_count": 0, # 增量超标函数数据
+ "over_cc_func_average": 22.333333333333332, # 平均超标圈复杂度
+ "cc_func_average": 2.5099750623441395, # 平均圈复杂度
+ "over_cc_sum": 14, # 文件超标方法圈复杂度超过阈值的差值之和
+ "cc_average_of_lines": 1.0422094841063054 # 千行代码平均圈复杂度
+ },
+ "custom_summary": null, # 自定义概览数据
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "diff_cc_num": 0, # 增量超标函数数量
+ "cc_open_num": 6, # 超标函数量
+ "cc_average_of_lines": 1.0422094841063054, # 千行代码平均圈复杂度
+ "cc_fix_num": 0, # 修复数量
+ "worse_cc_file_num": 0, # 圈复杂度恶化的文件数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "code_line_num": 13433, # 代码行数
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "code_line_num": 140490, # 代码行数
+ "comment_line_num": 5410, # 注释行数
+ "blank_line_num": 3408, # 空白行数
+ "total_line_num": 149308, # 总行数
+ "add_code_line_num": 6673, # 增加的代码行数
+ "add_comment_line_num": 2309, # 增加的注释行数
+ "add_blank_line_num": 1289, # 增加的空白行数
+ "add_total_line_num": 10271, # 增加的总行数
+ "mod_code_line_num": 965, # 修改的代码行数
+ "mod_comment_line_num": 297, # 修改的注释行数
+ "mod_blank_line_num": 0, # 修改的空白行数
+ "mod_total_line_num": 1262, # 修改的总行数
+ "del_code_line_num": 35844, # 删除的代码行数
+ "del_comment_line_num": 2117, # 删除的注释行数
+ "del_blank_line_num": 1794, # 删除的空白行数
+ "del_total_line_num": 39755, # 删除的总行数
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/lintscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2, # 本次扫描关闭存量问题数
+ "issue_detail_num": 310, # 本次扫描上报原始问题数(问题展示会进行聚合)
+ "scan": { # 扫描信息
+ "id": 1, # 扫描任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描开始时间
+ "execute_time": "00:02:17.844712" # 扫描执行耗时
+ },
+ "current_scan": { # 本次扫描信息
+ "active_category_detail": { # 活跃问题分类,包含 CORRECTNESS(1-功能)、SECURITY(2-安全)、PERFORMANCE(3-性能)、USABILITY(4-可用性)、ACCESSIBILITY(5-无障碍化)、I18N(6-国际化)、CONVENTION(7-代码风格)、OTHER(8-其他)
+ "convention": 70, # 代码风格类型问题
+ "other": 4 # 其他类型问题
+ },
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": { # 不同分类下不同处理状态的问题量
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0, # 扫描状态,0表示成功
+ "text": "成功",
+ "description": null,
+ "scan_summary": { # 扫描概览
+ "convention": {
+ "error": {
+ "rule_count": 7, # 规则数
+ "active": 65 # 活跃问题数
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/cycscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/dupscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/clocscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
腾讯云代码分析平台支持用户自助添加代码分析工具。
适用场景:自定义规则无法满足团队业务复杂需求,需要更多的代码逻辑来匹配目标代码的情况。通常需要团队业务方自行实现对应代码分析工具。
只需要几步操作:
扩展集成工具免责声明
被扩展集成进腾讯云代码分析系统的任何非官方工具,该类工具对于腾讯云代码分析系统等于黑盒,腾讯云代码分析系统不对该类工具负责,由该类工具方承担所有责任(包括但不限于分发被分析代码,产生代码以及相关信息泄漏)。
运行方式:支持命令行执行,比如 python run.py 或 run.exe,执行命令的工作目录为工具代码的根目录。
运行环境说明:
工具管理
-工具依赖
中查看,创建工具时可供选择,执行时会自动配置好依赖环境。SOURCE_DIR:要扫描的代码目录路径
+DIFF_FILES: 值为一个json文件路径,文件内容为增量扫描的文件列表(增量扫描时可用)
+SCAN_FILES: 值为一个json文件路径,文件内容为需要扫描的文件列表(增量或全量扫描均可用)
+TASK_REQUEST: 值为一个json文件路径,文件内容为当前扫描任务参数
+RESULT_DIR: 结果result.json输出的结果目录路径
+
工具命令声明
在工具仓库根目录下,添加一个tool.json
文件,声明工具的检查和扫描命令,比如:
{
+ "check_cmd": "python src/main.py check",
+ "run_cmd": "python src/main.py scan"
+}
+
参数说明:
check_cmd
: check_result.json
文件中,文件内容为{"usable": true}
或{"usable": false}
。run_cmd
: result.json
文件中。工具输出格式要求
RESULT_DIR
环境变量指定的目录下的result.json
文件中(Python 示例代码)import os
+import json
+result_dir = os.getenv("RESULT_DIR", os.getcwd())
+result_path = os.path.join(result_dir, "result.json")
+with open(result_path, "w") as fp:
+ json.dump(result, fp, indent=2)
+
result.json
文件格式如下:[
+ {
+ "path": "文件绝对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+ },
+ ...
+]
+
refs
字段说明:
非必需项,可无。该字段记录问题回溯路径信息。比如当前行的代码问题,是经过上下文的三行代码执行路径而导致的,可以将这三行的位置及提示信息,按顺序添加到 refs 数组中。
创建代码库,将工具源代码或编译打包后的可执行文件,提交到代码仓库中(建议提交到master分支,TCA默认拉取的是master分支)。
建议代码库中加入 README.md 文件,说明工具功能和维护人。
后续需要修改工具实现逻辑,可以直接更新代码库,TCA 平台在执行该工具时,会自动拉取最新工具代码版本。
进入工具管理页面,点击创建工具
填写工具信息
部分参数说明:
工具仓库地址,即前述步骤中提交的工具 git 代码库地址,默认拉取的是master分支,如果是其他分支,需要在仓库地址后加上#分支名
,比如:https://github.com/xxx/xxx.git#main
工具认证,授权拉取工具仓库的权限
执行命令,该命令会在工具根目录下执行
环境变量,工具执行所需的环境变量
License,如果是开源工具,填写工具遵循的开源协议,或者填写自研共建
是否为编译型工具,表示在使用该工具对用户代码进行分析时,是否要求代码需要编译或可执行编译
注意:针对特殊扫描场景的工具(比如检查代码库下是否包含某些第三方依赖目录,结果不涉及单个代码文件的),无法对结果进行代码文件处理,可以通过设置以下环境变量,跳过一些通用的结果处理步骤,避免问题结果被过滤掉:
BLAME_TYPE=NO_BLAME
,跳过对代码行/代码文件进行文件责任人定位(结果非单个文件/代码行时使用)FILTER_TYPE=NO_VERSION_FILTER
,跳过检查问题路径(path字段)是否为已提交到代码库中的文件(结果非单个文件/代码行时使用)IGNORE_TYPE=NO_ISSUE_IGNORE
,跳过注释忽略处理(结果非单个文件/代码行时使用)添加工具依赖
添加完成后,会展示已添加的依赖方案:
工具依赖说明:
完成工具创建后,进入规则列表,为工具添加规则
填写规则信息
部分参数说明:
规则简介:简要描述规则发现的是什么问题,扫描结果中会作为问题标题展示
详细描述:可详细描述规则,以及规则的解决方式,建议附上解决案例 demo
解决方法:按照实际情况,说明该代码问题的解决方法,建议附上解决案例 demo
规则参数:如果不需要通过规则参数传递信息,可留空
提示
需要联系平台管理员协助操作,在管理入口
-节点管理
中进入需要配置的机器节点的工具进程配置
中,找到对应工具,勾选工具进程。
完成节点配置工具进程后,才能在项目中采用该工具进行分析。
进入到项目中,在分析方案
-代码检查
进行规则配置。
点击添加规则,找到对应工具规则进行添加。
添加完成后,启动分析,为了将规则应用到所有代码文件,建议启动一次全量分析(增量分析只会分析自上次扫描后变更的文件)。
默认自定义工具仅团队管理员可操作,团队内所有成员可使用。
团队管理员才能创建工具,添加工具规则等,具备该工具全部权限
团队内所有成员可使用该工具规则,如在规则配置中添加此工具规则,团队普通成员仅只读权限
工具希望全平台使用?
由于全平台使用的工具影响范围较大,建议团队先在团队内对工具进行充分测试,保障团队内工具的高有效性,如需全平台使用,需联系平台管理员进行申请
平台管理员需对此工具进行审核,在确保工具的高有效性下可将此工具权限调整为全平台可使用
腾讯云代码分析平台支持用户自助添加代码分析工具。
适用场景:自定义规则无法满足团队业务复杂需求,需要更多的代码逻辑来匹配目标代码的情况。通常需要团队业务方自行实现对应代码分析工具。
只需要几步操作:
扩展集成工具免责声明
被扩展集成进腾讯云代码分析系统的任何非官方工具,该类工具对于腾讯云代码分析系统等于黑盒,腾讯云代码分析系统不对该类工具负责,由该类工具方承担所有责任(包括但不限于分发被分析代码,产生代码以及相关信息泄漏)。
运行方式:支持命令行执行,比如 python run.py 或 run.exe,执行命令的工作目录为工具代码的根目录。
运行环境说明:
工具管理
-工具依赖
中查看,创建工具时可供选择,执行时会自动配置好依赖环境。SOURCE_DIR:要扫描的代码目录路径
+DIFF_FILES: 值为一个json文件路径,文件内容为增量扫描的文件列表(增量扫描时可用)
+SCAN_FILES: 值为一个json文件路径,文件内容为需要扫描的文件列表(增量或全量扫描均可用)
+TASK_REQUEST: 值为一个json文件路径,文件内容为当前扫描任务参数
+RESULT_DIR: 结果result.json输出的结果目录路径
+
工具命令声明
在工具仓库根目录下,添加一个tool.json
文件,声明工具的检查和扫描命令,比如:
{
+ "check_cmd": "python src/main.py check",
+ "run_cmd": "python src/main.py scan"
+}
+
参数说明:
check_cmd
: check_result.json
文件中,文件内容为{"usable": true}
或{"usable": false}
。run_cmd
: result.json
文件中。工具输出格式要求
RESULT_DIR
环境变量指定的目录下的result.json
文件中(Python 示例代码)import os
+import json
+result_dir = os.getenv("RESULT_DIR", os.getcwd())
+result_path = os.path.join(result_dir, "result.json")
+with open(result_path, "w") as fp:
+ json.dump(result, fp, indent=2)
+
result.json
文件格式如下:[
+ {
+ "path": "文件绝对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+ },
+ ...
+]
+
refs
字段说明:
非必需项,可无。该字段记录问题回溯路径信息。比如当前行的代码问题,是经过上下文的三行代码执行路径而导致的,可以将这三行的位置及提示信息,按顺序添加到 refs 数组中。
创建代码库,将工具源代码或编译打包后的可执行文件,提交到代码仓库中(建议提交到master分支,TCA默认拉取的是master分支)。
建议代码库中加入 README.md 文件,说明工具功能和维护人。
后续需要修改工具实现逻辑,可以直接更新代码库,TCA 平台在执行该工具时,会自动拉取最新工具代码版本。
进入工具管理页面,点击创建工具
填写工具信息
部分参数说明:
工具仓库地址,即前述步骤中提交的工具 git 代码库地址,默认拉取的是master分支,如果是其他分支,需要在仓库地址后加上#分支名
,比如:https://github.com/xxx/xxx.git#main
工具认证,授权拉取工具仓库的权限
执行命令,该命令会在工具根目录下执行
环境变量,工具执行所需的环境变量
License,如果是开源工具,填写工具遵循的开源协议,或者填写自研共建
是否为编译型工具,表示在使用该工具对用户代码进行分析时,是否要求代码需要编译或可执行编译
注意:针对特殊扫描场景的工具(比如检查代码库下是否包含某些第三方依赖目录,结果不涉及单个代码文件的),无法对结果进行代码文件处理,可以通过设置以下环境变量,跳过一些通用的结果处理步骤,避免问题结果被过滤掉:
BLAME_TYPE=NO_BLAME
,跳过对代码行/代码文件进行文件责任人定位(结果非单个文件/代码行时使用)FILTER_TYPE=NO_VERSION_FILTER
,跳过检查问题路径(path字段)是否为已提交到代码库中的文件(结果非单个文件/代码行时使用)IGNORE_TYPE=NO_ISSUE_IGNORE
,跳过注释忽略处理(结果非单个文件/代码行时使用)添加工具依赖
添加完成后,会展示已添加的依赖方案:
工具依赖说明:
完成工具创建后,进入规则列表,为工具添加规则
填写规则信息
部分参数说明:
规则简介:简要描述规则发现的是什么问题,扫描结果中会作为问题标题展示
详细描述:可详细描述规则,以及规则的解决方式,建议附上解决案例 demo
解决方法:按照实际情况,说明该代码问题的解决方法,建议附上解决案例 demo
规则参数:如果不需要通过规则参数传递信息,可留空
TIP
需要联系平台管理员协助操作,在管理入口
-节点管理
中进入需要配置的机器节点的工具进程配置
中,找到对应工具,勾选工具进程。
完成节点配置工具进程后,才能在项目中采用该工具进行分析。
进入到项目中,在分析方案
-代码检查
进行规则配置。
点击添加规则,找到对应工具规则进行添加。
添加完成后,启动分析,为了将规则应用到所有代码文件,建议启动一次全量分析(增量分析只会分析自上次扫描后变更的文件)。
默认自定义工具仅团队管理员可操作,团队内所有成员可使用。
团队管理员才能创建工具,添加工具规则等,具备该工具全部权限
团队内所有成员可使用该工具规则,如在规则配置中添加此工具规则,团队普通成员仅只读权限
工具希望全平台使用?
由于全平台使用的工具影响范围较大,建议团队先在团队内对工具进行充分测试,保障团队内工具的高有效性,如需全平台使用,需联系平台管理员进行申请
平台管理员需对此工具进行审核,在确保工具的高有效性下可将此工具权限调整为全平台可使用
进入正则工具添加自定义规则
进入工具管理页面,找到正则工具RegexScan
,并点击进入自定义规则列表页,点击添加规则按钮。
填写规则信息
规则参数填写说明(必要):
参数格式类似 ini 的格式, 也就是 key = value 的格式
【必要】 regex 参数,用于指定分析的正则表达式, 例如: regex = \\busleep\\s*\\(\\s*\\d{1,2}\\s*\\)
。
【必要】 msg 参数,用于展现 issue 说明, 例如: msg = 函数方法%s 已经废弃,请使用 xxx 方法
。
msg 中的“%s”使用 regex 中的 group(用“()"括起来的部分)一一匹配。
如果 regex 没有定义 group,则 msg 最多有一个%s, 并由整个 regex 匹配的字符串替代
如果 msg 里没有包含“%s”,则直接显示 msg
如果 msg 没有提供,则默认为“发现不规范代码:%s”(不建议使用默认格式,太笼统)
【可选填】 ignore_comment 参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如 ignore_comment=True
, 默认是 False
【可选填】 include 参数,用于将指定分析文件匹配范围,使用 unix 的文件匹配格式,多项使用英文分号;隔开。例如 include = path/to/dir;path/to/\\*.cpp
【可选填】 exclude 参数,用于指定不分析的文件。格式参考 include 参数。
将自定义规则添加到项目分析方案中
添加完成,可在分析方案-代码检查-规则配置中添加该自定义规则
进入正则工具添加自定义规则
进入工具管理页面,找到正则工具RegexScan
,并点击进入自定义规则列表页,点击添加规则按钮。
填写规则信息
规则参数填写说明(必要):
参数格式类似 ini 的格式, 也就是 key = value 的格式
【必要】 regex 参数,用于指定分析的正则表达式, 例如: regex = \\busleep\\s*\\(\\s*\\d{1,2}\\s*\\)
。
【必要】 msg 参数,用于展现 issue 说明, 例如: msg = 函数方法%s 已经废弃,请使用 xxx 方法
。
msg 中的“%s”使用 regex 中的 group(用“()"括起来的部分)一一匹配。
如果 regex 没有定义 group,则 msg 最多有一个%s, 并由整个 regex 匹配的字符串替代
如果 msg 里没有包含“%s”,则直接显示 msg
如果 msg 没有提供,则默认为“发现不规范代码:%s”(不建议使用默认格式,太笼统)
【可选填】 ignore_comment 参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如 ignore_comment=True
, 默认是 False
【可选填】 include 参数,用于将指定分析文件匹配范围,使用 unix 的文件匹配格式,多项使用英文分号;隔开。例如 include = path/to/dir;path/to/\\*.cpp
【可选填】 exclude 参数,用于指定不分析的文件。格式参考 include 参数。
将自定义规则添加到项目分析方案中
添加完成,可在分析方案-代码检查-规则配置中添加该自定义规则
WARNING
团队节点及标签说明
团队节点是团队注册并管理的私有节点。
团队标签用于关联团队内的节点机器与分析项目。
团队可以利用团队标签注册并使用团队节点。
在项目的分析方案中配置运行环境为团队标签后,才可将该项目的分析任务下发到对应的团队节点。
团队节点仅支持运行当前团队中的分析任务,节点可执行的任务范围取决于该节点的负责人权限:
团队因资源可靠性或项目敏感性,需使用私有机器资源
团队项目分析依赖特定机器环境(比如CPU架构、操作系统等)
以上场景,团队可接入专机资源作为团队节点,仅分析自己业务的代码库,以保证执行效率,保护源码安全,支持项目环境依赖等。
完成团队节点注册后,可以在当前团队节点管理
下看到对应的节点信息,同时需要进行节点配置
WARNING
首次注册团队节点,节点状态默认为不可用,需调整节点状态为“活跃”:
配置节点关联的工具进程:
TIP
CodeDog
标签为不同的系统类型(Linux、MacOS、Windows)建立标签,比如专属标签-Linux
、专属标签-Mac
等您可以创建一个团队标签,并配置到您的团队节点和您的分析方案中
创建团队标签。
配置团队节点所属标签。
配置分析方案运行环境。
可查看常驻节点状态,包含公共节点和团队节点。
可查看、编辑、删除常驻节点。
可配置节点工具进程。
可配置节点标签
注意
团队节点及标签说明
团队节点是团队注册并管理的私有节点。
团队标签用于关联团队内的节点机器与分析项目。
团队可以利用团队标签注册并使用团队节点。
在项目的分析方案中配置运行环境为团队标签后,才可将该项目的分析任务下发到对应的团队节点。
团队节点仅支持运行当前团队中的分析任务,节点可执行的任务范围取决于该节点的负责人权限:
团队因资源可靠性或项目敏感性,需使用私有机器资源
团队项目分析依赖特定机器环境(比如CPU架构、操作系统等)
以上场景,团队可接入专机资源作为团队节点,仅分析自己业务的代码库,以保证执行效率,保护源码安全,支持项目环境依赖等。
完成团队节点注册后,可以在当前团队节点管理
下看到对应的节点信息,同时需要进行节点配置
注意
首次注册团队节点,节点状态默认为不可用,需调整节点状态为“活跃”:
配置节点关联的工具进程:
提示
CodeDog
标签为不同的系统类型(Linux、MacOS、Windows)建立标签,比如专属标签-Linux
、专属标签-Mac
等您可以创建一个团队标签,并配置到您的团队节点和您的分析方案中
创建团队标签。
配置团队节点所属标签。
配置分析方案运行环境。
可查看常驻节点状态,包含公共节点和团队节点。
可查看、编辑、删除常驻节点。
可配置节点工具进程。
可配置节点标签
用于设定代码分析的范围,设定后,已经开启的代码检查、代码度量各项功能都会在指定的代码范围内生效。
目前支持正则表达式和通配符两种类型:
正则表达式
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用正则表达式格式,示例如下:
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/.*
+ 匹配根目录下的test目录:test/.*
+ 匹配所有_test.py后缀的文件:.*_test\\\\.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/.*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/.*
+
通配符
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用Unix通配符格式,示例如下
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/*
+ 匹配根目录下的test目录:test/*
+ 匹配所有_test.py后缀的文件:*_test.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/*
+
如果几个分析方案希望共享相同的路径过滤方案,可以通过导入导出路径配置的方式进行处理。
TIP
配置更改后,下次启动分析生效
全局 Issue 忽略状态同步
仅对代码检查生效。开启后,在 Issue 页面进行全局忽略操作时,其他利用该方案分析的分析项目在发现相同 Issue 时,会同步忽略该 Issue。否则不受全局 Issue 忽略状态同步影响。
用于设定代码分析的范围,设定后,已经开启的代码检查、代码度量各项功能都会在指定的代码范围内生效。
目前支持正则表达式和通配符两种类型:
正则表达式
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用正则表达式格式,示例如下:
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/.*
+ 匹配根目录下的test目录:test/.*
+ 匹配所有_test.py后缀的文件:.*_test\\\\.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/.*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/.*
+
通配符
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用Unix通配符格式,示例如下
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/*
+ 匹配根目录下的test目录:test/*
+ 匹配所有_test.py后缀的文件:*_test.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/*
+
如果几个分析方案希望共享相同的路径过滤方案,可以通过导入导出路径配置的方式进行处理。
提示
配置更改后,下次启动分析生效
全局 Issue 忽略状态同步
仅对代码检查生效。开启后,在 Issue 页面进行全局忽略操作时,其他利用该方案分析的分析项目在发现相同 Issue 时,会同步忽略该 Issue。否则不受全局 Issue 忽略状态同步影响。
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
-(1)将<Server IP地址>
替换成实际的serve ip(可包含端口号)。
填写以下必填项:token
,org_sid
,team_name
,source_dir
字段名 | 填写说明 |
---|---|
token | 从tca页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从tca项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他可选项按需填写。
提示
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
在client
目录下,执行以下命令:docker build -t tca-client .
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
提示
适用于深度体验,可以复用本地编译环境,使用编译型代码分析工具。
可能会有系统环境兼容问题。
python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)client
目录下python3 codepuppy.py localscan
提示
localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)个人中心
-个人令牌
-复制Tokenclient
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。管理入口
-节点管理
,可以看到当前在线的节点,可以修改节点名称、标签、负责人等信息。注意
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。注意
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
-(1)将<Server IP地址>
替换成实际的serve ip(可包含端口号)。
填写以下必填项:token
,org_sid
,team_name
,source_dir
字段名 | 填写说明 |
---|---|
token | 从tca页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从tca项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他可选项按需填写。
TIP
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
在client
目录下,执行以下命令:docker build -t tca-client .
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
TIP
适用于深度体验,可以复用本地编译环境,使用编译型代码分析工具。
可能会有系统环境兼容问题。
python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)client
目录下python3 codepuppy.py localscan
TIP
localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)个人中心
-个人令牌
-复制Tokenclient
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。管理入口
-节点管理
,可以看到当前在线的节点,可以修改节点名称、标签、负责人等信息。WARNING
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。WARNING
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。task_request
分发到能够执行该工具的机器task_name
字段,字段对应于工具的name
字段task_name
在client中的tool目录查找对应python启动脚本根据上述的任务机制添加工具需要做到以下几点
tca_ql_php
工具及其所含的规则tca_ql_php
工具tca_ql_php
对应的启动脚本是什么找到server/projects/main/apps/scan_conf/management/commands/open_source
目录
创建工具json文件,json文件名尽量对应工具名称方便查看
json文件内容为(以 tca_ql_php 为例)
[
+ {
+ "name": "tca_ql_php",
+ "display_name": "Hades_PHP(展示名称用于前端展示使用)",
+ "description": "工具描述",
+ "license": "工具license",
+ "libscheme_set": [], # 暂时不需要
+ "task_processes": [
+ "analyze",
+ "datahandle",
+ "compile"
+ ], # 工具进程,包含compile编译, analyze分析, datahandle数据处理
+ "scan_app": "codelint", # 代码分析统一为codelint
+ "scm_url": "", # 暂时为空
+ "run_cmd": "",
+ "envs": null, # 是否需要特殊环境,这里无需填写
+ "build_flag": false, # 是否需要编译命令才能运行
+ "checkrule_set": [ # 工具包含的规则
+ {
+ "real_name": "deser", # 规则名
+ "display_name": "反序列化漏洞", # 规则前端展示,考虑各工具规则名可能晦涩难懂,设置展示名称方便查找
+ "severity": "error", # 规则等级 从上到下分为 fatal, error, warning, info 四个等级
+ "category": "security", # 规则类别。correctness 功能 security安全 performance性能 usability可用性 accessibility无障碍化 i18n国际化 convention代码风格 other其他
+ "rule_title": "反序列化漏洞", # 一句话概括规则简介
+ "rule_params": null, # 规则参数
+ "languages": [ # 支持语言
+ "php"
+ ],
+ "solution": "", # 建议的解决方法
+ "owner": "",
+ "labels": [],
+ "description": "", # 规则详细介绍
+ }
+ ]
+ }
+]
+
server/projects/main/
目录执行python manage.py loadcheckers --dir open_source tca_ql_php
加载工具进入数据库tca_ql_php
工具; env_path 主要填写存放工具文件所在的相对目录,一般都存放/拉取在tools下,会在工具执行前加载到环境变量中提供使用
+[env_path]
+ZEUS_HOME : Zeus
+HADES_HOME : Hades
+
+; toolz_url
+[tool_url] 主要填写工具的git仓库,这里因为 tca_ql_php 直接使用tools下的目录所以不用再进行额外拉取也无需再写
+CPPCHECK : \${base_value:git_url}/linux-cppcheck-1.78
+
+; 各工具配置 以 tca_ql_php 为例
+; env_path 填写上面需要加载的环境变量
+; env_value 通用环境变量,一般无需填写如果有需求需要现在 [env_value] 中定义好再填写
+; path 工具所在目录填写上面的定义
+; tool_url 工具git仓库,使用本地相对目录故为空
+[tca_ql_php]
+env_path : ZEUS_HOME;HADES_HOME
+env_value :
+path : \${env_path:ZEUS_HOME};\${env_path:HADES_HOME}
+tool_url :
+
+
tca_ql_php
对应的启动脚本是什么以上述步骤在client/tool
目录添加脚本tca_ql_php.py
作为启动脚本 注:启动脚本必须与工具名称相同
编写脚本
以tca_ql_php
为例
+from task.codelintmodel import CodeLintModel
+from util.logutil import LogPrinter
+from util.subprocc import SubProcController
+
+logger = LogPrinter()
+
+
+class TcaQlPHP(CodeLintModel):
+ # 代码分析工具集成基类CodeLintModel
+ def __init__(self, params):
+ logger.info("找到工具了Q_Q")
+ super().__init__(params)
+
+ def compile(self, params):
+ logger.info("开始编译了Q_Q")
+ build_cmd = params.get('build_cmd', None) # 从params中获取编译命令, params内容可以在最后附录查看
+ lang = "php"
+ do_some_things()
+
+ def analyze(self, params):
+ logger.info("开始分析了Q_Q")
+ lang = "php"
+ HADES_HOME = envs.get("HADES_HOME", None)
+ output_json = "result.json"
+ sp = SubProcController(
+ command=["Hades", "analyze", "test.php", "-o", output_json],
+ cwd=HADES_HOME,
+ stdout_line_callback=subprocc_log,
+ stderr_line_callback=subprocc_log,
+ )
+ sp.wait() # 执行工具分析命令
+ issues = []
+ # 工具结果输出到output_json,具体工具可能有所不同
+ if os.path.exists(output_json):
+ with open(output_json, "r") as result_reader:
+ result = json.load(result_reader)
+ issues.extend(result)
+ return issues
+
+tool = TcaQlPHP # 必须,必须包含tool变量并且为该工具的类
+
task_request
中的task_params
字段,具体字段将在最后附录进行说明{
+ "path": "文件相对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+}
+说明:
+ refs:可选,记录问题回溯路径信息。比如当前文件的回溯路径其他的3行代码,可以将这三行的路径及提示信息,按顺序添加到refs数组中。
+
如果有意公开您添加的工具欢迎发起PR
注:别忘了puppy-tool-config 也需要PR
字段 | 说明 | 类型 |
---|---|---|
scan_languages | 语言 | 字符串列表如 ["python", "php"] |
pre_cmd | 编译前置命令 | 字符串 |
build_cmd | 编译命令 | 字符串 |
envs | 额外环境变量 | 字符串 |
scm_last_revision | 上次成功分析的代码版本,增量使用 | 字符串 |
incr_scan | 是否为增量分析 | bool |
rules | 规则名称列表,只有规则名 | 字符串列表 |
rule_list | 详细的规则列表包含规则名和规则参数等 | 字典列表 |
checktool | 工具详细信息,执行一般用不到 | 字典 |
path_filters | 过滤路径 | 字典 |
scm_url | 代码库url | 字符串 |
source_dir | 代码库本地目录 | 字符串 |
work_dir | 本次任务的work_dir目录 | 字符串 |
project_id | 分析项目id | int |
repo_id | 仓库id | int |
task_id | 任务id | int |
job_id | 本次分析的id | int |
task_request
分发到能够执行该工具的机器task_name
字段,字段对应于工具的name
字段task_name
在client中的tool目录查找对应python启动脚本根据上述的任务机制添加工具需要做到以下几点
tca_ql_php
工具及其所含的规则tca_ql_php
工具tca_ql_php
对应的启动脚本是什么找到server/projects/main/apps/scan_conf/management/commands/open_source
目录
创建工具json文件,json文件名尽量对应工具名称方便查看
json文件内容为(以 tca_ql_php 为例)
[
+ {
+ "name": "tca_ql_php",
+ "display_name": "Hades_PHP(展示名称用于前端展示使用)",
+ "description": "工具描述",
+ "license": "工具license",
+ "libscheme_set": [], # 暂时不需要
+ "task_processes": [
+ "analyze",
+ "datahandle",
+ "compile"
+ ], # 工具进程,包含compile编译, analyze分析, datahandle数据处理
+ "scan_app": "codelint", # 代码分析统一为codelint
+ "scm_url": "", # 暂时为空
+ "run_cmd": "",
+ "envs": null, # 是否需要特殊环境,这里无需填写
+ "build_flag": false, # 是否需要编译命令才能运行
+ "checkrule_set": [ # 工具包含的规则
+ {
+ "real_name": "deser", # 规则名
+ "display_name": "反序列化漏洞", # 规则前端展示,考虑各工具规则名可能晦涩难懂,设置展示名称方便查找
+ "severity": "error", # 规则等级 从上到下分为 fatal, error, warning, info 四个等级
+ "category": "security", # 规则类别。correctness 功能 security安全 performance性能 usability可用性 accessibility无障碍化 i18n国际化 convention代码风格 other其他
+ "rule_title": "反序列化漏洞", # 一句话概括规则简介
+ "rule_params": null, # 规则参数
+ "languages": [ # 支持语言
+ "php"
+ ],
+ "solution": "", # 建议的解决方法
+ "owner": "",
+ "labels": [],
+ "description": "", # 规则详细介绍
+ }
+ ]
+ }
+]
+
server/projects/main/
目录执行python manage.py loadcheckers --dir open_source tca_ql_php
加载工具进入数据库tca_ql_php
工具; env_path 主要填写存放工具文件所在的相对目录,一般都存放/拉取在tools下,会在工具执行前加载到环境变量中提供使用
+[env_path]
+ZEUS_HOME : Zeus
+HADES_HOME : Hades
+
+; toolz_url
+[tool_url] 主要填写工具的git仓库,这里因为 tca_ql_php 直接使用tools下的目录所以不用再进行额外拉取也无需再写
+CPPCHECK : \${base_value:git_url}/linux-cppcheck-1.78
+
+; 各工具配置 以 tca_ql_php 为例
+; env_path 填写上面需要加载的环境变量
+; env_value 通用环境变量,一般无需填写如果有需求需要现在 [env_value] 中定义好再填写
+; path 工具所在目录填写上面的定义
+; tool_url 工具git仓库,使用本地相对目录故为空
+[tca_ql_php]
+env_path : ZEUS_HOME;HADES_HOME
+env_value :
+path : \${env_path:ZEUS_HOME};\${env_path:HADES_HOME}
+tool_url :
+
+
tca_ql_php
对应的启动脚本是什么以上述步骤在client/tool
目录添加脚本tca_ql_php.py
作为启动脚本 注:启动脚本必须与工具名称相同
编写脚本
以tca_ql_php
为例
+from task.codelintmodel import CodeLintModel
+from util.logutil import LogPrinter
+from util.subprocc import SubProcController
+
+logger = LogPrinter()
+
+
+class TcaQlPHP(CodeLintModel):
+ # 代码分析工具集成基类CodeLintModel
+ def __init__(self, params):
+ logger.info("找到工具了Q_Q")
+ super().__init__(params)
+
+ def compile(self, params):
+ logger.info("开始编译了Q_Q")
+ build_cmd = params.get('build_cmd', None) # 从params中获取编译命令, params内容可以在最后附录查看
+ lang = "php"
+ do_some_things()
+
+ def analyze(self, params):
+ logger.info("开始分析了Q_Q")
+ lang = "php"
+ HADES_HOME = envs.get("HADES_HOME", None)
+ output_json = "result.json"
+ sp = SubProcController(
+ command=["Hades", "analyze", "test.php", "-o", output_json],
+ cwd=HADES_HOME,
+ stdout_line_callback=subprocc_log,
+ stderr_line_callback=subprocc_log,
+ )
+ sp.wait() # 执行工具分析命令
+ issues = []
+ # 工具结果输出到output_json,具体工具可能有所不同
+ if os.path.exists(output_json):
+ with open(output_json, "r") as result_reader:
+ result = json.load(result_reader)
+ issues.extend(result)
+ return issues
+
+tool = TcaQlPHP # 必须,必须包含tool变量并且为该工具的类
+
task_request
中的task_params
字段,具体字段将在最后附录进行说明{
+ "path": "文件相对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+}
+说明:
+ refs:可选,记录问题回溯路径信息。比如当前文件的回溯路径其他的3行代码,可以将这三行的路径及提示信息,按顺序添加到refs数组中。
+
如果有意公开您添加的工具欢迎发起PR
注:别忘了puppy-tool-config 也需要PR
字段 | 说明 | 类型 |
---|---|---|
scan_languages | 语言 | 字符串列表如 ["python", "php"] |
pre_cmd | 编译前置命令 | 字符串 |
build_cmd | 编译命令 | 字符串 |
envs | 额外环境变量 | 字符串 |
scm_last_revision | 上次成功分析的代码版本,增量使用 | 字符串 |
incr_scan | 是否为增量分析 | bool |
rules | 规则名称列表,只有规则名 | 字符串列表 |
rule_list | 详细的规则列表包含规则名和规则参数等 | 字典列表 |
checktool | 工具详细信息,执行一般用不到 | 字典 |
path_filters | 过滤路径 | 字典 |
scm_url | 代码库url | 字符串 |
source_dir | 代码库本地目录 | 字符串 |
work_dir | 本次任务的work_dir目录 | 字符串 |
project_id | 分析项目id | int |
repo_id | 仓库id | int |
task_id | 任务id | int |
job_id | 本次分析的id | int |
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url_or_name | str | 代码库地址或者名称,支持模糊匹配 |
scm_url | str | 代码库仓库匹配 |
scope | str | 过滤范围(my/subscribed/related_me),my表示我创建的,subscribed表示我关注的,related_me表示我有权限的 |
{
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ }
+ ]
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/
+
{
+ "data":{
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/branches/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "branch": "master",
+ "schemes": [
+ {
+ "project_id": 1,
+ "scan_scheme_id": 1,
+ "scan_scheme_name": "默认"
+ }
+ ]
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
branch | str | 分支名称 |
scan_scheme | int | 扫描方案名称 |
scan_scheme__status | int | 扫描方案状态,1为活跃,2为废弃 |
branch_or_scheme | str | 分支名称/扫描方案名称 |
status | int | 项目状态筛选,1表示活跃,2表示失活,3表示关闭 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "codedog_web",
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
scan_scheme_id | int | 当前代码库的扫描方案编号 |
global_scheme_id | int | 扫描方案模板编号 |
custom_scheme_name | str | 自定义方案名称 |
branch | str | 分支 |
created_from | str | 创建渠道,用于区分不同运行场景 |
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/<project_id>/
+
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 扫描方案名称 |
status | int | 扫描方案状态,1为活跃,2为废弃 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/copyscheme/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 扫描方案名称 |
ref_scheme | int | 参照扫描方案编号 |
{
+ "data": {
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
{
+ "data": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
参数 | 类型 | 描述 |
---|---|---|
languages | list | 代码语言 |
tag | str | 执行标签,目前只支持 CodeDog_Linux |
name | str | 方案名称 |
description | str | 方案描述 |
default_flag | bool | 默认方案标志,一个代码库只能有一个默认方案 |
job_runtime_limit | int | 任务执行超时时间,默认为600分钟 |
ignore_merged_issue | bool | 忽略合入的问题 |
ignore_branch_issue | str | 过滤参考分支引入的问题 |
ignore_submodule_clone | bool | 不拉取子模块扫描,True表示不拉取,False表示拉取 |
ignore_submodule_issue | bool | 忽略子模块引入的问题,True表示忽略,False表示不忽略 |
issue_global_ignore | bool | 问题全局忽略 |
daily_save | bool | 每次扫描原始数据存储,默认存储7天 |
lfs_flag | bool | 拉取lfs模块开关 |
issue_revision_merge_flag | bool | "是否开启Issue按引入版本号聚合开关 |
status | int | 方案状态,1表示活跃,2表示废弃 |
同查看指定代码库的指定扫描方案的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
{
+ "data": {
+ "id": 1,
+ "enabled": true,
+ "checkprofile": {
+ "id": 1,
+ "profile_type": 1,
+ "custom_checkpackage": 1,
+ "checkpackages": [
+ 1
+ ]
+ },
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
参数 | 类型 | 描述 |
---|---|---|
enabled | bool | 是否开启代码扫描 |
同指定代码库的指定方案的代码扫描配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
{
+ "data": {
+ "id": 1,
+ "cc_scan_enabled": false,
+ "min_ccn": 20,
+ "dup_scan_enabled": false,
+ "dup_block_length_min": 120,
+ "dup_block_length_max": null,
+ "dup_min_dup_times": 2,
+ "dup_max_dup_times": null,
+ "dup_min_midd_rate": 5,
+ "dup_min_high_rate": 11,
+ "dup_min_exhi_rate": 20,
+ "dup_issue_limit": 1000,
+ "cloc_scan_enabled": false,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
参数 | 类型 | 描述 |
---|---|---|
cc_scan_enabled | bool | 圈复杂度扫描开关 |
min_ccn | int | 最小圈复杂度 |
dup_scan_enabled | bool | 重复代码扫描开关 |
dup_block_length_min | int | 重复块最小长度 |
dup_block_length_max | int | 重复块最大长度 |
dup_max_dup_times | int | 最大重复次数 |
dup_min_midd_rate | int | 中风险最小重复率 |
dup_min_high_rate | int | 高风险最小重复率 |
dup_min_exhi_rate | int | 极高风险风险最小重复率 |
dup_issue_limit | int | 上报重复代码块数上限 |
cloc_scan_enabled | boolean | 代码统计扫描开关 |
同指定代码库的指定方案的代码度量配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "dir_path": "test/*",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 指定过滤路径 |
path_type | int | 路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
{
+ "data": {
+ "id": 1,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 指定过滤路径 |
path_type | int | 路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
DELETE /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
无
`,97),s=[u];function a(l,o){return t(),i("div",null,s)}const v=e(d,[["render",a],["__file","项目管理模块接口.html.vue"]]);export{v as default}; diff --git "a/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-3cef7840.js" "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-3cef7840.js" new file mode 100644 index 000000000..503944193 --- /dev/null +++ "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-3cef7840.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-bb3cf496","path":"/en/api/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E6%A8%A1%E5%9D%97%E6%8E%A5%E5%8F%A3.html","title":"项目管理模块","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"查看指定代码库的指定分析项目列表","slug":"查看指定代码库的指定分析项目列表","link":"#查看指定代码库的指定分析项目列表","children":[]},{"level":2,"title":"查看指定代码库详情","slug":"查看指定代码库详情","link":"#查看指定代码库详情","children":[]},{"level":2,"title":"查看指定代码库的不同分支的列表接口","slug":"查看指定代码库的不同分支的列表接口","link":"#查看指定代码库的不同分支的列表接口","children":[]},{"level":2,"title":"查看指定代码库的分析项目列表","slug":"查看指定代码库的分析项目列表","link":"#查看指定代码库的分析项目列表","children":[]},{"level":2,"title":"创建指定代码库的指定分析项目","slug":"创建指定代码库的指定分析项目","link":"#创建指定代码库的指定分析项目","children":[]},{"level":2,"title":"查看指定代码库的指定分析项目","slug":"查看指定代码库的指定分析项目","link":"#查看指定代码库的指定分析项目","children":[]},{"level":2,"title":"查看指定代码库的扫描方案列表","slug":"查看指定代码库的扫描方案列表","link":"#查看指定代码库的扫描方案列表","children":[]},{"level":2,"title":"使用指定扫描方案模板创建指定代码库的扫描方案","slug":"使用指定扫描方案模板创建指定代码库的扫描方案","link":"#使用指定扫描方案模板创建指定代码库的扫描方案","children":[]},{"level":2,"title":"查看指定代码库的指定扫描方案","slug":"查看指定代码库的指定扫描方案","link":"#查看指定代码库的指定扫描方案","children":[]},{"level":2,"title":"更新指定代码库的指定方案","slug":"更新指定代码库的指定方案","link":"#更新指定代码库的指定方案","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的代码扫描配置","slug":"查看指定代码库的扫描方案的代码扫描配置","link":"#查看指定代码库的扫描方案的代码扫描配置","children":[]},{"level":2,"title":"更新指定代码库的指定方案的代码扫描配置","slug":"更新指定代码库的指定方案的代码扫描配置","link":"#更新指定代码库的指定方案的代码扫描配置","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的代码度量配置","slug":"查看指定代码库的扫描方案的代码度量配置","link":"#查看指定代码库的扫描方案的代码度量配置","children":[]},{"level":2,"title":"更新指定代码库的指定方案的代码度量配置","slug":"更新指定代码库的指定方案的代码度量配置","link":"#更新指定代码库的指定方案的代码度量配置","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的过滤路径列表","slug":"查看指定代码库的扫描方案的过滤路径列表","link":"#查看指定代码库的扫描方案的过滤路径列表","children":[]},{"level":2,"title":"创建指定代码库的指定方案的过滤路径列表","slug":"创建指定代码库的指定方案的过滤路径列表","link":"#创建指定代码库的指定方案的过滤路径列表","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的指定过滤路径","slug":"查看指定代码库的扫描方案的指定过滤路径","link":"#查看指定代码库的扫描方案的指定过滤路径","children":[]},{"level":2,"title":"更新指定代码库的指定方案的指定过滤路径","slug":"更新指定代码库的指定方案的指定过滤路径","link":"#更新指定代码库的指定方案的指定过滤路径","children":[]},{"level":2,"title":"删除指定代码库的指定方案的指定过滤路径","slug":"删除指定代码库的指定方案的指定过滤路径","link":"#删除指定代码库的指定方案的指定过滤路径","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"en/api/项目管理模块接口.md"}');export{l as data}; diff --git "a/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-73b341fb.js" "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-73b341fb.js" new file mode 100644 index 000000000..edeec9f93 --- /dev/null +++ "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-73b341fb.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-c525ae0c","path":"/zh/api/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E6%A8%A1%E5%9D%97%E6%8E%A5%E5%8F%A3.html","title":"项目管理模块","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"查看指定代码库的指定分析项目列表","slug":"查看指定代码库的指定分析项目列表","link":"#查看指定代码库的指定分析项目列表","children":[]},{"level":2,"title":"查看已创建的授权信息","slug":"查看已创建的授权信息","link":"#查看已创建的授权信息","children":[]},{"level":2,"title":"登记代码库","slug":"登记代码库","link":"#登记代码库","children":[]},{"level":2,"title":"查看指定代码库详情","slug":"查看指定代码库详情","link":"#查看指定代码库详情","children":[]},{"level":2,"title":"查看指定代码库的不同分支的列表接口","slug":"查看指定代码库的不同分支的列表接口","link":"#查看指定代码库的不同分支的列表接口","children":[]},{"level":2,"title":"查看指定代码库的分析项目列表","slug":"查看指定代码库的分析项目列表","link":"#查看指定代码库的分析项目列表","children":[]},{"level":2,"title":"创建指定代码库的指定分析项目","slug":"创建指定代码库的指定分析项目","link":"#创建指定代码库的指定分析项目","children":[]},{"level":2,"title":"查看指定代码库的指定分析项目","slug":"查看指定代码库的指定分析项目","link":"#查看指定代码库的指定分析项目","children":[]},{"level":2,"title":"查看指定代码库的扫描方案列表","slug":"查看指定代码库的扫描方案列表","link":"#查看指定代码库的扫描方案列表","children":[]},{"level":2,"title":"查看指定代码库的指定扫描方案","slug":"查看指定代码库的指定扫描方案","link":"#查看指定代码库的指定扫描方案","children":[]},{"level":2,"title":"更新指定代码库的指定方案","slug":"更新指定代码库的指定方案","link":"#更新指定代码库的指定方案","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的代码扫描配置","slug":"查看指定代码库的扫描方案的代码扫描配置","link":"#查看指定代码库的扫描方案的代码扫描配置","children":[]},{"level":2,"title":"更新指定代码库的指定方案的代码扫描配置","slug":"更新指定代码库的指定方案的代码扫描配置","link":"#更新指定代码库的指定方案的代码扫描配置","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的代码度量配置","slug":"查看指定代码库的扫描方案的代码度量配置","link":"#查看指定代码库的扫描方案的代码度量配置","children":[]},{"level":2,"title":"更新指定代码库的指定方案的代码度量配置","slug":"更新指定代码库的指定方案的代码度量配置","link":"#更新指定代码库的指定方案的代码度量配置","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的过滤路径列表","slug":"查看指定代码库的扫描方案的过滤路径列表","link":"#查看指定代码库的扫描方案的过滤路径列表","children":[]},{"level":2,"title":"创建指定代码库的指定方案的过滤路径列表","slug":"创建指定代码库的指定方案的过滤路径列表","link":"#创建指定代码库的指定方案的过滤路径列表","children":[]},{"level":2,"title":"查看指定代码库的扫描方案的指定过滤路径","slug":"查看指定代码库的扫描方案的指定过滤路径","link":"#查看指定代码库的扫描方案的指定过滤路径","children":[]},{"level":2,"title":"更新指定代码库的指定方案的指定过滤路径","slug":"更新指定代码库的指定方案的指定过滤路径","link":"#更新指定代码库的指定方案的指定过滤路径","children":[]},{"level":2,"title":"删除指定代码库的指定方案的指定过滤路径","slug":"删除指定代码库的指定方案的指定过滤路径","link":"#删除指定代码库的指定方案的指定过滤路径","children":[]}],"git":{"updatedTime":1725872649000,"contributors":[{"name":"Jero","email":"lingh0927@hotmail.com","commits":1}]},"filePathRelative":"zh/api/项目管理模块接口.md"}');export{l as data}; diff --git "a/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-eba8e5dc.js" "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-eba8e5dc.js" new file mode 100644 index 000000000..d832098cc --- /dev/null +++ "b/assets/\351\241\271\347\233\256\347\256\241\347\220\206\346\250\241\345\235\227\346\216\245\345\217\243.html-eba8e5dc.js" @@ -0,0 +1,628 @@ +import{_ as e,o as t,c as i,e as n}from"./app-2a91d8ab.js";const d={},u=n(`GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url_or_name | str | 选填,代码库地址或者名称,支持模糊匹配 |
scm_url | str | 选填,代码库仓库匹配 |
scope | str | 选填,过滤范围(my/subscribed/related_me),my表示我创建的,subscribed表示我关注的,related_me表示我有权限的 |
{
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ }
+ ]
+}
+
GET /server/main/api/authen/scmallaccounts/
+
{
+ "data": {
+ "ssh": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "indentity": "xxx",
+ "display_scm_platform": "tgit",
+ "name": "gerrit",
+ "scm_platform": 1,
+ "scm_platform_desc": null
+ }
+ ],
+ "account": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "display_scm_platform": "tgit",
+ "scm_username": "CodeDog",
+ "scm_platform": 1,
+ "scm_platform_desc": null
+ }
+ ],
+ "oauth": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "scm_platform_name": "tgit"
+ }
+ ],
+ }
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url | str | 必填,代码库地址 |
scm_type | str | 必填,git或svn |
ssh_url | str | 选填,代码库SSH地址 |
name | str | 选填, 代码库名称 |
scm_auth | dict | 选填,代码库授权 |
例子:
{
+ "scm_url": "https://github.com/Tencent/CodeAnalysis",
+ "scm_type": "git",
+ "name": "CodeAnalysis",
+ "scm_auth": {
+ # 通过 查看已创建的授权信息 接口获取到对应的凭证id,scm_account、scm_oauth、scm_ssh 只需填一个
+ "scm_account": account_id,
+ "scm_ssh": ssh_id,
+ "scm_oauth": oauth_id
+ }
+}
+
{
+ "data":{
+ "id": 1,
+ "name": "CodeAnalysis",
+ "scm_url": "http://github.com/Tencent/CodeAnalysis",
+ "scm_type": "git",
+ "branch_count": 0,
+ "scheme_count": 0,
+ "job_count": 0,
+ "created_time": "2022-10-22T16:30:30+08:00",
+ "recent_active": {
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/
+
{
+ "data":{
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/branches/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "branch": "master",
+ "schemes": [
+ {
+ "project_id": 1,
+ "scan_scheme_id": 1,
+ "scan_scheme_name": "默认"
+ }
+ ]
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
branch | str | 选填,分支名称 |
scan_scheme | int | 选填,扫描方案名称 |
scan_scheme__status | int | 选填,扫描方案状态,1为活跃,2为废弃 |
branch_or_scheme | str | 选填,分支名称/扫描方案名称 |
status | int | 选填,项目状态筛选,1表示活跃,2表示失活,3表示关闭 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "codedog_web",
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
scan_scheme_id | int | 和global_scheme_id二选一进行填写,当前代码库的扫描方案编号 |
global_scheme_id | int | 和scan_scheme_id二选一进行填写,扫描方案模板编号 |
custom_scheme_name | str | 选填,自定义方案名称 |
branch | str | 必填,分支 |
created_from | str | 选填,创建渠道,用于区分不同运行场景 |
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/
+
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 选填,扫描方案名称 |
status | int | 选填,扫描方案状态,1为活跃,2为废弃 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
{
+ "data": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
参数 | 类型 | 描述 |
---|---|---|
languages | list | 选填,代码语言 |
tag | str | 选填,执行标签,目前只支持 CodeDog_Linux |
name | str | 必填,方案名称 |
description | str | 选填,方案描述 |
default_flag | bool | 选填,默认方案标志,一个代码库只能有一个默认方案 |
job_runtime_limit | int | 选填,任务执行超时时间,默认为600分钟 |
ignore_merged_issue | bool | 选填,忽略合入的问题 |
ignore_branch_issue | str | 选填,过滤参考分支引入的问题 |
ignore_submodule_clone | bool | 选填,不拉取子模块扫描,True表示不拉取,False表示拉取 |
ignore_submodule_issue | bool | 选填,忽略子模块引入的问题,True表示忽略,False表示不忽略 |
issue_global_ignore | bool | 选填,问题全局忽略 |
daily_save | bool | 选填,每次扫描原始数据存储,默认存储7天 |
lfs_flag | bool | 选填,拉取lfs模块开关 |
issue_revision_merge_flag | bool | 选填,"是否开启Issue按引入版本号聚合开关 |
status | int | 选填,方案状态,1表示活跃,2表示废弃 |
同查看指定代码库的指定扫描方案的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
{
+ "data": {
+ "id": 1,
+ "enabled": true,
+ "checkprofile": {
+ "id": 1,
+ "profile_type": 1,
+ "custom_checkpackage": 1,
+ "checkpackages": [
+ 1
+ ]
+ },
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
参数 | 类型 | 描述 |
---|---|---|
enabled | bool | 必填,是否开启代码扫描 |
同指定代码库的指定方案的代码扫描配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
{
+ "data": {
+ "id": 1,
+ "cc_scan_enabled": false,
+ "min_ccn": 20,
+ "dup_scan_enabled": false,
+ "dup_block_length_min": 120,
+ "dup_block_length_max": null,
+ "dup_min_dup_times": 2,
+ "dup_max_dup_times": null,
+ "dup_min_midd_rate": 5,
+ "dup_min_high_rate": 11,
+ "dup_min_exhi_rate": 20,
+ "dup_issue_limit": 1000,
+ "cloc_scan_enabled": false,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
参数 | 类型 | 描述 |
---|---|---|
cc_scan_enabled | bool | 选填,圈复杂度扫描开关 |
min_ccn | int | 选填,最小圈复杂度 |
dup_scan_enabled | bool | 选填,重复代码扫描开关 |
dup_block_length_min | int | 选填,重复块最小长度 |
dup_block_length_max | int | 选填,重复块最大长度 |
dup_max_dup_times | int | 选填,最大重复次数 |
dup_min_midd_rate | int | 选填,中风险最小重复率 |
dup_min_high_rate | int | 选填,高风险最小重复率 |
dup_min_exhi_rate | int | 选填,极高风险风险最小重复率 |
dup_issue_limit | int | 选填,上报重复代码块数上限 |
cloc_scan_enabled | boolean | 选填,代码统计扫描开关 |
同指定代码库的指定方案的代码度量配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "dir_path": "test/*",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 必填,指定过滤路径 |
path_type | int | 选填,路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 选填,扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
{
+ "data": {
+ "id": 1,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 必填,指定过滤路径 |
path_type | int | 选填,路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 选填,扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
DELETE /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
无
`,103),s=[u];function a(l,o){return t(),i("div",null,s)}const v=e(d,[["render",a],["__file","项目管理模块接口.html.vue"]]);export{v as default}; diff --git a/en/advanced/install_mysql_on_centos.html b/en/advanced/install_mysql_on_centos.html new file mode 100644 index 000000000..ad655d145 --- /dev/null +++ b/en/advanced/install_mysql_on_centos.html @@ -0,0 +1,61 @@ + + + + + + + + +本文档仅供参考,不适用于正式环境部署,正式环境建议使用专业的MySQL服务(比如腾讯云的MySQL产品)
CentOS 7.3 版本
wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm
+yum localinstall mysql57-community-release-el7-11.noarch.rpm
+
安装成功后,查看MySQL版本:
yum repolist all | grep mysql
+
输出结果:
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community 禁用
+mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community - 禁用
+mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community 禁用
+mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community - 禁用
+!mysql-connectors-community/x86_64 MySQL Connectors Community 启用: 221
+mysql-connectors-community-source MySQL Connectors Community - S 禁用
+!mysql-tools-community/x86_64 MySQL Tools Community 启用: 135
+mysql-tools-community-source MySQL Tools Community - Source 禁用
+mysql-tools-preview/x86_64 MySQL Tools Preview 禁用
+mysql-tools-preview-source MySQL Tools Preview - Source 禁用
+mysql55-community/x86_64 MySQL 5.5 Community Server 禁用
+mysql55-community-source MySQL 5.5 Community Server - S 禁用
+mysql56-community/x86_64 MySQL 5.6 Community Server 禁用
+mysql56-community-source MySQL 5.6 Community Server - S 禁用
+!mysql57-community/x86_64 MySQL 5.7 Community Server 启用: 544
+mysql57-community-source MySQL 5.7 Community Server - S 禁用
+mysql80-community/x86_64 MySQL 8.0 Community Server 禁用
+mysql80-community-source MySQL 8.0 Community Server - S 禁用
+
yum install mysql-community-server
+
1.如遇以下报错,可尝试运行
yum install mysql-community-server --nogpgcheck
安装
Public key for mysql-community-libs-compat-5.7.37-1.el7.x86_64.rpm is not installed
Failing package is: mysql-community-libs-compat-5.7.37-1.el7.x86_64 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
2.如遇以下报错,可执行yum module disable mysql
后重试安装
All matches were filtered out by modular filtering for argument: mysql-community-serve
Error: Unable to find a match: mysql-community-server
安装好的MySQL配置文件路径是/etc/my.cnf
,这里可以根据需要调整,比如可以调整:
systemctl start mysqld
+
确认MySQL正常启动
systemctl status mysqld
+
查看生成 MySQL root用户临时密码:
grep 'temporary password' /var/log/mysqld.log
+
连接MySQL服务
$ mysql -uroot -p
+# 输出上述查询到的临时密码
+
修改root用户的密码(下面是改成 Password@2021
,这里根据自行需要进行调整):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Password@2021';
+
安装编译打包需要的工具
yum -y install gcc zlib-devel pcre-devel bzip2-devel openssl-devel readline-devel
+
Ubuntu:
apt install gcc libssl-dev zlib1g-dev libpcre3-dev libbz2-dev libreadline-dev
wget http://nginx.org/download/nginx-1.20.2.tar.gz
+
# 解压
+$ tar zvxf nginx-1.20.2.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/nginx-1.20.2
+
+# 配置
+$ ./configure \
+--sbin-path=/usr/local/nginx/nginx \
+--conf-path=/etc/nginx/nginx.conf \
+--pid-path=/run/nginx.pid \
+--with-stream \
+--with-http_ssl_module --with-http_v2_module --with-http_auth_request_module
+
+# 构建nginx
+$ make -j4
+$ make install
+$ make clean
+
+# 建立软链
+$ ln -s /usr/local/nginx/nginx /usr/local/bin/nginx
+
mkdir /etc/nginx/conf.d/
+vi /etc/nginx/nginx.conf
+
检查nginx.conf
配置文件:
pid /run/nginx.pid
,如果缺失或被注释则加上,加上位置如下所示:include conf.d/*.conf;
,如果缺失则加上,加上位置如下所示:# ...省略内容
+#pid logs/nginx.pid; # 默认有的
+pid /run/nginx.pid;
+
+events {
+ # ...省略内容
+}
+
+# ...省略内容
+
+http {
+ # ...省略内容
+ #
+ include conf.d/*.conf;
+ server {
+ # ...省略内容
+ }
+}
+
+
后续可以将nginx配置文件放置到/etc/nginx/conf.d/
目录下
vim /usr/lib/systemd/system/nginx.service
+
输入以下内容:
[Unit]
+Description=The nginx HTTP and reverse proxy server
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/run/nginx.pid
+# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
+# SELinux context. This might happen when running `nginx -t` from the cmdline.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
+ExecStartPre=/bin/rm -f /run/nginx.pid
+ExecStartPre=/usr/local/bin/nginx -t
+ExecStart=/usr/local/bin/nginx
+ExecReload=/usr/local/bin/nginx -s reload
+ExecStop=/usr/local/bin/nginx -s stop
+KillSignal=SIGQUIT
+TimeoutStopSec=5
+KillMode=process
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动nginx:
systemctl start nginx
+
开机自动启动nginx:
systemctl enable nginx
+
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/bin/python
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
以下脚本内容是上面的步骤集合,省去了复制粘贴的重复动作。
install_py37.sh
,写入以下 shell 脚本chmox +x install_py37.sh
./install_py37.sh
#!/bin/env bash
+
+## 下载 Python 源码,如果已下载源码在脚本当前目录下,可注释跳过下载步骤
+wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
+## 安装编译依赖组件
+yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
+## 解压安装
+# 解压到/usr/local/src目录
+tar zvxf Python-3.7.12.tgz -C /usr/local/src
+cd /usr/local/src/Python-3.7.12
+# 编译前配置
+./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+make -j8
+# 安装Python
+make install
+# 清理编译产出的中间文件
+make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+ldconfig
+
+## 检查Python版本是否安装成功
+echo -e "\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\033[0m"
+python --version
+echo -e "\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\033[0m"
+
+## pypi下载源配置
+mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
注:当前Ubuntu版本为18.04
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
apt-get update
+apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev wget libbz2-dev tk-dev gcc make
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
安装编译打包需要的工具
yum install -y gcc make tcl wget
+
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
+
# 解压
+$ tar zvxf redis-5.0.4.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/redis-5.0.4
+
+# 构建redis依赖库
+$ cd deps; make -j4 hiredis jemalloc linenoise lua
+$ cd ..
+
+# 构建redis
+$ make -j4
+$ make install
+$ make clean
+
安装后,可以在/usr/local/src/redis-5.0.4/src
目录和/usr/local/bin/
目录下找到redis-server
与redis-cli
两个文件
cp /usr/local/src/redis/redis.conf /etc/redis.conf
+vim /usr/local/src/redis/redis.conf
+
# 设置Redis密码
+requirepass 123456
+
+# 将 daemonize no 调整为 daemonize yes,将redis-server调整为默认后台启动
+daemonize yes
+
+# 配置日志
+logfile '/var/log/redis/redis-server.log'
+
redis-server /etc/redis.conf
+
vim /etc/systemd/system/redis.service
+
输入以下内容:
[Unit]
+Description=redis-server
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/local/bin/redis-server /etc/redis.conf
+ExecStop=/usr/local/bin/redis-cli shutdown
+Restart=always
+
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动redis-server:
systemctl start redis
+
开机自动启动redis:
systemctl enable redis
+
本文档仅供参考,不适用于正式环境部署,正式环境建议使用专业的Redis服务(比如腾讯云的Redis产品)
CentOS 7.3 版本
yum install redis
+
注:安装redis可能会出现"no package redis available"的错误提示,请执行yum install epel-release
后重试redis安装命令。
$ vi /etc/redis.conf
+
+# 找到 requirepass foobared
+# 复制一行并根据自己需要调整密码,比如
+requirepass tca123
+
systemctl start redis
+
查看redis运行状态
systemctl status redis
+
$ redis-cli
+
+127.0.0.1:6379> auth tca123
+OK # 鉴权通过
+
以往的单机器单进程,性能比较低,工具排队等待时间过长。希望通过并行执行分析来提高分析效率。
希望尽量使用公共资源或使用专机资源。
为了满足以上需求,TCA已经进行如下支持:
支持工具在多台机器上并行执行。
支持指定工具在指定的机器上运行。
支持与本地启动的任务衔接,加速本地任务扫描。
配套任务状态监控能力,及时重置初始化超时或机器掉线的任务。
TIP
TCA 客户端除了通过 localscan 命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
请参考客户端-常驻节点分析
client/config.ini
中的字段指定puppy-tools-config,如下[COMMON]
+; [必填]工具配置库git地址
+; 如果github网络慢,建议修改为腾讯工蜂地址:https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
+; 这里可以修改为自己维护的puppy-tools-config
+TOOL_CONFIG_URL=
+PASSWORD_KEY=
+; [可选]日志级别,默认为info级别,设置为True则调整为debug级别
+DEBUG=
+; [可选]是否使用本地工具目录,默认为False,如果设置为True,不从git拉取(需要事先准备好工具,存放到tools目录下)
+USE_LOCAL_TOOL=
+
+[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果TOOL_CONFIG_URL使用的是腾讯工蜂,账号密码必填(如果没有,可以先去https://git.code.tencent.com注册)
+USERNAME=
+PASSWORD=
+
; ---------------------------------------------------------------------------------------------------------------------
+; 配置文件填写说明:
+; 填写过程中,如果有多个值,用英文分号分隔
+; [env_path] - 环境变量路径定义,基于tools目录的相对路径,比如:PYLINT_HOME : puppy_tools_common/pylint-1.4.5
+; [env_value] - 环境变量值定义,比如:GIT_SSL_NO_VERIFY : 1
+; [tool_url] - 工具库地址定义,格式:工具名:url,比如 CHECKSTYLE : http://xxxxxx.git
+; [common] - 公共环境配置,比如git环境变量等, 包含以下4个字段
+; env_path - 需要的环境变量路径,填写[env_path]中的KEY值,比如 env_path : ANDROID_HOME;CHECKSTYLE_HOME
+; env_value - 需要的环境变量值,填写[env_value]中的KEY值,比如 env_value : GIT_SSL_NO_VERIFY
+; path - 需要加到path环境变量中的路径,基于tools目录的相对路径,推荐使用变量格式,比如 path : ${env_path:PYLINT_HOME}/bin
+; tool_url - 需要拉取的工具库,多个地址用英文分号分隔,推荐使用变量格式,比如 tool_url : ${tool_url:PYLINT}
+; [工具名] - 各工具配置,工具名需要与tool目录下的模块名匹配,字段格式参考[common]
+; ---------------------------------------------------------------------------------------------------------------------
+[base_value]
+git_url=https://github.com/TCATools
+
+;------------------
+; 1.环境变量路径定义
+;------------------
+; 用来记录工具路径,会在工具执行时写入到环境变量中
+[env_path]
+CPPLINT_HOME : cpplint
+
+;------------------
+; 2.环境变量值定义
+;------------------
+; 记录部分环境变量并在执行时写入环境变量
+[env_value]
+PYTHON_VERSION : 3
+
+
+;------------------
+; 3.工具git库定义
+;------------------
+; 拉工具的仓库地址
+[tool_url]
+CPPLINT : ${base_value:git_url}/cpplint.git
+
+;------------------
+; 5.各个工具配置
+;------------------
+; 整合工具配置
+[cpplint]
+env_path : CPPLINT_HOME
+env_value : PYTHON_VERSION
+path : ${env_path:CPPLINT_HOME}
+tool_url : ${tool_url:CPPLINT}
+
client/config.ini
中指定[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果使用的工具仓库必须账号密码才能拉取则必须填写
+USERNAME=
+PASSWORD=
+
task_request
分发到能够执行该工具的机器task_name
字段,字段对应于工具的name
字段task_name
在client中的tool目录查找对应python启动脚本根据上述的任务机制添加工具需要做到以下几点
tca_ql_php
工具及其所含的规则tca_ql_php
工具tca_ql_php
对应的启动脚本是什么找到server/projects/main/apps/scan_conf/management/commands/open_source
目录
创建工具json文件,json文件名尽量对应工具名称方便查看
json文件内容为(以 tca_ql_php 为例)
[
+ {
+ "name": "tca_ql_php",
+ "display_name": "Hades_PHP(展示名称用于前端展示使用)",
+ "description": "工具描述",
+ "license": "工具license",
+ "libscheme_set": [], # 暂时不需要
+ "task_processes": [
+ "analyze",
+ "datahandle",
+ "compile"
+ ], # 工具进程,包含compile编译, analyze分析, datahandle数据处理
+ "scan_app": "codelint", # 代码分析统一为codelint
+ "scm_url": "", # 暂时为空
+ "run_cmd": "",
+ "envs": null, # 是否需要特殊环境,这里无需填写
+ "build_flag": false, # 是否需要编译命令才能运行
+ "checkrule_set": [ # 工具包含的规则
+ {
+ "real_name": "deser", # 规则名
+ "display_name": "反序列化漏洞", # 规则前端展示,考虑各工具规则名可能晦涩难懂,设置展示名称方便查找
+ "severity": "error", # 规则等级 从上到下分为 fatal, error, warning, info 四个等级
+ "category": "security", # 规则类别。correctness 功能 security安全 performance性能 usability可用性 accessibility无障碍化 i18n国际化 convention代码风格 other其他
+ "rule_title": "反序列化漏洞", # 一句话概括规则简介
+ "rule_params": null, # 规则参数
+ "languages": [ # 支持语言
+ "php"
+ ],
+ "solution": "", # 建议的解决方法
+ "owner": "",
+ "labels": [],
+ "description": "", # 规则详细介绍
+ }
+ ]
+ }
+]
+
server/projects/main/
目录执行python manage.py loadcheckers --dir open_source tca_ql_php
加载工具进入数据库tca_ql_php
工具; env_path 主要填写存放工具文件所在的相对目录,一般都存放/拉取在tools下,会在工具执行前加载到环境变量中提供使用
+[env_path]
+ZEUS_HOME : Zeus
+HADES_HOME : Hades
+
+; toolz_url
+[tool_url] 主要填写工具的git仓库,这里因为 tca_ql_php 直接使用tools下的目录所以不用再进行额外拉取也无需再写
+CPPCHECK : ${base_value:git_url}/linux-cppcheck-1.78
+
+; 各工具配置 以 tca_ql_php 为例
+; env_path 填写上面需要加载的环境变量
+; env_value 通用环境变量,一般无需填写如果有需求需要现在 [env_value] 中定义好再填写
+; path 工具所在目录填写上面的定义
+; tool_url 工具git仓库,使用本地相对目录故为空
+[tca_ql_php]
+env_path : ZEUS_HOME;HADES_HOME
+env_value :
+path : ${env_path:ZEUS_HOME};${env_path:HADES_HOME}
+tool_url :
+
+
tca_ql_php
对应的启动脚本是什么以上述步骤在client/tool
目录添加脚本tca_ql_php.py
作为启动脚本 注:启动脚本必须与工具名称相同
编写脚本
以tca_ql_php
为例
+from task.codelintmodel import CodeLintModel
+from util.logutil import LogPrinter
+from util.subprocc import SubProcController
+
+logger = LogPrinter()
+
+
+class TcaQlPHP(CodeLintModel):
+ # 代码分析工具集成基类CodeLintModel
+ def __init__(self, params):
+ logger.info("找到工具了Q_Q")
+ super().__init__(params)
+
+ def compile(self, params):
+ logger.info("开始编译了Q_Q")
+ build_cmd = params.get('build_cmd', None) # 从params中获取编译命令, params内容可以在最后附录查看
+ lang = "php"
+ do_some_things()
+
+ def analyze(self, params):
+ logger.info("开始分析了Q_Q")
+ lang = "php"
+ HADES_HOME = envs.get("HADES_HOME", None)
+ output_json = "result.json"
+ sp = SubProcController(
+ command=["Hades", "analyze", "test.php", "-o", output_json],
+ cwd=HADES_HOME,
+ stdout_line_callback=subprocc_log,
+ stderr_line_callback=subprocc_log,
+ )
+ sp.wait() # 执行工具分析命令
+ issues = []
+ # 工具结果输出到output_json,具体工具可能有所不同
+ if os.path.exists(output_json):
+ with open(output_json, "r") as result_reader:
+ result = json.load(result_reader)
+ issues.extend(result)
+ return issues
+
+tool = TcaQlPHP # 必须,必须包含tool变量并且为该工具的类
+
task_request
中的task_params
字段,具体字段将在最后附录进行说明{
+ "path": "文件相对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+}
+说明:
+ refs:可选,记录问题回溯路径信息。比如当前文件的回溯路径其他的3行代码,可以将这三行的路径及提示信息,按顺序添加到refs数组中。
+
如果有意公开您添加的工具欢迎发起PR
注:别忘了puppy-tool-config 也需要PR
字段 | 说明 | 类型 |
---|---|---|
scan_languages | 语言 | 字符串列表如 ["python", "php"] |
pre_cmd | 编译前置命令 | 字符串 |
build_cmd | 编译命令 | 字符串 |
envs | 额外环境变量 | 字符串 |
scm_last_revision | 上次成功分析的代码版本,增量使用 | 字符串 |
incr_scan | 是否为增量分析 | bool |
rules | 规则名称列表,只有规则名 | 字符串列表 |
rule_list | 详细的规则列表包含规则名和规则参数等 | 字典列表 |
checktool | 工具详细信息,执行一般用不到 | 字典 |
path_filters | 过滤路径 | 字典 |
scm_url | 代码库url | 字符串 |
source_dir | 代码库本地目录 | 字符串 |
work_dir | 本次任务的work_dir目录 | 字符串 |
project_id | 分析项目id | int |
repo_id | 仓库id | int |
task_id | 任务id | int |
job_id | 本次分析的id | int |
http://{host}/server/
注:host 指当前浏览器访问该文档的 URL 域名部分。
发起请求时,需要在头部中添加以下格式形式,对应的 value 请看下面获取方式
{
+ "Authorization": "当前user的token"
+}
+
获取 token 位置(个人中心-个人令牌):
通过平台访问具体代码库扫描情况时,可从 URL 中获取对应 org_sid 和 project_team 字段,查看方式如下例子:
代码库扫描地址:http://{host}/t/xxx/p/yyy/code-analysis/repos/1/projects?limit=10&offset=0
其中,org_sid 为xxx
字段,project_team 为 yyy
字段
import requests
+# 假设:
+# 当前域名为http://tca.com/,当前org_sid为helloworld
+# 获取helloworld团队下的hellotca项目下登记的代码库
+url="http://tca.com/server/main/api/orgs/helloworld/teams/hellotca/repos/?limit=12&offset=0"
+headers = {
+ "Authorization": token,
+}
+
+response = requests.get(url, headers=headers)
+print(response.json())
+# 结果如下:
+{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 23,
+ "name": "repo_name",
+ "scm_url": "http://git.repo.com/group/repo_name",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-05-14 02:34:44.509118+00:00",
+ "recent_active": {
+ "id": 27,
+ "branch_name": "master",
+ "active_time": "2021-05-14 02:34:44.509118+00:00",
+ "total_line_num": 1,
+ "code_line_num": 1
+ },
+ "created_from": "tca",
+ "creator": {
+ "username": "author",
+ "nickname": "author",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ },
+ "symbol": null,
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "test",
+ "scm_platform": 2,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-05-14T10:34:44.552859+08:00",
+ "modified_time": "2021-05-14T10:34:44.552887+08:00"
+ },
+ "project_team": {
+ "name": "test",
+ "display_name": "测试",
+ "status": 1,
+ "org_sid": "test"
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
平台返回的数据分页格式是使用limit
和offset
参数进行分页处理
比如:server/main/api/orgs/<org_sid>/teams/?limit=12&offset=12
获取得到的数据是从第 13 条开始获取
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
scan_open | int | 发现问题的扫描编号 |
scan_close | int | 修复问题的扫描编号 |
worse | boolean | 圈复杂度是否恶化 |
over_cc_sum_gte | int | 圈复杂度总和最小值 |
over_cc_sum_lte | int | 圈复杂度总和最大值 |
over_cc_avg_gte | int | 平均圈复杂度最小值 |
over_cc_avg_lte | int | 平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
scan_open_id | int | 发现问题的扫描编号 |
scan_close_id | int | 修复问题的扫描编号 |
worse | boolean | 圈复杂度是否恶化 |
over_cc_sum_gte | int | 圈复杂度总和最小值 |
over_cc_sum_lte | int | 圈复杂度总和最大值 |
over_cc_avg_gte | int | 平均圈复杂度最小值 |
over_cc_avg_lte | int | 平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 32,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "tapd_url": null,
+ "created_time": "2020-06-02T10:59:09.418250+08:00",
+ "creator": null,
+ "modified_time": "2020-06-03T16:17:40.892224+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "over_func_cc": 0,
+ "over_cc_sum": 0,
+ "over_cc_avg": 0,
+ "over_cc_func_count": 0,
+ "diff_over_func_cc": 0,
+ "diff_over_cc_sum": 0,
+ "diff_over_cc_avg": 0,
+ "diff_over_cc_func_count": 0,
+ "worse": false,
+ "file_path": "test/demo.py",
+ "state": 3,
+ "change_type": 0,
+ "last_modifier": "author1",
+ "author": null,
+ "related_modifiers": "author1;author2",
+ "file_owners": null,
+ "language": "python",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "revision": null,
+ "ci_time": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": 2
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
ccn_gte | str | 圈复杂度最小值 |
ccn_lte | str | 圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/
+
参数 | 类型 | 描述 |
---|---|---|
issue__state | str | 问题状态, 1为未处理,2为可忽略,3为关闭,可多选,格式为1,2,3 |
change_type | str | 重复文件更改类型,add为新增,del为删除,mod为删除,可多选,格式为add,del,mod |
issue__owner | str | 问题责任人 |
last_modifier | str | 最近修改人 |
file_path | str | 文件路径 |
duplicate_rate_gte | int | 重复率最小值 |
duplicate_rate_lte | int | 重复率最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "project_id": 1,
+ "scan_id": 1,
+ "issue_id": 1,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "12345678abc",
+ "is_latest": true
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/
+
{
+ "data": {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "blocks": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ],
+ "duplicate_rate_trend": 0.0,
+ "project_id": 1815,
+ "scan_id": 488,
+ "issue_id": 3,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "xxx",
+ "is_latest": true
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/blocks/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/clocfiles/
+
参数 | 类型 | 描述 |
---|---|---|
change_type | str | 改变类型(add、mod、del),支持多值,使用英文逗号','分隔 |
file_path | str | 文件路径 |
{
+ "data": {
+ "count": 1,
+ "next": "",
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 108587,
+ "comment_line_num": 0,
+ "blank_line_num": 0,
+ "total_line_num": 108587,
+ "add_code_line_num": 108587,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 0,
+ "add_total_line_num": 108587,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1,
+ "scan_id": 1,
+ "is_latest": true,
+ "dir_path": "test",
+ "file_name": "test.json",
+ "language": "JSON",
+ "change_type": "add"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/cloclangs/
+
{
+ "data": {
+ "count": 2,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 9753,
+ "comment_line_num": 4220,
+ "blank_line_num": 2454,
+ "total_line_num": 16427,
+ "add_code_line_num": 9753,
+ "add_comment_line_num": 4220,
+ "add_blank_line_num": 2454,
+ "add_total_line_num": 16427,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Python",
+ "file_num": 165
+ },
+ {
+ "id": 2,
+ "code_line_num": 379,
+ "comment_line_num": 0,
+ "blank_line_num": 153,
+ "total_line_num": 532,
+ "add_code_line_num": 379,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 153,
+ "add_total_line_num": 532,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Markdown",
+ "file_num": 7
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 问题责任人 |
scan_open | int | 发现问题的扫描编号 |
scan_fix | int | 修复问题的扫描编号 |
ci_time_gte | str | 修复问题的起始时间,格式为"2021-01-01 00:00:00" |
ci_time_lte | str | 修复问题的结束时间 |
file_path | str | 文件路径 |
checkrule_display_name | str | 检查规则名 |
checkpackage | int | 问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "file_path": "test/demo.py",
+ "project": 1,
+ "repo": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checktool_name": "xxx",
+ "msg": "xxx",
+ "state": 3,
+ "resolution": 1,
+ "author": "author",
+ "author_email": null,
+ "severity": 2,
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "is_external": false,
+ "scm_url": "",
+ "real_file_path": "",
+ "scan_open": 1,
+ "scan_fix": 2,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/
+
{
+ "data": {
+ "id": 1,
+ "issue_details": [
+ {
+ "id": 1,
+ "issue_refers": [],
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "issuedetail_uuid": "0fcc376e-7283-11eb-bd53-5254005e71ca",
+ "checkrule_real_name": "xxx",
+ "checktool_name": "xxx",
+ "author": "author",
+ "author_email": null,
+ "line": 1809,
+ "column": 15,
+ "scan_revision": "scan_revision",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "real_revision": "",
+ "created_time": "2021-02-19T15:21:19.625658+08:00",
+ "modified_time": "2021-02-19T15:21:19.625662+08:00",
+ "issue": null,
+ "project": 1
+ }
+ ],
+ "is_external": false,
+ "repo": 1,
+ "author": "author",
+ "created_time": "2021-02-19T15:21:19.625685+08:00",
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "file_path": "test/demo.py",
+ "file_hash": "xxx",
+ "scm_url": "",
+ "real_file_path": "",
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "state": 3,
+ "resolution": 1,
+ "scan_revision": null,
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "modified_time": "2021-02-19T15:25:17.807478+08:00",
+ "project": 1,
+ "scan_open": 1,
+ "scan_fix": 2
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/
+
参数 | 类型 | 描述 |
---|---|---|
incr_scan | bool | 增量扫描标志,true表示增量,false表示全量 |
async_flag | bool | 异步启动标志,true表示异步,false表示同步,建议选择异步 |
force_create | bool | 强制启动标志,true表示强制启动,不等待上一个任务结束 |
{
+ "job": {
+ "id": 7974
+ },
+ "scan": {
+ "id": 5528
+ }
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/
+
参数 | 类型 | 描述 |
---|---|---|
create_time_gte | datetime | 最小任务启动时间 |
create_time_lte | datetime | 最大任务启动时间 |
result_code_gte | int | 最小错误码值 |
result_code_lte | int | 最大错误码值 |
result_msg | str | 结果信息 |
state | int | 任务状态, 0为等待中,1为执行中,2为关闭,3为入库中,可多选,格式为1,2,3 |
created_from | str | 创建来源 |
creator | str | 创建用户 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/
+
{
+ "data": {
+ "id": 1,
+ "scan_id": 1,
+ "create_time": "2021-01-28T10:27:26.442961+08:00",
+ "waiting_time": "1",
+ "start_time": "2021-01-28T11:14:56.760427+08:00",
+ "execute_time": "3",
+ "project": {
+ "id": 1,
+ "branch": "master",
+ "repo_id": 1,
+ "scan_scheme": 1,
+ "repo_scm_url": "http://github.com/xxx/test_demo.git"
+ },
+ "end_time": "2021-01-28T11:14:59.760427+08:00",
+ "expire_time": "2021-01-28T14:07:52.968932+08:00",
+ "task_num": 1,
+ "task_done": 1,
+ "tasks": [
+ {
+ "id": 1,
+ "module": "codelint",
+ "task_name": "pylint",
+ "progress_rate": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "result_path": null
+ }
+ ],
+ "co_jobs": [],
+ "state": 2,
+ "result_code": 0,
+ "result_code_msg": null,
+ "result_msg": "success",
+ "result_path": null,
+ "remarks": null,
+ "remarked_by": null,
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400,
+ "created_from": "codedog_web",
+ "creator": "creator"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
注:以下字段用于参考,具体字段格式需要以具体接口返回为准
org_sid: str,团队编号
+name: str,团队名称
+description: str,团队描述
+certificated: boolean,团队认证标志位
+created_time: datetime,团队创建时间
+updated_time: datetime,团队更新时间
+admins: list,管理员列表
+project_count: int,分析任务数量
+team_count: int,项目组数量
+user_count: int,成员数量
+owner: str,负责人名称
+tel_number: str,负责人电话
+address: str,办公地址
+
name: str,项目组名称
+display_name: str,项目组展示名称
+description: str,项目组描述信息
+
name: str,代码库名称
+scm_url: str,代码库地址
+scm_type: int,代码库类型
+created_from: str,创建来源
+state:str,代码库状态,1表示活跃,2表示失活,3表示暂停使用
+labels:list,标签
+project_team: 项目
+organization: 团队
+
name: str,扫描方案名称
+repo:关联的代码库
+refer_scheme: 参照的扫描方案
+description: str,描述
+tag: 执行标签
+languages: 包含语言
+default_flag: boolean,默认方案标志
+created_from: str,创建来源
+ignore_merged_issue: boolean,过滤其他分支引入的问题,默认False,不过滤
+ignore_branch_issue: str,过滤指定分支引入的问题
+ignore_submodule_clone: boolean,不拉取子模块,默认False
+ignore_submodule_issue: boolean,忽略子模块问题,默认False
+issue_global_ignore: boolean,开启问题全局忽略,默认False
+daily_save: boolean,日常扫描记录保存7天开关,默认False
+lfs_flag: boolean,自动拉取lfs文件,默认True
+status: int,扫描方案状态,1为活跃,2为废弃
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/
+
{
+ "lintscan": {
+ "issue_open_num": 74,
+ "issue_fix_num": 439,
+ "issue_detail_num": 310,
+ "scan": {
+ "id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "execute_time": "00:02:17.844712"
+ },
+ "current_scan": {
+ "active_category_detail": {
+ "convention": 70,
+ "other": 4
+ },
+ "active_severity_detail": {
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 74,
+ "issue_fix_num": 439
+ },
+ "total": {
+ "state_detail": {
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": {
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": {
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0,
+ "text": "成功",
+ "description": null,
+ "scan_summary": {
+ "convention": {
+ "error": {
+ "rule_count": 7,
+ "active": 65
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ },
+ "cyclomaticcomplexityscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ },
+ "duplicatescan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/latestscan/
+
参数 | 类型 | 描述 |
---|---|---|
scan_revision | str | 指定查询的扫描版本号,如不指定则为当前项目最新的一次扫描 |
{
+ "data": {
+ "id": 1, # 扫描编号
+ "repo_id": 1, # 代码库编号
+ "project_id": 1, # 项目编号
+ "job_gid": 1, # 关联任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "current_revision": "current_revision", # 扫描版本号
+ "result_code": 0, # 扫描任务结果码,0表示正常
+ "result_code_msg": "成功",
+ "result_msg": null,
+ "lintscan": { # 代码扫描结果信息
+ "current_scan": { # 本次扫描信息
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ }
+ },
+ "duplicatescan": { # 重复代码扫描结果信息
+ "id": 1, # 扫描任务编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "default_summary": { # 默认概览
+ "exhi_risk": { # 极高风险
+ "range": [ # 重复率范围: 0.2-1
+ 0.2,
+ 1
+ ],
+ "file_count": 1, # 文件数量
+ "diff": { # 增量数据
+ "diff_file_count": 0 # 增量文件数量
+ }
+ },
+ "high_risk": { # 高风险
+ "range": [ # 重复率范围:0.11-0.2
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": { # 中风险
+ "range": [ # 重复率范围:0.05-0.11
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": { # 低风险
+ "range": [ # 重复率范围:0-0.05
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null, # 自定义概览数据
+ "last_revision": "2010ef28ff3a26424d4e8f32df022f90cd682eda", # 上次扫描版本号
+ "duplicate_file_count": 8, # 重复文件数量
+ "duplicate_block_count": 55, # 重复代码块数量
+ "duplicate_line_count": 1177, # 重复代码行数
+ "diff_duplicate_block_count": 0, # 增量重复代码块数量
+ "diff_duplicate_line_count": 0, # 增量重复代码行数
+ "close_issue_count": 0, # 关闭问题数
+ "new_issue_count": 0, # 新增问题数
+ "reopen_issue_count": 5, # 重新打开问题数
+ "ignored_issue_count": 0, # 忽略问题数
+ "duplicate_rate": 4.98, # 重复率
+ "unique_duplicate_line_count": 1083, # 去重后的重复代码行数
+ "total_duplicate_line_count": 1083, # 项目总的去重后的重复代码行数
+ "total_line_count": 21745, # 项目总行书
+ "scan": 1 # 关联扫描任务编号
+ },
+ "cyclomaticcomplexityscan": { # 圈复杂度扫描数据
+ "id": 1, # 圈复杂度扫描编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": { # 默认概览数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "over_cc_func_count": 6, # 超标函数数量
+ "under_cc_func_count": 796, # 未超标函数数量
+ "diff_over_cc_func_count": 0, # 增量超标函数数据
+ "over_cc_func_average": 22.333333333333332, # 平均超标圈复杂度
+ "cc_func_average": 2.5099750623441395, # 平均圈复杂度
+ "over_cc_sum": 14, # 文件超标方法圈复杂度超过阈值的差值之和
+ "cc_average_of_lines": 1.0422094841063054 # 千行代码平均圈复杂度
+ },
+ "custom_summary": null, # 自定义概览数据
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "diff_cc_num": 0, # 增量超标函数数量
+ "cc_open_num": 6, # 超标函数量
+ "cc_average_of_lines": 1.0422094841063054, # 千行代码平均圈复杂度
+ "cc_fix_num": 0, # 修复数量
+ "worse_cc_file_num": 0, # 圈复杂度恶化的文件数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "code_line_num": 13433, # 代码行数
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "code_line_num": 140490, # 代码行数
+ "comment_line_num": 5410, # 注释行数
+ "blank_line_num": 3408, # 空白行数
+ "total_line_num": 149308, # 总行数
+ "add_code_line_num": 6673, # 增加的代码行数
+ "add_comment_line_num": 2309, # 增加的注释行数
+ "add_blank_line_num": 1289, # 增加的空白行数
+ "add_total_line_num": 10271, # 增加的总行数
+ "mod_code_line_num": 965, # 修改的代码行数
+ "mod_comment_line_num": 297, # 修改的注释行数
+ "mod_blank_line_num": 0, # 修改的空白行数
+ "mod_total_line_num": 1262, # 修改的总行数
+ "del_code_line_num": 35844, # 删除的代码行数
+ "del_comment_line_num": 2117, # 删除的注释行数
+ "del_blank_line_num": 1794, # 删除的空白行数
+ "del_total_line_num": 39755, # 删除的总行数
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/lintscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2, # 本次扫描关闭存量问题数
+ "issue_detail_num": 310, # 本次扫描上报原始问题数(问题展示会进行聚合)
+ "scan": { # 扫描信息
+ "id": 1, # 扫描任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描开始时间
+ "execute_time": "00:02:17.844712" # 扫描执行耗时
+ },
+ "current_scan": { # 本次扫描信息
+ "active_category_detail": { # 活跃问题分类,包含 CORRECTNESS(1-功能)、SECURITY(2-安全)、PERFORMANCE(3-性能)、USABILITY(4-可用性)、ACCESSIBILITY(5-无障碍化)、I18N(6-国际化)、CONVENTION(7-代码风格)、OTHER(8-其他)
+ "convention": 70, # 代码风格类型问题
+ "other": 4 # 其他类型问题
+ },
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": { # 不同分类下不同处理状态的问题量
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0, # 扫描状态,0表示成功
+ "text": "成功",
+ "description": null,
+ "scan_summary": { # 扫描概览
+ "convention": {
+ "error": {
+ "rule_count": 7, # 规则数
+ "active": 65 # 活跃问题数
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/cycscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/dupscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/clocscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url_or_name | str | 代码库地址或者名称,支持模糊匹配 |
scm_url | str | 代码库仓库匹配 |
scope | str | 过滤范围(my/subscribed/related_me),my表示我创建的,subscribed表示我关注的,related_me表示我有权限的 |
{
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ }
+ ]
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/
+
{
+ "data":{
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/branches/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "branch": "master",
+ "schemes": [
+ {
+ "project_id": 1,
+ "scan_scheme_id": 1,
+ "scan_scheme_name": "默认"
+ }
+ ]
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
branch | str | 分支名称 |
scan_scheme | int | 扫描方案名称 |
scan_scheme__status | int | 扫描方案状态,1为活跃,2为废弃 |
branch_or_scheme | str | 分支名称/扫描方案名称 |
status | int | 项目状态筛选,1表示活跃,2表示失活,3表示关闭 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "codedog_web",
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
scan_scheme_id | int | 当前代码库的扫描方案编号 |
global_scheme_id | int | 扫描方案模板编号 |
custom_scheme_name | str | 自定义方案名称 |
branch | str | 分支 |
created_from | str | 创建渠道,用于区分不同运行场景 |
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/<project_id>/
+
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 扫描方案名称 |
status | int | 扫描方案状态,1为活跃,2为废弃 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/copyscheme/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 扫描方案名称 |
ref_scheme | int | 参照扫描方案编号 |
{
+ "data": {
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
{
+ "data": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
参数 | 类型 | 描述 |
---|---|---|
languages | list | 代码语言 |
tag | str | 执行标签,目前只支持 CodeDog_Linux |
name | str | 方案名称 |
description | str | 方案描述 |
default_flag | bool | 默认方案标志,一个代码库只能有一个默认方案 |
job_runtime_limit | int | 任务执行超时时间,默认为600分钟 |
ignore_merged_issue | bool | 忽略合入的问题 |
ignore_branch_issue | str | 过滤参考分支引入的问题 |
ignore_submodule_clone | bool | 不拉取子模块扫描,True表示不拉取,False表示拉取 |
ignore_submodule_issue | bool | 忽略子模块引入的问题,True表示忽略,False表示不忽略 |
issue_global_ignore | bool | 问题全局忽略 |
daily_save | bool | 每次扫描原始数据存储,默认存储7天 |
lfs_flag | bool | 拉取lfs模块开关 |
issue_revision_merge_flag | bool | "是否开启Issue按引入版本号聚合开关 |
status | int | 方案状态,1表示活跃,2表示废弃 |
同查看指定代码库的指定扫描方案的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
{
+ "data": {
+ "id": 1,
+ "enabled": true,
+ "checkprofile": {
+ "id": 1,
+ "profile_type": 1,
+ "custom_checkpackage": 1,
+ "checkpackages": [
+ 1
+ ]
+ },
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
参数 | 类型 | 描述 |
---|---|---|
enabled | bool | 是否开启代码扫描 |
同指定代码库的指定方案的代码扫描配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
{
+ "data": {
+ "id": 1,
+ "cc_scan_enabled": false,
+ "min_ccn": 20,
+ "dup_scan_enabled": false,
+ "dup_block_length_min": 120,
+ "dup_block_length_max": null,
+ "dup_min_dup_times": 2,
+ "dup_max_dup_times": null,
+ "dup_min_midd_rate": 5,
+ "dup_min_high_rate": 11,
+ "dup_min_exhi_rate": 20,
+ "dup_issue_limit": 1000,
+ "cloc_scan_enabled": false,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
参数 | 类型 | 描述 |
---|---|---|
cc_scan_enabled | bool | 圈复杂度扫描开关 |
min_ccn | int | 最小圈复杂度 |
dup_scan_enabled | bool | 重复代码扫描开关 |
dup_block_length_min | int | 重复块最小长度 |
dup_block_length_max | int | 重复块最大长度 |
dup_max_dup_times | int | 最大重复次数 |
dup_min_midd_rate | int | 中风险最小重复率 |
dup_min_high_rate | int | 高风险最小重复率 |
dup_min_exhi_rate | int | 极高风险风险最小重复率 |
dup_issue_limit | int | 上报重复代码块数上限 |
cloc_scan_enabled | boolean | 代码统计扫描开关 |
同指定代码库的指定方案的代码度量配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "dir_path": "test/*",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 指定过滤路径 |
path_type | int | 路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
{
+ "data": {
+ "id": 1,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 指定过滤路径 |
path_type | int | 路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
DELETE /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
无
初始发布
欢迎报告Issue或提交Pull Request。建议在贡献代码前先阅读以下贡献指南。
我们使用Github Issues来跟踪漏洞和功能请求。
在您提交新的issue前,请搜索现有issue以查看是否已有人提交任何类似问题或功能请求,确认不存在重复的issue。
当您提交新的issue时,请尽量提供更多的信息,例如与问题相关的详细描述、屏幕截图、视频、logcat和导致崩溃的代码块。
我们非常欢迎您提出Pull Request来帮助TCA变得更好,操作流程详见PullRequests操作流程。
TCA有两个主要分支:
main
分支: main
作为标签, 带有版本号 v1.0.1
, v1.0.2
...main
分支提交任何PR.dev
分支: dev
分支将合并到 main
分支的下一个版本。dev
分支。代码团队将监控所有拉取请求,我们对其进行一些代码检查和测试。在所有测试通过后,我们将接受此PR。但它不会立即合并到 main
分支,这有一些延迟。
在提交拉取请求之前,请确保完成以下工作:
main
创建分支。dev
分支提交Pull Request。MIT LICENSE 是 TCA 的开源许可证。任何人贡献的代码都受此许可证保护。在贡献代码之前,请确保您可以接受许可。
如果您需要有关TCA的帮助,希望与TCA开发者们相互认识和交流,欢迎通过以下渠道加入TCA社区!
PR全称为Pull Request,它是一种代码库的协作方式。开发者可以通过PR将自己在代码库的修改通知到代码库负责人,由原作者评审代码并决定是否能合入。
TIP
Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.
点击Fork后,会在自己名下产生一个相同代码库,比如我Fork CodeAnalysis项目后,会在我名下多出一个CodeAnalysis代码库,地址为https://github.com/Lingghh/CodeAnalysis
在本地克隆Fork的代码库并创建分支
git clone https://github.com/Lingghh/CodeAnalysis
+git checkout -b dev/add_qa_20220301
+
注:也可以在自己Fork的代码库GitHub页面上创建分支。
接下来就可以在本地修改代码,修改完成后先push到Fork的代码库中.
点击compare across forks 。
点击head repository 。
选择自己Fork的代码库和比较的分支,比如我这里选择Lingghh/CodeAnalysis和待合入的分支dev/add_arm64_file 。
最后确认commits和changed files是否准确,如果没有问题就可以点击Create pull request 。
PR创建后,代码库管理员会评审你提交的代码,并决定是否接受该PR。
腾讯云代码分析(Tencent Cloud Code Analysis, TCA)起步于 2012 年(内部代号CodeDog),是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是精准跟踪管理代码分析发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码,以及度量代码复杂度、重复代码、代码统计。持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
用心关注每行代码迭代,助力传承卓越代码文化!
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
通过代码检查精准跟踪管理发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码等。
目前已集成众多自研、知名开源分析工具,并采用了分层分离架构,可以满足团队快速自助管理工具。
包含代码圈复杂度、代码重复率和代码统计等度量信息。
圈复杂度也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度。圈复杂度大说明程序代码的判断逻辑复杂,可能造成代码质量低下且难于测试和维护。
定期分析工程项目中代码的圈复杂度,可以有效地帮助开发与测试逐步优化代码质量。
定期分析工程项目中的重复代码,可以有效地帮助开发发现冗余代码,进行代码抽象和重构,降低代码风险,以便于更好的管理和维护代码。
支持全量增量展示代码行数统计,包含代码行、注释行和空白行,可以有效地跟踪了解工程项目中代码量持续变化,并可以查看各个语言的占比情况。
Linux 环境
系统已安装 nginx
TCA Server 服务已部署完毕,具备后端服务地址
进入前端部署源码目录
进入web服务目录,并切换至tca-deploy-source
目录,将其视为工作目录(假设工作目录为 /data/CodeAnalysis/web/tca-deploy-source
)
部署/更新前端服务
# 部署、更新都使用此命令
+sh ./scripts/deploy.sh init -d
+
具体请查阅部署脚本内容,可根据业务调整配置。
额外说明
tca-deploy-source/scripts/config.sh
已配置默认环境变量,用户可根据需要调整环境变量再部署前端服务,具体可查阅脚本内容。
TCA Web 采用 Lerna 进行 monorepo
管理。
由 framework
、login
、tca-layout
、tca-analysis
、tca-manage
微前端以及tca-document
前端帮助文档组成。
shared
: 公共模块
framework
: 微前端基座
login
: 登录微前端
tca-layout
: 腾讯云代码分析layout微前端
tca-analysis
: 腾讯云代码分析analysis微前端
tca-manage
: 腾讯云代码分析后台管理微前端
tca-document
: 腾讯云代码分析帮助文档
已将当前版本各个微前端构建打包到此目录,可通过阅读该目录下的 README 直接进行前端部署。
按上一节完成一套 TCA Web 部署
根据要调整的内容,启动对应的微前端(login、tca-layout、tca-analysis),具体可进入不同 package
参考阅读其目录下的 README
进行开发。
其他:
根目录下启动单个项目
# framework
+yarn dev --scope framework
+# login
+PUBLIC_PATH=http://127.0.0.1:5055/ yarn dev --scope login
+# tca-layout
+PUBLIC_PATH=http://127.0.0.1:5056/ yarn dev --scope tca-layout
+# tca-analysis
+PUBLIC_PATH=http://127.0.0.1:5057/ yarn dev --scope tca-analysis
+# tca-manage
+PUBLIC_PATH=http://127.0.0.1:5058/ yarn dev --scope tca-manage
+# tca-document
+yarn dev --scope tca-document
+# 或进入对应项目内,查阅对应README
+
如对项目进行变更,本地开发结束后,需要部署最新资源可通过执行 sh build-source.sh
将构建后资源更新到tca-deploy-source 目录内,再参考该目录下的 README 直接进行前端更新/重新部署操作。
可通过阅读 build-source.sh
内容,以及 tca-deploy-source 目录下的 README,用户可根据需要自行进行前端部署。
客户端分析完毕后,如果分析方案含有代码检查功能,则代码分析结束后会上报结果信息到腾讯云代码分析平台,用户可在平台上查看问题列表及详情。
进入代码检查问题列表页面后,默认展示**当前分支 + 当前分析方案(即分析项目)**发现的全部未处理问题。
如果仅希望查看增量问题,可以进入分析历史页面,指定查看某一次的扫描结果即可。也可以在过滤筛选项中填入发现问题的扫描 id
进行筛选查看结果(该id
为扫描任务 ID,需要到扫描任务列表中查询)。
责任人说明
责任人为 git blame
操作得到的代码提交人。
问题级别说明
代码检查的问题级别是根据对应分析方案中规则设置的严重级别定义的,从高到低分为 致命、错误、警告、提示
。如果调整问题级别,则需要进入分析方案中调整这个规则的严重级别,调整后需要进行全量扫描使得调整生效。
批量处理说明
问题列表支持批量修改问题状态。
点击规则信息可以查看规则说明。
Error Prone是google开源的Java编译时检测工具,将常见的Java错误捕获为编译时错误,增强对java代码的类型分析,从而让开发人员及时发现问题
TCA原有编译时检测工具JavaWarning获取java代码编译时的告警信息,现集成Error Prone规则至JavaWarning工具以增加获取Error Prone的错误告警信息。
bazel build :project
构建项目即可。编辑pom.xml文件将设置添加到maven-compiler-plugin,例如:
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ <encoding>UTF-8</encoding>
+ <compilerArgs>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>-Xplugin:ErrorProne</arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${error-prone.version}</version>
+ </path>
+ <!-- Other annotation processors go here.
+
+ If 'annotationProcessorPaths' is set, processors will no longer be
+ discovered on the regular -classpath; see also 'Using Error Prone
+ together with other annotation processors' below. -->
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
对于JDK 16
或更高的版本,需要将以下内容--add-exports
和--add-opens
标志添加到.mvn/jvm.config
文件中:
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+
###命令行 Error Prone 支持com.sun.source.util.Plugin
API,并且可以通过将 Error Prone 添加到-processorpath
并设置-Xplugin
标志来与JDK 9
及更高版本一起使用:
wget https://repo1.maven.org/maven2/com/google/errorprone/error_prone_core/${EP_VERSION?}/error_prone_core-${EP_VERSION?}-with-dependencies.jar
+wget https://repo1.maven.org/maven2/org/checkerframework/dataflow-errorprone/3.15.0/dataflow-errorprone-3.15.0.jar
+javac \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
+ -XDcompilePolicy=simple \
+ -processorpath error_prone_core-${EP_VERSION?}-with-dependencies.jar:dataflow-errorprone-3.15.0.jar \
+ '-Xplugin:ErrorProne -XepDisableAllChecks -Xep:CollectionIncompatibleType:ERROR' \
+ Example.java
+
JDK 16
以及更高的版本--add-exports
和--add-opens
参数是必须的JDK 8
,请参考旧版本安装说明TCA-Armory-C1 属于 TCA 的增强分析模块。
支持的语言:Java
CmdInject 规则用于检查代码中是否存在命令行注入漏洞
。 当使用 childprocess 等模块执行命令时,拼接了用户可控的输入,会导致命令执行漏洞。攻击者利用漏洞可以控制目标主机或者容器。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String cmd = req.getParameter("cmd");
+ Runtime rt = Runtime.getRuntime();
+ rt.exec(cmd); // 触发规则
+}
+
需要评估 childprocess 等模块执行命令的使用,应限定或校验命令和参数的内容。
支持的语言:Java
PathTraversal 规则用于检查代码中是否存在路径穿越漏洞
。 操作文件时,应该限定文件的路径范围,如果拼接用户输入到文件路径,可能导致路径穿越漏洞。攻击者利用漏洞可以访问到文件系统上的任意文件,这可能导致信息泄漏等问题。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String image = req.getParameter("image");
+ File file = new File("resources/images/", image); // 触发规则
+
+ if (!file.exists()) {
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ return Response.ok().entity(new FileInputStream(file)).build();
+}
+
按业务需求,使用白名单限定后缀范围,校验并限定文件路径范围。
支持的语言:Java
SQLInject 规则用于检查代码中是否存在SQL注入漏洞
。 错误的拼接用户可控的值到 sql 语句,可能导致 sql 注入漏洞。攻击者可以修改 sql 语法来更改查询的目标或结果,泄露数据库敏感信息,也可以使用SQL文件操作攻击底层Web服务器。如果使用该 sql 查询进行授权认证,攻击者还可以用于提权。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = req.getParameter("id");
+ Connection conn = null;
+ Statement statement = null;
+ ResultSet rs = null;
+
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sec_sql", "root", "admin888");
+ String sql = "select * from userinfo where id = " + id;
+ statement = conn.createStatement();
+ statement.executeUpdate(sql); // 触发规则
+}
+
SQL 语句默认使用预编译并绑定变量,使用安全的ORM操作。
支持的语言:Java
SSRF 规则用于检查代码中是否存在服务端请求伪造漏洞 SSRF(Server-side request forgery)
。 攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。
无
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf ->
+ csrf.disable() // 触发规则
+ );
+ }
+}
+
限定访问网络资源地址范围,请求网络资源应加密传输。
支持的语言:Java
XSS 规则用于检查代码中是否存在跨站脚本攻击漏洞 XSS(Cross-site scripting)
。 如果 web 页面在动态展示数据时使用了用户的输入内容,没有对输入的内容过滤或者进行转义,黑客可以通过参数传入恶意代码,当用户浏览该页面时恶意代码会被执行。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = request.getParameter("id") != null ? request.getParameter("id") : "0";
+ Doc doc = getdetailsById(id);
+ byte[] b = doc.getUploaded();
+ try {
+ response.setContentType("APPLICATION/OCTET-STREAM");
+ String disHeader = "Attachment;Filename=" + doc.getName();
+ response.setHeader("Content-Disposition", disHeader);
+ ServletOutputStream out = response.getOutputStream();
+ out.print(b); // 触发规则
+ }
+}
+
在输出所有用户可控的数据时, 对数据做转义或者编码。
检查 Objective-C/C++ 代码文件的copyright信息。
无
// 触发规则
+@interface Test : NSObject
+@end
+
+
在代码文件头部添加 Copyright 信息。比如:
// Copyright (c) xxxx Tencent. All rights reserved.
+//
+
+@interface Test : NSObject
+@end
+
+
检查 Objective-C/C++ 代码文件的缩进。
\t
,默认是 spaces;参考以下示例:
IndentStyle=spaces
+IndentSize=4
+
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
调整为对应的缩进方式。比如默认是4个空格缩进。
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
检查 Objective-C/C++ 代码中超出行数长度阈值的函数。
参考以下示例:
LineThreshold=100
+
无
可以基于单一职责原则拆分函数,缩减函数长度。
检查 Objective-C/C++ 代码中 interface 是否有注释信息。
无
无
为 inferface 增加注释。
检查 Objective-C/C++ 代码中 Property 是否有注释信息。
无
无
为 Property 增加注释。
检查 Objective-C/C++ 代码中 Protocol 是否有注释信息。
无
无
为 Protocol 增加注释。
检查 Objective-C/C++ 代码中方法的参数个数是否超过阈值。
参考以下示例:
Max=6
+
无。
参数个数越少越好,多于 6 个参数时建议考虑重构。
检查 Objective-C/C++ 代码中 class 名称是否符合命名规范。
参考以下示例:
ClassCase=CamelCase
+
无。
修改 class 名称符合命名规范。
检查 Objective-C/C++ 代码中 Function 名称是否符合命名规范。
参考以下示例:
FunctionCase=camelBack
+
无。
修改 Function 名称符合命名规范。
检查 Objective-C/C++ 代码中 GlobalVariable 名称是否符合命名规范。
g
;参考以下示例:
GlobalVariablePrefix=g
+GlobalVariableCase=camelBack
+
无。
修改 GlobalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 LocalVariable 名称是否符合命名规范。
参考以下示例:
LocalVariableCase=camelBack
+
无。
修改 LocalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 Macro 名称是否符合命名规范。
参考以下示例:
MacroCase=UPPER_CASE
+
无。
修改 Macro 名称符合命名规范。
检查 Objective-C/C++ 代码中 Method 名称是否符合命名规范。
参考以下示例:
MethodCase=camelBack
+
无。
修改 Method 名称符合命名规范。
检查 Objective-C/C++ 代码中 Parameter 名称是否符合命名规范。
参考以下示例:
ParameterCase=camelBack
+
无。
修改 Parameter 名称符合命名规范。
检查 Objective-C/C++ 代码中一行长度是否超过阈值。
参考以下示例:
tabWidth=4
+MaxLineLength=150
+
无。
通过换行、优化逻辑等方式,缩减一行长度。
TCA-Armory-Q1, 又名 tca_ql_cpp 主要用于分析Cpp质量问题。
包含规则:
在使用多线程对文件全局变量或类成员在进行读写时,工具会对未正确的进行上锁操作和上锁异常而引发死锁的情况进行检查。
支持的多线程标准库库包括(若有其他库需求可提issue):
missing_lock 如果发现多线程中某个全局变量在未持有锁便更新时,则会上报错误。
以下提供一个或多个 missing_loc 案例 在下面代码中,函数 increase1, increase2 皆以将 counter 加到 1000 为目的。如果使用 increase1 函数则有可能多个线程皆在 1000 时进入循环导致最后 counter结果大于 1000
int counter = 0;
+std::mutex mtx; // 保护counter
+void increase1() {
+ while (1) {
+ if (counter <= 1000)
+ counter++; // defect: missing_lock
+ else
+ break;
+ }
+}
+void increase2() {
+ while (1) {
+ mtx.lock(); // example_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx.unlock(); // example_release
+ }
+}
+
dead_lock 如果发现文件内存在 mtx1 -> mtx2 的上锁顺序时,另存在mtx2 -> mtx1 的上锁顺序,视为死锁或存在死锁的可能,则会上报错误。 死锁发生时程序将会卡死无法正常执行。
以下提供一个或多个 dead_lock 案例
在下面代码中,函数 increase 以将 counter 加到 1000 为目的。但在线程 1 中第一次释放 mtx 后,线程 2 的 mtx 上锁,此时线程1等待线程2释放mtx,线程2等待线程1释放mtx2,形成死锁,程序卡死。
int counter = 0;
+std::mutex mtx;
+std::mutex mtx2;
+void increase() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ mtx.unlock();
+ mtx.lock(); // defect: dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
在下面代码中 线程函数increase1存在mtx -> mtx2 的顺序,increase2顺序为 mtx2 -> mtx;视为出现死锁。
void increase1() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+void increase2() {
+ while (1) {
+ mtx2.lock();
+ mtx.lock(); // defect: dead_lock;
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
以下案例在better-lock
参数为True
时将会生效 使用better-lock
规则会检查在上锁期间若调用其他函数时将视为可能会出现预期之外的异常,且上锁期间应只做对全局变量操作以提升性能
void increase1() {
+ while (1) {
+ mtx.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter); // defect: dead_lock
+ mtx.unlock()
+ }
+}
+void read_counter(counter){
+ std::cout << counter << std::endl;
+ do_something_more();
+}
+void increase1() {
+ while (1) {
+ std::lock_guard<std::mutex> lk(mtx); // good: 使用lock_guard会自动上锁解锁将不会检查dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter);
+ }
+}
+
包含规则
resource_leak 在程序申请了资源但并未按时释放时上报错误 目前场景包括:句柄打开时未关闭,指针分配内存后没有及时释放
以下将提供一个或多个resource_leak案例
int leak_example1(int c) {
+ void *p = malloc(10);
+ if(c)
+ return -1; // defect: if c "p" is leaked
+ free(p);
+ return 0;
+}
+
+int leak_example2() {
+ void *p = malloc(10);
+ void *q = malloc(20);
+ if(!p || !q)
+ return -1; // defect: "p" or "q" may be leaked if the other is NULL
+ /*...*/
+ free(q);
+ free(p);
+ return 0;
+}
+
+void leak_example3(int c) {
+ FILE *p = fopen("starwar.anakin", "rb");
+ if(c)
+ return; // defect: leaking file pointer "p"
+ fclose(p);
+}
+
指针为返回值目前不会进行上报与检查,需要后期增加对返回值是否释放的检查
包含规则
unused_value 检查那些赋予给变量的值是否正确被使用,存在连续两次赋予变量值的情况,视为第一次赋予的值未被正确使用,报出错误。 两次连续赋值可能存在条件控制语句出现错误、变量名拼写错误等情况。
以下提供一个或多个unused_value案例
以下函数会因为key的不同去不一样的神明,但实际上 Zeus Hades却永远不会使用到。
const char* key_value(const int key) {
+ const char * value = 0;
+ if (key != 0) {
+ value = "Zeus";
+ } else if (key != 1) {
+ value = "Hades";
+ }
+ if (key != 2) { // Should be 'else if' here.
+ value = "Poseidon"; // defect: unused_value Zeus Hades never used
+ }
+ else {
+ value = "Unknow
+ }
+ return result;
+}
+
以下继续提供几个unused_value代码
const char* key_value1(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // defect: Zeus never used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ } else { // May else need not be here
+ value = "Unknow";
+ }
+ return value
+}
+
+const char* key_value2(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // better Zeus used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ }
+ return value
+}
+
+const char* key_value3(const int key) {
+ const char * value = 0;
+ if (key == 1) {
+ value = "Hades;
+ } else {
+ value = "Poseidon";
+ }
+ value = "Zeus"; // defect: Hades Poseidon never used
+ return value
+}
+
包含规则
array_overflow 检查数组越界的情况。不正确的缓存区访问可能损坏内存,导致程序崩溃或读取到权限外的内存。
以下提供一个或多个array_overflow案例
void foo() {
+ int array[10];
+ int i = get();
+ // i = 9;
+ if (i > 8 && i <= length(array)) { // Shoud be i < length(array)
+ array[i] = 1; // defect: array[10] overflow
+ }
+ array[i] = 1; // defect: array[10] overflow
+}
+
+
+void test(int i) {
+ int n= 10;
+ char *p = malloc(sizeof(int) * 10);
+ int y = n;
+ p[y] = 'a'; // defect: writing to buffer[y] overflow
+}
+
buff_overflow 检查strcpy
,strcat
字符串复制/拼接过程中长度不当导致的溢出, 同样gets
scanf
函数也视为不安全
以下提供一个或多个buff_overflow案例
void overflow1() {
+
+ char a[4]={0};
+ strcpy(a, "Poseidon"); // defect: len("Poseidon") > 4 strncpy is better
+ return;
+}
+
+void overflow2() {
+ char s1[10] = "1";
+ char s2[] = "1234567890";
+ strcat(s1, s2); // defect: len(s1 + s2) > 10
+ // strncat(s1, s2, 6) // strncat is better
+ return 0;
+}
+
+
包含规则
func_ret_null 函数返回值可能为nullpointer,但是调用该函数时指针未经判空便进行使用
在选用func_ret_null_full 时, 检查器会在项目内全局搜索空指针函数的调用情况,否则只会在相关文件内进行检查。
以下提供一个或多个func_ret_null代码案例
在下面代码中test
函数中调用get_name
可能返回空指针,在后续使用name
指针前应该判断是否为空指针
// name.hpp
+
+char* get_name(int id) {
+ char* name = 0;
+ if (id == 1) {
+ name = "Zeus";
+ } else if (id == 2) {
+ name = "Hades"
+ } else {
+ return nullpointer;
+ }
+ return name;
+}
+
+void test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect: name may nullpointer should check it
+ if (name != nullpointer) {
+ dosomething(name); // good
+ }
+}
+
+
在选用full_ret_null_full时,将会全局分析函数get_name
调用情况
// third.cpp
+# include "name.h"
+
+void name_test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect
+}
+
use_after_free 检查当指针已经被释放但在后续仍然使用该指针的情况。
以下提供一个或多个use_after_free代码案例
通常情况下已经释放的指针只允许置空或重新指向新的值,不允许存在读取或作为函数参数使用。
+void UAR() {
+ int* p = new int[];
+ p = get_array();
+ dosomething(p);
+ delete p;
+ p = NULL; // allow
+ p = get_array(); // allow: get array again
+ delete p;
+ dosomething(p); // defect: use as param
+ std::cout << "p[0] = " << p[0] << std::endl; // defect: read p
+}
+
forward_null 检查可能导致程序终止或运行时异常的错误。它查找指针或引用被检查是否为 null 或被赋值为 null,且之后被解引用的很多情况。
以下提供一个或多个forward_null代码案例
指针曾经有过检查null的操作则会视为有可能为空指针,之后在未被确认为非空指针情况下直接使用。将会视为forward_null
错误
void forward_null_1() {
+ int * p;
+ p = get_int_pointer();
+ dosomething(p);
+ if (p == NULL) {
+ std::cout << "Null Pointer Find" << srd::endl;
+ // return; // prefer: if return here
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // defect forward_null: p may NULL
+}
+
+
+void forward_null_2(int *p) {
+ dosomething(p);
+ if (p == NULL) {
+ return;
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // good
+ ...
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
以下案例在设置trust_param
为False
时将会生效,其将会默认认为函数参数存在空指针可能,必须确认无空指针可能时方可使用
void forward_null_2(int *p) {
+ dosomething(p); // defect: param p may NULL
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
reverse_null 检查已经使用过指针,但在后续又对指针进行了判空操作;会被认为之前使用指针也有可能是空指针。
以下将提供一个或多个reverse_null案例
void reverse_null(int *p) {
+ dosomething(p); // use p
+ if (p != NULL) { // defect reverse_null: It means p may NULL
+ dosomething(p);
+ }
+ ...
+
glob_null_pointer 检查文件内全局指针是否为空,指针赋值将会被认为不为空指针,但检测到空指针判断则视为指针此时可能为空,如果在可能为空时使用则会报错
以下将提供一个或多个glob_null_pointer案例
int *p;
+
+
+void thread1() {
+ p = get_int_pointer(); // p is not NULL
+ dosomething(p); // good
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL, because check p before
+}
+
+
+void thread2() {
+ *p = 6; // defect: p may NULL
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL
+}
+
包含规则
仅类虚拟函数允许重写。
function_override 检查非虚拟函数重写的情况。
以下提供一个或多个function_override代码案例
+
+class father{
+ public:
+ father(){};
+ ~father(){};
+
+ private:
+ virtual void test(){};
+ void test2(){ std::cout<<"hello";};
+};
+
+class man{};
+
+
+class son: public father, public man{
+ public:
+ son(){};
+ ~son(){};
+ private:
+ void test(){ std::cout<<"hello";}; // allow: virtual function override
+ void test2(){ std::cout<<"hello";}; // defect: bad override
+};
+
TCA独立工具TCA-Armory-R,别名RegexScanner,正则匹配工具,支持扫描文件名称和文本内容,支持页面直接自定义创建规则。
以下是接入步骤:
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到TCA-Armory-R工具,并将其权限状态调整为支持自定义规则。
规则权限详见自定义规则权限说明
进入工具管理入口,进入TCA-Armory-R工具页面,选择上方的“自定义规则”,然后点击“添加规则”:
进入“创建规则”页面,按照需求填写相关信息,完成后,点击页面最后的“确定”按钮提交。
规则扫描场景:扫描代码中的 github token,如果token以明文形式写在源码文件中,会造成隐私泄露,可能造成严重的安全事故。
正则表达式:匹配 github token 字符串,根据github token的一般形式,可以推断出正则表达式 ((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})。
TIP
只支持go正则语法: regexp
建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则名称、前端展示名称:建议使用单词首字母大写的格式,如 DetectedGithubToken
规则简述:作为扫描出来到问题标题
规则参数:
TIP
规则参数中的(3)(4)(5)属于新功能,需要将客户端client和工具库TCA-Armory更新到最新版本
(1) 参数格式类似ini的格式, 也就是key = value的格式
(2) [必选] regex
参数,用于指定扫描的正则表达式,例如: regex=((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})
。只支持go正则语法: regexp。建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
(3) [可选] regex{N}
参数,只有在已有regex
参数情况下生效,用于扩展扫描的正则表达式,其中 N 从1开始计数,例如: regex1=EAAAACZAVC6ygB[0-9A-Za-z]+
, regex2=EAAAAZAw4[0-9A-Za-z]+
。regex{N}
和regex
的表达式均为或关系,每一个匹配结果上报一个问题。
(4) [可选] regex_not
参数,用于指定正则过滤表达式,例如: regex_not=(?i)example
。可以对(2)(3)中regex匹配的字符串进行筛选,如果匹配则过滤该结果,不予上报。
(5) [可选] regex_not{N}
参数,只有在已有regex_not
参数情况下生效,用于扩展正则过滤表达式,其中 N 从1开始计数,例如: regex_not1=(?i)test
, regex_not2=(?i)fake
。regex_not{N}
和regex_not
的表达式均为或关系。
(6) [必选] msg
参数,用于展现issue说明, 例如: msg=检测到高危函数%s,建议替换。
msg中的“%s”使用regex中的group(用“()"括起来的部分)一一匹配,单个%s默认为整个regex匹配的字符串
如果regex没有定义group,则msg最多有一个%s, 并由整个regex匹配的字符串替代
如果msg里没有包含“%s”,则直接显示msg
如果msg没有提供,则会给出默认信息
(7) [可选] ignore_comment
参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如: ignore_comment=True
, 默认是False
(8) [可选] file_scan
参数,用于指定是否扫描文件名称,可选值:True、true、False、false 。例如: file_scan=True
, 默认是False
(9) [可选] include
参数,用于指定只扫描的文件匹配范围,基于相对路径,使用通配符格式,多项使用英文分号(;)隔开。例如: include=src/test;src/main.*;*.cpp
(10) [可选] exclude
参数,用于指定不扫描的文件匹配范围,格式同include参数,例如: exclude=tests;*.json
路径过滤(
exclude
,include
)采用Glob-Style的匹配模式,详见 Go-filepath-Match, 除了**
用来匹配零或多个目录,本工具会默认匹配前后目录。举例:
exclude=*.py
会忽略以下文件: main.py, src/main.py, main.py/install.shexclude=tests
会忽略以下文件: tests/test.py, a/tests/b/test.pyinclude=main.*
会只扫描以下文件: src/main.py, app/main.goinclude=src
且exclude=src/lib
会只扫描以下文件: src/main.py, src/project/proj.py; 忽略以下文件: src/lib/lib.py, src/lib/package/pack.js
(11)[可选] match_group
参数,用于指定正则匹配的分组,数值不能大于正则匹配分组数,例如: regex=(aws_account_id)\s{0,50}(:|=>|=)\s{0,50}([0-9]{12})
match_group=3
,匹配到第3个分组([0-9]{12})
(12)[可选] entropy
参数,用于指定正则匹配结果的最小信息熵,例如:entropy=3
,熵不大于3的匹配结果将被过滤
信息熵:熵(信息论) 可用于敏感信息(密钥、token)的检测 含义:可以理解为字符串的混乱程度,字符越随机,熵越大。因此,设置合适的熵,可以过滤掉一些误报或者人为测试用例。
进入 代码分析 - 分析方案 - 代码检查 - 自定义规则包 - 查看详细规则,添加规则。
代码分析支持 Eslint 分析,并支持用户自由扩展配置。
目前 TCA-Eslint 的适用场景很广,灵活扩展:
以下是接入步骤:
在进行高级配置之前,这里先普及下代码分析这边的基础概念——Eslint 类型。 由于 JavaScript 语法、 Vue 语法和 TypeScript 语法之间的区别,三者使用的语法解析器也是不一样的,这里基于其使用的语法解析器的不同,从 Eslint 中拆分出来了 Eslint_vue 和 Eslint_typescript 工具。可以根据需要选择对应工具下的规则进行分析。而配置也会基于类型的不同匹配到对应的工具中。 目前代码分析上 Eslint 类型有:
因为项目会用到各式各样的框架,其中会有全局变量是 Eslint 无法识别到的,比如 _
或者 jtest,从而导致分析出不少误报。这里支持使用下面环境变量设置这些全局变量,减少误报。可以在代码分析项目中设置对应的环境变量。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_GLOBALS | 字符串,以分号分割 |
ESLINT_VUE_GLOBALS | 字符串,以分号分割 |
ESLINT_TYPESCRIPT_GLOBALS | 字符串,以分号分割 |
比如:
ESLINT_JAVASCRIPT_GLOBALS=_:readonly;jtest:readonly
+
其中,
代码分析执行 Eslint 分析,默认会使用 Alloy Team 的 Eslint 配置来分析,但是也支持修改配置。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_VUE_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
代码分析也支持用户指定自己维护的 Eslint 配置文件进行分析。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_VUE_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
代码分析自带支持 Google 代码规范,可以在代码分析项目设置对应环境变量,使用对应的配置文件。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG_TYPE | 字符串, google,default,custom |
ESLINT_VUE_CONFIG_TYPE | 字符串, 可选:default,custom |
ESLINT_TYPESCRIPT_CONFIG_TYPE | 字符串, 可选:default,custom |
其中:
这里介绍 TCA-Eslint 的配置使用顺序:
可以在代码分析页面上设置分析路径设置,这里建议多使用 Exclude 设置,因为 Eslint 工具本身对 include 支持不友好。
Q:JavaScript 内存溢出
A:Eslint 执行可能会出现 Js 内存溢出,以下有三种方案可以解决:
NODE_OPTIONS="--max-old-space-size=4096"
+
ESLINT_MAX_OLD_SPACE_SIZE=4096
+
Q:一个配置同时分析 JS 和 TS
A:若代码库中既有 JavaScript 代码,又有 TypeScript 代码,并且共用一个配置文件。 若规则集中既有 Eslint 规则又有 Eslint_typescript 规则,为了避免执行两次 Eslint 以及可能出现重复单的情况,并且因为 Eslint_typescript 的语法解析器也能够解析 JavaScript 代码,所以这里将这样的项目当作 TypeScript 项目。
Q:找不到依赖
A:用户自己配置的配置文件中,可能会用到代码分析没有管理到的规则插件,导致分析时候找不到对应的依赖,这里有两个方案提供解决:
Q:custom 与指定配置文件的区别
A:- custom 模式,会检测代码库中的 Eslint 配置文件进行分析,包括子目录和代码注释中设置的配置,都是可以生效的。
Golangci-lint 是为了解决 GoMetalinter 的弊端而改版升级的。
比 GoMetaliner 快个 2 到 7 倍
共享代码缓存,消耗内存比 Gometaliner 少 26%
更精准的 issue,会内置一些 exclude 列表过滤掉误报 issue
支持增量分析
在 CI 系统上选用 TCA 插件,或者下载 TCA 客户端到本地机器上
因为 GolangCiLint 要求找寻到项目需要的全部依赖,否则就会执行失败。所以这里需要在 Ci 系统或者本地机器上配置好项目的依赖,并确保能够编译通过
检查是否设置了 GOPATH 和 GOROOT,在分析方案的环境变量中设置 GOPATH=$GOPATH
在 代码分析 页面上关联待分析的代码库并创建分析方案,并在代码检查-规则设置的自定义规则包里面添加 GolangCiLint 工具规则
在分析方案中增加编译命令
然后在 CI 系统上或者本地启动代码分析即可
若项目目录结构如下图,需要设置 include 执行 myproj,比如 src/myproj/*
这是因为 GolangCiLint 分析前会优先检查所有代码文件的依赖是否齐全,所以需要设置 include,让工具只关注 include 下面的代码文件的依赖。
在分析方案的过滤配置,路径过滤中添加 include 路径。
Q:出现 no go files to analyze 问题
A:这里可能为以下原因:
机器环境没有项目的完整依赖,使用以下命令查找对应依赖在 GOPATH 下是否存在或者 GOPATH 设置是否完整(有的项目有多个 GOPATH 内容),或者对应依赖是否存在,需要用户部署好机器环境
grep -nr "path/to/GOPATH" .
+
没有指定 include 分析路径过滤,这样才不会检查依赖中的依赖,而是关注源码文件的依赖完整性
也可能是某 go 文件中使用到该依赖,但是 GOPATH 没有设置正确的依赖搜索路径导致。需要找到依赖相对的当前目录:
grep -nr "path/to/GOPATH" .
+
然后设置到 GOPATH 中,比如
GOPATH=$GOPATH:$SOURCE_DIR/test
+
还有可能是部分依赖是需要编译之后生成的,需要正确填写好编译命令,使得项目编译成功。
Q:could not determine GOARCH and Go compiler 问题
A:跟问题 1 是一样的问题。解决方案也是一样。
Q:failed to run 'go env': exit status 1 问题
A:原因是找不到正确的 GOPATH。解决方案是设置 GOPATH 环境变量。
Q:GO 版本限制
A:因为 golangci-lint 用到了 go mod 特性,该特性是在 1.11 之后才有的。所以要求 go 版本在 1.11 版本以上。
规则配置是代码检查应用的规则集合,用于指定用哪些工具和规则进行代码分析扫描。目前,TCA 提供了覆盖代码规范、安全扫描、风格检查等方面的官方推荐规则包。
官方推荐规则包是TCA长期以来在业务中实践的经验结果,将相关的有效性高的工具和规则打包在一起。业务可以根据需要选择官方推荐规则包。也可以在自定义规则包中添加希望的工具和规则。
TIP
规则配置 = 自定义规则包 + 官方规则包
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置
可以单选或者批量多选规则
也可以根据搜索框进行多维度查询
该规则包针对 Objective-C/C++ 语言进行代码规范相关检查。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
为了帮助你正确地格式化代码,我们建议你使用clang-format进行代码自动格式化。工具可直接通过 Homebrew 进行安装:
brew install clang-format
+
安装完成后将 .clang-format 配置文件置于工程根目录,执行 clang-format -i FILE.m 即可完成自动格式化。目前格式化工具配置仅支持11.0版本。
该规则包可分析项目依赖组件,以及依赖组件中是否存在漏洞等问题。辅助开发者准确分析到依赖组件的安全性,选用安全可靠的依赖组件。
规则包中将漏洞规则分为“低危漏洞”、“中危漏洞”、“高危漏洞”三个等级,扫描出有漏洞的组件,TCA会提供问题组件名称和版本、漏洞情况介绍,以及可用的修复版本(如获取到)。
已支持语言:C/C++、C#、Go、Java、JavaScript、PHP、Python、Ruby、Scala、TypeScript等。
<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.javaweb.vuln</groupId>
+ <artifactId>javaweb-vuln</artifactId>
+ <version>3.0.3</version>
+ </parent>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <!-- 触发规则 -->
+ <version>2.1.8</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+</project>
+
TCA 现已支持依赖漏洞扫描规则包,可以在 TCA 分析方案中搜索勾选该规则包,快速体验。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
更多场景支持,欢迎提 issue 进行咨询扩展。
前端项目在长期发展过程中,由于框架开源许可证变更、框架性能外观等不适用等因素,需要对前端框架进行平滑切换,而这就需要腾讯云代码分析 TCA 的介入,方便对企业内所有前端项目进行批量分析统计,方便管理。
{
+ "name": "framework",
+ "version": "1.0.0",
+ "dependencies": {
+ "react": "^17.0.2", // 触发规则
+ "react-dom": "^17.0.2", // 触发规则
+ "react-hotkeys-hook": "^3.4.3", // 触发规则
+ "react-redux": "^7.2.5", // 触发规则
+ "single-spa": "^5.9.3",
+ "universal-cookie": "^4.0.4"
+ },
+}
+
TCA 现已支持前端框架检查规则包,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 前端框架检查规则包 -> 启用/查看规则
更多框架支持,欢迎提 issue 进行咨询扩展。
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。也是提升现网质量的最广泛最简单有效的方式。
但是在实际开发工作中,由于工作繁忙而遗漏或缺乏对单元测试的正确认识,有些开发盲目追求高覆盖率,没有对单元测试做断言,这样的单元测试用例属于无效用例。 为了检测此类无效用例,业务侧找来了代码分析介入,进行单元测试有效性验证。
// Bad case
+func Test_Demo1(t *testing.T) {
+}
+
+
+// Good case
+func Test_Demo2(t *testing.T) {
+ assert.NoError(t, err)
+}
+
TCA 现已支持 Go 语言的单元测试有效行验证,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 单元测试有效性验证 -> 启用/查看规则
更多语言更多单元测试框架支持,欢迎提 issue 进行咨询扩展。
可以发现执行路径较多的方法,降低代码的圈复杂度,可测性更高
检测阈值
默认为 20,表示当一个方法的圈复杂度超过 20 时则认为该方法为超标方法,需要被关注修改。
可以根据需要调整
可以发现重复的代码,避免重复代码可以让代码更简洁,更易维护
长度区间
是一个区间值,默认代码中一个单词(变量/操作符)长度为 1。
重复次数
是一个区间值,当一段代码重复次数达到指定区间才认为是有风险的。
上报限制
限制上报的重复代码块数,可以减少开发的压力,提高修复积极性。
从目录和业务纬度统计代码行数,也可以获取提交记录便于代码 Review
腾讯云代码分析平台支持给编译类的工具或编译型项目配置相关命令。
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描,申购完成后可联系平台管理员进行相关配置。
TIP
对于编译型语言,有些分析工具是可以通过分析编译产出的中间文件,更为准确地发现代码质量问题。
WARNING
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描(私有化版由客户自行评估即可)。
如果配置了编译命令,则需要在具有代码执行所需的编译环境的节点上执行代码分析。即需要用户在专机上提供编译环境(针对私有化版,客户可根据业务情况选择在公共节点机、用户专机、本地节点机提供编译环境即可)。
如以下一些编译环境:
JDK 环境及版本
gradle 环境
cmake & make 环境
visual studio 环境
...
WARNING
如果机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本,可以在分析方案的基础属性当中设定相应环境变量。
前置命令:
通常是项目编译前需要执行的命令,或用于清理之前编译过程的命令,如:make clean
, xcodebuild clean [-optionName]
。如无需要,可以不填。
编译命令:
项目的编译命令,具体可以咨询该代码库所属项目的开发
能够使项目编译成功的编译命令,可以填写多行或用 && 连接命令。
TIP
前置命令与编译命令是隔离的,即在前置命令中的操作不会对编译命令产生影响。
如在前置命令中 cd src && export TEST=src
,在执行编译命令时并不会跳到src
目录和获取TEST
环境变量。
TIP
咨询该代码库所属项目的开发,先确保先在本地工程根目录调试通过
编译命令:
android-studio 项目编译命令示例
gradle compileDebugSources --no-daemon -Dorg.gradle.jvmargs=
+
ant 项目编译命令示例
ant build
+
编译命令:
xcodebuild 命令(确保先在本地工程根目录调试通过)
xcodebuild -target dailybuildipa -configuration DailyBuild -sdk iphonesimulator
+
环境变量(分析方案-基础属性中配置):
XCODE_VERISON=10.1
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=DebugCopy
+
make 项目编译命令示例
make all
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=Debug
+
在上一节文档代码检查配置中我们大致已经了解规则配置主要由官方规则包和自定义规则包构成,本节将详细描述规则配置。
官方规则包是由腾讯云代码分析平台经过多年深耕,在业务中不断实践整理而出的规则集合包,然而平台有超过**10000+**的规则,有些规则并未放到官方规则包中,甚至有些规则是由用户自定义的规则。此外,有些官方规则包中的规则,对于不同的团队所需可能存在差异,因此产生了如下几种问题:
在规则配置中,如何添加规则?
在规则配置中,如果将官方规则包中的规则进行调整?
添加规则存在两种入口:
TIP
无论何种,最终都是将规则添加到自定义规则包中
用户可直接点击页面中的添加规则
用户可点击自定义规则,进入自定义规则包后,再点击添加规则
在添加规则过程中,可以单选或者批量多选规则,可以根据搜索栏进行多维度查询规则
用户可以点击进入官方规则包,进入官方规则包中,对已存在的规则进行编辑。
WARNING
在官方规则包中对规则的任意操作,实质上是将对应规则增加到自定义规则包中进行了相关操作。
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置。
腾讯云代码分析采用业界/自研的 80+ 款工具,配置代码检查项能够有效地发现代码中存在的异味代码
规则配置主要是以规则包为元素,由官方规则包和自定义规则包两部分组成。平台提供一些系列的官方规则包,覆盖规范、安全、推荐等方面。
用户可根据项目语言、规则包类型筛选不同的规则包,并启用/关闭规则包。
TIP
用户可以根据需要选择官方规则包进行扫描,并可以在官方规则包的基础上屏蔽某些规则或者调整默认的优先级,设置指定参数。这些操作都会记录在自定义规则包中。
自定义规则包是提供给用户自由选择工具规则的包。官方规则包上的调整实质上会记录到自定义规则包中,当自定义规则包中的规则和官方规则包的规则发生冲突,则自定义规则包优先级更高。
通过编译(代码解析和翻译过程)分析中间代码进行辅助分析,能更精准地发现更多潜在的代码问题。
为便于用户快速创建代码库进行分析,复用同类型的分析配置,平台提供了分析方案模板功能。
分析方案模板分为系统方案模板和个人自定义方案模板。
系统方案模板
全局可用。但是用户无法变更系统方案模板内容。如系统方案模板产生变更,需用户自行拉取最新模板内容。
个人自定义方案模板
自定义方案模板与团队挂钩,用户可自行创建、更新、同步方案模板,以及可进行权限控制。默认自定义方案模板团队内都可见。
分析方案模版用于在创建分析方案时作为模版参考。分析方案模版全局可用,不用和某个代码库关联。
创建分析项目时,可选择使用分析方案模板创建。默认会根据该分析方案模板创建出一个新的分析方案,并用该方案配置进行分析项目创建。
创建分析方案时,可选择使用分析方案模板创建。
用模版生成的分析方案和模版建立关联关系,当模版和生成的方案由差异时,可以由用户选择是否同步模版的内容到方案。并可以选择拉群哪些功能模块的配置。
方案名称
用于标示一个方案,每个方案名称都是唯一的。
分析语言
用于指明该方案是针对代码库何种语言进行分析。初次创建分析方案时会根据语言初始化分析方案相关配置。
运行环境
用于将任务分配到指定的环境节点机器上执行代码分析,需考虑项目在对应环境的节点机器上能否正常执行。
环境变量
每行 key-value 形式,非必填项。
可用于指定特殊编译环境:如机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本的可以设定相应环境变量。
可用于工具传递参数: 如ESLINT_MAX_OLD_SPACE_SIZE=4096
配置 Js 内存大小
可用于指定项目配置,如PYTHON_VERSION=2
指定为 python2 项目
TIP
对 Python 的分析默认采用 Python3,如果需要分析 Python2 请在环境变量中设置:PYTHON_VERSION=2
用于设定代码分析的范围,设定后,已经开启的代码检查、代码度量各项功能都会在指定的代码范围内生效。
目前支持正则表达式和通配符两种类型:
正则表达式
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用正则表达式格式,示例如下:
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/.*
+ 匹配根目录下的test目录:test/.*
+ 匹配所有_test.py后缀的文件:.*_test\\.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/.*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/.*
+
通配符
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用Unix通配符格式,示例如下
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/*
+ 匹配根目录下的test目录:test/*
+ 匹配所有_test.py后缀的文件:*_test.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/*
+
如果几个分析方案希望共享相同的路径过滤方案,可以通过导入导出路径配置的方式进行处理。
TIP
配置更改后,下次启动分析生效
全局 Issue 忽略状态同步
仅对代码检查生效。开启后,在 Issue 页面进行全局忽略操作时,其他利用该方案分析的分析项目在发现相同 Issue 时,会同步忽略该 Issue。否则不受全局 Issue 忽略状态同步影响。
可创建、编辑、清除主流代码托管平台的Oauth应用配置,为使用者提供OAuth授权支持。
支持平台及如何创建OAuth应用:
TIP
配置OAuth应用时,回调地址栏需填入当前TCA平台配置的域名或IP地址(如当前页面非80端口,需要显式指定端口号),作为Git平台上OAuth应用的回调地址。
可查看平台全部分析记录。
可点击查阅分析记录详情。
可查看平台创建的团队列表,并提供了相应筛选
可禁用、恢复团队
可查看全部工具(包含平台提供工具、团队自定义工具)。
可查看、编辑工具。
可变更工具权限状态。
TIP
工具的权限状态仅能由平台管理员进行变更调整,需谨慎调整
团队内可用:即工具配置了可用团队白名单的团队可以使用该工具,默认创建工具的团队已在白名单内
全平台可用:即不同团队都可见可用该工具
支持自定义规则,全平台可用:即该工具不同团队都可见可用,且支持用户添加团队所需的自定义规则,该自定义规则存在团队隔离,仅团队内可以,其他团队不可使用
可查看、编辑、创建平台用户。
可配置用户的登录密码、用户级别、超级管理员等。
可查看常驻节点状态,包含公共节点和团队节点。
可查看、编辑、删除常驻节点。
可配置节点工具进程。
可配置节点标签
可查看平台创建的项目列表,并提供了提供相应筛选
可禁用、恢复项目
团队 > 项目 > 代码库 > 分析项目
您可以创建一个团队,并可以在团队中创建多个项目来进行项目区分和项目管理。可以在一个项目中创建多个代码库进行代码分析。
团队成员分为管理员和普通成员两类。团队管理员具备团队全部权限。
项目成员分为管理员和普通成员两类。项目管理员具备项目全部权限。
成员权限的区分,具体点击查看成员权限
管理员可以通过成员管理为您的团队添加成员,通过分享邀请链接的方式邀请您的团队。
团队成员分为团队管理员和团队普通成员两类。
团队管理员:可以邀请其他成员加入团队,具备团队内所有权限。
团队普通成员:可以创建项目,可以访问自己有权限的项目。创建项目的人会自动成为这个项目的项目管理员。
项目成员分为项目管理员和项目普通成员。
项目管理员:具备项目内全部权限。
项目普通成员:可以查看项目内的配置信息和分析结果等各项信息,并且可以启动分析,但是无其他操作权限。
WARNING
团队节点及标签说明
团队节点是团队注册并管理的私有节点。
团队标签用于关联团队内的节点机器与分析项目。
团队可以利用团队标签注册并使用团队节点。
在项目的分析方案中配置运行环境为团队标签后,才可将该项目的分析任务下发到对应的团队节点。
团队节点仅支持运行当前团队中的分析任务,节点可执行的任务范围取决于该节点的负责人权限:
团队因资源可靠性或项目敏感性,需使用私有机器资源
团队项目分析依赖特定机器环境(比如CPU架构、操作系统等)
以上场景,团队可接入专机资源作为团队节点,仅分析自己业务的代码库,以保证执行效率,保护源码安全,支持项目环境依赖等。
参考客户端常驻节点分析进行环境配置和启动节点。
完成团队节点注册后,可以在当前团队节点管理
下看到对应的节点信息,同时需要进行节点配置
WARNING
首次注册团队节点,节点状态默认为不可用,需调整节点状态为“活跃”:
配置节点关联的工具进程:
TIP
CodeDog
标签为不同的系统类型(Linux、MacOS、Windows)建立标签,比如专属标签-Linux
、专属标签-Mac
等您可以创建一个团队标签,并配置到您的团队节点和您的分析方案中
创建团队标签。
配置团队节点所属标签。
配置分析方案运行环境。
WARNING
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。WARNING
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。TIP
TCA 客户端除了通过localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。
和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
希望通过并行执行分析来提高分析效率
希望尽量使用公共资源或使用专机资源
节点机器上具备客户端及客户端相关依赖环境,可查阅本地分析-前置步骤部分进行配置。
config.ini
文件将<Server IP地址>
替换成实际的 TCA 平台 IP(可包含端口号)。
国内使用 github 拉取网络较慢,推荐使用腾讯工蜂拉取,需要修改以下配置:
TOOL_CONFIG_URL=https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
TOOL_LOAD_ACCOUNT
中。(注:没有腾讯工蜂账号的需要注册;由于腾讯工蜂的开源仓库也要求使用账号才能拉取,所以此处必须填写账号密码)从TCA前端页面中获取 token
,前往 个人中心-个人令牌-复制Token
如启动团队节点,还需获取团队编号:org_sid,获取方式: 从 TCA 平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
两种方式可选启动客户端:
client
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
+
python3 codepuppy.py -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
client
目录下,执行命令:./codepuppy -l codepuppy.log start -t <token>
+
./codepuppy -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
常驻节点首次启动后,需要到节点管理页面管理节点状态:
设置节点状态: 进入 TCA 节点管理页面。管理入口
-节点管理
,可以看到当前在线的节点,节点状态默认为不可用
,需将其设置为**活跃
**才可用于接收和执行任务。 也可以按需修改节点名称、标签、负责人等信息。
(按需可选)配置节点工具进程: 进入工具进程配置页面,对节点支持的工具进程进行管理(默认会全部勾选),未勾选的工具进程,将不会在该节点上执行。
(按需可选)设置节点标签: 节点标签会与分析方案中的运行环境标签进行匹配,只有相同标签的任务才会下发到该机器节点上。
对本地代码目录下的临时代码(未关联scm仓库或未提交到scm仓库的本地代码)进行扫描,对某个目录或某些文件进行快速扫描,产出本地扫描结果。
该模式不与scm代码仓库关联,只对给定的目录或文件进行扫描,不依据提交版本号做增量分析,也不定位问题责任人。
由于该模式不与scm代码仓库绑定,因此不能直接使用分析方案(分析方案上归属于某个代码仓库下的),需要使用分析方案模板的配置来扫描。
目前快速扫描模式只支持代码检查,暂不支持代码度量,请勿开启代码度量配置项(无法展示结果)。
配置好方案模板后,从页面URL中获取到分析方案模板ID,分析方案模板页面URL格式:http://{域名}/t/{org_sid}/p/{team_name}/template/{分析方案模板ID}
,template
后面的数字即分析方案模板ID。
client
目录下,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
TOKEN
: 必选,从TCA平台页面获取,前往[个人中心]
-[个人令牌]
-复制TokenSCHEME_TEMPLATE_ID
: 必选,分析方案模板ID,从步骤1中获取ORG_SID
: 必选,团队编号,从TCA平台团队概览URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/profile
client
目录下,执行命令:python3 codepuppy.py quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
参数说明:
SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
希望在本地随时分析。
接入持续集成系统实现自动化分析。
1. 客户端运行环境机器配置推荐
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
2. 本地需具备客户端
下载开源版源码。 或从开源版release下载客户端以运行客户端二进制;
3. 安装Python环境和第三方库(仅客户端源码启动分析需要)
python3
和 pip3
命令pip3 install -r CodeAnalysis/client/requirements/app_reqs.pip
4. 安装第三方工具(docker下启动分析可跳过)
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)config.ini
文件<Server IP地址>
替换成实际的TCA平台IP(可包含端口号)codedog.ini
文件codedog.ini
获取方法:
方法一: 打开TCA源码CodeAnalysis/client/codedog.ini
,填写配置信息
方法二: 从开源版release下载客户端包,解压后打开codedog.ini,填写配置信息。
方法三: 在TCA平台平台上配置好对应信息后,下载配置文件到本地使用。
codedog.ini
中以下字段为必填项:
字段名 | 填写说明 |
---|---|
token | 从TCA平台页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从TCA平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他字段按需填写。
启动客户端分析有三种方式可选:客户端源码下启动分析、客户端二进制启动分析、docker下启动分析
进入到客户端client
目录下
执行命令: 客户端源码:python3 codepuppy.py localscan
进入到客户端client
目录下
执行命令: 客户端源码:./codepuppy localscan
在client目录下,执行以下命令:docker build -t tca-client .
(需已安装Docker)
WARNING
注意:因为以下步骤会将代码目录挂载到容器中,需要先将codedog.ini里面的source_dir修改为/workspace/src,其他参数保持不变。
执行Docker容器有以下两种方式:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
通过以下方式,进入容器内的bash终端后,通过命令行启动client代码:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
-(1)将<Server IP地址>
替换成实际的serve ip(可包含端口号)。
填写以下必填项:token
,org_sid
,team_name
,source_dir
字段名 | 填写说明 |
---|---|
token | 从tca页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从tca项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他可选项按需填写。
TIP
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
参考Docker官方文档:Docker下载和安装
在client
目录下,执行以下命令:docker build -t tca-client .
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
TIP
适用于深度体验,可以复用本地编译环境,使用编译型代码分析工具。
可能会有系统环境兼容问题。
python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)client
目录下python3 codepuppy.py localscan
TIP
localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)个人中心
-个人令牌
-复制Tokenclient
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。管理入口
-节点管理
,可以看到当前在线的节点,可以修改节点名称、标签、负责人等信息。WARNING
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。WARNING
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。目前 TCA 支持以下工具:
官方工具 | 第三方工具 |
---|---|
TCA-0Day_Checker(测试版) | androidlint |
clangwarning | checkstyle |
codecount | clang |
customfilescan | cobra |
customscan | cpd |
fbrjs | cppcheck |
javawarning | cpplint |
regexfilescan | dart_code_metrics |
regexscan | dartanalyzer |
TCA-Armory(测试版) | detekt |
TCA-Loong_Beta龙(测试版) | eslint |
unusedresource | eslint_typescript |
eslint_vue | |
findbugs | |
flake8 | |
flawfinder | |
flow | |
golangcilint | |
gometalinter | |
htmlcs | |
infer_cpp | |
infer_java | |
infer_objectivec | |
ktlint | |
kunlun-M | |
lizard | |
luacheck | |
phpcs | |
pmd | |
pylint | |
rips | |
scalastyle | |
semgrep | |
shellcheck | |
spotbugs | |
stylecop | |
stylelint | |
swiftlint | |
sonarqube | |
sonarqube_java | |
sonarqube_cs | |
tca_plugin_sqlcheck | |
tscan_cpp | |
tscan_csharp | |
tscan_lua | |
include-what-you-use |
腾讯云代码分析平台目前已集成众多自研、知名开源工具,并采用分层分离的架构,可以快速对接企业内部团队研发的工具,并将其集成到平台内供企业内部团队使用,满足快速自助的管理工具。
按工具来源划分,工具包含平台提供的工具,以及团队接入的工具。
平台提供工具:由腾讯云代码分析平台提供的一系列自研、知名开源工具,此类工具都为公开工具,任何团队都可以使用此工具及工具规则进行代码分析。
团队接入:由团队自行接入的工具,默认该工具仅能在团队内使用,如需跨团队使用或任何团队都可以使用需联系平台管理员进行配置。
按工具使用划分,工具包含可自定义规则工具、可使用工具两种。
可自定义规则工具:该工具任何团队都可以使用,且该工具可以支持添加团队所需的自定义规则。如RegexScan
工具,各个团队都可以使用该工具提供的规则,也可以自定义规则,此自定义规则团队隔离。
可使用工具:该工具团队内可使用,但不能添加自定义规则
TIP
目前开源版仅**RegexFileScan
、RegexScan
、TCA-Armory-R**等三款工具支持用户自定义规则
需平台管理员在后台管理-工具管理中找到对应工具,并将其权限状态调整为支持自定义规则。
默认自定义工具只能当前团队内使用,添加 工具白名单
后可以让其他团队使用。
TIP
添加工具、添加工具规则、添加自定义规则等均需团队内管理员可操作。分析。
【用户 A1】【用户 A2】为【团队 O1】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 B1】【用户 B2】为【团队 O2】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 A1】在工具管理页面添加了【工具 T1】,该工具为团队内工具; -【用户 A1】【用户 A2】均可操作该工具,如修改工具信息、添加工具规则等,【用户 A3】仅可以使用该工具,如在规则配置页面添加该工具规则;
由于【工具 T1】目前仅【团队 O1】可用,【团队 O2】中无法看到此工具,即【团队 O2】内的成员无法使用该工具。
如需【工具 T1】也让【团队 O2】使用有两种解决方法:1. 【工具 T1】将【团队 O2】加入使用白名单;2. 向平台发起申请,由平台管理员将【工具 T1】调整为全部团队都可使用。
正则工具 RegexScan
,进入工具-自定义规则栏,发现没有添加规则的入口;腾讯云代码分析平台支持用户自助添加代码分析工具。
适用场景:自定义规则无法满足团队业务复杂需求,需要更多的代码逻辑来匹配目标代码的情况。通常需要团队业务方自行实现对应代码分析工具。
只需要几步操作:
扩展集成工具免责声明
被扩展集成进腾讯云代码分析系统的任何非官方工具,该类工具对于腾讯云代码分析系统等于黑盒,腾讯云代码分析系统不对该类工具负责,由该类工具方承担所有责任(包括但不限于分发被分析代码,产生代码以及相关信息泄漏)。
根据需要匹配的目标代码场景,编写对应的工具逻辑。 可以参考 Python 实现的 Demo 项目。
必要:
运行方式:支持命令行执行,比如 python run.py 或 run.exe,执行命令的工作目录为工具代码的根目录。
运行环境说明:
工具管理
-工具依赖
中查看,创建工具时可供选择,执行时会自动配置好依赖环境。平台已提供的环境变量
SOURCE_DIR:要扫描的代码目录路径
+DIFF_FILES: 值为一个json文件路径,文件内容为增量扫描的文件列表(增量扫描时可用)
+SCAN_FILES: 值为一个json文件路径,文件内容为需要扫描的文件列表(增量或全量扫描均可用)
+TASK_REQUEST: 值为一个json文件路径,文件内容为当前扫描任务参数
+RESULT_DIR: 结果result.json输出的结果目录路径
+
工具命令声明
在工具仓库根目录下,添加一个tool.json
文件,声明工具的检查和扫描命令,比如:
{
+ "check_cmd": "python src/main.py check",
+ "run_cmd": "python src/main.py scan"
+}
+
参数说明:
check_cmd
: check_result.json
文件中,文件内容为{"usable": true}
或{"usable": false}
。run_cmd
: result.json
文件中。工具输出格式要求
RESULT_DIR
环境变量指定的目录下的result.json
文件中(Python 示例代码)import os
+import json
+result_dir = os.getenv("RESULT_DIR", os.getcwd())
+result_path = os.path.join(result_dir, "result.json")
+with open(result_path, "w") as fp:
+ json.dump(result, fp, indent=2)
+
result.json
文件格式如下:[
+ {
+ "path": "文件绝对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+ },
+ ...
+]
+
refs
字段说明:
非必需项,可无。该字段记录问题回溯路径信息。比如当前行的代码问题,是经过上下文的三行代码执行路径而导致的,可以将这三行的位置及提示信息,按顺序添加到 refs 数组中。
创建代码库,将工具源代码或编译打包后的可执行文件,提交到代码仓库中(建议提交到master分支,TCA默认拉取的是master分支)。
建议代码库中加入 README.md 文件,说明工具功能和维护人。
后续需要修改工具实现逻辑,可以直接更新代码库,TCA 平台在执行该工具时,会自动拉取最新工具代码版本。
进入工具管理页面,点击创建工具
填写工具信息
部分参数说明:
工具仓库地址,即前述步骤中提交的工具 git 代码库地址,默认拉取的是master分支,如果是其他分支,需要在仓库地址后加上#分支名
,比如:https://github.com/xxx/xxx.git#main
工具认证,授权拉取工具仓库的权限
执行命令,该命令会在工具根目录下执行
环境变量,工具执行所需的环境变量
License,如果是开源工具,填写工具遵循的开源协议,或者填写自研共建
是否为编译型工具,表示在使用该工具对用户代码进行分析时,是否要求代码需要编译或可执行编译
注意:针对特殊扫描场景的工具(比如检查代码库下是否包含某些第三方依赖目录,结果不涉及单个代码文件的),无法对结果进行代码文件处理,可以通过设置以下环境变量,跳过一些通用的结果处理步骤,避免问题结果被过滤掉:
BLAME_TYPE=NO_BLAME
,跳过对代码行/代码文件进行文件责任人定位(结果非单个文件/代码行时使用)FILTER_TYPE=NO_VERSION_FILTER
,跳过检查问题路径(path字段)是否为已提交到代码库中的文件(结果非单个文件/代码行时使用)IGNORE_TYPE=NO_ISSUE_IGNORE
,跳过注释忽略处理(结果非单个文件/代码行时使用)添加工具依赖
添加完成后,会展示已添加的依赖方案:
工具依赖说明:
完成工具创建后,进入规则列表,为工具添加规则
填写规则信息
部分参数说明:
规则简介:简要描述规则发现的是什么问题,扫描结果中会作为问题标题展示
详细描述:可详细描述规则,以及规则的解决方式,建议附上解决案例 demo
解决方法:按照实际情况,说明该代码问题的解决方法,建议附上解决案例 demo
规则参数:如果不需要通过规则参数传递信息,可留空
TIP
需要联系平台管理员协助操作,在管理入口
-节点管理
中进入需要配置的机器节点的工具进程配置
中,找到对应工具,勾选工具进程。
完成节点配置工具进程后,才能在项目中采用该工具进行分析。
进入到项目中,在分析方案
-代码检查
进行规则配置。
点击添加规则,找到对应工具规则进行添加。
添加完成后,启动分析,为了将规则应用到所有代码文件,建议启动一次全量分析(增量分析只会分析自上次扫描后变更的文件)。
默认自定义工具仅团队管理员可操作,团队内所有成员可使用。
团队管理员才能创建工具,添加工具规则等,具备该工具全部权限
团队内所有成员可使用该工具规则,如在规则配置中添加此工具规则,团队普通成员仅只读权限
工具希望全平台使用?
由于全平台使用的工具影响范围较大,建议团队先在团队内对工具进行充分测试,保障团队内工具的高有效性,如需全平台使用,需联系平台管理员进行申请
平台管理员需对此工具进行审核,在确保工具的高有效性下可将此工具权限调整为全平台可使用
自定义规则即由业务团队根据自身需求,由业务团队自行设计提供的规则。
工具需开放支持自定义规则权限,才可添加自定义规则。
当前平台提供的工具中,仅TCA-Armory-R、RegexFileScan
、RegexScan
三款工具支持使用用户自定义规则。
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到对应工具,并将其权限状态调整为支持自定义规则。
自定义规则仅支持团队管理员添加,且默认仅团队内可见。
如需将自定义规则加入工具默认规则,需联系工具提供方团队管理员添加。
正则工具 RegexScan
即为开放了自定义规则功能的工具,可进入工具管理页面,搜索工具名称RegexScan
,查看该工具已存在的规则以及根据团队业务需求,添加自定义规则。
适用场景:通过正则表达式,能够匹配到目标代码的情况。
根据团队业务需求设计正则表达式
TIP
建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则示例:
规则分析场景
分析代码中的 usleep() 方法调用,如果参数小于 100 ,容易造成 CPU 使用率过高,造成性能浪费,判断为缺陷。
正则表达式
匹配 usleep() 字符串,括号中的内容为 1 位或 2 位整数,那么正则表达式可以写成 \busleep\s*\(\s*\d{1,2}\s*\)
,这里考虑了字符串中存在空格的情况。
进入正则工具添加自定义规则
进入工具管理页面,找到正则工具RegexScan
,并点击进入自定义规则列表页,点击添加规则按钮。
填写规则信息
规则参数填写说明(必要):
参数格式类似 ini 的格式, 也就是 key = value 的格式
【必要】 regex 参数,用于指定分析的正则表达式, 例如: regex = \busleep\s*\(\s*\d{1,2}\s*\)
。
【必要】 msg 参数,用于展现 issue 说明, 例如: msg = 函数方法%s 已经废弃,请使用 xxx 方法
。
msg 中的“%s”使用 regex 中的 group(用“()"括起来的部分)一一匹配。
如果 regex 没有定义 group,则 msg 最多有一个%s, 并由整个 regex 匹配的字符串替代
如果 msg 里没有包含“%s”,则直接显示 msg
如果 msg 没有提供,则默认为“发现不规范代码:%s”(不建议使用默认格式,太笼统)
【可选填】 ignore_comment 参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如 ignore_comment=True
, 默认是 False
【可选填】 include 参数,用于将指定分析文件匹配范围,使用 unix 的文件匹配格式,多项使用英文分号;隔开。例如 include = path/to/dir;path/to/\*.cpp
【可选填】 exclude 参数,用于指定不分析的文件。格式参考 include 参数。
将自定义规则添加到项目分析方案中
添加完成,可在分析方案-代码检查-规则配置中添加该自定义规则
Create a new team
Check here about Team manage
Create a new project for your team, or select an existing project then open the project
Register your repository and go to code analysis
TIP
After initialization, you can use Online analysis
or Client analysis
to start a code analysis。
Online analysis means that the analysis task is registered to the execution queue in the server, and the task is assigned to the resident analysis node configured in the TCA. After the analysis is completed, the analysis result will upload to the TCA.
TIP
Use online analysis, the TCA must have at least resident analysis node:
If your TCA is deployed using the official out-of-the-box deployment script (Docker deployment, Docker-compose deployment, and source code deployment), an analysis node (client) has been started by default, which can be directly used for online analysis. Check here about Node management.
You can also add more analysis nodes to perform parallel code analysis. To add new nodes, see About node
If there is no node avaliable, online analysis tasks cannot be assigned. Unassigned tasks will be automatically cancelled after timeout。
Client analysis is local analysis. You need to have a client locally and configure the client configuration file codelog.ini
, see Start a local analysis to configure your local client. After analysis, the report data will be uploaded.
After the analysis, the data will be reported to the server. You can enter the analysis history page to check the analysis records and results.
After the analysis, you can check a branch overview and Defects list by entering Branch overview
等。
TIP
以下说明以 Jenkins 2.361.2 版本为例。
Jenkins插件有以下两种获取方式:
方式一:在 TCA 源码的plugin/jenkins_plugin
目录下,执行命令mvn package -DskipTests
,打包完成后进入target目录会看到tca_jenkins_plugin.hpi
的安装包。
方式二:从TCA release 安装包中,获取jenkins_plugin.hpi
:https://github.com/Tencent/CodeAnalysis/releases。
在Jenkins中通过【Manage Plugin】-> 【Advanced】->【Deploy plugin】的方式选择 Jenkins_plugin.hpi文件上传安装,并重启Jenkins。
最终在【Installed】里搜索出【TCA】代表插件安装成功。
在CodeAnalysis目录下执行代码
bash ./scripts/base/install_bin.sh
+
将client
目录下的config.ini
文件中的<Server IP地址>
替换为部署的开源版TCA的IP地址(可包含端口号)
如已创建后待使用的团队和项目,可跳过此步。
进入已部署好的TCA页面,点击【创建团队】,成功后【创建项目】。
进入Jenkins设置界面,在【Manage Jenkins】->【Configure System】->【Global properties】中添加环境变量:
Name:PYTHONPATH
Value:xxxx(路径不包含python3)
Value:GITPATH
Value:xxxx(路径不包含git)
创建一个构建任务,配置代码库信息,进入Jenkins,通过【New Item】创建一个空白任务,在任务配置中【Source Code Management】配置待分析的代码库地址和凭证。Repository URL
: 填入远端仓库地址Credentials
: 添加仓库的用户名和密码作为凭证,如果是公开仓库,可以不设置仓库凭证
在构建任务的【Build】中选择【TCA】插件并配置以下参数:
CodeAnalysis目录绝对路径
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)团队ID
: 在 TCA 中创建的团队的标识ID,可在TCA【团队概览】中获取“团队唯一标识”项目名称
: 在 TCA 中创建的项目的标识ID,可在TCA【项目概览】中获取“项目唯一标识”Token
: 在 TCA 的【个人中心】->【个人令牌】中获取分支名称
: 需要扫描的代码分支名称语言类别
: 项目需要扫描的语言分析方案模板ID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)分析方案名称
: 指定创建出来的分析方案的名称(选填)全量扫描
: 不勾选默认启动增量扫描质量门禁
: 设置质量门禁值,配置和使用参考 设置质量门禁
配置完成后点击【Save】保存。
在步骤中添加TCA插件参数配置语句,下面的配置语句可作为参考;注意:如果是release版本v1.11.0及之前的老版本(包含源代码构建生成和release获取)插件,语法参数略有差别,请参考issue1150
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ }
+ }
+ }
+}
+
+
codeAnalysisPath
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)teamId
:团队IDprojectName
: 项目名称token
: 在 TCA 的【个人中心】->【个人令牌】中获取branchName
: 需要扫描的代码分支名称languageType
: 项目需要扫描的语言refSchemeID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)scanPlan
: 指定创建出来的分析方案的名称(选填)threshold
: 设置质量门禁值total
: 是否全量扫描,填ture
为全量扫描,不填或填false
为增量扫描
点击【Build Now】启动构建。
进入构建任务,在【Console Output】中查看执行过程。
执行完成后,可在下方看到代码分析的结果链接,也可在【代码分析报告】中获取代码分析的json报告。
在上述 TCA 插件配置部分填写质量门禁
参数,需要填写一个整数,即当前分支的扫描问题量大于该质量门禁值时,判断为不通过;否则为通过。完成后会将TCA结果状态(success
|failure
)输出到工作空间下的tca_threshold.txt
文件中,供后续步骤判断和终止流水线。
在TCA插件后增加shell命令步骤,输入以下脚本内容:
tca_status=`cat tca_threshold.txt`
+if [ "${tca_status}" == "success" ]; then
+ echo ">> tca scan pass!"
+else
+ echo ">> tca scan fail! exit code 255"
+ exit 255
+fi
+
当质量门禁不通过时,会终止流水线(退出码:255)。
以下是pipeline脚本使用质量门禁进行相应操作的示例,你可以在if和else部分写入你想要运行的脚本
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ script{
+ def tca_status = readFile('tca_threshold.txt')
+ if (tca_status == "success") {
+ echo ">> tca scan pass!"
+ } else {
+ echo ">> tca scan fail! exit code 255"
+ error("TCA scan failed. Terminating pipeline.")
+ }
+ }
+ }
+ }
+ }
+}
+
TCA的file
服务支持对接MinIO
作为底层存储,将文件转发到已部署的MinIO平台上进行持久化存储
注意:如果之前已经使用本地进行存储,切换为MinIO后,之前已经上传的文件只能到服务部署的目录
server/projects/file/data
查看,不支持通过页面进行下载
获取MinIO平台登录的账号密码,用于上传文件
file
服务的配置修改server/configs/django/local_file.py
文件,取消以下代码的注释
# MINIO
+STORAGE = {
+ "CLIENT": os.environ.get("FILE_STORAGE_CLIENT", "MINIO"), # 存储方式
+ "OPTIONS": {
+ "MINIO_ENTRYPOINT": os.environ.get("FILE_MINIO_ENTRYPOINT"),
+ "MINIO_ACCESS_KEY": os.environ.get("FILE_MINIO_ACCESS_KEY"),
+ "MINIO_SECRET_KEY": os.environ.get("FILE_MINIO_SECRET_KEY"),
+ }
+}
+
修改server/scripts/config.sh
文件,填写MinIO的信息
export FILE_MINIO_ENTRYPOINT=<MinIO平台的地址>
+export FILE_MINIO_ACCESS_KEY=<MinIO平台的登录账号>
+export FILE_MINIO_SECRET_KEY=<MinIO平台的登录密码>
+
修改完配置后,如果服务已经正在运行,则执行以下命令重启服务
$ cd server
+$ ./scripts/deploy.sh start
+
删除nginx已有的文件服务器配置文件/etc/nginx/conf.d/tca_file_local.conf
文件,然后执行
rm /etc/nginx/conf.d/tca_file_local.conf
+ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf
+
也可以修改
server/scripts/init_config.sh
# 注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_local.conf /etc/nginx/conf.d/tca_file_local.conf +# 取消注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf +
修改完配置后,如果nginx已经正在运行,则执行nginx -s reload
以上两个步骤操作完成后,就可以通过MinIO
存储文件了~
在实际的生产环境的部署过程中,团队的MySQL的管理员可能不会给到应用账号create等比较敏感的权限,这种情况下,我们可以通过手动迁移数据的方式起到和等同Django migrate的效果。
操作步骤:
/data/CodeAnalysis/server/
,以下路径均为工作目录内的相对路径)vi ./scripts/config.sh
:填写一个有全部权限的MySQL数据库地址和Redis信息以及根据需要调整配置信息,主要的工程配置已提供默认值,字段说明可以查看文档bash ./scripts/deploy.sh init
:初始化DB、安装依赖和运行初始化脚本mysqldump -u user -p –databases codedog_main codedog_analysis codedog_file codedog_login > codedog_all.sql
server/sql/init.sql
SET SESSION FOREIGN_KEY_CHECKS=0
,否则会因为数据中有外键关联导致导入失败source /youdir/codedog_all.sql;
SET SESSION FOREIGN_KEY_CHECKS=1
bash ./scripts/deploy.sh start
,无需执行 init
方法,否则会导致数据重复写入TCA Server由Main、Analysis、Login、File、ScmProxy五个微服务组成,主要技术栈为Django+uwsgi+nginx
注意:以下配置内容可以参考 config.sh文件进行查阅,使用时主要关注 MySQL、Redis 的配置,其他配置均已提供默认值,可以根据需要进行调整
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Main服务DB配置:
Main服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Analysis服务DB配置:
Analysis服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Login服务DB配置:
服务交互配置:
注:配置文件中的pub_key与private_key生成方式可以参考以下方法:
$ ssh-keygen -t rsa -b 1024 -m PEM -f tca_login.key
+$ openssl rsa -in tca_login.key -pubout -outform PEM -out tca_login.key.pub
+$ cat tca_login.key # 作为private_key的内容
+$ cat tca_login.key.pub # 作为pub_key的内容
+
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取File服务DB配置:
服务交互配置:
File存储引擎配置
LOCAL
/MINIO
/COS
LOCAL
,可以指定FILE_STORAGE_DIR
文件存放的路径MINIO
,可以指定以下变量: COS
,可以指定以下变量 服务配置:
0.0.0.0
8009
127.0.0.1:8009
TIP
该Q&A文档会持续更新,非常欢迎您的建议与共建!
如果您遇到任何未在此处列出的部署或使用问题,请在 GitHub issue 系统中进行搜索。如果仍未找到该错误消息,您可以通过社区提出问题,获得帮助。
如果在执行pip install
环节出现以下错误,可以调整一下镜像源:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='files.pythonhosted. org', port=443): Read timed out.(read timeout=15)") '
+
该错误是访问官方pypi
下载源时网络不通或者不稳定导致,可以通过以下方式调整:
本地部署时,调整pypi
下载源配置方式:
mkdir ~/.pip/
+echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
Docker-Compose部署时,调整pypi
下载源配置方式:
vi server/dockerconfs/Dockerfile-common
+
调整文件中最后一行 RUN
指令
RUN mkdir -p log/ && \
+ mkdir ~/.pip/ && \
+ echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf && \
+ pip install -U setuptools pip && \
+ pip install -r requirements.txt
+
注:如果需要指定其他pypi
下载源,可以将https://mirrors.cloud.tencent.com/pypi/simple
进行替换
如果出现以下错误:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f6d4ac24910>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/setuptools/
+
该错误是无法正常解析pypi
访问域名,需要检查一下本地的dns配置是否正常
TCA Server使用Docker-Compose依赖的Docker版本需要是1.13.0
及以上,可以执行以下命令查看Docker版本
$ docker --version
+Docker version 18.09.7, build 2d0083d
+
文档相关:
如果启动Docker-Compose输出以下错误:
* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+
问题原因:可能镜像构建目录权限不足,导致异常。 解决方案:
docker-compose build
可以通过日志查看是哪个镜像构建异常docker build .
可以看到详细错误信息,结合具体错误信息进行处理文档相关:
目前TCA基础镜像是使用python:3.7.12-slim
,该镜像是基于debian bullseye(debian 11)
版本构建的,对应的源需要选择 bullseye
版本的源。
如果使用默认的下载源会报错或访问速度比较慢,可以调整server/dockerconfs/Dockerfile-common
,指定其他国内下载源:
# FROM python:3.7.12-slim
+
+# 增加一下内容用于指定下载源
+RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye main non-free contrib' > /etc/apt/sources.list && \
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list && \
+ echo 'deb http://mirrors.tencent.com/debian-security bullseye-security main non-free contrib' >> /etc/apt/sources.list
+
+# ARG EXTRA_TOOLS=...
+
如果出现以下错误:E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages
可以做以下检查,确认是什么原因:
使用Python执行时提示ImportError: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory
,该如何处理
在本地安装Python的目录中查找该文件,比如Python的安装目录是/usr/local/python3
,可以执行find /usr/local/python3 -name "libpython3.7m.so.1.0"
,确认本地是否存在该文件
如果本地存在该文件,则执行以下命令:(注:需要将/usr/local/python3
调整为本地实际的Python3安装路径)
# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
如果本地不存在该文件,则可能需要重新安装Python3:(注:以下是将Python安装到/usr/local/python3
,可以根据实际情况进行调整)
# 编译前配置,注意重点:需要加上参数 --enable-shared
+$ ./configure prefix=/usr/local/python3 --enable-shared
+
文档相关:
compose_init.sh
脚本的pip install
提示sha256
不匹配错误在构建镜像的pip install
步骤提示以下报错时:
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
+ setuptools from https://mirrors.cloud.tencent.com/pypi/packages/fb/58/9efbfe68482dab9557c49d433a60fff9efd7ed8835f829eba8297c2c124a/setuptools-62.1.0-py3-none-any.whl#sha256=26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8:
+ Expected sha256 26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8
+ Got ddaacc49de5c08c09d744573240a9a49f24f65c5c72380e972433784caa68d98
+
可以执行export ORIGIN=normal
,然后再执行./compose_init.sh
注:执行
export
命令的作用是调整为pypi
默认官方下载源进行pip install
在M1机器上使用默认配置启动docker-compose,会出现mysql
和scmproxy
服务启动失败,需要做以下两步调整
调整docker-compose.yml
文件,修改MySQL的镜像版本:
# 默认:
+image: mysql:5.7.24
+
+# 调整后:
+image: mariadb:10.5.8
+
调整server/dockerconfs/Dockerfile-common
文件,修改Python的镜像版本:
# 默认:
+FROM python:3.7.12-slim
+
+# 调整后:
+FROM amd64/python:3.7.12-slim
+
如果启动服务时,提示:celery could not be found
或gunicorn could not be found
,需要做以下检查
python -v
检查输出,确认当前python版本是否为python3.7pip install celery
和pip install gunicorn
检查celery和gunicorn是否已经安装/usr/local/python3
调整为本地实际的Python3安装路径)ln -s /usr/local/python3/bin/gunicorn /usr/local/bin/gunicorn
+ln -s /usr/local/python3/bin/celery /usr/local/bin/celery
+
TCA 本地部署启动后,会监听多个端口:
如果出现端口占用冲突,建议采用以下方式解决:
不推荐调整TCA指定服务的端口号,需要调整多处配置,以及可能会影响到后续服务的升级
本地部署输出的日志位置:
main
服务输出的日志目录:server/projects/main/log
server/projects/main/log/gunicorn_error.log
server/projects/main/log/gunicorn_access.log
server/projects/main/nohup_worker.out
server/projects/main/nohup_beat.out
server/projects/main/log/codedog.log
server/projects/main/log/main_celery.log
server/projects/main/log/main_beat.log
analysis
服务输出的日志目录:server/projects/analysis/log
server/projects/analysis/log/gunicorn_error.log
server/projects/analysis/nohup.out
server/projects/analysis/log/gunicorn_access.log
server/projects/analysis/log/codedog.log
server/projects/analysis/log/celery.log
login
服务输出的日志目录:server/projects/login/log
server/projects/login/log/gunicorn_error.log
server/projects/login/log/gunicorn_access.log
server/projects/login/log/codedog.log
file
服务输出的日志目录:server/projects/file/log
server/projects/file/log/gunicorn_error.log
server/projects/file/log/gunicorn_access.log
server/projects/file/log/codedog_file.log
scmproxy
服务输出的日志目录:server/projects/scmproxy/logs
server/projects/scmproxy/nohup.out
server/projects/scmproxy/logs/scmproxy.log
默认账号: CodeDog
,密码: admin
默认Token是0712b895f30c5e958ec71a7c22e1b1a2ad1d5c6b
如果在平台上刷新了CodeDog
用户的Token,需要将刷新后的Token填写到以下文件中:
server/scripts/config.sh
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)server/dockerconfs/.env.local
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)然后重启服务。
本地部署:
cd server/
+./scripts/deploy.sh start
+
docker-compose部署:
$ docker-compose stop
+# 稍等片刻
+$ docker-compose up -d
+
该错误出现可能有以下几个原因:
github
使用的密码需要使用personal access token
ps aux | grep proxyserver
看看是否有python proxyserver.py
执行进程,如果不存在可以看一下server/projects/scmproxy/nohup.out
看看启动失败的原因docker-compose ps
看看scmproxy
容器是否正常启动,如果没有启动,可以执行docker-compose logs scmproxy
看看启动失败的原因git clone xxxx
(xxx表示待登记的代码库),检查看看是否能够正常拉取unknown option `local`
错误 1.8.3.1
出现该提示的原因是,代码库偏大或clone
代码库时间较长,可以稍等一会再刷新重试
method(upload_file) call fails on error: Expecting value: line 1 column 1 (char 0)
出现这种错误,可能是本地配置异常或token配置有问题,检查方式如下:
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
如果xxx不一致需要调整为一致
注: xxx地址与在浏览器访问平台的xxx地址是一致的,不需要区分端口
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
检查当前在codedog.ini
-[config]token
与config.ini
文件配置的[FILE_SERVER]TOKEN
是否一致,如果不一致需要调整为一致
检查用户CodeDog
的Token
是否被刷新了然后没有更新到配置文件中
Connection timed out
本地客户端执行过程提示method (upload file) call fails on error: <urlopen error [Errno 110] Connection timed out>
该如何处理? 一般情况下,这个问题是客户端与Server之间网络不通导致,可以检查一下是否有防火墙限制或者配置的URL是内部IP或地址,可以通过以下方式检查
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
出现该错误提示,一般是访问文件器出错或文件服务器本身有问题,可以通过以下方式检查: 需要检查analysis-worker
的日志(本地部署:server/projects/analysis/log/celery.log
,docker-compose部署:docker-compose exec analysis-worker /bin/bash
进入容器后访问log/celery.log
查看具体错误原因
如果提示no route to host
可能是当前机器/容器无法访问当前宿主机的IP,可以检查一下当前防火墙的设置,是否限制了analysis-worker
来源的访问
出现该错误提示,一般是Server未进行初始化,可以通过执行以下命令初始化后再启动测试
cd server && ./scripts/deploy.sh init
./compose_init.sh
为防止国内用户访问CodeAnalysis Github首页时图片资源加载失败,目前各个md文件中的图片资源引用地址调整增加了URL前缀https://tencent.github.io/CodeAnalysis/
。
用户下载代码库到本地后,发现无法访问资源文件时,请检查本地网络是否能够连通外网,如果无法连通外网,可以在文档引入资源地址中进行相对路径替换,调整各个资源文件的链接。
对于根目录下的md文件,直接删除URL前缀即可:
例如在https://tencent.github.io/CodeAnalysis/media/homepage.png
这个链接可以调整为media/homepage.png
对于其他目录下的md文件,删除URL前缀后,需调整文件相对路径链接:
例如对于doc/client.md
, 需将https://tencent.github.io/CodeAnalysis/media/clientConfigIni.png
这个链接调整为../media/clientConfigIni.png
TCA提供部署脚本,支持一键式快速部署Server、Web、Client。
脚本共提供三种部署方式:Docker部署(平台体验首推)、Docker-Compose部署、源码部署, 可根据您的具体使用场景任意选择其一进行部署。
系统环境
环境准备
TIP
TCA 一键部署脚本已封装好 Python、Mariadb、Redis 与 Nginx 安装步骤,无需自行安装,本地部署体验可按 操作说明 内容直接进行部署操作。
注意:生产环境建议使用专业的 MySQL、Redis 等服务
Python 3.7
MySQL 服务(MySQL5.7.8 以上版本或 Mariadb 10.5 以上版本)
Redis 服务(4.0版本以上)
Nginx 服务
权限准备
CREATE、ALTER、INDEX、DELETE、LOCK TABLES、SELECT、INSERT、REFERENCES、UPDATE
权限端口使用:需要开放80端口的访问权限(80为TCA平台默认访问端口),或调整 Web 服务默认的访问端口地址
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
安装基础软件与部署 TCA(可根据脚本选项确定是否要安装 Python、MySQL、Redis、Nginx 相关基础软件),执行
$ bash ./quick_install.sh local deploy
+
执行该命令会做以下四个步骤:
Install
:检测本地 Python3.7、Mariadb/MySQL、Redis 与 Nginx,如果不存在会提示安装Init
:部署 TCA Server、Web与Client,并进行初始化Start
:启动 TCA Server、Web与ClientCheck
:检测 TCA 的运行状态注意:在运行过程中,脚本会检测本地是否安装了相关基础软件(Python3.7、MySQL/Mariadb、Redis、Nignx),如果未安装会输出以下类似提示语:
Do you want to install [Redis] by this script?
+Please enter:[Y/N]
+
如果确定通过脚本安装可以输入Y
。
TIP
至此,您已完成 TCA 平台部署,请在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可开启您的腾讯云代码分析。
平台内操作指引请查看:快速启动一次代码分析
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
1. 更新代码
2. 执行以下命令
bash ./quick_install.sh local install tca #更新相关配置
+bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+bash ./quick_install.sh local check #检查服务是否启动失败
+
注意:local install
命令行参数说明:
- base
:安装 Python、Mariadb/MySQL、Redis 与 Nginx
- tca
:初始化或更新 TCA Server、Web、Client 相关配置和数据
- server
:初始化或更新 TCA Server 相关配置和数据
- web
:初始化或更新 TCA Web 相关配置和数据
- client
:初始化或更新 TCA Client 相关配置和数据
- 不填参数,默认会执行base
、tca
相关操作
启动所有服务:bash ./quick_install.sh local start
启动Main相关服务:bash ./quick_install.sh local start main
local start
支持启动指定服务,如上述的启动Main服务,还支持mysql/redis/analysis/file/login/scmproxy/nginx/client/all
停止所有服务:bash ./quick_install.sh local stop
停止Main相关服务:bash ./quick_install.sh local stop main
local stop
支持停止指定服务,如上述的停止Main服务,还支持analysis/file/login/scmproxy/nginx/client/all
注意:
启动时会自动关闭之前已经运行的服务
mysql
和redis
默认会使用systemctl
进行启动,如果systemctl
无法使用,则会直接使用nohup
方式运行相关服务
检查服务运行状态:bash ./quick_install.sh local check
打印 TCA Server 各个服务的日志路径: bash ./quick_install.sh local log
系统环境
环境准备
# 源码根目录下执行
+pip3 install -r client/requirements/app_reqs.pip
+
# 源码根目录
+cd client/requirements
+
+# 执行安装脚本
+# Linux/macOS环境
+./install.sh
+# Windows环境
+./install.bat
+
配置 client/config.ini
文件
将 <Server IP地址>
替换成实际的serve ip(可包含端口号)。
配置 client/codedog.ini
文件
必填项:token
、org_sid
、team_name
、source_dir
个人令牌 - token
:从 TCA 页面获取,前往[个人中心]-[个人令牌]-复制Token
团队编号 - org_sid
:进入 TCA 项目概览页,从 URL 中获取
项目名称 - team_name
::进入 TCA 项目概览页,从 URL 中获取
TIP
项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
分析路径 - source_dir
: 本地代码目录路径
TIP
如果项目代码为编译型语言(比如:C/C++,C#,Go,Java,Kotlin,Objective-C等),且使用的分析方案中配置了编译型工具(如图,使用了OC推荐规则包),需要填写build_cmd
编译命令。
其他可选项按需填写,不填写时按默认配置执行
# 源码根目录
+cd client
+
+# 执行客户端脚本
+python3 codepuppy.py localscan
+
WARNING
Client 的实现及启动脚本均依赖 Python3 版本为 3.7,可执行 python3 --version
查看版本。若版本有误,可安装版本为3.7的python并软链接到python3命令。
TIP
codedog.ini
各项参数可由命令行传入,获取详细参数说明可运行 python3 codepuppy.py localscan -h
使用localscan
命令启动本地单次的代码分析,如需启动分布式并行分析任务,请参考使用分布式节点模式进行配置。
TIP
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
TIP
同通过源代码使用-配置客户端
docker build -t tca-client .
+
进入client
目录,执行以下命令
# 按照实际情况填写`SOURCE_DIR`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
进入docker容器内的bash终端
# 按照实际情况填写`SOURCE_DIR`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+
通过命令行启动client代码
python3 codepuppy.py localscan
+
系统环境
从发布页面下载与系统相对应的客户端压缩包到本地。
解压缩。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
TIP
同通过源代码使用-配置客户端
进入到client
目录下,执行客户端
./codepuppy localscan
+
TCA提供部署脚本,支持一键式快速部署Server、Web、Client。
脚本共提供三种部署方式:Docker部署(推荐)、Docker-Compose部署、源码部署,可根据您的具体使用场景任意选择其一进行部署。
WARNING
仅适用于Docker部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
TIP
通过Docker部署默认会在当前根目录下的挂载三个路径:
.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy
:重新构建并启动tca容器TIP
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
成功部署TCA后,请开始您的代码分析。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
TIP
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
TIP
分析方案是用于对代码库进行分析的一套配置集合。
更多分析方案配置可查阅帮助文档-分析方案
TIP
本次部署会默认启动运行环境为「Codedog_Linux」的客户端,若需扩展更多运行环境,详见客户端常驻节点分析
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
TIP
在线分析
,您可根据具体使用场景选择其一。在线分析
表示配置代码库链接后,TCA客户端拉取代码后进行分析;客户端分析
在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。在线分析
与客户端分析
具体详情及配置参考TCA客户端配置详情分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
分析结束后,进入分支概览可以查看该分支指定分析方案的概览数据以及 问题列表 等。
WARNING
Docker deployment include Mariadb and Redis. Configuration file can be modified to indicate a MySQL/Mariadb and Redis, which satisfied operation and maintenance specification for extensive use.
Server, Web and Client
~/CodeAnalysis
), the following paths are relative paths within the directory.bash ./quick_install.sh docker deploy
+
TIP
tencenttca/tca:latest
image will be pulled from dockerhub by default..docker_temp/logs
:/var/log/tca/
in container,TCA daily log output;.docker_temp/data
:/var/opt/tca/
in container, TCA service data, mainly about Mariadb,Redis;.docker_temp/configs
:/etc/tca
in container,TCA configuration file,mainly config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy # Re-build and start TCA Container
+
TIP
TCA_IMAGE_BUILD=true
Indicates that the TCA image is built locally to run
If docker deploy
has been executed on the machine and the container data is retained, you can execute the following command to start the container and continue to run TCA
bash ./quick_install.sh docker start
+
If a container is running and you want to stop it, you can run command
bash ./quick_install.sh docker stop
+
Now, you have done the deployment of your first TCA. Please type http://<Deploy server IP>
in your browser. click "立即体验", after login you can start your Tencent Code Analysis trip.
More operation instructions please check:Quick start a code analysis
TIP
Default account/Password:CodeDog/admin
If the default account password has been modified during deployment, please login according to the modified account and password.
TCA提供部署脚本,支持一键式快速部署 Server、Web、Client。
脚本共提供三种部署方式:Docker部署(平台体验首推)、Docker-Compose部署、源码部署, 可根据您的具体使用场景任意选择其一进行部署。
Server、Web 与 Client
WARNING
仅适用于 Docker-Compose 部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
执行命令:
bash ./quick_install.sh docker-compose deploy #启动tca_server容器
+
注意:通过 Docker-Compose 部署默认会在当前根目录下的挂载三个路径:
.docker_data/logs
:存放 TCA 平台的各个服务日志输出目录;.docker_data/mysql
:存放 TCA 平台的 MySQL 数据.docker_data/redis
:存放 TCA 平台的 Redis 数据.docker_data/filedata
:存放 TCA 平台文件服务器的文件TIP
完成 TCA 平台部署后,请在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可开启您的腾讯云代码分析。
平台内操作指引请查看:快速启动一次代码分析
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
更新代码
执行以下命令:
bash ./quick_install.sh docker-compose build #重新构建TCA相关镜像
+bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
如果已经在机器上执行过docker-compose deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行 TCA
bash ./quick_install.sh docker-compose start
+
如果容器正在运行,希望停止容器,可以执行以下命令
bash ./quick_install.sh docker-compose stop
+
如果希望构建镜像,可以执行以下命令
bash ./quick_install.sh docker-compose build
+
In addition to integrating well-known analysis tools in the industry, TCA also has its own independently developed tools, which serve as the enhanced analysis module of TCA.
The TCA enhanced analysis module requires users to additionally deploy the License authentication microservice and apply for a License by email.
TIP
1. License application is completely free! 2. Enterprises or universities are given priority in applying for a License.
Continuously updating...
If users usually use TCA official website version public service and want to experience the analysis capabilities of the enhanced analysis module on the official website version, they can follow this help document to apply for configuration.
If you are using TCA in an enterprise intranet environment and want to experience the enhanced analysis module capabilities of TCA on the intranet, you can apply as follows.
WARNING
Note: The CLS directory cannot be deleted at will
server/cls
directory of the TCA source code to obtain the Server ID
and Client License
WARNING
Note: The command needs to be executed in the CLS directory
# install Git LFS
+$ bash ./scripts/base/install_git_lfs.sh
+# If the cls binary is not found in this directory, you can execute the following command to synchronize.
+$ bash ./scripts/base/install_bin.sh
+$ cd server/cls
+$ ./cls server
+2022-04-13 18:35:29.356510559 +0800 CST [INFO] Version: 20220328.1
+2022-04-13 18:35:29.44083463 +0800 CST [INFO] The client license is:
+xxx
+2022-04-13 18:35:29.454552966 +0800 CST [INFO] License Server ID: xxx
+
Server ID
: Machine code, used to apply for License authorization from the TCA teamClient License
: Provided to the TCA Client to facilitate tool authentication (important, it is recommended to back up)config.ini
of the TCA Client directory, for example[LICENSE_CONFIG]
+; [optional] Fill in when using independent tools, no need by default
+; Domain name and port of the License service
+URL=http://<IP or domain name>:<port>
+BASE_PATH=
+LICENSE=<Client License>
+
WARNING
Note: The URL corresponding value does not need to follow the slash /
at the end.
WARNING
Different deployment methods can modify the config.ini
configuration according to the following methods:
client/config.ini
in the source code directory./quick_install.sh local start client
.docker_temp/configs/client/config.ini
in the source code directory and restart the tca-services
containertca-service
container, modify /CodeAnalysis/client/config.ini
, and exit and restart the tca-services
containerdocker restart tca-service
client/config.ini
in the source code directory and restart the client
containerdocker-compose restart client
Server ID
output in step 1, the machine code for the first registrationClient License
output in step 1config.yaml
file in the CLS directoryWARNING
Note: Follow the yaml format, for example:
:
, for example key: value
../cls server -d
+
# Find if there is a CLS process
+ps aux|grep cls
+
WARNING
Note: If the above command does not find the CLS process, it means that CLS did not start normally.
Please try to change the port in the config.yaml
file to another port, such as 8080, the default is port 80, and then re-execute the command in step 5.
# Find the CLS process ID
+ps aux|grep cls
+# Restart the microservice
+kill -USR2 <pid>
+
If the above deployment steps have been completed, but the enhanced function still encounters the License check failed! Please check the license. License Server is not available!
exception. You can troubleshoot as follows:
method(head) call fails on error: <urlopen error [Errno 111] Connection refused>
+
ping <CLS IP or domain name filled in config.ini>
+telnet <CLS IP or domain name filled in config.ini> <corresponding port>
+
Background: Xiao Ming deployed TCA in Docker mode and deployed the CLS service on the same host. Then he set the IP in the URL in config.ini to 127.0.0.1
, restarted and started the enhanced function task and encountered the above network disconnection exception.
Reason: The reason is that the 127.0.0.1
at this time points to the TCA Client container itself, not the CLS service deployed on the host.
Solution: Change 127.0.0.1
to the host's own IP.
# Find the CLS process ID
+ps aux|grep cls
+# Restart the microservice
+kill -9 <pid>
+
WARNING
Note: You cannot delete the original cls directory, you only need to replace the cls binary file in it.
./cls server -d
+
Tencent Cloud Code Analysis (TCA for short, code-named CodeDog inside the company early) is a comprehensive platform for code analysis and issue tracking. TCA consist of three components, server, web and client. It integrates of a number of self-developed tools, and also supports dynamic integration of code analysis tools in various programming languages.
Code analysis is a technology, using lexical analysis, syntax analysis, control-flow analysis, data-flow analysis to make a comprehensive analysis of the code, so as to verify whether the code meets the requirements of normative, security, reliability, maintainability and other indicators.
Using TCA can help team find normative, structural, security vulnerabilities and other issues in the code, continuously monitor the quality of the project code and issue alerts. At the same time, TCA opens up APIs to support connection with upstream and downstream systems, so as to integrate code analysis capabilities, ensure code quality, and be more conducive to inheriting an excellent team code culture.
For the first experience, it is recommended that you use the Docker deployment to quickly build and experience the Tencent Cloud code analysis platform for the first experience.
If you have more environmental requirements, you can also deploy Tencent Cloud Code Analysis Platform in the following two ways:
Deploy through Docker-Compose
Deploy through source code
成功部署并启动 Server 与 Web 服务后,通过以下步骤创建您的第一个代码分析项目。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
TIP
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
TIP
分析方案是用于对代码库进行分析的一套配置集合。
更多分析方案配置可查阅帮助文档-分析方案
腾讯云代码分析(Tencent Cloud Code Analysis,简称TCA,内部曾用研发代号 CodeDog )是集众多分析工具的云原生、分布式、高性能的代码综合分析跟踪平台,包含服务端、Web端和客户端三个组件,已集成一批自研工具,同时也支持动态集成业界各编程语言的分析工具。
使用TCA Action,只需要在代码仓库中添加.github/workflows/tca.yml
文件,就可以直接在GitHub工作流中快速体验代码分析。请参考:TCA-action指引
拉取 代码库 后,您可以通过以下三种方式部署腾讯云代码分析平台:
成功部署并启动TCA后,您可以按照 指引 创建您的首个代码分析项目。
TIP
默认平台登录账号/密码:CodeDog/admin
TCA客户端支持通过可执行文件进行快速扩展部署,详见通过可执行文件
TIP
客户端可在本地执行代码分析,也可以作为在线常驻节点进行在线分析。
更多关于腾讯云代码分析平台的使用指南和配置说明,参见帮助文档。
在完成 Server、Web 和 Client 相关部署和配置后,可通过平台执行代码分析。
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
注:
在线分析
,您可根据具体使用场景选择其一。在线分析
表示配置代码库链接后,TCA客户端拉取代码后进行分析;客户端分析
在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。在线分析
与客户端分析
具体详情及配置参考TCA客户端配置详情分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
分析结束后,进入分支概览可以查看该分支指定分析方案的概览数据以及 问题列表 等。
本文档仅供参考,不适用于正式环境部署,正式环境建议使用专业的MySQL服务(比如腾讯云的MySQL产品)
CentOS 7.3 版本
wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm
+yum localinstall mysql57-community-release-el7-11.noarch.rpm
+
安装成功后,查看MySQL版本:
yum repolist all | grep mysql
+
输出结果:
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community 禁用
+mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community - 禁用
+mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community 禁用
+mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community - 禁用
+!mysql-connectors-community/x86_64 MySQL Connectors Community 启用: 221
+mysql-connectors-community-source MySQL Connectors Community - S 禁用
+!mysql-tools-community/x86_64 MySQL Tools Community 启用: 135
+mysql-tools-community-source MySQL Tools Community - Source 禁用
+mysql-tools-preview/x86_64 MySQL Tools Preview 禁用
+mysql-tools-preview-source MySQL Tools Preview - Source 禁用
+mysql55-community/x86_64 MySQL 5.5 Community Server 禁用
+mysql55-community-source MySQL 5.5 Community Server - S 禁用
+mysql56-community/x86_64 MySQL 5.6 Community Server 禁用
+mysql56-community-source MySQL 5.6 Community Server - S 禁用
+!mysql57-community/x86_64 MySQL 5.7 Community Server 启用: 544
+mysql57-community-source MySQL 5.7 Community Server - S 禁用
+mysql80-community/x86_64 MySQL 8.0 Community Server 禁用
+mysql80-community-source MySQL 8.0 Community Server - S 禁用
+
yum install mysql-community-server
+
1.如遇以下报错,可尝试运行
yum install mysql-community-server --nogpgcheck
安装
Public key for mysql-community-libs-compat-5.7.37-1.el7.x86_64.rpm is not installed
Failing package is: mysql-community-libs-compat-5.7.37-1.el7.x86_64 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
2.如遇以下报错,可执行yum module disable mysql
后重试安装
All matches were filtered out by modular filtering for argument: mysql-community-serve
Error: Unable to find a match: mysql-community-server
安装好的MySQL配置文件路径是/etc/my.cnf
,这里可以根据需要调整,比如可以调整:
systemctl start mysqld
+
确认MySQL正常启动
systemctl status mysqld
+
查看生成 MySQL root用户临时密码:
grep 'temporary password' /var/log/mysqld.log
+
连接MySQL服务
$ mysql -uroot -p
+# 输出上述查询到的临时密码
+
修改root用户的密码(下面是改成 Password@2021
,这里根据自行需要进行调整):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Password@2021';
+
安装编译打包需要的工具
yum -y install gcc zlib-devel pcre-devel bzip2-devel openssl-devel readline-devel
+
Ubuntu:
apt install gcc libssl-dev zlib1g-dev libpcre3-dev libbz2-dev libreadline-dev
wget http://nginx.org/download/nginx-1.20.2.tar.gz
+
# 解压
+$ tar zvxf nginx-1.20.2.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/nginx-1.20.2
+
+# 配置
+$ ./configure \
+--sbin-path=/usr/local/nginx/nginx \
+--conf-path=/etc/nginx/nginx.conf \
+--pid-path=/run/nginx.pid \
+--with-stream \
+--with-http_ssl_module --with-http_v2_module --with-http_auth_request_module
+
+# 构建nginx
+$ make -j4
+$ make install
+$ make clean
+
+# 建立软链
+$ ln -s /usr/local/nginx/nginx /usr/local/bin/nginx
+
mkdir /etc/nginx/conf.d/
+vi /etc/nginx/nginx.conf
+
检查nginx.conf
配置文件:
pid /run/nginx.pid
,如果缺失或被注释则加上,加上位置如下所示:include conf.d/*.conf;
,如果缺失则加上,加上位置如下所示:# ...省略内容
+#pid logs/nginx.pid; # 默认有的
+pid /run/nginx.pid;
+
+events {
+ # ...省略内容
+}
+
+# ...省略内容
+
+http {
+ # ...省略内容
+ #
+ include conf.d/*.conf;
+ server {
+ # ...省略内容
+ }
+}
+
+
后续可以将nginx配置文件放置到/etc/nginx/conf.d/
目录下
vim /usr/lib/systemd/system/nginx.service
+
输入以下内容:
[Unit]
+Description=The nginx HTTP and reverse proxy server
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/run/nginx.pid
+# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
+# SELinux context. This might happen when running `nginx -t` from the cmdline.
+# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
+ExecStartPre=/bin/rm -f /run/nginx.pid
+ExecStartPre=/usr/local/bin/nginx -t
+ExecStart=/usr/local/bin/nginx
+ExecReload=/usr/local/bin/nginx -s reload
+ExecStop=/usr/local/bin/nginx -s stop
+KillSignal=SIGQUIT
+TimeoutStopSec=5
+KillMode=process
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动nginx:
systemctl start nginx
+
开机自动启动nginx:
systemctl enable nginx
+
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/bin/python
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
以下脚本内容是上面的步骤集合,省去了复制粘贴的重复动作。
install_py37.sh
,写入以下 shell 脚本chmox +x install_py37.sh
./install_py37.sh
#!/bin/env bash
+
+## 下载 Python 源码,如果已下载源码在脚本当前目录下,可注释跳过下载步骤
+wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
+## 安装编译依赖组件
+yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel
+
+## 解压安装
+# 解压到/usr/local/src目录
+tar zvxf Python-3.7.12.tgz -C /usr/local/src
+cd /usr/local/src/Python-3.7.12
+# 编译前配置
+./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+make -j8
+# 安装Python
+make install
+# 清理编译产出的中间文件
+make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+ldconfig
+
+## 检查Python版本是否安装成功
+echo -e "\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\033[0m"
+python --version
+echo -e "\033[1;42;37m[$(date "+%Y/%m/%d %H:%M:%S")] [Check]: 检查Python版本\033[0m"
+
+## pypi下载源配置
+mkdir ~/.pip/
+echo "extra-index-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
注:当前Ubuntu版本为18.04
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
+
安装依赖组件
apt-get update
+apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev wget libbz2-dev tk-dev gcc make
+
# 解压到/usr/local/src目录
+$ tar zvxf Python-3.7.12.tgz -C /usr/local/src
+$ cd /usr/local/src/Python-3.7.12
+# 编译前配置
+$ ./configure prefix=/usr/local/python3 --enable-shared
+# 编译构建
+$ make -j8
+# 安装Python
+$ make install
+# 清理编译产出的中间文件
+$ make clean
+# 链接构建产出的Python可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python
+# 链接构建产出的pip3可执行文件到/usr/local/bin目录
+$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip
+# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
检查Python版本是否安装成功
$ python --version
+Python 3.7.12 # 正常输出,表示安装成功
+
注:
/usr/local/bin
再/usr/bin
python -v
输出结果是否为Python 3.7.12
版本,如果不是该版本,可能影响后续依赖安装和服务运行pip默认是到pypi
官方源下载第三方依赖包,下载速度可能会比较慢,可以考虑调整为腾讯云的pypi
下载源,调整方式:
mkdir ~/.pip/
+echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
安装编译打包需要的工具
yum install -y gcc make tcl wget
+
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
+
# 解压
+$ tar zvxf redis-5.0.4.tar.gz -C /usr/local/src
+
+# 进入源码目录
+$ cd /usr/local/src/redis-5.0.4
+
+# 构建redis依赖库
+$ cd deps; make -j4 hiredis jemalloc linenoise lua
+$ cd ..
+
+# 构建redis
+$ make -j4
+$ make install
+$ make clean
+
安装后,可以在/usr/local/src/redis-5.0.4/src
目录和/usr/local/bin/
目录下找到redis-server
与redis-cli
两个文件
cp /usr/local/src/redis/redis.conf /etc/redis.conf
+vim /usr/local/src/redis/redis.conf
+
# 设置Redis密码
+requirepass 123456
+
+# 将 daemonize no 调整为 daemonize yes,将redis-server调整为默认后台启动
+daemonize yes
+
+# 配置日志
+logfile '/var/log/redis/redis-server.log'
+
redis-server /etc/redis.conf
+
vim /etc/systemd/system/redis.service
+
输入以下内容:
[Unit]
+Description=redis-server
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/local/bin/redis-server /etc/redis.conf
+ExecStop=/usr/local/bin/redis-cli shutdown
+Restart=always
+
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
+
启动redis-server:
systemctl start redis
+
开机自动启动redis:
systemctl enable redis
+
本文档仅供参考,不适用于正式环境部署,正式环境建议使用专业的Redis服务(比如腾讯云的Redis产品)
CentOS 7.3 版本
yum install redis
+
注:安装redis可能会出现"no package redis available"的错误提示,请执行yum install epel-release
后重试redis安装命令。
$ vi /etc/redis.conf
+
+# 找到 requirepass foobared
+# 复制一行并根据自己需要调整密码,比如
+requirepass tca123
+
systemctl start redis
+
查看redis运行状态
systemctl status redis
+
$ redis-cli
+
+127.0.0.1:6379> auth tca123
+OK # 鉴权通过
+
以往的单机器单进程,性能比较低,工具排队等待时间过长。希望通过并行执行分析来提高分析效率。
希望尽量使用公共资源或使用专机资源。
为了满足以上需求,TCA已经进行如下支持:
支持工具在多台机器上并行执行。
支持指定工具在指定的机器上运行。
支持与本地启动的任务衔接,加速本地任务扫描。
配套任务状态监控能力,及时重置初始化超时或机器掉线的任务。
提示
TCA客户端除了通过localscan命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
请参考客户端-常驻节点分析
client/config.ini
中的字段指定puppy-tools-config,如下[COMMON]
+; [必填]工具配置库git地址
+; 如果github网络慢,建议修改为腾讯工蜂地址:https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
+; 这里可以修改为自己维护的puppy-tools-config
+TOOL_CONFIG_URL=
+PASSWORD_KEY=
+; [可选]日志级别,默认为info级别,设置为True则调整为debug级别
+DEBUG=
+; [可选]是否使用本地工具目录,默认为False,如果设置为True,不从git拉取(需要事先准备好工具,存放到tools目录下)
+USE_LOCAL_TOOL=
+
+[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果TOOL_CONFIG_URL使用的是腾讯工蜂,账号密码必填(如果没有,可以先去https://git.code.tencent.com注册)
+USERNAME=
+PASSWORD=
+
; ---------------------------------------------------------------------------------------------------------------------
+; 配置文件填写说明:
+; 填写过程中,如果有多个值,用英文分号分隔
+; [env_path] - 环境变量路径定义,基于tools目录的相对路径,比如:PYLINT_HOME : puppy_tools_common/pylint-1.4.5
+; [env_value] - 环境变量值定义,比如:GIT_SSL_NO_VERIFY : 1
+; [tool_url] - 工具库地址定义,格式:工具名:url,比如 CHECKSTYLE : http://xxxxxx.git
+; [common] - 公共环境配置,比如git环境变量等, 包含以下4个字段
+; env_path - 需要的环境变量路径,填写[env_path]中的KEY值,比如 env_path : ANDROID_HOME;CHECKSTYLE_HOME
+; env_value - 需要的环境变量值,填写[env_value]中的KEY值,比如 env_value : GIT_SSL_NO_VERIFY
+; path - 需要加到path环境变量中的路径,基于tools目录的相对路径,推荐使用变量格式,比如 path : ${env_path:PYLINT_HOME}/bin
+; tool_url - 需要拉取的工具库,多个地址用英文分号分隔,推荐使用变量格式,比如 tool_url : ${tool_url:PYLINT}
+; [工具名] - 各工具配置,工具名需要与tool目录下的模块名匹配,字段格式参考[common]
+; ---------------------------------------------------------------------------------------------------------------------
+[base_value]
+git_url=https://github.com/TCATools
+
+;------------------
+; 1.环境变量路径定义
+;------------------
+; 用来记录工具路径,会在工具执行时写入到环境变量中
+[env_path]
+CPPLINT_HOME : cpplint
+
+;------------------
+; 2.环境变量值定义
+;------------------
+; 记录部分环境变量并在执行时写入环境变量
+[env_value]
+PYTHON_VERSION : 3
+
+
+;------------------
+; 3.工具git库定义
+;------------------
+; 拉工具的仓库地址
+[tool_url]
+CPPLINT : ${base_value:git_url}/cpplint.git
+
+;------------------
+; 5.各个工具配置
+;------------------
+; 整合工具配置
+[cpplint]
+env_path : CPPLINT_HOME
+env_value : PYTHON_VERSION
+path : ${env_path:CPPLINT_HOME}
+tool_url : ${tool_url:CPPLINT}
+
client/config.ini
中指定[TOOL_LOAD_ACCOUNT]
+; [可选]拉取工具库的账号密码
+; 如果使用的工具仓库必须账号密码才能拉取则必须填写
+USERNAME=
+PASSWORD=
+
task_request
分发到能够执行该工具的机器task_name
字段,字段对应于工具的name
字段task_name
在client中的tool目录查找对应python启动脚本根据上述的任务机制添加工具需要做到以下几点
tca_ql_php
工具及其所含的规则tca_ql_php
工具tca_ql_php
对应的启动脚本是什么找到server/projects/main/apps/scan_conf/management/commands/open_source
目录
创建工具json文件,json文件名尽量对应工具名称方便查看
json文件内容为(以 tca_ql_php 为例)
[
+ {
+ "name": "tca_ql_php",
+ "display_name": "Hades_PHP(展示名称用于前端展示使用)",
+ "description": "工具描述",
+ "license": "工具license",
+ "libscheme_set": [], # 暂时不需要
+ "task_processes": [
+ "analyze",
+ "datahandle",
+ "compile"
+ ], # 工具进程,包含compile编译, analyze分析, datahandle数据处理
+ "scan_app": "codelint", # 代码分析统一为codelint
+ "scm_url": "", # 暂时为空
+ "run_cmd": "",
+ "envs": null, # 是否需要特殊环境,这里无需填写
+ "build_flag": false, # 是否需要编译命令才能运行
+ "checkrule_set": [ # 工具包含的规则
+ {
+ "real_name": "deser", # 规则名
+ "display_name": "反序列化漏洞", # 规则前端展示,考虑各工具规则名可能晦涩难懂,设置展示名称方便查找
+ "severity": "error", # 规则等级 从上到下分为 fatal, error, warning, info 四个等级
+ "category": "security", # 规则类别。correctness 功能 security安全 performance性能 usability可用性 accessibility无障碍化 i18n国际化 convention代码风格 other其他
+ "rule_title": "反序列化漏洞", # 一句话概括规则简介
+ "rule_params": null, # 规则参数
+ "languages": [ # 支持语言
+ "php"
+ ],
+ "solution": "", # 建议的解决方法
+ "owner": "",
+ "labels": [],
+ "description": "", # 规则详细介绍
+ }
+ ]
+ }
+]
+
server/projects/main/
目录执行python manage.py loadcheckers --dir open_source tca_ql_php
加载工具进入数据库tca_ql_php
工具; env_path 主要填写存放工具文件所在的相对目录,一般都存放/拉取在tools下,会在工具执行前加载到环境变量中提供使用
+[env_path]
+ZEUS_HOME : Zeus
+HADES_HOME : Hades
+
+; toolz_url
+[tool_url] 主要填写工具的git仓库,这里因为 tca_ql_php 直接使用tools下的目录所以不用再进行额外拉取也无需再写
+CPPCHECK : ${base_value:git_url}/linux-cppcheck-1.78
+
+; 各工具配置 以 tca_ql_php 为例
+; env_path 填写上面需要加载的环境变量
+; env_value 通用环境变量,一般无需填写如果有需求需要现在 [env_value] 中定义好再填写
+; path 工具所在目录填写上面的定义
+; tool_url 工具git仓库,使用本地相对目录故为空
+[tca_ql_php]
+env_path : ZEUS_HOME;HADES_HOME
+env_value :
+path : ${env_path:ZEUS_HOME};${env_path:HADES_HOME}
+tool_url :
+
+
tca_ql_php
对应的启动脚本是什么以上述步骤在client/tool
目录添加脚本tca_ql_php.py
作为启动脚本 注:启动脚本必须与工具名称相同
编写脚本
以tca_ql_php
为例
+from task.codelintmodel import CodeLintModel
+from util.logutil import LogPrinter
+from util.subprocc import SubProcController
+
+logger = LogPrinter()
+
+
+class TcaQlPHP(CodeLintModel):
+ # 代码分析工具集成基类CodeLintModel
+ def __init__(self, params):
+ logger.info("找到工具了Q_Q")
+ super().__init__(params)
+
+ def compile(self, params):
+ logger.info("开始编译了Q_Q")
+ build_cmd = params.get('build_cmd', None) # 从params中获取编译命令, params内容可以在最后附录查看
+ lang = "php"
+ do_some_things()
+
+ def analyze(self, params):
+ logger.info("开始分析了Q_Q")
+ lang = "php"
+ HADES_HOME = envs.get("HADES_HOME", None)
+ output_json = "result.json"
+ sp = SubProcController(
+ command=["Hades", "analyze", "test.php", "-o", output_json],
+ cwd=HADES_HOME,
+ stdout_line_callback=subprocc_log,
+ stderr_line_callback=subprocc_log,
+ )
+ sp.wait() # 执行工具分析命令
+ issues = []
+ # 工具结果输出到output_json,具体工具可能有所不同
+ if os.path.exists(output_json):
+ with open(output_json, "r") as result_reader:
+ result = json.load(result_reader)
+ issues.extend(result)
+ return issues
+
+tool = TcaQlPHP # 必须,必须包含tool变量并且为该工具的类
+
task_request
中的task_params
字段,具体字段将在最后附录进行说明{
+ "path": "文件相对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+}
+说明:
+ refs:可选,记录问题回溯路径信息。比如当前文件的回溯路径其他的3行代码,可以将这三行的路径及提示信息,按顺序添加到refs数组中。
+
如果有意公开您添加的工具欢迎发起PR
注:别忘了puppy-tool-config 也需要PR
字段 | 说明 | 类型 |
---|---|---|
scan_languages | 语言 | 字符串列表如 ["python", "php"] |
pre_cmd | 编译前置命令 | 字符串 |
build_cmd | 编译命令 | 字符串 |
envs | 额外环境变量 | 字符串 |
scm_last_revision | 上次成功分析的代码版本,增量使用 | 字符串 |
incr_scan | 是否为增量分析 | bool |
rules | 规则名称列表,只有规则名 | 字符串列表 |
rule_list | 详细的规则列表包含规则名和规则参数等 | 字典列表 |
checktool | 工具详细信息,执行一般用不到 | 字典 |
path_filters | 过滤路径 | 字典 |
scm_url | 代码库url | 字符串 |
source_dir | 代码库本地目录 | 字符串 |
work_dir | 本次任务的work_dir目录 | 字符串 |
project_id | 分析项目id | int |
repo_id | 仓库id | int |
task_id | 任务id | int |
job_id | 本次分析的id | int |
http://{host}/server/
注:host 指当前浏览器访问该文档的 URL 域名部分。
发起请求时,需要在头部中添加以下格式形式,对应的 value 请看下面获取方式
{
+ "Authorization": "Token 当前user的token"
+}
+
获取 token 位置(个人中心-个人令牌):
通过平台访问具体代码库扫描情况时,可从 URL 中获取对应 org_sid 和 project_team 字段,查看方式如下例子:
代码库扫描地址:http://{host}/t/xxx/p/yyy/code-analysis/repos/1/projects?limit=10&offset=0
其中,org_sid 为xxx
字段,project_team 为 yyy
字段
import requests
+# 假设:
+# 当前域名为http://tca.com/,当前org_sid为helloworld
+# 获取helloworld团队下的hellotca项目下登记的代码库
+url="http://tca.com/server/main/api/orgs/helloworld/teams/hellotca/repos/?limit=12&offset=0"
+headers = {
+ "Authorization": "Token %s" % token,
+}
+
+response = requests.get(url, headers=headers)
+print(response.json())
+# 结果如下:
+{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 23,
+ "name": "repo_name",
+ "scm_url": "http://git.repo.com/group/repo_name",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-05-14 02:34:44.509118+00:00",
+ "recent_active": {
+ "id": 27,
+ "branch_name": "master",
+ "active_time": "2021-05-14 02:34:44.509118+00:00",
+ "total_line_num": 1,
+ "code_line_num": 1
+ },
+ "created_from": "tca",
+ "creator": {
+ "username": "author",
+ "nickname": "author",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ },
+ "symbol": null,
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "test",
+ "scm_platform": 2,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": "url",
+ "org": "org_name"
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-05-14T10:34:44.552859+08:00",
+ "modified_time": "2021-05-14T10:34:44.552887+08:00"
+ },
+ "project_team": {
+ "name": "test",
+ "display_name": "测试",
+ "status": 1,
+ "org_sid": "test"
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
平台返回的数据分页格式是使用limit
和offset
参数进行分页处理
比如:server/main/api/orgs/<org_sid>/teams/?limit=12&offset=12
获取得到的数据是从第 13 条开始获取
平台返回的响应格式如下:
{
+ "data": {...}, # 详细数据
+ "code": 0, # 请求结果码,为0表示正常
+ "msg": "xxx" , # 请求结果信息
+ "status_code": 200 # 请求响应码
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
scan_open | int | 选填,发现问题的扫描编号 |
scan_close | int | 选填,修复问题的扫描编号 |
worse | boolean | 选填,圈复杂度是否恶化 |
over_cc_sum_gte | int | 选填, 圈复杂度总和最小值 |
over_cc_sum_lte | int | 选填,圈复杂度总和最大值 |
over_cc_avg_gte | int | 选填,平均圈复杂度最小值 |
over_cc_avg_lte | int | 选填,平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 选填,超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 选填,超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_close_id | int | 选填,修复问题的扫描编号 |
worse | boolean | 选填,圈复杂度是否恶化 |
over_cc_sum_gte | int | 选填,圈复杂度总和最小值 |
over_cc_sum_lte | int | 选填,圈复杂度总和最大值 |
over_cc_avg_gte | int | 选填,平均圈复杂度最小值 |
over_cc_avg_lte | int | 选填,平均圈复杂度总和最大值 |
over_cc_func_count_gte | int | 选填,超标圈复杂度函数个数最小值 |
over_cc_func_count_lte | int | 选填,超标圈复杂度函数个数最大值 |
{
+ "data": {
+ "count": 32,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "tapd_url": null,
+ "created_time": "2020-06-02T10:59:09.418250+08:00",
+ "creator": null,
+ "modified_time": "2020-06-03T16:17:40.892224+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "over_func_cc": 0,
+ "over_cc_sum": 0,
+ "over_cc_avg": 0,
+ "over_cc_func_count": 0,
+ "diff_over_func_cc": 0,
+ "diff_over_cc_sum": 0,
+ "diff_over_cc_avg": 0,
+ "diff_over_cc_func_count": 0,
+ "worse": false,
+ "file_path": "test/demo.py",
+ "state": 3,
+ "change_type": 0,
+ "last_modifier": "author1",
+ "author": null,
+ "related_modifiers": "author1;author2",
+ "file_owners": null,
+ "language": "python",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "revision": null,
+ "ci_time": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": 2
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccfiles/<file_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/scans/<scan_id>/ccissues/
+
参数 | 类型 | 描述 |
---|---|---|
status | str | 选填,问题状态,1为需要关注,2为无需关注,可多选,格式为1,2,3 |
change_type | str | 选填,圈复杂度变化情况,0为无,1为新增,2为删除,3为无变化,可多选,格式为1,2,3 |
author | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
ccn_gte | str | 选填,圈复杂度最小值 |
ccn_lte | str | 选填,圈复杂度最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "created_time": "2021-02-19T15:30:20.968525+08:00",
+ "creator": null,
+ "modified_time": "2021-02-19T15:30:20.968532+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "ccn": 22,
+ "g_cc_hash": null,
+ "cc_hash": null,
+ "file_path": "test/demo.py",
+ "func_name": "test_func",
+ "func_param_num": 4,
+ "long_name": "test_func( project , result_data , scan , task_params )",
+ "change_type": 0,
+ "status": 1,
+ "last_modifier": "author",
+ "author": null,
+ "related_modifiers": "author,author2",
+ "is_tapdbug": false,
+ "ignore_time": null,
+ "is_latest": true,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2020-03-18T19:46:48+08:00",
+ "diff_ccn": null,
+ "project": 1,
+ "scan_open": 1,
+ "scan_close": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/
+
参数 | 类型 | 描述 |
---|---|---|
issue__state | str | 选填,问题状态, 1为未处理,2为可忽略,3为关闭,可多选,格式为1,2,3 |
change_type | str | 选填,重复文件更改类型,add为新增,del为删除,mod为删除,可多选,格式为add,del,mod |
issue__owner | str | 选填,问题责任人 |
last_modifier | str | 选填,最近修改人 |
file_path | str | 选填,文件路径 |
duplicate_rate_gte | int | 选填,重复率最小值 |
duplicate_rate_lte | int | 选填,重复率最大值 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "project_id": 1,
+ "scan_id": 1,
+ "issue_id": 1,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "12345678abc",
+ "is_latest": true
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/
+
{
+ "data": {
+ "id": 1,
+ "repo": 1,
+ "issue": {
+ "id": 1,
+ "state": 1,
+ "owner": "author"
+ },
+ "blocks": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ],
+ "duplicate_rate_trend": 0.0,
+ "project_id": 1815,
+ "scan_id": 488,
+ "issue_id": 3,
+ "issue_state": 1,
+ "issue_owner": "author",
+ "dir_path": "test",
+ "file_name": "demo.py",
+ "file_path": "test/demo.py",
+ "duplicate_rate": 4.63,
+ "total_line_count": 259,
+ "total_duplicate_line_count": 12,
+ "distinct_hash_num": 1,
+ "block_num": 1,
+ "last_modifier": "author",
+ "change_type": null,
+ "scm_revision": "xxx",
+ "is_latest": true
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/<file_id>/blocks/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "duplicate_file": 1,
+ "project_id": 1,
+ "scan_id": 1,
+ "duplicate_file_id": 1,
+ "token_num": 120,
+ "duplicate_times": 2,
+ "duplicate_rate": 4.63,
+ "start_line_num": 216,
+ "end_line_num": 227,
+ "duplicate_line_count": 12,
+ "last_modifier": "author",
+ "change_type": null,
+ "related_modifiers": "author"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/clocfiles/
+
参数 | 类型 | 描述 |
---|---|---|
change_type | str | 选填,改变类型(add、mod、del),支持多值,使用英文逗号','分隔 |
file_path | str | 选填,文件路径 |
{
+ "data": {
+ "count": 1,
+ "next": "",
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 108587,
+ "comment_line_num": 0,
+ "blank_line_num": 0,
+ "total_line_num": 108587,
+ "add_code_line_num": 108587,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 0,
+ "add_total_line_num": 108587,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1,
+ "scan_id": 1,
+ "is_latest": true,
+ "dir_path": "test",
+ "file_name": "test.json",
+ "language": "JSON",
+ "change_type": "add"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/cloclangs/
+
{
+ "data": {
+ "count": 2,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "code_line_num": 9753,
+ "comment_line_num": 4220,
+ "blank_line_num": 2454,
+ "total_line_num": 16427,
+ "add_code_line_num": 9753,
+ "add_comment_line_num": 4220,
+ "add_blank_line_num": 2454,
+ "add_total_line_num": 16427,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Python",
+ "file_num": 165
+ },
+ {
+ "id": 2,
+ "code_line_num": 379,
+ "comment_line_num": 0,
+ "blank_line_num": 153,
+ "total_line_num": 532,
+ "add_code_line_num": 379,
+ "add_comment_line_num": 0,
+ "add_blank_line_num": 153,
+ "add_total_line_num": 532,
+ "mod_code_line_num": 0,
+ "mod_comment_line_num": 0,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 0,
+ "del_code_line_num": 0,
+ "del_comment_line_num": 0,
+ "del_blank_line_num": 0,
+ "del_total_line_num": 0,
+ "project_id": 1815,
+ "scan_id": 695,
+ "is_latest": true,
+ "name": "Markdown",
+ "file_num": 7
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open | int | 选填,发现问题的扫描编号 |
scan_fix | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间,格式为"2021-01-01 00:00:00" |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "file_path": "test/demo.py",
+ "project": 1,
+ "repo": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checktool_name": "xxx",
+ "msg": "xxx",
+ "state": 3,
+ "resolution": 1,
+ "author": "author",
+ "author_email": null,
+ "severity": 2,
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "is_external": false,
+ "scm_url": "",
+ "real_file_path": "",
+ "scan_open": 1,
+ "scan_fix": 2,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00"
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/
+
{
+ "data": {
+ "id": 1,
+ "issue_details": [
+ {
+ "id": 1,
+ "issue_refers": [],
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "issuedetail_uuid": "0fcc376e-7283-11eb-bd53-5254005e71ca",
+ "checkrule_real_name": "xxx",
+ "checktool_name": "xxx",
+ "author": "author",
+ "author_email": null,
+ "line": 1809,
+ "column": 15,
+ "scan_revision": "scan_revision",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "real_revision": "",
+ "created_time": "2021-02-19T15:21:19.625658+08:00",
+ "modified_time": "2021-02-19T15:21:19.625662+08:00",
+ "issue": null,
+ "project": 1
+ }
+ ],
+ "is_external": false,
+ "repo": 1,
+ "author": "author",
+ "created_time": "2021-02-19T15:21:19.625685+08:00",
+ "creator": null,
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "file_path": "test/demo.py",
+ "file_hash": "xxx",
+ "scm_url": "",
+ "real_file_path": "",
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "state": 3,
+ "resolution": 1,
+ "scan_revision": null,
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2021-02-02T13:31:38+08:00",
+ "file_owners": null,
+ "fixed_time": "2021-02-19T15:25:15.152350+08:00",
+ "tapd_ws_id": null,
+ "tapd_bug_id": null,
+ "modified_time": "2021-02-19T15:25:17.807478+08:00",
+ "project": 1,
+ "scan_open": 1,
+ "scan_fix": 2
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/scans/<scan_id>/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_fix_id | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间 |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo_id": 1,
+ "project_id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "file_path": "test/demo.py",
+ "scm_url": "",
+ "real_file_path": "",
+ "line": 21,
+ "column": 68,
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "msg": "xxx",
+ "state": 1,
+ "resolution": null,
+ "author": "author",
+ "scan_open_id": 1,
+ "scan_fix_id": null,
+ "issuedetail_uuid": "26d7ba88-8268-11eb-a304-5254005e71ca",
+ "scan_revision": "scan_revision",
+ "real_revision": "",
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2019-07-01T10:28:19+08:00",
+ "file_owners": null,
+ "created_time": "2021-03-11T20:49:00.539537+08:00",
+ "fixed_time": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/crscans/<scan_id>/issues/
+
参数 | 类型 | 描述 |
---|---|---|
state | str | 选填,问题状态, 1为未处理,2为已处理,3为关闭,可多选,格式为1,2,3 |
severity | str | 选填,严重程度, 1为致命,2为错误,3为警告,4为提示,可多选,格式为1,2,3,4 |
resolution | str | 选填,解决方式, 0为无,1为修复,2为无需修复,3为误报,4为重复单过滤,5为路径过滤,6为规则移除 |
author | str | 选填,问题责任人 |
scan_open_id | int | 选填,发现问题的扫描编号 |
scan_fix_id | int | 选填,修复问题的扫描编号 |
ci_time_gte | str | 选填,修复问题的起始时间 |
ci_time_lte | str | 选填,修复问题的结束时间 |
file_path | str | 选填,文件路径 |
checkrule_display_name | str | 选填,检查规则名 |
checkpackage | int | 选填,问题所属的规则包 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "repo_id": 1,
+ "project_id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "file_path": "test/demo.py",
+ "scm_url": "",
+ "real_file_path": "",
+ "line": 21,
+ "column": 68,
+ "checkrule_gid": 1,
+ "checkrule_real_name": "xxx",
+ "checkrule_display_name": "xxx",
+ "checkrule_rule_title": "xxx",
+ "checktool_name": "xxx",
+ "category": 7,
+ "msg": "xxx",
+ "state": 1,
+ "resolution": null,
+ "author": "author",
+ "scan_open_id": 1,
+ "scan_fix_id": null,
+ "issuedetail_uuid": "26d7ba88-8268-11eb-a304-5254005e71ca",
+ "scan_revision": "scan_revision",
+ "real_revision": "",
+ "severity": 2,
+ "language": "python",
+ "revision": "revision",
+ "ci_time": "2019-07-01T10:28:19+08:00",
+ "file_owners": null,
+ "created_time": "2021-03-11T20:49:00.539537+08:00",
+ "fixed_time": null
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "xxx",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/
+
参数 | 类型 | 描述 |
---|---|---|
incr_scan | bool | 选填,增量扫描标志,true表示增量,false表示全量 |
async_flag | bool | 选填,异步启动标志,true表示异步,false表示同步,建议选择异步 |
force_create | bool | 选填,强制启动标志,true表示强制启动,不等待上一个任务结束 |
{
+ "job": {
+ "id": 7974
+ },
+ "scan": {
+ "id": 5528
+ }
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/
+
参数 | 类型 | 描述 |
---|---|---|
create_time_gte | datetime | 选填,最小任务启动时间 |
create_time_lte | datetime | 选填,最大任务启动时间 |
result_code_gte | int | 选填,最小错误码值 |
result_code_lte | int | 选填,最大错误码值 |
result_msg | str | 选填,结果信息 |
state | int | 选填,任务状态, 0为等待中,1为执行中,2为关闭,3为入库中,可多选,格式为1,2,3 |
created_from | str | 选填,创建来源 |
creator | str | 选填,创建用户 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/
+
{
+ "data": {
+ "id": 1,
+ "scan_id": 1,
+ "create_time": "2021-01-28T10:27:26.442961+08:00",
+ "waiting_time": "1",
+ "start_time": "2021-01-28T11:14:56.760427+08:00",
+ "execute_time": "3",
+ "project": {
+ "id": 1,
+ "branch": "master",
+ "repo_id": 1,
+ "scan_scheme": 1,
+ "repo_scm_url": "http://github.com/xxx/test_demo.git"
+ },
+ "end_time": "2021-01-28T11:14:59.760427+08:00",
+ "expire_time": "2021-01-28T14:07:52.968932+08:00",
+ "task_num": 1,
+ "task_done": 1,
+ "tasks": [
+ {
+ "id": 1,
+ "module": "codelint",
+ "task_name": "pylint",
+ "progress_rate": 1,
+ "state": 2,
+ "result_code": 0,
+ "result_msg": "success",
+ "result_path": null
+ }
+ ],
+ "co_jobs": [],
+ "state": 2,
+ "result_code": 0,
+ "result_code_msg": null,
+ "result_msg": "success",
+ "result_path": null,
+ "remarks": null,
+ "remarked_by": null,
+ "code_line_num": 1000,
+ "comment_line_num": 5,
+ "blank_line_num": 305,
+ "total_line_num": 1400,
+ "created_from": "codedog_web",
+ "creator": "creator"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
注:以下字段用于参考,具体字段格式需要以具体接口返回为准
org_sid: str,团队编号
+name: str,团队名称
+description: str,团队描述
+certificated: boolean,团队认证标志位
+created_time: datetime,团队创建时间
+updated_time: datetime,团队更新时间
+admins: list,管理员列表
+project_count: int,分析任务数量
+team_count: int,项目组数量
+user_count: int,成员数量
+owner: str,负责人名称
+tel_number: str,负责人电话
+address: str,办公地址
+
name: str,项目组名称
+display_name: str,项目组展示名称
+description: str,项目组描述信息
+
name: str,代码库名称
+scm_url: str,代码库地址
+scm_type: int,代码库类型
+created_from: str,创建来源
+state:str,代码库状态,1表示活跃,2表示失活,3表示暂停使用
+labels:list,标签
+project_team: 项目
+organization: 团队
+
name: str,扫描方案名称
+repo:关联的代码库
+refer_scheme: 参照的扫描方案
+description: str,描述
+tag: 执行标签
+languages: 包含语言
+default_flag: boolean,默认方案标志
+created_from: str,创建来源
+ignore_merged_issue: boolean,过滤其他分支引入的问题,默认False,不过滤
+ignore_branch_issue: str,过滤指定分支引入的问题
+ignore_submodule_clone: boolean,不拉取子模块,默认False
+ignore_submodule_issue: boolean,忽略子模块问题,默认False
+issue_global_ignore: boolean,开启问题全局忽略,默认False
+daily_save: boolean,日常扫描记录保存7天开关,默认False
+lfs_flag: boolean,自动拉取lfs文件,默认True
+status: int,扫描方案状态,1为活跃,2为废弃
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/
+
{
+ "data": {
+ "lintscan": {
+ "issue_open_num": 74,
+ "issue_fix_num": 439,
+ "issue_detail_num": 310,
+ "scan": {
+ "id": 1,
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "execute_time": "00:02:17.844712"
+ },
+ "current_scan": {
+ "active_category_detail": {
+ "convention": 70,
+ "other": 4
+ },
+ "active_severity_detail": {
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 74,
+ "issue_fix_num": 439
+ },
+ "total": {
+ "state_detail": {
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": {
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": {
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0,
+ "text": "成功",
+ "description": null,
+ "scan_summary": {
+ "convention": {
+ "error": {
+ "rule_count": 7,
+ "active": 65
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ },
+ "cyclomaticcomplexityscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ },
+ "duplicatescan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/latestscan/
+
参数 | 类型 | 描述 |
---|---|---|
scan_revision | str | 选填,指定查询的扫描版本号,如不指定则为当前项目最新的一次扫描 |
{
+ "data": {
+ "id": 1, # 扫描编号
+ "repo_id": 1, # 代码库编号
+ "project_id": 1, # 项目编号
+ "job_gid": 1, # 关联任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "current_revision": "current_revision", # 扫描版本号
+ "result_code": 0, # 扫描任务结果码,0表示正常
+ "result_code_msg": "成功",
+ "result_msg": null,
+ "lintscan": { # 代码扫描结果信息
+ "current_scan": { # 本次扫描信息
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ }
+ },
+ "duplicatescan": { # 重复代码扫描结果信息
+ "id": 1, # 扫描任务编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "default_summary": { # 默认概览
+ "exhi_risk": { # 极高风险
+ "range": [ # 重复率范围: 0.2-1
+ 0.2,
+ 1
+ ],
+ "file_count": 1, # 文件数量
+ "diff": { # 增量数据
+ "diff_file_count": 0 # 增量文件数量
+ }
+ },
+ "high_risk": { # 高风险
+ "range": [ # 重复率范围:0.11-0.2
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": { # 中风险
+ "range": [ # 重复率范围:0.05-0.11
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": { # 低风险
+ "range": [ # 重复率范围:0-0.05
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null, # 自定义概览数据
+ "last_revision": "2010ef28ff3a26424d4e8f32df022f90cd682eda", # 上次扫描版本号
+ "duplicate_file_count": 8, # 重复文件数量
+ "duplicate_block_count": 55, # 重复代码块数量
+ "duplicate_line_count": 1177, # 重复代码行数
+ "diff_duplicate_block_count": 0, # 增量重复代码块数量
+ "diff_duplicate_line_count": 0, # 增量重复代码行数
+ "close_issue_count": 0, # 关闭问题数
+ "new_issue_count": 0, # 新增问题数
+ "reopen_issue_count": 5, # 重新打开问题数
+ "ignored_issue_count": 0, # 忽略问题数
+ "duplicate_rate": 4.98, # 重复率
+ "unique_duplicate_line_count": 1083, # 去重后的重复代码行数
+ "total_duplicate_line_count": 1083, # 项目总的去重后的重复代码行数
+ "total_line_count": 21745, # 项目总行书
+ "scan": 1 # 关联扫描任务编号
+ },
+ "cyclomaticcomplexityscan": { # 圈复杂度扫描数据
+ "id": 1, # 圈复杂度扫描编号
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": { # 默认概览数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "over_cc_func_count": 6, # 超标函数数量
+ "under_cc_func_count": 796, # 未超标函数数量
+ "diff_over_cc_func_count": 0, # 增量超标函数数据
+ "over_cc_func_average": 22.333333333333332, # 平均超标圈复杂度
+ "cc_func_average": 2.5099750623441395, # 平均圈复杂度
+ "over_cc_sum": 14, # 文件超标方法圈复杂度超过阈值的差值之和
+ "cc_average_of_lines": 1.0422094841063054 # 千行代码平均圈复杂度
+ },
+ "custom_summary": null, # 自定义概览数据
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "diff_cc_num": 0, # 增量超标函数数量
+ "cc_open_num": 6, # 超标函数量
+ "cc_average_of_lines": 1.0422094841063054, # 千行代码平均圈复杂度
+ "cc_fix_num": 0, # 修复数量
+ "worse_cc_file_num": 0, # 圈复杂度恶化的文件数据
+ "min_ccn": 20, # 最小圈复杂度阈值
+ "code_line_num": 13433, # 代码行数
+ "scan": 1
+ },
+ "clocscan": {
+ "id": 1,
+ "scan_revision": "scan_revision", # 扫描版本号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描时间
+ "last_revision": "last_revision", # 上一次扫描版本号
+ "code_line_num": 140490, # 代码行数
+ "comment_line_num": 5410, # 注释行数
+ "blank_line_num": 3408, # 空白行数
+ "total_line_num": 149308, # 总行数
+ "add_code_line_num": 6673, # 增加的代码行数
+ "add_comment_line_num": 2309, # 增加的注释行数
+ "add_blank_line_num": 1289, # 增加的空白行数
+ "add_total_line_num": 10271, # 增加的总行数
+ "mod_code_line_num": 965, # 修改的代码行数
+ "mod_comment_line_num": 297, # 修改的注释行数
+ "mod_blank_line_num": 0, # 修改的空白行数
+ "mod_total_line_num": 1262, # 修改的总行数
+ "del_code_line_num": 35844, # 删除的代码行数
+ "del_comment_line_num": 2117, # 删除的注释行数
+ "del_blank_line_num": 1794, # 删除的空白行数
+ "del_total_line_num": 39755, # 删除的总行数
+ "scan": 1
+ }
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/lintscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2, # 本次扫描关闭存量问题数
+ "issue_detail_num": 310, # 本次扫描上报原始问题数(问题展示会进行聚合)
+ "scan": { # 扫描信息
+ "id": 1, # 扫描任务编号
+ "scan_time": "2021-03-11T20:46:44.171607+08:00", # 扫描开始时间
+ "execute_time": "00:02:17.844712" # 扫描执行耗时
+ },
+ "current_scan": { # 本次扫描信息
+ "active_category_detail": { # 活跃问题分类,包含 CORRECTNESS(1-功能)、SECURITY(2-安全)、PERFORMANCE(3-性能)、USABILITY(4-可用性)、ACCESSIBILITY(5-无障碍化)、I18N(6-国际化)、CONVENTION(7-代码风格)、OTHER(8-其他)
+ "convention": 70, # 代码风格类型问题
+ "other": 4 # 其他类型问题
+ },
+ "active_severity_detail": { # 不同严重级别的活跃问题数,包含 fatal(1-致命), error(2-错误), warning(3-警告), info(4-提示)
+ "error": 69,
+ "warning": 5
+ },
+ "issue_open_num": 10, # 本次扫描新发现问题数
+ "issue_fix_num": 2 # 本次扫描关闭存量问题数
+ },
+ "total": { # 当前项目整体信息
+ "state_detail": { # 不同处理状态的问题数,包含 active(1-活跃)、resolved(2-已处理)、closed(3-已关闭)
+ "active": 197,
+ "resolved": 13,
+ "closed": 23297
+ },
+ "category_detail": { # 不同分类下不同处理状态的问题量
+ "convention": {
+ "active": 184,
+ "resolved": 13,
+ "closed": 21143
+ },
+ "other": {
+ "active": 13,
+ "closed": 154
+ },
+ "correctness": {
+ "closed": 1997
+ },
+ "performance": {
+ "closed": 3
+ }
+ },
+ "severity_detail": { # 不同严重级别下不同处理状态的问题量
+ "error": {
+ "active": 157,
+ "resolved": 11,
+ "closed": 20113
+ },
+ "warning": {
+ "active": 40,
+ "resolved": 2,
+ "closed": 2930
+ },
+ "info": {
+ "closed": 254
+ }
+ }
+ },
+ "status": 0, # 扫描状态,0表示成功
+ "text": "成功",
+ "description": null,
+ "scan_summary": { # 扫描概览
+ "convention": {
+ "error": {
+ "rule_count": 7, # 规则数
+ "active": 65 # 活跃问题数
+ },
+ "warning": {
+ "rule_count": 2,
+ "active": 5
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 1,
+ "active": 4
+ }
+ }
+ },
+ "total_summary": {
+ "correctness": {
+ "error": {
+ "rule_count": 16,
+ "closed": 1315
+ },
+ "warning": {
+ "rule_count": 10,
+ "closed": 629
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 53
+ }
+ },
+ "performance": {
+ "warning": {
+ "rule_count": 1,
+ "closed": 3
+ }
+ },
+ "convention": {
+ "error": {
+ "rule_count": 42,
+ "active": 149,
+ "resolved": 11,
+ "closed": 18778
+ },
+ "warning": {
+ "rule_count": 17,
+ "active": 35,
+ "resolved": 2,
+ "closed": 2298
+ },
+ "info": {
+ "rule_count": 1,
+ "closed": 67
+ }
+ },
+ "other": {
+ "error": {
+ "rule_count": 2,
+ "active": 8,
+ "closed": 20
+ },
+ "warning": {
+ "rule_count": 1,
+ "active": 5
+ },
+ "info": {
+ "rule_count": 3,
+ "closed": 134
+ }
+ }
+ }
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/cycscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "min_ccn": 20,
+ "over_cc_func_count": 6,
+ "under_cc_func_count": 796,
+ "diff_over_cc_func_count": 0,
+ "over_cc_func_average": 22.333333333333332,
+ "cc_func_average": 2.5099750623441395,
+ "over_cc_sum": 14,
+ "cc_average_of_lines": 1.0422094841063054
+ },
+ "custom_summary": null,
+ "created_time": "2021-03-11T20:48:59.976947+08:00",
+ "creator": null,
+ "modified_time": "2021-03-11T20:49:00.088841+08:00",
+ "modifier": null,
+ "deleted_time": null,
+ "deleter": null,
+ "last_revision": "last_revision",
+ "diff_cc_num": 0,
+ "cc_open_num": 6,
+ "cc_average_of_lines": 1.0422094841063054,
+ "cc_fix_num": 0,
+ "worse_cc_file_num": 0,
+ "min_ccn": 20,
+ "code_line_num": 13433,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/dupscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "default_summary": {
+ "exhi_risk": {
+ "range": [
+ 0.2,
+ 1
+ ],
+ "file_count": 1,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "high_risk": {
+ "range": [
+ 0.11,
+ 0.2
+ ],
+ "file_count": 3,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "midd_risk": {
+ "range": [
+ 0.05,
+ 0.11
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ },
+ "low_risk": {
+ "range": [
+ 0,
+ 0.05
+ ],
+ "file_count": 2,
+ "diff": {
+ "diff_file_count": 0
+ }
+ }
+ },
+ "custom_summary": null,
+ "last_revision": "last_revision",
+ "duplicate_file_count": 8,
+ "duplicate_block_count": 55,
+ "duplicate_line_count": 1177,
+ "diff_duplicate_block_count": 0,
+ "diff_duplicate_line_count": 0,
+ "close_issue_count": 0,
+ "new_issue_count": 0,
+ "reopen_issue_count": 5,
+ "ignored_issue_count": 0,
+ "duplicate_rate": 4.98,
+ "unique_duplicate_line_count": 1083,
+ "total_duplicate_line_count": 1083,
+ "total_line_count": 21745,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/clocscans/
+
参数 | 类型 | 描述 |
---|---|---|
scan_time_before | str | 选填,扫描任务起始时间,格式: 2021-01-01 00:00:00 |
scan_time_after | str | 选填,扫描任务结束时间 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "scan_revision": "scan_revision",
+ "scan_time": "2021-03-11T20:46:44.171607+08:00",
+ "last_revision": "last_revision",
+ "code_line_num": 140490,
+ "comment_line_num": 5410,
+ "blank_line_num": 3408,
+ "total_line_num": 149308,
+ "add_code_line_num": 6673,
+ "add_comment_line_num": 2309,
+ "add_blank_line_num": 1289,
+ "add_total_line_num": 10271,
+ "mod_code_line_num": 965,
+ "mod_comment_line_num": 297,
+ "mod_blank_line_num": 0,
+ "mod_total_line_num": 1262,
+ "del_code_line_num": 35844,
+ "del_comment_line_num": 2117,
+ "del_blank_line_num": 1794,
+ "del_total_line_num": 39755,
+ "scan": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url_or_name | str | 选填,代码库地址或者名称,支持模糊匹配 |
scm_url | str | 选填,代码库仓库匹配 |
scope | str | 选填,过滤范围(my/subscribed/related_me),my表示我创建的,subscribed表示我关注的,related_me表示我有权限的 |
{
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ }
+ ]
+}
+
GET /server/main/api/authen/scmallaccounts/
+
{
+ "data": {
+ "ssh": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "indentity": "xxx",
+ "display_scm_platform": "tgit",
+ "name": "gerrit",
+ "scm_platform": 1,
+ "scm_platform_desc": null
+ }
+ ],
+ "account": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "display_scm_platform": "tgit",
+ "scm_username": "CodeDog",
+ "scm_platform": 1,
+ "scm_platform_desc": null
+ }
+ ],
+ "oauth": [
+ {
+ "id": 1,
+ "user": {
+ "username": "CodeDog",
+ "nickname": "CodeDog",
+ "status": 1,
+ "avatar": null,
+ "latest_login_time": "2022-10-22T15:30:30+08:00",
+ "org": null
+ },
+ "auth_origin": "CodeDog",
+ "scm_platform_name": "tgit"
+ }
+ ],
+ }
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
参数 | 类型 | 描述 |
---|---|---|
scm_url | str | 必填,代码库地址 |
scm_type | str | 必填,git或svn |
ssh_url | str | 选填,代码库SSH地址 |
name | str | 选填, 代码库名称 |
scm_auth | dict | 选填,代码库授权 |
例子:
{
+ "scm_url": "https://github.com/Tencent/CodeAnalysis",
+ "scm_type": "git",
+ "name": "CodeAnalysis",
+ "scm_auth": {
+ # 通过 查看已创建的授权信息 接口获取到对应的凭证id,scm_account、scm_oauth、scm_ssh 只需填一个
+ "scm_account": account_id,
+ "scm_ssh": ssh_id,
+ "scm_oauth": oauth_id
+ }
+}
+
{
+ "data":{
+ "id": 1,
+ "name": "CodeAnalysis",
+ "scm_url": "http://github.com/Tencent/CodeAnalysis",
+ "scm_type": "git",
+ "branch_count": 0,
+ "scheme_count": 0,
+ "job_count": 0,
+ "created_time": "2022-10-22T16:30:30+08:00",
+ "recent_active": {
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/
+
{
+ "data":{
+ "id": 1,
+ "name": "test_repo.git",
+ "scm_url": "http://git.com/xxx/test_repo",
+ "scm_type": "git",
+ "branch_count": 1,
+ "scheme_count": 1,
+ "job_count": 1,
+ "created_time": "2021-03-15 02:26:31.423674+00:00",
+ "recent_active": {
+ "id": 1,
+ "branch_name": "master",
+ "active_time": "2021-03-15T03:14:56.760427Z",
+ "total_line_num": null,
+ "code_line_num": null
+ },
+ "created_from": "codedog_web",
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "symbol": null
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/branches/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "branch": "master",
+ "schemes": [
+ {
+ "project_id": 1,
+ "scan_scheme_id": 1,
+ "scan_scheme_name": "默认"
+ }
+ ]
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
branch | str | 选填,分支名称 |
scan_scheme | int | 选填,扫描方案名称 |
scan_scheme__status | int | 选填,扫描方案状态,1为活跃,2为废弃 |
branch_or_scheme | str | 选填,分支名称/扫描方案名称 |
status | int | 选填,项目状态筛选,1表示活跃,2表示失活,3表示关闭 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "codedog_web",
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
参数 | 类型 | 描述 |
---|---|---|
scan_scheme_id | int | 和global_scheme_id二选一进行填写,当前代码库的扫描方案编号 |
global_scheme_id | int | 和scan_scheme_id二选一进行填写,扫描方案模板编号 |
custom_scheme_name | str | 选填,自定义方案名称 |
branch | str | 必填,分支 |
created_from | str | 选填,创建渠道,用于区分不同运行场景 |
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/
+
{
+ "data": {
+ "id":1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.256015+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.256284+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "repo": {
+ "id": 1,
+ "name": "test_demo.git",
+ "scm_url": "http://github.com/xxxx/test_demo.git",
+ "scm_type": "git",
+ "scm_auth": {
+ "id": 1,
+ "scm_account": null,
+ "scm_oauth": null,
+ "scm_ssh": {
+ "id": 1,
+ "name": "1",
+ "scm_platform": 1,
+ "scm_platform_desc": null,
+ "user": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ }
+ },
+ "auth_type": "ssh_token",
+ "created_time": "2021-01-28T10:26:31.453389+08:00",
+ "modified_time": "2021-01-28T10:26:31.453417+08:00"
+ },
+ "symbol": null
+ },
+ "scan_scheme": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme_info": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "webhook_flag": false,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "scheme_key": null,
+ "repo": 1
+ },
+ "branch": "master",
+ "status": 1,
+ "created_from": "tca_web"
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/
+
参数 | 类型 | 描述 |
---|---|---|
name | str | 选填,扫描方案名称 |
status | int | 选填,扫描方案状态,1为活跃,2为废弃 |
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
{
+ "data": {
+ "id": 1,
+ "creator": {
+ "username": "username",
+ "nickname": "nickname",
+ "status": 1,
+ "avatar": null,
+ "org": 1
+ },
+ "created_time": "2021-01-28 02:27:26.209661+00:00",
+ "modifier": null,
+ "modified_time": "2021-01-28 02:27:26.255023+00:00",
+ "deleter": null,
+ "deleted_time": null,
+ "languages": [
+ "python"
+ ],
+ "tag": "TCA_Linux",
+ "refer_scheme": null,
+ "name": "默认",
+ "description": null,
+ "default_flag": true,
+ "created_from": "web",
+ "job_runtime_limit": 600,
+ "ignore_merged_issue": false,
+ "ignore_branch_issue": null,
+ "ignore_submodule_clone": false,
+ "ignore_submodule_issue": true,
+ "issue_global_ignore": false,
+ "daily_save": false,
+ "lfs_flag": null,
+ "issue_revision_merge_flag": false,
+ "status": 1,
+ "repo": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/basicconf/
+
参数 | 类型 | 描述 |
---|---|---|
languages | list | 选填,代码语言 |
tag | str | 选填,执行标签,目前只支持 CodeDog_Linux |
name | str | 必填,方案名称 |
description | str | 选填,方案描述 |
default_flag | bool | 选填,默认方案标志,一个代码库只能有一个默认方案 |
job_runtime_limit | int | 选填,任务执行超时时间,默认为600分钟 |
ignore_merged_issue | bool | 选填,忽略合入的问题 |
ignore_branch_issue | str | 选填,过滤参考分支引入的问题 |
ignore_submodule_clone | bool | 选填,不拉取子模块扫描,True表示不拉取,False表示拉取 |
ignore_submodule_issue | bool | 选填,忽略子模块引入的问题,True表示忽略,False表示不忽略 |
issue_global_ignore | bool | 选填,问题全局忽略 |
daily_save | bool | 选填,每次扫描原始数据存储,默认存储7天 |
lfs_flag | bool | 选填,拉取lfs模块开关 |
issue_revision_merge_flag | bool | 选填,"是否开启Issue按引入版本号聚合开关 |
status | int | 选填,方案状态,1表示活跃,2表示废弃 |
同查看指定代码库的指定扫描方案的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
{
+ "data": {
+ "id": 1,
+ "enabled": true,
+ "checkprofile": {
+ "id": 1,
+ "profile_type": 1,
+ "custom_checkpackage": 1,
+ "checkpackages": [
+ 1
+ ]
+ },
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/lintconf/
+
参数 | 类型 | 描述 |
---|---|---|
enabled | bool | 必填,是否开启代码扫描 |
同指定代码库的指定方案的代码扫描配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
{
+ "data": {
+ "id": 1,
+ "cc_scan_enabled": false,
+ "min_ccn": 20,
+ "dup_scan_enabled": false,
+ "dup_block_length_min": 120,
+ "dup_block_length_max": null,
+ "dup_min_dup_times": 2,
+ "dup_max_dup_times": null,
+ "dup_min_midd_rate": 5,
+ "dup_min_high_rate": 11,
+ "dup_min_exhi_rate": 20,
+ "dup_issue_limit": 1000,
+ "cloc_scan_enabled": false,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
参数 | 类型 | 描述 |
---|---|---|
cc_scan_enabled | bool | 选填,圈复杂度扫描开关 |
min_ccn | int | 选填,最小圈复杂度 |
dup_scan_enabled | bool | 选填,重复代码扫描开关 |
dup_block_length_min | int | 选填,重复块最小长度 |
dup_block_length_max | int | 选填,重复块最大长度 |
dup_max_dup_times | int | 选填,最大重复次数 |
dup_min_midd_rate | int | 选填,中风险最小重复率 |
dup_min_high_rate | int | 选填,高风险最小重复率 |
dup_min_exhi_rate | int | 选填,极高风险风险最小重复率 |
dup_issue_limit | int | 选填,上报重复代码块数上限 |
cloc_scan_enabled | boolean | 选填,代码统计扫描开关 |
同指定代码库的指定方案的代码度量配置的返回结果一致
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
{
+ "data": {
+ "count": 1,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "id": 1,
+ "dir_path": "test/*",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ }
+ ]
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 必填,指定过滤路径 |
path_type | int | 选填,路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 选填,扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
{
+ "data": {
+ "id": 1,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 1
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 200
+}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
参数 | 类型 | 描述 |
---|---|---|
dir_path | str | 必填,指定过滤路径 |
path_type | int | 选填,路径格式,1表示通配符,2表示正则表达式,默认为通配符 |
scan_type | int | 选填,扫描类型,1表示包含,2表示排除 |
{
+ "data": {
+ "id": 13,
+ "dir_path": "test/*.py",
+ "path_type": 1,
+ "scan_type": 1,
+ "scan_scheme": 36
+ },
+ "code": 0,
+ "msg": "请求成功",
+ "status_code": 201
+}
+
DELETE /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/scandirs/<dir_id>/
+
无
初始发布
欢迎报告Issue或提交Pull Request。建议在贡献代码前先阅读以下贡献指南。
我们使用Github Issues来跟踪漏洞和功能请求。
在您提交新的issue前,请搜索现有issue以查看是否已有人提交任何类似问题或功能请求,确认不存在重复的issue。
当您提交新的issue时,请尽量提供更多的信息,例如与问题相关的详细描述、屏幕截图、视频、logcat和导致崩溃的代码块。
我们非常欢迎您提出Pull Request来帮助TCA变得更好,操作流程详见PullRequests操作流程。
TCA有两个主要分支:
main
分支: main
作为标签, 带有版本号 v1.0.1
, v1.0.2
...main
分支提交任何PR.dev
分支: dev
分支将合并到 main
分支的下一个版本。dev
分支。代码团队将监控所有拉取请求,我们对其进行一些代码检查和测试。在所有测试通过后,我们将接受此PR。但它不会立即合并到 main
分支,这有一些延迟。
在提交拉取请求之前,请确保完成以下工作:
main
创建分支。dev
分支提交Pull Request。MIT LICENSE 是 TCA 的开源许可证。任何人贡献的代码都受此许可证保护。在贡献代码之前,请确保您可以接受许可。
PR全称为Pull Request,它是一种代码库的协作方式。开发者可以通过PR将自己在代码库的修改通知到代码库负责人,由原作者评审代码并决定是否能合入。
提示
Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.
点击Fork后,会在自己名下产生一个相同代码库,比如我Fork CodeAnalysis项目后,会在我名下多出一个CodeAnalysis代码库,地址为https://github.com/Lingghh/CodeAnalysis
在本地克隆Fork的代码库并创建分支
git clone https://github.com/Lingghh/CodeAnalysis
+git checkout -b dev/add_qa_20220301
+
注:也可以在自己Fork的代码库GitHub页面上创建分支。
接下来就可以在本地修改代码,修改完成后先push到Fork的代码库中.
点击compare across forks 。
点击head repository 。
选择自己Fork的代码库和比较的分支,比如我这里选择Lingghh/CodeAnalysis和待合入的分支dev/add_arm64_file 。
最后确认commits和changed files是否准确,如果没有问题就可以点击Create pull request 。
PR创建后,代码库管理员会评审你提交的代码,并决定是否接受该PR。
腾讯云代码分析(Tencent Cloud Code Analysis, TCA)起步于 2012 年(内部代号CodeDog),是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是精准跟踪管理代码分析发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码,以及度量代码复杂度、重复代码、代码统计。持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
用心关注每行代码迭代,助力传承卓越代码文化!
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
通过代码检查精准跟踪管理发现的代码质量缺陷、代码规范、代码安全漏洞、无效代码等。
目前已集成众多自研、知名开源分析工具,并采用了分层分离架构,可以满足团队快速自助管理工具。
包含代码圈复杂度、代码重复率和代码统计等度量信息。
圈复杂度也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度。圈复杂度大说明程序代码的判断逻辑复杂,可能造成代码质量低下且难于测试和维护。
定期分析工程项目中代码的圈复杂度,可以有效地帮助开发与测试逐步优化代码质量。
定期分析工程项目中的重复代码,可以有效地帮助开发发现冗余代码,进行代码抽象和重构,降低代码风险,以便于更好的管理和维护代码。
支持全量增量展示代码行数统计,包含代码行、注释行和空白行,可以有效地跟踪了解工程项目中代码量持续变化,并可以查看各个语言的占比情况。
Linux 环境
系统已安装 nginx
TCA Server 服务已部署完毕,具备后端服务地址
进入前端部署源码目录
进入web服务目录,并切换至tca-deploy-source
目录,将其视为工作目录(假设工作目录为 /data/CodeAnalysis/web/tca-deploy-source
)
部署/更新前端服务
# 部署、更新都使用此命令
+sh ./scripts/deploy.sh init -d
+
具体请查阅部署脚本内容,可根据业务调整配置。
额外说明
tca-deploy-source/scripts/config.sh
已配置默认环境变量,用户可根据需要调整环境变量再部署前端服务,具体可查阅脚本内容。
TCA Web 采用 Lerna 进行 monorepo
管理。
由 framework
、login
、tca-layout
、tca-analysis
、tca-manage
微前端以及tca-document
前端帮助文档组成。
shared
: 公共模块
framework
: 微前端基座
login
: 登录微前端
tca-layout
: 腾讯云代码分析layout微前端
tca-analysis
: 腾讯云代码分析analysis微前端
tca-manage
: 腾讯云代码分析后台管理微前端
tca-document
: 腾讯云代码分析帮助文档
已将当前版本各个微前端构建打包到此目录,可通过阅读该目录下的 README 直接进行前端部署。
按上一节完成一套 TCA Web 部署
根据要调整的内容,启动对应的微前端(login、tca-layout、tca-analysis),具体可进入不同 package
参考阅读其目录下的 README
进行开发。
其他:
根目录下启动单个项目
# framework
+yarn dev --scope framework
+# login
+PUBLIC_PATH=http://127.0.0.1:5055/ yarn dev --scope login
+# tca-layout
+PUBLIC_PATH=http://127.0.0.1:5056/ yarn dev --scope tca-layout
+# tca-analysis
+PUBLIC_PATH=http://127.0.0.1:5057/ yarn dev --scope tca-analysis
+# tca-manage
+PUBLIC_PATH=http://127.0.0.1:5058/ yarn dev --scope tca-manage
+# tca-document
+yarn dev --scope tca-document
+# 或进入对应项目内,查阅对应README
+
如对项目进行变更,本地开发结束后,需要部署最新资源可通过执行 sh build-source.sh
将构建后资源更新到tca-deploy-source 目录内,再参考该目录下的 README 直接进行前端更新/重新部署操作。
可通过阅读 build-source.sh
内容,以及 tca-deploy-source 目录下的 README,用户可根据需要自行进行前端部署。
代码分析完毕后,可在分支概览
页面查看分析结果概览。如果分析方案含有代码检查功能,则会上报代码检查结果信息到腾讯云代码分析平台,用户可在平台上查看问题列表及问题详情。
进入代码检查问题列表页面后,默认展示当前分析项目发现的全部未处理问题。
如果仅希望查看增量问题,可以进入分析历史
页面,指定查看某一次的扫描结果即可。也可以在过滤筛选项中填入发现问题的扫描 id
进行筛选查看结果(该id
为扫描任务 ID,需要到扫描任务列表中查询)。
责任人说明
责任人为 git blame
操作得到的代码提交人。
问题级别说明
代码检查的问题级别是根据对应分析方案中规则设置的严重级别定义的,从高到低分为 致命、错误、警告、提示
。如果调整问题级别,则需要进入分析方案中调整这个规则的严重级别,调整后需要进行全量扫描使得调整生效。
批量处理说明
问题列表支持批量修改问题状态。
点击规则信息可以查看规则说明。
Error Prone是google开源的Java编译时检测工具,将常见的Java错误捕获为编译时错误,增强对java代码的类型分析,从而让开发人员及时发现问题
TCA原有编译时检测工具JavaWarning获取java代码编译时的告警信息,现集成Error Prone规则至JavaWarning工具以增加获取Error Prone的错误告警信息。
bazel build :project
构建项目即可。编辑pom.xml文件将设置添加到maven-compiler-plugin,例如:
<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ <encoding>UTF-8</encoding>
+ <compilerArgs>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>-Xplugin:ErrorProne</arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${error-prone.version}</version>
+ </path>
+ <!-- Other annotation processors go here.
+
+ If 'annotationProcessorPaths' is set, processors will no longer be
+ discovered on the regular -classpath; see also 'Using Error Prone
+ together with other annotation processors' below. -->
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
对于JDK 16
或更高的版本,需要将以下内容--add-exports
和--add-opens
标志添加到.mvn/jvm.config
文件中:
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+
###命令行 Error Prone 支持com.sun.source.util.Plugin
API,并且可以通过将 Error Prone 添加到-processorpath
并设置-Xplugin
标志来与JDK 9
及更高版本一起使用:
wget https://repo1.maven.org/maven2/com/google/errorprone/error_prone_core/${EP_VERSION?}/error_prone_core-${EP_VERSION?}-with-dependencies.jar
+wget https://repo1.maven.org/maven2/org/checkerframework/dataflow-errorprone/3.15.0/dataflow-errorprone-3.15.0.jar
+javac \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
+ -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
+ -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
+ -XDcompilePolicy=simple \
+ -processorpath error_prone_core-${EP_VERSION?}-with-dependencies.jar:dataflow-errorprone-3.15.0.jar \
+ '-Xplugin:ErrorProne -XepDisableAllChecks -Xep:CollectionIncompatibleType:ERROR' \
+ Example.java
+
JDK 16
以及更高的版本--add-exports
和--add-opens
参数是必须的JDK 8
,请参考旧版本安装说明TCA-Armory-C1 属于 TCA 的增强分析模块。
支持的语言:Java
CmdInject 规则用于检查代码中是否存在命令行注入漏洞
。 当使用 childprocess 等模块执行命令时,拼接了用户可控的输入,会导致命令执行漏洞。攻击者利用漏洞可以控制目标主机或者容器。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String cmd = req.getParameter("cmd");
+ Runtime rt = Runtime.getRuntime();
+ rt.exec(cmd); // 触发规则
+}
+
需要评估 childprocess 等模块执行命令的使用,应限定或校验命令和参数的内容。
支持的语言:Java
PathTraversal 规则用于检查代码中是否存在路径穿越漏洞
。 操作文件时,应该限定文件的路径范围,如果拼接用户输入到文件路径,可能导致路径穿越漏洞。攻击者利用漏洞可以访问到文件系统上的任意文件,这可能导致信息泄漏等问题。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String image = req.getParameter("image");
+ File file = new File("resources/images/", image); // 触发规则
+
+ if (!file.exists()) {
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
+ return Response.ok().entity(new FileInputStream(file)).build();
+}
+
按业务需求,使用白名单限定后缀范围,校验并限定文件路径范围。
支持的语言:Java
SQLInject 规则用于检查代码中是否存在SQL注入漏洞
。 错误的拼接用户可控的值到 sql 语句,可能导致 sql 注入漏洞。攻击者可以修改 sql 语法来更改查询的目标或结果,泄露数据库敏感信息,也可以使用SQL文件操作攻击底层Web服务器。如果使用该 sql 查询进行授权认证,攻击者还可以用于提权。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = req.getParameter("id");
+ Connection conn = null;
+ Statement statement = null;
+ ResultSet rs = null;
+
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sec_sql", "root", "admin888");
+ String sql = "select * from userinfo where id = " + id;
+ statement = conn.createStatement();
+ statement.executeUpdate(sql); // 触发规则
+}
+
SQL 语句默认使用预编译并绑定变量,使用安全的ORM操作。
支持的语言:Java
SSRF 规则用于检查代码中是否存在服务端请求伪造漏洞 SSRF(Server-side request forgery)
。 攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。
无
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf ->
+ csrf.disable() // 触发规则
+ );
+ }
+}
+
限定访问网络资源地址范围,请求网络资源应加密传输。
支持的语言:Java
XSS 规则用于检查代码中是否存在跨站脚本攻击漏洞 XSS(Cross-site scripting)
。 如果 web 页面在动态展示数据时使用了用户的输入内容,没有对输入的内容过滤或者进行转义,黑客可以通过参数传入恶意代码,当用户浏览该页面时恶意代码会被执行。
无
void bad(HttpServletRequest req, HttpServletResponse resp){
+ String id = request.getParameter("id") != null ? request.getParameter("id") : "0";
+ Doc doc = getdetailsById(id);
+ byte[] b = doc.getUploaded();
+ try {
+ response.setContentType("APPLICATION/OCTET-STREAM");
+ String disHeader = "Attachment;Filename=" + doc.getName();
+ response.setHeader("Content-Disposition", disHeader);
+ ServletOutputStream out = response.getOutputStream();
+ out.print(b); // 触发规则
+ }
+}
+
在输出所有用户可控的数据时, 对数据做转义或者编码。
检查 Objective-C/C++ 代码文件的copyright信息。
无
// 触发规则
+@interface Test : NSObject
+@end
+
+
在代码文件头部添加 Copyright 信息。比如:
// Copyright (c) xxxx Tencent. All rights reserved.
+//
+
+@interface Test : NSObject
+@end
+
+
检查 Objective-C/C++ 代码文件的缩进。
\t
,默认是 spaces;参考以下示例:
IndentStyle=spaces
+IndentSize=4
+
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
调整为对应的缩进方式。比如默认是4个空格缩进。
for (int i = 0; i < 10; i++) {
+ doThings(); // 触发规则
+}
+
检查 Objective-C/C++ 代码中超出行数长度阈值的函数。
参考以下示例:
LineThreshold=100
+
无
可以基于单一职责原则拆分函数,缩减函数长度。
检查 Objective-C/C++ 代码中 interface 是否有注释信息。
无
无
为 inferface 增加注释。
检查 Objective-C/C++ 代码中 Property 是否有注释信息。
无
无
为 Property 增加注释。
检查 Objective-C/C++ 代码中 Protocol 是否有注释信息。
无
无
为 Protocol 增加注释。
检查 Objective-C/C++ 代码中方法的参数个数是否超过阈值。
参考以下示例:
Max=6
+
无。
参数个数越少越好,多于 6 个参数时建议考虑重构。
检查 Objective-C/C++ 代码中 class 名称是否符合命名规范。
参考以下示例:
ClassCase=CamelCase
+
无。
修改 class 名称符合命名规范。
检查 Objective-C/C++ 代码中 Function 名称是否符合命名规范。
参考以下示例:
FunctionCase=camelBack
+
无。
修改 Function 名称符合命名规范。
检查 Objective-C/C++ 代码中 GlobalVariable 名称是否符合命名规范。
g
;参考以下示例:
GlobalVariablePrefix=g
+GlobalVariableCase=camelBack
+
无。
修改 GlobalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 LocalVariable 名称是否符合命名规范。
参考以下示例:
LocalVariableCase=camelBack
+
无。
修改 LocalVariable 名称符合命名规范。
检查 Objective-C/C++ 代码中 Macro 名称是否符合命名规范。
参考以下示例:
MacroCase=UPPER_CASE
+
无。
修改 Macro 名称符合命名规范。
检查 Objective-C/C++ 代码中 Method 名称是否符合命名规范。
参考以下示例:
MethodCase=camelBack
+
无。
修改 Method 名称符合命名规范。
检查 Objective-C/C++ 代码中 Parameter 名称是否符合命名规范。
参考以下示例:
ParameterCase=camelBack
+
无。
修改 Parameter 名称符合命名规范。
检查 Objective-C/C++ 代码中一行长度是否超过阈值。
参考以下示例:
tabWidth=4
+MaxLineLength=150
+
无。
通过换行、优化逻辑等方式,缩减一行长度。
TCA-Armory-Q1, 又名 tca_ql_cpp 主要用于分析Cpp质量问题。
包含规则:
在使用多线程对文件全局变量或类成员在进行读写时,工具会对未正确的进行上锁操作和上锁异常而引发死锁的情况进行检查。
支持的多线程标准库库包括(若有其他库需求可提issue):
missing_lock 如果发现多线程中某个全局变量在未持有锁便更新时,则会上报错误。
以下提供一个或多个 missing_loc 案例 在下面代码中,函数 increase1, increase2 皆以将 counter 加到 1000 为目的。如果使用 increase1 函数则有可能多个线程皆在 1000 时进入循环导致最后 counter结果大于 1000
int counter = 0;
+std::mutex mtx; // 保护counter
+void increase1() {
+ while (1) {
+ if (counter <= 1000)
+ counter++; // defect: missing_lock
+ else
+ break;
+ }
+}
+void increase2() {
+ while (1) {
+ mtx.lock(); // example_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx.unlock(); // example_release
+ }
+}
+
dead_lock 如果发现文件内存在 mtx1 -> mtx2 的上锁顺序时,另存在mtx2 -> mtx1 的上锁顺序,视为死锁或存在死锁的可能,则会上报错误。 死锁发生时程序将会卡死无法正常执行。
以下提供一个或多个 dead_lock 案例
在下面代码中,函数 increase 以将 counter 加到 1000 为目的。但在线程 1 中第一次释放 mtx 后,线程 2 的 mtx 上锁,此时线程1等待线程2释放mtx,线程2等待线程1释放mtx2,形成死锁,程序卡死。
int counter = 0;
+std::mutex mtx;
+std::mutex mtx2;
+void increase() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ mtx.unlock();
+ mtx.lock(); // defect: dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
在下面代码中 线程函数increase1存在mtx -> mtx2 的顺序,increase2顺序为 mtx2 -> mtx;视为出现死锁。
void increase1() {
+ while (1) {
+ mtx.lock();
+ mtx2.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+void increase2() {
+ while (1) {
+ mtx2.lock();
+ mtx.lock(); // defect: dead_lock;
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ mtx2.unlock();
+ mtx.unlock()
+ }
+}
+
以下案例在better-lock
参数为True
时将会生效 使用better-lock
规则会检查在上锁期间若调用其他函数时将视为可能会出现预期之外的异常,且上锁期间应只做对全局变量操作以提升性能
void increase1() {
+ while (1) {
+ mtx.lock();
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter); // defect: dead_lock
+ mtx.unlock()
+ }
+}
+void read_counter(counter){
+ std::cout << counter << std::endl;
+ do_something_more();
+}
+void increase1() {
+ while (1) {
+ std::lock_guard<std::mutex> lk(mtx); // good: 使用lock_guard会自动上锁解锁将不会检查dead_lock
+ if (counter <= 1000)
+ counter++;
+ else
+ break;
+ read_counter(counter);
+ }
+}
+
包含规则
resource_leak 在程序申请了资源但并未按时释放时上报错误 目前场景包括:句柄打开时未关闭,指针分配内存后没有及时释放
以下将提供一个或多个resource_leak案例
int leak_example1(int c) {
+ void *p = malloc(10);
+ if(c)
+ return -1; // defect: if c "p" is leaked
+ free(p);
+ return 0;
+}
+
+int leak_example2() {
+ void *p = malloc(10);
+ void *q = malloc(20);
+ if(!p || !q)
+ return -1; // defect: "p" or "q" may be leaked if the other is NULL
+ /*...*/
+ free(q);
+ free(p);
+ return 0;
+}
+
+void leak_example3(int c) {
+ FILE *p = fopen("starwar.anakin", "rb");
+ if(c)
+ return; // defect: leaking file pointer "p"
+ fclose(p);
+}
+
包含规则
unused_value 检查那些赋予给变量的值是否正确被使用,存在连续两次赋予变量值的情况,视为第一次赋予的值未被正确使用,报出错误。 两次连续赋值可能存在条件控制语句出现错误、变量名拼写错误等情况。
以下提供一个或多个unused_value案例
以下函数会因为key的不同去不一样的神明,但实际上 Zeus Hades却永远不会使用到。
const char* key_value(const int key) {
+ const char * value = 0;
+ if (key != 0) {
+ value = "Zeus";
+ } else if (key != 1) {
+ value = "Hades";
+ }
+ if (key != 2) { // Should be 'else if' here.
+ value = "Poseidon"; // defect: unused_value Zeus Hades never used
+ }
+ else {
+ value = "Unknow
+ }
+ return result;
+}
+
以下继续提供几个unused_value代码
const char* key_value1(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // defect: Zeus never used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ } else { // May else need not be here
+ value = "Unknow";
+ }
+ return value
+}
+
+const char* key_value2(const int key) {
+ const char * value = 0;
+ value = "Zeus"; // better Zeus used
+ if (key == 1) {
+ value = "Hades;
+ } else if (key == 2) {
+ value = "Poseidon";
+ }
+ return value
+}
+
+const char* key_value3(const int key) {
+ const char * value = 0;
+ if (key == 1) {
+ value = "Hades;
+ } else {
+ value = "Poseidon";
+ }
+ value = "Zeus"; // defect: Hades Poseidon never used
+ return value
+}
+
包含规则
array_overflow 检查数组越界的情况。不正确的缓存区访问可能损坏内存,导致程序崩溃或读取到权限外的内存。
以下提供一个或多个array_overflow案例
void foo() {
+ int array[10];
+ int i = get();
+ // i = 9;
+ if (i > 8 && i <= length(array)) { // Shoud be i < length(array)
+ array[i] = 1; // defect: array[10] overflow
+ }
+ array[i] = 1; // defect: array[10] overflow
+}
+
+
+void test(int i) {
+ int n= 10;
+ char *p = malloc(sizeof(int) * 10);
+ int y = n;
+ p[y] = 'a'; // defect: writing to buffer[y] overflow
+}
+
buff_overflow 检查strcpy
,strcat
字符串复制/拼接过程中长度不当导致的溢出, 同样gets
scanf
函数也视为不安全
以下提供一个或多个buff_overflow案例
void overflow1() {
+
+ char a[4]={0};
+ strcpy(a, "Poseidon"); // defect: len("Poseidon") > 4 strncpy is better
+ return;
+}
+
+void overflow2() {
+ char s1[10] = "1";
+ char s2[] = "1234567890";
+ strcat(s1, s2); // defect: len(s1 + s2) > 10
+ // strncat(s1, s2, 6) // strncat is better
+ return 0;
+}
+
+
包含规则
func_ret_null 函数返回值可能为nullpointer,但是调用该函数时指针未经判空便进行使用
在选用func_ret_null_full 时, 检查器会在项目内全局搜索空指针函数的调用情况,否则只会在相关文件内进行检查。
以下提供一个或多个func_ret_null代码案例
在下面代码中test
函数中调用get_name
可能返回空指针,在后续使用name
指针前应该判断是否为空指针
// name.hpp
+
+char* get_name(int id) {
+ char* name = 0;
+ if (id == 1) {
+ name = "Zeus";
+ } else if (id == 2) {
+ name = "Hades"
+ } else {
+ return nullpointer;
+ }
+ return name;
+}
+
+void test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect: name may nullpointer should check it
+ if (name != nullpointer) {
+ dosomething(name); // good
+ }
+}
+
+
在选用full_ret_null_full时,将会全局分析函数get_name
调用情况
// third.cpp
+# include "name.h"
+
+void name_test(int i) {
+ char* name = get_name(i);
+ dosomething(name); // defect
+}
+
use_after_free 检查当指针已经被释放但在后续仍然使用该指针的情况。
以下提供一个或多个use_after_free代码案例
通常情况下已经释放的指针只允许置空或重新指向新的值,不允许存在读取或作为函数参数使用。
+void UAR() {
+ int* p = new int[];
+ p = get_array();
+ dosomething(p);
+ delete p;
+ p = NULL; // allow
+ p = get_array(); // allow: get array again
+ delete p;
+ dosomething(p); // defect: use as param
+ std::cout << "p[0] = " << p[0] << std::endl; // defect: read p
+}
+
forward_null 检查可能导致程序终止或运行时异常的错误。它查找指针或引用被检查是否为 null 或被赋值为 null,且之后被解引用的很多情况。
以下提供一个或多个forward_null代码案例
指针曾经有过检查null的操作则会视为有可能为空指针,之后在未被确认为非空指针情况下直接使用。将会视为forward_null
错误
void forward_null_1() {
+ int * p;
+ p = get_int_pointer();
+ dosomething(p);
+ if (p == NULL) {
+ std::cout << "Null Pointer Find" << srd::endl;
+ // return; // prefer: if return here
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // defect forward_null: p may NULL
+}
+
+
+void forward_null_2(int *p) {
+ dosomething(p);
+ if (p == NULL) {
+ return;
+ } else {
+ dosomething(p); // good: p is not NULL
+ }
+ dosomething(p); // good
+ ...
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
以下案例在设置trust_param
为False
时将会生效,其将会默认认为函数参数存在空指针可能,必须确认无空指针可能时方可使用
void forward_null_2(int *p) {
+ dosomething(p); // defect: param p may NULL
+ if (p != NULL) { // means p may nullpointer here
+ dosomething(p);
+ }
+ dosomething(p); // defect forward_null:p may NULL
+}
+
reverse_null 检查已经使用过指针,但在后续又对指针进行了判空操作;会被认为之前使用指针也有可能是空指针。
以下将提供一个或多个reverse_null案例
void reverse_null(int *p) {
+ dosomething(p); // use p
+ if (p != NULL) { // defect reverse_null: It means p may NULL
+ dosomething(p);
+ }
+ ...
+
glob_null_pointer 检查文件内全局指针是否为空,指针赋值将会被认为不为空指针,但检测到空指针判断则视为指针此时可能为空,如果在可能为空时使用则会报错
以下将提供一个或多个glob_null_pointer案例
int *p;
+
+
+void thread1() {
+ p = get_int_pointer(); // p is not NULL
+ dosomething(p); // good
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL, because check p before
+}
+
+
+void thread2() {
+ *p = 6; // defect: p may NULL
+ if (p != NULL) {
+ something(p); // good
+ }
+ something(p); // defect: p may NULL
+}
+
包含规则
仅类虚拟函数允许重写。
function_override 检查非虚拟函数重写的情况。
以下提供一个或多个function_override代码案例
+
+class father{
+ public:
+ father(){};
+ ~father(){};
+
+ private:
+ virtual void test(){};
+ void test2(){ std::cout<<"hello";};
+};
+
+class man{};
+
+
+class son: public father, public man{
+ public:
+ son(){};
+ ~son(){};
+ private:
+ void test(){ std::cout<<"hello";}; // allow: virtual function override
+ void test2(){ std::cout<<"hello";}; // defect: bad override
+};
+
dead_code 检查永远不会执行到的代码,主要为在同一作用域内 return, break 后的代码
以下提供一个或多个dead_code代码案例
// C/Cpp
+void dead_code(int t) {
+ int sum = 0;
+ for (int i = 1; i <= 100; i++) {
+ if (i == t) {
+ break;
+ sum = t; // Defect: dead_code
+ }
+ sum += i;
+ }
+}
+
dead_branch 检查永远不会被执行到的分支代码,其原因可能是具有相同效果的控制语句或某些条件在特定情况下永远不会执行。
以下提供一个或多个dead_branch代码案例
+void dead_branch(int i) {
+ if (i < 100) {
+ if ( i > 100) { // Defect: dead_branch, i 属于 (-inf, 100) 不存在 (100, inf)的可能
+ dosomething() ;
+ }
+ return;
+ } else if (i >= 100) {
+ if ( i < 99 ) { // Defect: dead_branch, i 属于[100, inf) 不存在 (-inf, 99)的可能
+ dosomething();
+ }
+ return;
+ } else if (i < 10){ // Defect: dead_branch, 在前面分支中已经包含了所有i的可能,这里已经不存在 (-inf, 10)的可能
+ dosomething();
+ }
+ else { // Defect: dead_branch, 在前面分支中已经包含了所有i的可能
+ dosomething();
+ }
+ return;
+}
+
+
包含规则
uinit 检查变量在定义后直接使用,却没有初始化的场景;使用未初始化的变量 可能导致无法预测的行为、崩溃和安全漏洞。
以下提供一个或多个 uinit 代码案例
+void test(char* t) {
+ std::cout<< t << std::endl; // Defect: p 作为函数参数,此处未初始化。
+ return;
+}
+
+
+int uinit(int i) {
+ int a;
+ char * p;
+ test(p); // deep_level = true
+ if (i < 10)
+ a = 1;
+ else
+ i = 1;
+ return a; // Defect: i大于10时,a并未赋值
+}
+
TCA独立工具TCA-Armory-R,别名RegexScanner,正则匹配工具,支持扫描文件名称和文本内容,支持页面直接自定义创建规则。
以下是接入步骤:
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到TCA-Armory-R工具,并将其权限状态调整为支持自定义规则。
规则权限详见自定义规则权限说明
进入工具管理入口,进入TCA-Armory-R工具页面,选择上方的“自定义规则”,然后点击“添加规则”:
进入“创建规则”页面,按照需求填写相关信息,完成后,点击页面最后的“确定”按钮提交。
规则扫描场景:扫描代码中的 github token,如果token以明文形式写在源码文件中,会造成隐私泄露,可能造成严重的安全事故。
正则表达式:匹配 github token 字符串,根据github token的一般形式,可以推断出正则表达式 ((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})。
提示
只支持go正则语法: regexp
建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则名称、前端展示名称:建议使用单词首字母大写的格式,如 DetectedGithubToken
规则简述:作为扫描出来到问题标题
规则参数:
提示
规则参数中的(3)(4)(5)属于新功能,需要将客户端client和工具库TCA-Armory更新到最新版本
(1) 参数格式类似ini的格式, 也就是key = value的格式
(2) [必选] regex
参数,用于指定扫描的正则表达式,例如: regex=((ghp|gho|ghu|ghs)_[0-9a-zA-Z]{36})
。只支持go正则语法: regexp。建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
(3) [可选] regex{N}
参数,只有在已有regex
参数情况下生效,用于扩展扫描的正则表达式,其中 N 从1开始计数,例如: regex1=EAAAACZAVC6ygB[0-9A-Za-z]+
, regex2=EAAAAZAw4[0-9A-Za-z]+
。regex{N}
和regex
的表达式均为或关系,每一个匹配结果上报一个问题。
(4) [可选] regex_not
参数,用于指定正则过滤表达式,例如: regex_not=(?i)example
。可以对(2)(3)中regex匹配的字符串进行筛选,如果匹配则过滤该结果,不予上报。
(5) [可选] regex_not{N}
参数,只有在已有regex_not
参数情况下生效,用于扩展正则过滤表达式,其中 N 从1开始计数,例如: regex_not1=(?i)test
, regex_not2=(?i)fake
。regex_not{N}
和regex_not
的表达式均为或关系。
(6) [必选] msg
参数,用于展现issue说明, 例如: msg=检测到高危函数%s,建议替换。
msg中的“%s”使用regex中的group(用“()"括起来的部分)一一匹配,单个%s默认为整个regex匹配的字符串
如果regex没有定义group,则msg最多有一个%s, 并由整个regex匹配的字符串替代
如果msg里没有包含“%s”,则直接显示msg
如果msg没有提供,则会给出默认信息
(7) [可选] ignore_comment
参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如: ignore_comment=True
, 默认是False
(8) [可选] file_scan
参数,用于指定是否扫描文件名称,可选值:True、true、False、false 。例如: file_scan=True
, 默认是False
(9) [可选] include
参数,用于指定只扫描的文件匹配范围,基于相对路径,使用通配符格式,多项使用英文分号(;)隔开。例如: include=src/test;src/main.*;*.cpp
(10) [可选] exclude
参数,用于指定不扫描的文件匹配范围,格式同include参数,例如: exclude=tests;*.json
路径过滤(
exclude
,include
)采用Glob-Style的匹配模式,详见 Go-filepath-Match, 除了**
用来匹配零或多个目录,本工具会默认匹配前后目录。举例:
exclude=*.py
会忽略以下文件: main.py, src/main.py, main.py/install.shexclude=tests
会忽略以下文件: tests/test.py, a/tests/b/test.pyinclude=main.*
会只扫描以下文件: src/main.py, app/main.goinclude=src
且exclude=src/lib
会只扫描以下文件: src/main.py, src/project/proj.py; 忽略以下文件: src/lib/lib.py, src/lib/package/pack.js
(11)[可选] match_group
参数,用于指定正则匹配的分组,数值不能大于正则匹配分组数,例如: regex=(aws_account_id)\s{0,50}(:|=>|=)\s{0,50}([0-9]{12})
match_group=3
,匹配到第3个分组([0-9]{12})
(12)[可选] entropy
参数,用于指定正则匹配结果的最小信息熵,例如:entropy=3
,熵不大于3的匹配结果将被过滤
信息熵:熵(信息论) 可用于敏感信息(密钥、token)的检测 含义:可以理解为字符串的混乱程度,字符越随机,熵越大。因此,设置合适的熵,可以过滤掉一些误报或者人为测试用例。
进入 代码分析 - 分析方案 - 代码检查 - 自定义规则包 - 查看详细规则,添加规则。
代码分析支持 Eslint 分析,并支持用户自由扩展配置。
目前 TCA-Eslint 的适用场景很广,灵活扩展:
以下是接入步骤:
在进行高级配置之前,这里先普及下代码分析这边的基础概念——Eslint 类型。 由于 JavaScript 语法、 Vue 语法和 TypeScript 语法之间的区别,三者使用的语法解析器也是不一样的,这里基于其使用的语法解析器的不同,从 Eslint 中拆分出来了 Eslint_vue 和 Eslint_typescript 工具。可以根据需要选择对应工具下的规则进行分析。而配置也会基于类型的不同匹配到对应的工具中。 目前代码分析上 Eslint 类型有:
因为项目会用到各式各样的框架,其中会有全局变量是 Eslint 无法识别到的,比如 _
或者 jtest,从而导致分析出不少误报。这里支持使用下面环境变量设置这些全局变量,减少误报。可以在代码分析项目中设置对应的环境变量。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_GLOBALS | 字符串,以分号分割 |
ESLINT_VUE_GLOBALS | 字符串,以分号分割 |
ESLINT_TYPESCRIPT_GLOBALS | 字符串,以分号分割 |
比如:
ESLINT_JAVASCRIPT_GLOBALS=_:readonly;jtest:readonly
+
其中,
代码分析执行 Eslint 分析,默认会使用 Alloy Team 的 Eslint 配置来分析,但是也支持修改配置。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_VUE_OPTIONS | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_OPTIONS | 字符串,相对代码库根目录路径 |
代码分析也支持用户指定自己维护的 Eslint 配置文件进行分析。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_VUE_CONFIG | 字符串,相对代码库根目录路径 |
ESLINT_TYPESCRIPT_CONFIG | 字符串,相对代码库根目录路径 |
代码分析自带支持 Google 代码规范,可以在代码分析项目设置对应环境变量,使用对应的配置文件。
环境变量名称 | 描述 |
---|---|
ESLINT_JAVASCRIPT_CONFIG_TYPE | 字符串, google,default,custom |
ESLINT_VUE_CONFIG_TYPE | 字符串, 可选:default,custom |
ESLINT_TYPESCRIPT_CONFIG_TYPE | 字符串, 可选:default,custom |
其中:
这里介绍 TCA-Eslint 的配置使用顺序:
可以在代码分析页面上设置分析路径设置,这里建议多使用 Exclude 设置,因为 Eslint 工具本身对 include 支持不友好。
Q:JavaScript 内存溢出
A:Eslint 执行可能会出现 Js 内存溢出,以下有三种方案可以解决:
NODE_OPTIONS="--max-old-space-size=4096"
+
ESLINT_MAX_OLD_SPACE_SIZE=4096
+
Q:一个配置同时分析 JS 和 TS
A:若代码库中既有 JavaScript 代码,又有 TypeScript 代码,并且共用一个配置文件。 若规则集中既有 Eslint 规则又有 Eslint_typescript 规则,为了避免执行两次 Eslint 以及可能出现重复单的情况,并且因为 Eslint_typescript 的语法解析器也能够解析 JavaScript 代码,所以这里将这样的项目当作 TypeScript 项目。
Q:找不到依赖
A:用户自己配置的配置文件中,可能会用到代码分析没有管理到的规则插件,导致分析时候找不到对应的依赖,这里有两个方案提供解决:
Q:custom 与指定配置文件的区别
A:- custom 模式,会检测代码库中的 Eslint 配置文件进行分析,包括子目录和代码注释中设置的配置,都是可以生效的。
Golangci-lint 是为了解决 GoMetalinter 的弊端而改版升级的。
比 GoMetaliner 快个 2 到 7 倍
共享代码缓存,消耗内存比 Gometaliner 少 26%
更精准的 issue,会内置一些 exclude 列表过滤掉误报 issue
支持增量分析
在 CI 系统上选用 TCA 插件,或者下载 TCA 客户端到本地机器上
因为 GolangCiLint 要求找寻到项目需要的全部依赖,否则就会执行失败。所以这里需要在 Ci 系统或者本地机器上配置好项目的依赖,并确保能够编译通过
检查是否设置了 GOPATH 和 GOROOT,在分析方案的环境变量中设置 GOPATH=$GOPATH
在 代码分析 页面上关联待分析的代码库并创建分析方案,并在代码检查-规则设置的自定义规则包里面添加 GolangCiLint 工具规则
在分析方案中增加编译命令
然后在 CI 系统上或者本地启动代码分析即可
若项目目录结构如下图,需要设置 include 执行 myproj,比如 src/myproj/*
这是因为 GolangCiLint 分析前会优先检查所有代码文件的依赖是否齐全,所以需要设置 include,让工具只关注 include 下面的代码文件的依赖。
在分析方案的过滤配置,路径过滤中添加 include 路径。
Q:出现 no go files to analyze 问题
A:这里可能为以下原因:
机器环境没有项目的完整依赖,使用以下命令查找对应依赖在 GOPATH 下是否存在或者 GOPATH 设置是否完整(有的项目有多个 GOPATH 内容),或者对应依赖是否存在,需要用户部署好机器环境
grep -nr "path/to/GOPATH" .
+
没有指定 include 分析路径过滤,这样才不会检查依赖中的依赖,而是关注源码文件的依赖完整性
也可能是某 go 文件中使用到该依赖,但是 GOPATH 没有设置正确的依赖搜索路径导致。需要找到依赖相对的当前目录:
grep -nr "path/to/GOPATH" .
+
然后设置到 GOPATH 中,比如
GOPATH=$GOPATH:$SOURCE_DIR/test
+
还有可能是部分依赖是需要编译之后生成的,需要正确填写好编译命令,使得项目编译成功。
Q:could not determine GOARCH and Go compiler 问题
A:跟问题 1 是一样的问题。解决方案也是一样。
Q:failed to run 'go env': exit status 1 问题
A:原因是找不到正确的 GOPATH。解决方案是设置 GOPATH 环境变量。
Q:GO 版本限制
A:因为 golangci-lint 用到了 go mod 特性,该特性是在 1.11 之后才有的。所以要求 go 版本在 1.11 版本以上。
规则配置是代码检查应用的规则集合,用于指定用哪些工具和规则进行代码分析扫描。目前,TCA 提供了覆盖代码规范、安全扫描、风格检查等方面的官方推荐规则包。
官方推荐规则包是TCA长期以来在业务中实践的经验结果,将相关的有效性高的工具和规则打包在一起。业务可以根据需要选择官方推荐规则包。也可以在自定义规则包中添加希望的工具和规则。
提示
规则配置 = 自定义规则包 + 官方规则包
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置
可以单选或者批量多选规则
也可以根据搜索框进行多维度查询
该规则包针对 Objective-C/C++ 语言进行代码规范相关检查。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
为了帮助你正确地格式化代码,我们建议你使用clang-format进行代码自动格式化。工具可直接通过 Homebrew 进行安装:
brew install clang-format
+
安装完成后将 .clang-format 配置文件置于工程根目录,执行 clang-format -i FILE.m 即可完成自动格式化。目前格式化工具配置仅支持11.0版本。
该规则包可分析项目依赖组件,以及依赖组件中是否存在漏洞等问题。辅助开发者准确分析到依赖组件的安全性,选用安全可靠的依赖组件。
规则包中将漏洞规则分为“低危漏洞”、“中危漏洞”、“高危漏洞”三个等级,扫描出有漏洞的组件,TCA会提供问题组件名称和版本、漏洞情况介绍,以及可用的修复版本(如获取到)。
已支持语言:C/C++、C#、Go、Java、JavaScript、PHP、Python、Ruby、Scala、TypeScript等。
<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.javaweb.vuln</groupId>
+ <artifactId>javaweb-vuln</artifactId>
+ <version>3.0.3</version>
+ </parent>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <!-- 触发规则 -->
+ <version>2.1.8</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+</project>
+
TCA 现已支持依赖漏洞扫描规则包,可以在 TCA 分析方案中搜索勾选该规则包,快速体验。
分析方案 -> 代码检查 ->【Objective-C】代码规范规则包 -> 启用/查看规则。
更多场景支持,欢迎提 issue 进行咨询扩展。
前端项目在长期发展过程中,由于框架开源许可证变更、框架性能外观等不适用等因素,需要对前端框架进行平滑切换,而这就需要腾讯云代码分析 TCA 的介入,方便对企业内所有前端项目进行批量分析统计,方便管理。
{
+ "name": "framework",
+ "version": "1.0.0",
+ "dependencies": {
+ "react": "^17.0.2", // 触发规则
+ "react-dom": "^17.0.2", // 触发规则
+ "react-hotkeys-hook": "^3.4.3", // 触发规则
+ "react-redux": "^7.2.5", // 触发规则
+ "single-spa": "^5.9.3",
+ "universal-cookie": "^4.0.4"
+ },
+}
+
TCA 现已支持前端框架检查规则包,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 前端框架检查规则包 -> 启用/查看规则
更多框架支持,欢迎提 issue 进行咨询扩展。
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。也是提升现网质量的最广泛最简单有效的方式。
但是在实际开发工作中,由于工作繁忙而遗漏或缺乏对单元测试的正确认识,有些开发盲目追求高覆盖率,没有对单元测试做断言,这样的单元测试用例属于无效用例。 为了检测此类无效用例,业务侧找来了代码分析介入,进行单元测试有效性验证。
// Bad case
+func Test_Demo1(t *testing.T) {
+}
+
+
+// Good case
+func Test_Demo2(t *testing.T) {
+ assert.NoError(t, err)
+}
+
TCA 现已支持 Go 语言的单元测试有效行验证,可以在 TCA 分析方案中搜索勾选以下规则包,快速体验。
分析方案 -> 代码检查 -> 单元测试有效性验证 -> 启用/查看规则
更多语言更多单元测试框架支持,欢迎提 issue 进行咨询扩展。
可以发现执行路径较多的方法,降低代码的圈复杂度,可测性更高
检测阈值
默认为 20,表示当一个方法的圈复杂度超过 20 时则认为该方法为超标方法,需要被关注修改。
可以根据需要调整
可以发现重复的代码,避免重复代码可以让代码更简洁,更易维护
长度区间
是一个区间值,默认代码中一个单词(变量/操作符)长度为 1。
重复次数
是一个区间值,当一段代码重复次数达到指定区间才认为是有风险的。
上报限制
限制上报的重复代码块数,可以减少开发的压力,提高修复积极性。
从目录和业务纬度统计代码行数,也可以获取提交记录便于代码 Review
腾讯云代码分析平台支持给编译类的工具或编译型项目配置相关命令。
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描,申购完成后可联系平台管理员进行相关配置。
提示
对于编译型语言,有些分析工具是可以通过分析编译产出的中间文件,更为准确地发现代码质量问题。
注意
由于对代码进行编译型分析会存在安全风险,需要用户自行进行专机扫描(私有化版由客户自行评估即可)。
如果配置了编译命令,则需要在具有代码执行所需的编译环境的节点上执行代码分析。即需要用户在专机上提供编译环境(针对私有化版,客户可根据业务情况选择在公共节点机、用户专机、本地节点机提供编译环境即可)。
如以下一些编译环境:
JDK 环境及版本
gradle 环境
cmake & make 环境
visual studio 环境
...
注意
如果机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本,可以在分析方案的基础属性当中设定相应环境变量。
前置命令:
通常是项目编译前需要执行的命令,或用于清理之前编译过程的命令,如:make clean
, xcodebuild clean [-optionName]
。如无需要,可以不填。
编译命令:
项目的编译命令,具体可以咨询该代码库所属项目的开发
能够使项目编译成功的编译命令,可以填写多行或用 && 连接命令。
提示
前置命令与编译命令是隔离的,即在前置命令中的操作不会对编译命令产生影响。
如在前置命令中 cd src && export TEST=src
,在执行编译命令时并不会跳到src
目录和获取TEST
环境变量。
提示
咨询该代码库所属项目的开发,先确保先在本地工程根目录调试通过
编译命令:
android-studio 项目编译命令示例
gradle compileDebugSources --no-daemon -Dorg.gradle.jvmargs=
+
ant 项目编译命令示例
ant build
+
编译命令:
xcodebuild 命令(确保先在本地工程根目录调试通过)
xcodebuild -target dailybuildipa -configuration DailyBuild -sdk iphonesimulator
+
环境变量(分析方案-基础属性中配置):
XCODE_VERISON=10.1
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=DebugCopy
+
make 项目编译命令示例
make all
+
编译命令:
VS 项目编译命令示例
devenv.com demo.sln /Build "Debug|Win32"
+# 或
+msbuild demo.sln /t:Build /p:Configuration=Debug
+
在上一节文档代码检查配置中我们大致已经了解规则配置主要由官方规则包和自定义规则包构成,本节将详细描述规则配置。
官方规则包是由腾讯云代码分析平台经过多年深耕,在业务中不断实践整理而出的规则集合包,然而平台有超过**10000+**的规则,有些规则并未放到官方规则包中,甚至有些规则是由用户自定义的规则。此外,有些官方规则包中的规则,对于不同的团队所需可能存在差异,因此产生了如下几种问题:
在规则配置中,如何添加规则?
在规则配置中,如果将官方规则包中的规则进行调整?
添加规则存在两种入口:
提示
无论何种,最终都是将规则添加到自定义规则包中
用户可直接点击页面中的添加规则
用户可点击自定义规则,进入自定义规则包后,再点击添加规则
在添加规则过程中,可以单选或者批量多选规则,可以根据搜索栏进行多维度查询规则
用户可以点击进入官方规则包,进入官方规则包中,对已存在的规则进行编辑。
注意
在官方规则包中对规则的任意操作,实质上是将对应规则增加到自定义规则包中进行了相关操作。
自定义规则包中的规则配置会默认覆盖其他官方包中相同规则的配置。
腾讯云代码分析采用业界/自研的 80+ 款工具,配置代码检查项能够有效地发现代码中存在的异味代码
规则配置主要是以规则包为元素,由官方规则包和自定义规则包两部分组成。平台提供一些系列的官方规则包,覆盖规范、安全、推荐等方面。
用户可根据项目语言、规则包类型筛选不同的规则包,并启用/关闭规则包。
提示
用户可以根据需要选择官方规则包进行扫描,并可以在官方规则包的基础上屏蔽某些规则或者调整默认的优先级,设置指定参数。这些操作都会记录在自定义规则包中。
自定义规则包是提供给用户自由选择工具规则的包。官方规则包上的调整实质上会记录到自定义规则包中,当自定义规则包中的规则和官方规则包的规则发生冲突,则自定义规则包优先级更高。
通过编译(代码解析和翻译过程)分析中间代码进行辅助分析,能更精准地发现更多潜在的代码问题。
为便于用户快速创建代码库进行分析,复用同类型的分析配置,平台提供了分析方案模板功能。
分析方案模板分为系统方案模板和个人自定义方案模板。
系统方案模板
全局可用。但是用户无法变更系统方案模板内容。如系统方案模板产生变更,需用户自行拉取最新模板内容。
个人自定义方案模板
自定义方案模板与团队挂钩,用户可自行创建、更新、同步方案模板,以及可进行权限控制。默认自定义方案模板团队内都可见。
分析方案模版用于在创建分析方案时作为模版参考。分析方案模版全局可用,不用和某个代码库关联。
创建分析项目时,可选择使用分析方案模板创建。默认会根据该分析方案模板创建出一个新的分析方案,并用该方案配置进行分析项目创建。
创建分析方案时,可选择使用分析方案模板创建。
用模版生成的分析方案和模版建立关联关系,当模版和生成的方案由差异时,可以由用户选择是否同步模版的内容到方案。并可以选择拉群哪些功能模块的配置。
方案名称
用于标示一个方案,每个方案名称都是唯一的。
分析语言
用于指明该方案是针对代码库何种语言进行分析。初次创建分析方案时会根据语言初始化分析方案相关配置。
运行环境
用于将任务分配到指定的环境节点机器上执行代码分析,需考虑项目在对应环境的节点机器上能否正常执行。
环境变量
每行 key-value 形式,非必填项。
可用于指定特殊编译环境:如机器有多个 JDK 或者 gradle 环境,项目编译需指定 JDK 或 gradle 版本的可以设定相应环境变量。
可用于工具传递参数: 如ESLINT_MAX_OLD_SPACE_SIZE=4096
配置 Js 内存大小
可用于指定项目配置,如PYTHON_VERSION=2
指定为 python2 项目
提示
对 Python 的分析默认采用 Python3,如果需要分析 Python2 请在环境变量中设置:PYTHON_VERSION=2
用于设定代码分析的范围,设定后,已经开启的代码检查、代码度量各项功能都会在指定的代码范围内生效。
目前支持正则表达式和通配符两种类型:
正则表达式
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用正则表达式格式,示例如下:
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/.*
+ 匹配根目录下的test目录:test/.*
+ 匹配所有_test.py后缀的文件:.*_test\\.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/.*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/.*
+
通配符
请填写相对路径(基于代码库根目录),要求匹配到文件
+使用Unix通配符格式,示例如下
+ 代码根目录
+ |-src
+ |- test
+ |- main_test.py
+ |- input_test.py
+ |- main.py
+ |-test
+ |- param_test.py
+ 匹配src/test目录:src/test/*
+ 匹配根目录下的test目录:test/*
+ 匹配所有_test.py后缀的文件:*_test.py
+修改后,下次分析生效,需要启动一次全量分析处理历史存量问题。
+
Include 表示只分析,如只分析 src/ 目录:src/*
+Exclude 表示只屏蔽,如要屏蔽 src/lib/ 目录:src/lib/*
+
如果几个分析方案希望共享相同的路径过滤方案,可以通过导入导出路径配置的方式进行处理。
提示
配置更改后,下次启动分析生效
全局 Issue 忽略状态同步
仅对代码检查生效。开启后,在 Issue 页面进行全局忽略操作时,其他利用该方案分析的分析项目在发现相同 Issue 时,会同步忽略该 Issue。否则不受全局 Issue 忽略状态同步影响。
可创建、编辑、清除主流代码托管平台的Oauth应用配置,为使用者提供OAuth授权支持。
支持平台及如何创建OAuth应用:
提示
配置OAuth应用时,回调地址栏需填入当前TCA平台配置的域名或IP地址(如当前页面非80端口,需要显式指定端口号),作为Git平台上OAuth应用的回调地址。
可查看平台全部分析记录。
可点击查阅分析记录详情。
可查看平台创建的团队列表,并提供了相应筛选
可禁用、恢复团队
可查看全部工具(包含平台提供工具、团队自定义工具)。
可查看、编辑工具。
可变更工具权限状态。
提示
工具的权限状态仅能由平台管理员进行变更调整,需谨慎调整
团队内可用:即工具配置了可用团队白名单的团队可以使用该工具,默认创建工具的团队已在白名单内
全平台可用:即不同团队都可见可用该工具
支持自定义规则,全平台可用:即该工具不同团队都可见可用,且支持用户添加团队所需的自定义规则,该自定义规则存在团队隔离,仅团队内可以,其他团队不可使用
可查看、编辑、创建平台用户。
可配置用户的登录密码、用户级别、超级管理员等。
可查看常驻节点状态,包含公共节点和团队节点。
可查看、编辑、删除常驻节点。
可配置节点工具进程。
可配置节点标签
可查看平台创建的项目列表,并提供了提供相应筛选
可禁用、恢复项目
团队成员分为团队管理员和团队普通成员两类。
团队管理员:可以邀请其他成员加入团队,具备团队内所有权限。
团队普通成员:可以创建项目,可以访问自己有权限的项目。创建项目的人会自动成为这个项目的项目管理员。
项目成员分为项目管理员和项目普通成员。
项目管理员:具备项目内全部权限。
项目普通成员:可以查看项目内的配置信息和分析结果等各项信息,并且可以启动分析,但是无其他操作权限。
注意
团队节点及标签说明
团队节点是团队注册并管理的私有节点。
团队标签用于关联团队内的节点机器与分析项目。
团队可以利用团队标签注册并使用团队节点。
在项目的分析方案中配置运行环境为团队标签后,才可将该项目的分析任务下发到对应的团队节点。
团队节点仅支持运行当前团队中的分析任务,节点可执行的任务范围取决于该节点的负责人权限:
团队因资源可靠性或项目敏感性,需使用私有机器资源
团队项目分析依赖特定机器环境(比如CPU架构、操作系统等)
以上场景,团队可接入专机资源作为团队节点,仅分析自己业务的代码库,以保证执行效率,保护源码安全,支持项目环境依赖等。
参考客户端常驻节点分析进行环境配置和启动节点。
完成团队节点注册后,可以在当前团队节点管理
下看到对应的节点信息,同时需要进行节点配置
注意
首次注册团队节点,节点状态默认为不可用,需调整节点状态为“活跃”:
配置节点关联的工具进程:
提示
CodeDog
标签为不同的系统类型(Linux、MacOS、Windows)建立标签,比如专属标签-Linux
、专属标签-Mac
等您可以创建一个团队标签,并配置到您的团队节点和您的分析方案中
创建团队标签。
配置团队节点所属标签。
配置分析方案运行环境。
注意
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。注意
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。提示
TCA 客户端除了通过localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。
和本地分析一样,需要先安装环境和必要的工具,并配置好服务端地址。
希望通过并行执行分析来提高分析效率
希望尽量使用公共资源或使用专机资源
节点机器上具备客户端及客户端相关依赖环境,可查阅本地分析-前置步骤部分进行配置。
config.ini
文件将<Server IP地址>
替换成实际的 TCA 平台 IP(可包含端口号)。
国内使用 github 拉取网络较慢,推荐使用腾讯工蜂拉取,需要修改以下配置:
TOOL_CONFIG_URL=https://git.code.tencent.com/TCA/tca-tools/puppy-tools-config.git
TOOL_LOAD_ACCOUNT
中。(注:没有腾讯工蜂账号的需要注册;由于腾讯工蜂的开源仓库也要求使用账号才能拉取,所以此处必须填写账号密码)从TCA前端页面中获取 token
,前往 个人中心-个人令牌-复制Token
如启动团队节点,还需获取团队编号:org_sid,获取方式: 从 TCA 平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
两种方式可选启动客户端:
client
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
+
python3 codepuppy.py -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
client
目录下,执行命令:./codepuppy -l codepuppy.log start -t <token>
+
./codepuppy -l codepuppy.log start -t <token> --org-sid <org_sid>
+
启动后,可以在命令行输出或codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。
常驻节点首次启动后,需要到节点管理页面管理节点状态:
设置节点状态: 进入 TCA 节点管理页面。管理入口
-节点管理
,可以看到当前在线的节点,节点状态默认为不可用
,需将其设置为**活跃
**才可用于接收和执行任务。 也可以按需修改节点名称、标签、负责人等信息。
(按需可选)配置节点工具进程: 进入工具进程配置页面,对节点支持的工具进程进行管理(默认会全部勾选),未勾选的工具进程,将不会在该节点上执行。
(按需可选)设置节点标签: 节点标签会与分析方案中的运行环境标签进行匹配,只有相同标签的任务才会下发到该机器节点上。
对本地代码目录下的临时代码(未关联scm仓库或未提交到scm仓库的本地代码)进行扫描,对某个目录或某些文件进行快速扫描,产出本地扫描结果。
该模式不与scm代码仓库关联,只对给定的目录或文件进行扫描,不依据提交版本号做增量分析,也不定位问题责任人。
提示
客户端快扫模式已内置open_source_check
(开源)、safety
(基础安全)、sensitive
(敏感信息)三种常用分析方案,快速启动内置方案:
client
目录下,运行codepuppy.py或codepuppy二进制,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -l LABEL_NAME
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickinit -l LABEL_NAME
+
LABEL_NAME
: 必选,内置分析方案标签名,从open_source_check
、safety
、sensitive
三者中选一。client
目录下,执行命令:python3 codepuppy.py quickscan -l LABEL_NAME -s SOURCE_DIR --file FILE
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickscan -l LABEL_NAME -s SOURCE_DIR --file FILE
+
参数说明:
LABEL_NAME
: 必选,内置分析方案标签名,从open_source_check
、safety
、sensitive
三者中选一。SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
如需自行创建分析方案,参考以下步骤:
由于该模式不与scm代码仓库绑定,因此不能直接使用分析方案(分析方案上归属于某个代码仓库下的),需要使用分析方案模板的配置来扫描。
目前快速扫描模式只支持代码检查,暂不支持代码度量,请勿开启代码度量配置项(无法展示结果)。
配置好方案模板后,从页面URL中获取到分析方案模板ID,分析方案模板页面URL格式:http://{域名}/t/{org_sid}/p/{team_name}/template/{分析方案模板ID}
,template
后面的数字即分析方案模板ID。
client
目录下,使用quickinit
命令拉取指定分析方案模板所需要的分析工具:python3 codepuppy.py quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickinit -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID
+
TOKEN
: 必选,从TCA平台页面获取,前往[个人中心]
-[个人令牌]
-复制TokenSCHEME_TEMPLATE_ID
: 必选,分析方案模板ID,从步骤1中获取ORG_SID
: 必选,团队编号,从TCA平台团队概览中获取“团队唯一标识”client
目录下,执行命令:python3 codepuppy.py quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
+# 如使用codepuppy二进制,可执行:./codepuppy quickscan -t TOKEN --scheme-template-id SCHEME_TEMPLATE_ID --org-sid ORG_SID -s SOURCE_DIR --file FILE
+
参数说明:
SOURCE_DIR
: 必选,需要扫描的代码目录路径FILE
: 可选,指定文件扫描,格式为基于SOURCE_DIR的相对路径,多个文件用英文逗号(,)分隔。不指定文件,默认扫描整个代码目录。quickinit
命令。扫描完成后,结果会默认输出到客户端client
目录下的tca_quick_scan_report.json
文件中。结果只保存在本地,不会上报到服务端展示。
希望在本地随时分析。
接入持续集成系统实现自动化分析。
1. 客户端运行环境机器配置推荐
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
2. 本地需具备客户端
下载开源版源码。 或从开源版release下载客户端以运行客户端二进制;
3. 安装Python环境和第三方库(仅客户端源码启动分析需要)
python3
和 pip3
命令pip3 install -r CodeAnalysis/client/requirements/app_reqs.pip
4. 安装第三方工具(docker下启动分析可跳过)
git bash
)中执行以下命令:bash ./scripts/base/install_bin.sh
+
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)config.ini
文件<Server IP地址>
替换成实际的TCA平台IP(可包含端口号)codedog.ini
文件codedog.ini
获取方法:
方法一: 打开TCA源码CodeAnalysis/client/codedog.ini
,填写配置信息
方法二: 从开源版release下载客户端包,解压后打开codedog.ini,填写配置信息。
方法三: 在TCA平台平台上配置好对应信息后,下载配置文件到本地使用。
codedog.ini
中以下字段为必填项:
字段名 | 填写说明 |
---|---|
token | 从TCA平台页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从TCA平台项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他字段按需填写。
启动客户端分析有三种方式可选:客户端源码下启动分析、客户端二进制启动分析、docker下启动分析
进入到客户端client
目录下
执行命令: 客户端源码:python3 codepuppy.py localscan
进入到客户端client
目录下
执行命令: 客户端源码:./codepuppy localscan
在client目录下,执行以下命令:docker build -t tca-client .
(需已安装Docker)
注意
注意:因为以下步骤会将代码目录挂载到容器中,需要先将codedog.ini里面的source_dir修改为/workspace/src,其他参数保持不变。
执行Docker容器有以下两种方式:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
通过以下方式,进入容器内的bash终端后,通过命令行启动client代码:
在client
目录下,执行以下命令:(注意:按照实际情况填写SOURCE_DIR
环境变量值)
export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
操作系统 | 推荐配置 |
---|---|
Linux | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Mac | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
Windows | 8核16G内存,硬盘空间256G(可用空间不低于100G) |
以上为推荐配置,实际情况需要考虑扫描对象代码库的大小,按实际情况增加磁盘空间。
-(1)将<Server IP地址>
替换成实际的serve ip(可包含端口号)。
填写以下必填项:token
,org_sid
,team_name
,source_dir
字段名 | 填写说明 |
---|---|
token | 从tca页面获取,前往[个人中心]-[个人令牌]-复制Token |
org_sid (团队编号) | 从tca项目概览页面URL中获取,项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile |
team_name (项目名称) | 同上 |
source_dir | 本地代码目录路径 |
其他可选项按需填写。
提示
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
参考Docker官方文档:Docker下载和安装
在client
目录下,执行以下命令:docker build -t tca-client .
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
SOURCE_DIR
环境变量值)export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+# 进入容器内终端,通过命令行执行扫描
+python3 codepuppy.py localscan
+
提示
适用于深度体验,可以复用本地编译环境,使用编译型代码分析工具。
可能会有系统环境兼容问题。
python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)client
目录下python3 codepuppy.py localscan
提示
localscan
命令启动单次的代码分析,也可以作为一个分布式分析节点启动,作为常驻进程,多个节点可以分布式并行执行服务端下发的任务,提高扫描效率。python3
和 pip3
命令pip3 install -r client/requirements/app_reqs.pip
client/requirements
目录install.sh
(linux/mac环境)或install.bat
(windows环境)个人中心
-个人令牌
-复制Tokenclient
目录下,执行命令:python3 codepuppy.py -l codepuppy.log start -t <token>
codepuppy.log
中查看运行日志,如果未报异常,且输出task loop is started.
,表示节点已经正常启动。管理入口
-节点管理
,可以看到当前在线的节点,可以修改节点名称、标签、负责人等信息。注意
如果由于网络原因,执行时无法从github自动拉取工具,或拉取比较慢,可以参考基础配置腾讯工蜂工具地址,或使用以下方式预先下载好工具,配置使用本地工具目录。
https://github.com/TCATools/puppy-tools-config.git
,存放到 tools
目录下(如果未生成,可先创建该目录)。puppy-tools-config
目录下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件,将[tool_url]
中声明的所有工具下载到 tools
目录下。client/config.ini
中的配置:USE_LOCAL_TOOL
=True
,即可使用下载好的本地工具,不自动拉取和更新工具。注意
如果自己搭建了一套git server,可以将工具配置库 https://github.com/TCATools/puppy-tools-config.git
以及里面声明的工具仓库,存放到自建git serevr上。
https://github.com/TCATools/puppy-tools-config.git
上传到自建git仓库。puppy-tools-config
仓库下的linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[tool_url]
声明的所有工具库,上传到自建git仓库。linux_tools.ini
或mac_tools.ini
或windows_tools.ini
文件中[base_value]
中的git_url
为自建git server地址。client/config.ini
中的TOOL_CONFIG_URL
为自建git server的puppy-tools-config
仓库地址。client/config.ini
中的[TOOL_LOAD_ACCOUNT]
配置,输入有拉取权限的用户名密码,即可使用自建git server拉取工具。Download ZIP
的方式下载工具压缩包,再解压到tools
目录下。目前 TCA 支持以下工具:
官方工具 | 第三方工具 |
---|---|
TCA-0Day_Checker(测试版) | androidlint |
clangwarning | checkstyle |
codecount | clang |
customfilescan | cobra |
customscan | cpd |
fbrjs | cppcheck |
javawarning | cpplint |
regexfilescan | dart_code_metrics |
regexscan | dartanalyzer |
TCA-Armory(测试版) | detekt |
TCA-Loong_Beta龙(测试版) | eslint |
unusedresource | eslint_typescript |
eslint_vue | |
findbugs | |
flake8 | |
flawfinder | |
flow | |
golangcilint | |
gometalinter | |
htmlcs | |
infer_cpp | |
infer_java | |
infer_objectivec | |
ktlint | |
kunlun-M | |
lizard | |
luacheck | |
phpcs | |
pmd | |
pylint | |
rips | |
scalastyle | |
semgrep | |
shellcheck | |
spotbugs | |
stylecop | |
stylelint | |
swiftlint | |
sonarqube | |
sonarqube_java | |
sonarqube_cs | |
tca_plugin_sqlcheck | |
tscan_cpp | |
tscan_csharp | |
tscan_lua | |
include-what-you-use |
腾讯云代码分析平台目前已集成众多自研、知名开源工具,并采用分层分离的架构,可以快速对接企业内部团队研发的工具,并将其集成到平台内供企业内部团队使用,满足快速自助的管理工具。
按工具来源划分,工具包含平台提供的工具,以及团队接入的工具。
平台提供工具:由腾讯云代码分析平台提供的一系列自研、知名开源工具,此类工具都为公开工具,任何团队都可以使用此工具及工具规则进行代码分析。
团队接入:由团队自行接入的工具,默认该工具仅能在团队内使用,如需跨团队使用或任何团队都可以使用需联系平台管理员进行配置。
按工具使用划分,工具包含可自定义规则工具、可使用工具两种。
可自定义规则工具:该工具任何团队都可以使用,且该工具可以支持添加团队所需的自定义规则。如RegexScan
工具,各个团队都可以使用该工具提供的规则,也可以自定义规则,此自定义规则团队隔离。
可使用工具:该工具团队内可使用,但不能添加自定义规则
提示
目前开源版仅**RegexFileScan
、RegexScan
、TCA-Armory-R**等三款工具支持用户自定义规则
需平台管理员在后台管理-工具管理中找到对应工具,并将其权限状态调整为支持自定义规则。
默认自定义工具只能当前团队内使用,添加 工具白名单
后可以让其他团队使用。
提示
添加工具、添加工具规则、添加自定义规则等均需团队内管理员可操作。分析。
【用户 A1】【用户 A2】为【团队 O1】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 B1】【用户 B2】为【团队 O2】的管理员,【用户 A3】为【团队 O2】的普通成员。
【用户 A1】在工具管理页面添加了【工具 T1】,该工具为团队内工具; -【用户 A1】【用户 A2】均可操作该工具,如修改工具信息、添加工具规则等,【用户 A3】仅可以使用该工具,如在规则配置页面添加该工具规则;
由于【工具 T1】目前仅【团队 O1】可用,【团队 O2】中无法看到此工具,即【团队 O2】内的成员无法使用该工具。
如需【工具 T1】也让【团队 O2】使用有两种解决方法:1. 【工具 T1】将【团队 O2】加入使用白名单;2. 向平台发起申请,由平台管理员将【工具 T1】调整为全部团队都可使用。
正则工具 RegexScan
,进入工具-自定义规则栏,发现没有添加规则的入口;腾讯云代码分析平台支持用户自助添加代码分析工具。
适用场景:自定义规则无法满足团队业务复杂需求,需要更多的代码逻辑来匹配目标代码的情况。通常需要团队业务方自行实现对应代码分析工具。
只需要几步操作:
扩展集成工具免责声明
被扩展集成进腾讯云代码分析系统的任何非官方工具,该类工具对于腾讯云代码分析系统等于黑盒,腾讯云代码分析系统不对该类工具负责,由该类工具方承担所有责任(包括但不限于分发被分析代码,产生代码以及相关信息泄漏)。
根据需要匹配的目标代码场景,编写对应的工具逻辑。 可以参考 Python 实现的 Demo 项目。
必要:
运行方式:支持命令行执行,比如 python run.py 或 run.exe,执行命令的工作目录为工具代码的根目录。
运行环境说明:
工具管理
-工具依赖
中查看,创建工具时可供选择,执行时会自动配置好依赖环境。平台已提供的环境变量
SOURCE_DIR:要扫描的代码目录路径
+DIFF_FILES: 值为一个json文件路径,文件内容为增量扫描的文件列表(增量扫描时可用)
+SCAN_FILES: 值为一个json文件路径,文件内容为需要扫描的文件列表(增量或全量扫描均可用)
+TASK_REQUEST: 值为一个json文件路径,文件内容为当前扫描任务参数
+RESULT_DIR: 结果result.json输出的结果目录路径
+
工具命令声明
在工具仓库根目录下,添加一个tool.json
文件,声明工具的检查和扫描命令,比如:
{
+ "check_cmd": "python src/main.py check",
+ "run_cmd": "python src/main.py scan"
+}
+
参数说明:
check_cmd
: check_result.json
文件中,文件内容为{"usable": true}
或{"usable": false}
。run_cmd
: result.json
文件中。工具输出格式要求
RESULT_DIR
环境变量指定的目录下的result.json
文件中(Python 示例代码)import os
+import json
+result_dir = os.getenv("RESULT_DIR", os.getcwd())
+result_path = os.path.join(result_dir, "result.json")
+with open(result_path, "w") as fp:
+ json.dump(result, fp, indent=2)
+
result.json
文件格式如下:[
+ {
+ "path": "文件绝对路径",
+ "line": "行号,int类型",
+ "column": "列号, int类型,如果工具没有输出列号信息,可以用0代替",
+ "msg": "提示信息",
+ "rule": "规则名称,可以根据需要输出不同的规则名",
+ "refs": [
+ {
+ "line": "回溯行号",
+ "msg": "提示信息",
+ "tag": "用一个词简要标记该行信息,比如uninit_member,member_decl等,如果没有也可以都写成一样的",
+ "path": "回溯行所在文件绝对路径"
+ },
+ ...
+ ]
+ },
+ ...
+]
+
refs
字段说明:
非必需项,可无。该字段记录问题回溯路径信息。比如当前行的代码问题,是经过上下文的三行代码执行路径而导致的,可以将这三行的位置及提示信息,按顺序添加到 refs 数组中。
创建代码库,将工具源代码或编译打包后的可执行文件,提交到代码仓库中(建议提交到master分支,TCA默认拉取的是master分支)。
建议代码库中加入 README.md 文件,说明工具功能和维护人。
后续需要修改工具实现逻辑,可以直接更新代码库,TCA 平台在执行该工具时,会自动拉取最新工具代码版本。
进入工具管理页面,点击创建工具
填写工具信息
部分参数说明:
工具仓库地址,即前述步骤中提交的工具 git 代码库地址,默认拉取的是master分支,如果是其他分支,需要在仓库地址后加上#分支名
,比如:https://github.com/xxx/xxx.git#main
工具认证,授权拉取工具仓库的权限
执行命令,该命令会在工具根目录下执行
环境变量,工具执行所需的环境变量
License,如果是开源工具,填写工具遵循的开源协议,或者填写自研共建
是否为编译型工具,表示在使用该工具对用户代码进行分析时,是否要求代码需要编译或可执行编译
注意:针对特殊扫描场景的工具(比如检查代码库下是否包含某些第三方依赖目录,结果不涉及单个代码文件的),无法对结果进行代码文件处理,可以通过设置以下环境变量,跳过一些通用的结果处理步骤,避免问题结果被过滤掉:
BLAME_TYPE=NO_BLAME
,跳过对代码行/代码文件进行文件责任人定位(结果非单个文件/代码行时使用)FILTER_TYPE=NO_VERSION_FILTER
,跳过检查问题路径(path字段)是否为已提交到代码库中的文件(结果非单个文件/代码行时使用)IGNORE_TYPE=NO_ISSUE_IGNORE
,跳过注释忽略处理(结果非单个文件/代码行时使用)添加工具依赖
添加完成后,会展示已添加的依赖方案:
工具依赖说明:
完成工具创建后,进入规则列表,为工具添加规则
填写规则信息
部分参数说明:
规则简介:简要描述规则发现的是什么问题,扫描结果中会作为问题标题展示
详细描述:可详细描述规则,以及规则的解决方式,建议附上解决案例 demo
解决方法:按照实际情况,说明该代码问题的解决方法,建议附上解决案例 demo
规则参数:如果不需要通过规则参数传递信息,可留空
提示
需要联系平台管理员协助操作,在管理入口
-节点管理
中进入需要配置的机器节点的工具进程配置
中,找到对应工具,勾选工具进程。
完成节点配置工具进程后,才能在项目中采用该工具进行分析。
进入到项目中,在分析方案
-代码检查
进行规则配置。
点击添加规则,找到对应工具规则进行添加。
添加完成后,启动分析,为了将规则应用到所有代码文件,建议启动一次全量分析(增量分析只会分析自上次扫描后变更的文件)。
默认自定义工具仅团队管理员可操作,团队内所有成员可使用。
团队管理员才能创建工具,添加工具规则等,具备该工具全部权限
团队内所有成员可使用该工具规则,如在规则配置中添加此工具规则,团队普通成员仅只读权限
工具希望全平台使用?
由于全平台使用的工具影响范围较大,建议团队先在团队内对工具进行充分测试,保障团队内工具的高有效性,如需全平台使用,需联系平台管理员进行申请
平台管理员需对此工具进行审核,在确保工具的高有效性下可将此工具权限调整为全平台可使用
自定义规则即由业务团队根据自身需求,由业务团队自行设计提供的规则。
工具需开放支持自定义规则权限,才可添加自定义规则。
当前平台提供的工具中,仅TCA-Armory-R、RegexFileScan
、RegexScan
三款工具支持使用用户自定义规则。
开放支持自定义规则权限,需平台管理员在管理入口-工具管理中找到对应工具,并将其权限状态调整为支持自定义规则。
自定义规则仅支持团队管理员添加,且默认仅团队内可见。
如需将自定义规则加入工具默认规则,需联系工具提供方团队管理员添加。
正则工具 RegexScan
即为开放了自定义规则功能的工具,可进入工具管理页面,搜索工具名称RegexScan
,查看该工具已存在的规则以及根据团队业务需求,添加自定义规则。
适用场景:通过正则表达式,能够匹配到目标代码的情况。
根据团队业务需求设计正则表达式
提示
建议先测试好正则表达式是否正确,正则表达式测试网站推荐:http://tool.oschina.net/regex
规则示例:
规则分析场景
分析代码中的 usleep() 方法调用,如果参数小于 100 ,容易造成 CPU 使用率过高,造成性能浪费,判断为缺陷。
正则表达式
匹配 usleep() 字符串,括号中的内容为 1 位或 2 位整数,那么正则表达式可以写成 \busleep\s*\(\s*\d{1,2}\s*\)
,这里考虑了字符串中存在空格的情况。
进入正则工具添加自定义规则
进入工具管理页面,找到正则工具RegexScan
,并点击进入自定义规则列表页,点击添加规则按钮。
填写规则信息
规则参数填写说明(必要):
参数格式类似 ini 的格式, 也就是 key = value 的格式
【必要】 regex 参数,用于指定分析的正则表达式, 例如: regex = \busleep\s*\(\s*\d{1,2}\s*\)
。
【必要】 msg 参数,用于展现 issue 说明, 例如: msg = 函数方法%s 已经废弃,请使用 xxx 方法
。
msg 中的“%s”使用 regex 中的 group(用“()"括起来的部分)一一匹配。
如果 regex 没有定义 group,则 msg 最多有一个%s, 并由整个 regex 匹配的字符串替代
如果 msg 里没有包含“%s”,则直接显示 msg
如果 msg 没有提供,则默认为“发现不规范代码:%s”(不建议使用默认格式,太笼统)
【可选填】 ignore_comment 参数,用于指定是否忽略注释代码,可选值:True、true、False、false 。例如 ignore_comment=True
, 默认是 False
【可选填】 include 参数,用于将指定分析文件匹配范围,使用 unix 的文件匹配格式,多项使用英文分号;隔开。例如 include = path/to/dir;path/to/\*.cpp
【可选填】 exclude 参数,用于指定不分析的文件。格式参考 include 参数。
将自定义规则添加到项目分析方案中
添加完成,可在分析方案-代码检查-规则配置中添加该自定义规则
创建团队
点击了解团队管理
为团队创建一个项目,或选择一个已有项目,并进入项目内
完成代码库登记,并点击进入代码分析
提示
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
在线分析即是通过Server端将分析任务注册到执行队列中,并将任务分配到平台配置的常驻分析节点上进行,分析完毕后将分析结果上报入库。
提示
使用在线分析要求平台具有常驻分析节点:
如您的TCA平台是使用官方一键部署脚本完成的环境部署(Docker部署、Docker-Compose部署、源码部署三种),默认已启动一个分析节点(即客户端),可直接用于在线分析。可查看管理入口-节点管理确认该节点状态。
您也可自行接入更多分析节点实现并行执行代码分析,接入节点操作请查阅常驻节点分析
如无分析节点,在线分析任务将无法完成分配,未分配任务将于超时后自动注销。
客户端分析即是本地分析,需要在本地有客户端,并配置好客户端配置文件 codedog.ini
,详细操作参考:启动客户端分析。分析完毕后会将数据上报入库。
分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
分析结束后,进入分支概览可以查看该分支指定分析方案的概览数据以及 问题列表等。
提示
以下说明以 Jenkins 2.361.2 版本为例。
Jenkins插件有以下两种获取方式:
方式一:在 TCA 源码的plugin/jenkins_plugin
目录下,执行命令mvn package -DskipTests
,打包完成后进入target目录会看到tca_jenkins_plugin.hpi
的安装包。
方式二:从TCA release 安装包中,获取jenkins_plugin.hpi
:https://github.com/Tencent/CodeAnalysis/releases。
在Jenkins中通过【Manage Plugin】-> 【Advanced】->【Deploy plugin】的方式选择 Jenkins_plugin.hpi文件上传安装,并重启Jenkins。
最终在【Installed】里搜索出【TCA】代表插件安装成功。
在CodeAnalysis目录下执行代码
bash ./scripts/base/install_bin.sh
+
将client
目录下的config.ini
文件中的<Server IP地址>
替换为部署的开源版TCA的IP地址(可包含端口号)
如已创建后待使用的团队和项目,可跳过此步。
进入已部署好的TCA页面,点击【创建团队】,成功后【创建项目】。
进入Jenkins设置界面,在【Manage Jenkins】->【Configure System】->【Global properties】中添加环境变量:
Name:PYTHONPATH
Value:xxxx(路径不包含python3)
Value:GITPATH
Value:xxxx(路径不包含git)
创建一个构建任务,配置代码库信息,进入Jenkins,通过【New Item】创建一个空白任务,在任务配置中【Source Code Management】配置待分析的代码库地址和凭证。Repository URL
: 填入远端仓库地址Credentials
: 添加仓库的用户名和密码作为凭证,如果是公开仓库,可以不设置仓库凭证
在构建任务的【Build】中选择【TCA】插件并配置以下参数:
CodeAnalysis目录绝对路径
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)团队ID
: 在 TCA 中创建的团队的标识ID,可在TCA【团队概览】中获取“团队唯一标识”项目名称
: 在 TCA 中创建的项目的标识ID,可在TCA【项目概览】中获取“项目唯一标识”Token
: 在 TCA 的【个人中心】->【个人令牌】中获取分支名称
: 需要扫描的代码分支名称语言类别
: 项目需要扫描的语言分析方案模板ID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)分析方案名称
: 指定创建出来的分析方案的名称(选填)全量扫描
: 不勾选默认启动增量扫描质量门禁
: 设置质量门禁值,配置和使用参考 设置质量门禁
配置完成后点击【Save】保存。
在步骤中添加TCA插件参数配置语句,下面的配置语句可作为参考;注意:如果是release版本v1.11.0及之前的老版本(包含源代码构建生成和release获取)插件,语法参数略有差别,请参考issue1150
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ }
+ }
+ }
+}
+
+
codeAnalysisPath
: 拉取到本地的CodeAnalysis开源仓库目录的绝对路径(例如:/data/CodeAnalysis/)teamId
:团队IDprojectName
: 项目名称token
: 在 TCA 的【个人中心】->【个人令牌】中获取branchName
: 需要扫描的代码分支名称languageType
: 项目需要扫描的语言refSchemeID
: 需要使用的分析方案模板ID,在分析方案模板的“基础属性”中获取,将根据此模板创建分析方案(选填)scanPlan
: 指定创建出来的分析方案的名称(选填)threshold
: 设置质量门禁值total
: 是否全量扫描,填ture
为全量扫描,不填或填false
为增量扫描
点击【Build Now】启动构建。
进入构建任务,在【Console Output】中查看执行过程。
执行完成后,可在下方看到代码分析的结果链接,也可在【代码分析报告】中获取代码分析的json报告。
在上述 TCA 插件配置部分填写质量门禁
参数,需要填写一个整数,即当前分支的扫描问题量大于该质量门禁值时,判断为不通过;否则为通过。完成后会将TCA结果状态(success
|failure
)输出到工作空间下的tca_threshold.txt
文件中,供后续步骤判断和终止流水线。
在TCA插件后增加shell命令步骤,输入以下脚本内容:
tca_status=`cat tca_threshold.txt`
+if [ "${tca_status}" == "success" ]; then
+ echo ">> tca scan pass!"
+else
+ echo ">> tca scan fail! exit code 255"
+ exit 255
+fi
+
当质量门禁不通过时,会终止流水线(退出码:255)。
以下是pipeline脚本使用质量门禁进行相应操作的示例,你可以在if和else部分写入你想要运行的脚本
pipeline{
+ agent any
+
+ stages{
+ stage('Build'){
+ steps{
+ TCA(codeAnalysisPath: '/data/CodeAnalysis/', teamId: 'xxxx', projectName: 'demo', token: 'xxxxxxxxxxxx', branchName: 'master', languageType: 'Java', refSchemeID: '1', scanPlan: 'model', threshold: '90', total:true)
+ script{
+ def tca_status = readFile('tca_threshold.txt')
+ if (tca_status == "success") {
+ echo ">> tca scan pass!"
+ } else {
+ echo ">> tca scan fail! exit code 255"
+ error("TCA scan failed. Terminating pipeline.")
+ }
+ }
+ }
+ }
+ }
+}
+
pip install requests
+
method | 类型 |
---|---|
create_repository | 创建代码库 |
update_scheme_settings | 设置指定代码库的指定方案的代码度量配置 |
create_project | 创建分析项目 |
create_scans | 启动任务 |
get_scan_cons | 轮询任务结果 |
get_overview | 获取分析概览 |
get_issues | 查看扫描问题列表 |
get_issue_detail | 查看问题详情 |
get_ccissues | 查看指定项目的圈复杂度问题列表 |
get_dupfiles | 查看指定项目的重复文件列表 |
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_repository |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
scm_url | str | 代码库地址 |
scm_type | str | 填git或svn |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_repository --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --scm_url=${TCA_SCM_URL} --scm_type=${TCA_SCM_TYPE}
+
PUT /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/schemes/<scheme_id>/metricconf/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,update_scheme_settings |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
scheme_id | str | 扫描方案id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=update_scheme_settings --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --scheme_id=${TCA_SCHEME_ID}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_repository |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
scan_scheme_id | int | 和global_scheme_id二选一进行填写,当前代码库的扫描方案编号 |
global_scheme_id | int | 和scan_scheme_id二选一进行填写,扫描方案模板编号 |
branch | str | 分支 |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_project --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --scan_scheme_id=${TCA_SCAN_SCHEME_ID} --branch=${TCA_BRANCH}
+
POST /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/scans/create/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,create_scans |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=create_scans --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}
+
GET /server/main/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/jobs/<job_id>/detail/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_scan_cons |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
sleeptime | int | 轮询间隔的时间 |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_scan_cons --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID} --job_id=${TCA_JOB_ID}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/overview/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_overview |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_overview --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_issues |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_issues --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codelint/issues/<issue_id>/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_issue_detail |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
issue_id | str | 问题id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_issue_detail --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID} --issue_id=${TCA_ISSUE_ID}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/ccissues/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_ccissues |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_ccissues --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}
+
GET /server/analysis/api/orgs/<org_sid>/teams/<team_name>/repos/<repo_id>/projects/<project_id>/codemetric/dupfiles/
+
字段 | 类型 | 描述 |
---|---|---|
method | str | 调用的方法名,get_dupfiles |
base_url | str | 基础路径 |
org_sid | str | 项目组名称 |
team_name | str | 团队唯一标识 |
repo_id | str | 代码库id |
project_id | str | 分析项目id |
Key | 类型 | Value |
---|---|---|
Authorization | str | "Token 当前user的token" |
python ScriptsAPI.py --base_url=${TCA_BASE_URL} --method=get_dupfiles --org_sid=${TCA_ORG_SID} --team_name=${TCA_TEAM_NAME} --repo_id=${TCA_REPO_ID} --project_id=${TCA_PROJECT_ID}
+
TCA的file
服务支持对接MinIO
作为底层存储,将文件转发到已部署的MinIO平台上进行持久化存储
注意:如果之前已经使用本地进行存储,切换为MinIO后,之前已经上传的文件只能到服务部署的目录
server/projects/file/data
查看,不支持通过页面进行下载
获取MinIO平台登录的账号密码,用于上传文件
file
服务的配置修改server/configs/django/local_file.py
文件,取消以下代码的注释
# MINIO
+STORAGE = {
+ "CLIENT": os.environ.get("FILE_STORAGE_CLIENT", "MINIO"), # 存储方式
+ "OPTIONS": {
+ "MINIO_ENTRYPOINT": os.environ.get("FILE_MINIO_ENTRYPOINT"),
+ "MINIO_ACCESS_KEY": os.environ.get("FILE_MINIO_ACCESS_KEY"),
+ "MINIO_SECRET_KEY": os.environ.get("FILE_MINIO_SECRET_KEY"),
+ }
+}
+
修改server/scripts/config.sh
文件,填写MinIO的信息
export FILE_MINIO_ENTRYPOINT=<MinIO平台的地址>
+export FILE_MINIO_ACCESS_KEY=<MinIO平台的登录账号>
+export FILE_MINIO_SECRET_KEY=<MinIO平台的登录密码>
+
修改完配置后,如果服务已经正在运行,则执行以下命令重启服务
$ cd server
+$ ./scripts/deploy.sh start
+
删除nginx已有的文件服务器配置文件/etc/nginx/conf.d/tca_file_local.conf
文件,然后执行
rm /etc/nginx/conf.d/tca_file_local.conf
+ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf
+
也可以修改
server/scripts/init_config.sh
# 注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_local.conf /etc/nginx/conf.d/tca_file_local.conf +# 取消注释这一行 +ln -s $CURRENT_PATH/configs/nginx/tca_file_minio.conf /etc/nginx/conf.d/tca_file_local.conf +
修改完配置后,如果nginx已经正在运行,则执行nginx -s reload
以上两个步骤操作完成后,就可以通过MinIO
存储文件了~
在实际的生产环境的部署过程中,团队的MySQL的管理员可能不会给到应用账号create等比较敏感的权限,这种情况下,我们可以通过手动迁移数据的方式起到和等同Django migrate的效果。
操作步骤:
/data/CodeAnalysis/server/
,以下路径均为工作目录内的相对路径)vi ./scripts/config.sh
:填写一个有全部权限的MySQL数据库地址和Redis信息以及根据需要调整配置信息,主要的工程配置已提供默认值,字段说明可以查看文档bash ./scripts/deploy.sh init
:初始化DB、安装依赖和运行初始化脚本mysqldump -u user -p –databases codedog_main codedog_analysis codedog_file codedog_login > codedog_all.sql
server/sql/init.sql
SET SESSION FOREIGN_KEY_CHECKS=0
,否则会因为数据中有外键关联导致导入失败source /youdir/codedog_all.sql;
SET SESSION FOREIGN_KEY_CHECKS=1
bash ./scripts/deploy.sh start
,无需执行 init
方法,否则会导致数据重复写入以下三种部署方式选择其中一项即可。
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息。
#Oauth认证相关配置
+GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker deploy
+
在/scripts/config.sh 中添加以下配置
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行重新启动操作
bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+
填写重定向url,“http://<部署gitlab的ip地址>/cb_git_auth/gitlab”
scopes尽量都勾选,以开启对私有化代码库的访问权限
保存application 这里的Application ID、Secret 和 Callback URL 之后需要填写到代码分析服务中。
以下三种部署方式选择其中一项即可。
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息。
#Oauth认证相关配置
+GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行更新部署操作
bash ./quick_install.sh docker deploy
+
在/scripts/config.sh 中添加以下配置
#Oauth认证相关配置
+export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
在项目根目录下执行重新启动操作
bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+
将application中的Application ID、Secret 和 Callback URL分别填入
An error has occurred
Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
如图,GITLAB_OAUTH_URL没有配置,默认使用 https://gitlab.com/oauth/authorize 。
需要根据项目部署方式,修改配置信息。
(1)docker-compose 部署方式
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息
GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
(2)docker 部署方式
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
(3)源代码部署方式
在/scripts/config.sh 中添加以下配置
export GITLAB_OAUTH_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/oauth/authorize/"
+
此站点的连接不安全,发送了无效的响应。
ERR_SSL_PROTOCOL_ERROR
配置的url存在问题,可能使用了https协议,访问本地ip不能用https协议,修改成http。
(1)检查配置url是否加端口号,默认80端口可能已经被占用,或已经分配给代码分析平台。
(2)检查回调地址是否填写端口号
oauth failed, err: 未知错误: <class 'Exception'>:{method: git_oauth, error_message: [400] 授权异常,请稍后再试,异常原因:{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}}
client.py 中存在默认的GITLAB_URL,如果在配置文件中没有设置GITLAB_URL,那么TCA将默认访问https://gitlab.com
GITLAB_URL = os.environ.get("GITLAB_URL") or "https://gitlab.com"
+
客户端调用的API都需要使用到GITLAB_URL作为前缀的路径,会发送post请求到 https://gitlab.com 路径下,因此需要对路径进行修改。
要连接私有化的gitlab,需要根据项目部署方式,修改配置信息。
(1)docker-compose 部署方式
找到server/dockerconfs/ 目录下的 .env.local 文件,添加配置信息
GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
(2)docker 部署方式
在/.docker_temp/configs/config.sh 中添加以下配置 (首次部署无该文件夹)
export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
(3)源代码部署方式
在/scripts/config.sh 中添加以下配置
export GITLAB_URL="http://<部署gitlab的ip地址>:<gitlab 端口号>/"
+
TCA Server由Main、Analysis、Login、File、ScmProxy五个微服务组成,主要技术栈为Django+uwsgi+nginx
注意:以下配置内容可以参考 config.sh文件进行查阅,使用时主要关注 MySQL、Redis 的配置,其他配置均已提供默认值,可以根据需要进行调整
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Main服务DB配置:
Main服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Analysis服务DB配置:
Analysis服务Redis配置:
服务交互配置:
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取Login服务DB配置:
服务交互配置:
注:配置文件中的pub_key与private_key生成方式可以参考以下方法:
$ ssh-keygen -t rsa -b 1024 -m PEM -f tca_login.key
+$ openssl rsa -in tca_login.key -pubout -outform PEM -out tca_login.key.pub
+$ cat tca_login.key # 作为private_key的内容
+$ cat tca_login.key.pub # 作为pub_key的内容
+
框架配置:
true/false
from django.core.management.utils import get_random_secret_key;get_random_secret_key()
方法获取File服务DB配置:
服务交互配置:
File存储引擎配置
LOCAL
/MINIO
/COS
LOCAL
,可以指定FILE_STORAGE_DIR
文件存放的路径MINIO
,可以指定以下变量: COS
,可以指定以下变量 服务配置:
0.0.0.0
8009
127.0.0.1:8009
提示
该Q&A文档会持续更新,非常欢迎您的建议与共建!
如果您遇到任何未在此处列出的部署或使用问题,请在 GitHub issue 系统中进行搜索。如果仍未找到该错误消息,您可以通过社区提出问题,获得帮助。
如果在执行pip install
环节出现以下错误,可以调整一下镜像源:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='files.pythonhosted. org', port=443): Read timed out.(read timeout=15)") '
+
该错误是访问官方pypi
下载源时网络不通或者不稳定导致,可以通过以下方式调整:
本地部署时,调整pypi
下载源配置方式:
mkdir ~/.pip/
+echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf
+
Docker-Compose部署时,调整pypi
下载源配置方式:
vi server/dockerconfs/Dockerfile-common
+
调整文件中最后一行 RUN
指令
RUN mkdir -p log/ && \
+ mkdir ~/.pip/ && \
+ echo "[global]\nindex-url = https://mirrors.cloud.tencent.com/pypi/simple" >> ~/.pip/pip.conf && \
+ pip install -U setuptools pip && \
+ pip install -r requirements.txt
+
注:如果需要指定其他pypi
下载源,可以将https://mirrors.cloud.tencent.com/pypi/simple
进行替换
如果出现以下错误:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f6d4ac24910>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/setuptools/
+
该错误是无法正常解析pypi
访问域名,需要检查一下本地的dns配置是否正常
TCA Server使用Docker-Compose依赖的Docker版本需要是1.13.0
及以上,可以执行以下命令查看Docker版本
$ docker --version
+Docker version 18.09.7, build 2d0083d
+
文档相关:
如果启动Docker-Compose输出以下错误:
* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+* Error response from daemon: Error processing tar file(exit status 1): unexpected EOF
+
问题原因:可能镜像构建目录权限不足,导致异常。 解决方案:
docker-compose build
可以通过日志查看是哪个镜像构建异常docker build .
可以看到详细错误信息,结合具体错误信息进行处理文档相关:
目前TCA基础镜像是使用python:3.7.12-slim
,该镜像是基于debian bullseye(debian 11)
版本构建的,对应的源需要选择 bullseye
版本的源。
如果使用默认的下载源会报错或访问速度比较慢,可以调整server/dockerconfs/Dockerfile-common
,指定其他国内下载源:
# FROM python:3.7.12-slim
+
+# 增加一下内容用于指定下载源
+RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye main non-free contrib' > /etc/apt/sources.list && \
+ echo 'deb http://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list && \
+ echo 'deb http://mirrors.tencent.com/debian-security bullseye-security main non-free contrib' >> /etc/apt/sources.list
+
+# ARG EXTRA_TOOLS=...
+
如果出现以下错误:E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages
可以做以下检查,确认是什么原因:
使用Python执行时提示ImportError: libpython3.7m.so.1.0: cannot open shared object file: No such file or directory
,该如何处理
在本地安装Python的目录中查找该文件,比如Python的安装目录是/usr/local/python3
,可以执行find /usr/local/python3 -name "libpython3.7m.so.1.0"
,确认本地是否存在该文件
如果本地存在该文件,则执行以下命令:(注:需要将/usr/local/python3
调整为本地实际的Python3安装路径)
# 链接构建产出的Python动态库
+$ ln -s /usr/local/python3/lib/libpython3.7m.so.1.0 /usr/lib/libpython3.7m.so.1.0
+# 配置动态库
+$ ldconfig
+
如果本地不存在该文件,则可能需要重新安装Python3:(注:以下是将Python安装到/usr/local/python3
,可以根据实际情况进行调整)
# 编译前配置,注意重点:需要加上参数 --enable-shared
+$ ./configure prefix=/usr/local/python3 --enable-shared
+
文档相关:
compose_init.sh
脚本的pip install
提示sha256
不匹配错误在构建镜像的pip install
步骤提示以下报错时:
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
+ setuptools from https://mirrors.cloud.tencent.com/pypi/packages/fb/58/9efbfe68482dab9557c49d433a60fff9efd7ed8835f829eba8297c2c124a/setuptools-62.1.0-py3-none-any.whl#sha256=26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8:
+ Expected sha256 26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8
+ Got ddaacc49de5c08c09d744573240a9a49f24f65c5c72380e972433784caa68d98
+
可以执行export ORIGIN=normal
,然后再执行./compose_init.sh
注:执行
export
命令的作用是调整为pypi
默认官方下载源进行pip install
在M1机器上使用默认配置启动docker-compose,会出现mysql
和scmproxy
服务启动失败,需要做以下两步调整
调整docker-compose.yml
文件,修改MySQL的镜像版本:
# 默认:
+image: mysql:5.7.24
+
+# 调整后:
+image: mariadb:10.5.8
+
调整server/dockerconfs/Dockerfile-common
文件,修改Python的镜像版本:
# 默认:
+FROM python:3.7.12-slim
+
+# 调整后:
+FROM amd64/python:3.7.12-slim
+
如果启动服务时,提示:celery could not be found
或gunicorn could not be found
,需要做以下检查
python -v
检查输出,确认当前python版本是否为python3.7pip install celery
和pip install gunicorn
检查celery和gunicorn是否已经安装/usr/local/python3
调整为本地实际的Python3安装路径)ln -s /usr/local/python3/bin/gunicorn /usr/local/bin/gunicorn
+ln -s /usr/local/python3/bin/celery /usr/local/bin/celery
+
使用docker方式部署项目时,提示
fatal: 无法访问 'https://git.code.tencent.com/TCA/tca-tools/tca_lib.git/': URL using bad/illegal format or missing URL.
+Download lib failed
+
该如何处理。
出错原因可能是Windows系统、和macOs系统、linux系统的行分隔符不同,可以先查看当前文件的换行符是 CRLF 还是LF, 如果要部署在Windows系统系统上,行分隔符应该为CRLF格式,部署在linux和macOS系统预期是LF格式,如果不一致需要进行手动修改。
修改方式可以选择: 1、使用pycharm打开项目,依次点击”File”->”Settings”->”Editor”->”Code Style”->”General” 在面板中,可以找到”Line separator”选项,根据要部署的系统选择行分隔符格式。 2、也可以使用dos2unix、unix2dos等转换命令,例如从Windows系统打包到Linux系统,当前行分隔符为CRLF,需要对脚本执行 dos2unix fileName
指令进行转换 ,注意使用该指令前需要先进行安装。
完成以上操作之后再对代码进行打包,即可部署运行。
TCA 本地部署启动后,会监听多个端口:
如果出现端口占用冲突,建议采用以下方式解决:
不推荐调整TCA指定服务的端口号,需要调整多处配置,以及可能会影响到后续服务的升级
本地部署输出的日志位置:
main
服务输出的日志目录:server/projects/main/log
server/projects/main/log/gunicorn_error.log
server/projects/main/log/gunicorn_access.log
server/projects/main/nohup_worker.out
server/projects/main/nohup_beat.out
server/projects/main/log/codedog.log
server/projects/main/log/main_celery.log
server/projects/main/log/main_beat.log
analysis
服务输出的日志目录:server/projects/analysis/log
server/projects/analysis/log/gunicorn_error.log
server/projects/analysis/nohup.out
server/projects/analysis/log/gunicorn_access.log
server/projects/analysis/log/codedog.log
server/projects/analysis/log/celery.log
login
服务输出的日志目录:server/projects/login/log
server/projects/login/log/gunicorn_error.log
server/projects/login/log/gunicorn_access.log
server/projects/login/log/codedog.log
file
服务输出的日志目录:server/projects/file/log
server/projects/file/log/gunicorn_error.log
server/projects/file/log/gunicorn_access.log
server/projects/file/log/codedog_file.log
scmproxy
服务输出的日志目录:server/projects/scmproxy/logs
server/projects/scmproxy/nohup.out
server/projects/scmproxy/logs/scmproxy.log
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
config.ini
文件和codedog.ini
文件是否按照json格式正确填写config.ini
文件中的 【SERVER_URL】
已正确填写,则检查codedog.ini
文件中是否有填写codedog_env
配置项。如果有填写,往往因为填写有误(比如URL缺少最后的/
)导致报错。建议直接删除codedog.ini
文件的codedog_env
配置项(config.ini
已配置【SERVER_URL】
,无需重复配置),再尝试重启服务。默认账号: CodeDog
,密码: admin
默认Token是0712b895f30c5e958ec71a7c22e1b1a2ad1d5c6b
如果在平台上刷新了CodeDog
用户的Token,需要将刷新后的Token填写到以下文件中:
server/scripts/config.sh
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)server/dockerconfs/.env.local
文件 CODEDOG_TOKEN
、FILE_SERVER_TOKEN
变量的值(3个位置)然后重启服务。
本地部署:
cd server/
+./scripts/deploy.sh start
+
docker-compose部署:
$ docker-compose stop
+# 稍等片刻
+$ docker-compose up -d
+
该错误出现可能有以下几个原因:
github
使用的密码需要使用personal access token
ps aux | grep proxyserver
看看是否有python proxyserver.py
执行进程,如果不存在可以看一下server/projects/scmproxy/nohup.out
看看启动失败的原因docker-compose ps
看看scmproxy
容器是否正常启动,如果没有启动,可以执行docker-compose logs scmproxy
看看启动失败的原因git clone xxxx
(xxx表示待登记的代码库),检查看看是否能够正常拉取unknown option `local`
错误 1.8.3.1
该错误出现可能有以下几个原因:
.docker_temp/configs/config.sh
, 将HTTPS_CLONE_FLAG调整为false, 然后重启容器docker restart tca-services
出现该提示的原因是,代码库偏大或clone
代码库时间较长,可以稍等一会再刷新重试
method(upload_file) call fails on error: Expecting value: line 1 column 1 (char 0)
出现这种错误,可能是本地配置异常或token配置有问题,检查方式如下:
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
如果xxx不一致需要调整为一致
注: xxx地址与在浏览器访问平台的xxx地址是一致的,不需要区分端口
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
检查当前在codedog.ini
-[config]token
与config.ini
文件配置的[FILE_SERVER]TOKEN
是否一致,如果不一致需要调整为一致
检查用户CodeDog
的Token
是否被刷新了然后没有更新到配置文件中
Connection timed out
本地客户端执行过程提示method (upload file) call fails on error: <urlopen error [Errno 110] Connection timed out>
该如何处理? 一般情况下,这个问题是客户端与Server之间网络不通导致,可以检查一下是否有防火墙限制或者配置的URL是内部IP或地址,可以通过以下方式检查
检查客户端的config.ini
文件配置的URL是否为当前Server部署的地址:(xxx需要调整为实际的路径)
[SERVER_URL]
+URL=http://xxx/server/main/
+[FILE_SERVER]
+URL=http:/xxx/server/files/
+
检查客户端访问Server是否能通:
curl -v http://xxx/server/main/
+
如果不通,则需要检查客户端机器访问Server机器是否有网络限制
出现该错误提示,一般是访问文件器出错或文件服务器本身有问题,可以通过以下方式检查: 需要检查analysis-worker
的日志(本地部署:server/projects/analysis/log/celery.log
,docker-compose部署:docker-compose exec analysis-worker /bin/bash
进入容器后访问log/celery.log
查看具体错误原因
如果提示no route to host
可能是当前机器/容器无法访问当前宿主机的IP,可以检查一下当前防火墙的设置,是否限制了analysis-worker
来源的访问
出现该错误提示,一般是Server未进行初始化,可以通过执行以下命令初始化后再启动测试
cd server && ./scripts/deploy.sh init
./compose_init.sh
为防止国内用户访问CodeAnalysis Github首页时图片资源加载失败,目前各个md文件中的图片资源引用地址调整增加了URL前缀https://tencent.github.io/CodeAnalysis/
。
用户下载代码库到本地后,发现无法访问资源文件时,请检查本地网络是否能够连通外网,如果无法连通外网,可以在文档引入资源地址中进行相对路径替换,调整各个资源文件的链接。
对于根目录下的md文件,直接删除URL前缀即可:
例如在https://tencent.github.io/CodeAnalysis/media/homepage.png
这个链接可以调整为media/homepage.png
对于其他目录下的md文件,删除URL前缀后,需调整文件相对路径链接:
例如对于doc/client.md
, 需将https://tencent.github.io/CodeAnalysis/media/clientConfigIni.png
这个链接调整为../media/clientConfigIni.png
TCA提供部署脚本,支持一键式快速部署Server、Web、Client。
脚本共提供三种部署方式:Docker部署(平台体验首推)、Docker-Compose部署、源码部署, 可根据您的具体使用场景任意选择其一进行部署。
系统环境
环境准备
提示
TCA 一键部署脚本已封装好 Python、Mariadb、Redis 与 Nginx 安装步骤,无需自行安装,本地部署体验可按 操作说明 内容直接进行部署操作。
注意:生产环境建议使用专业的 MySQL、Redis 等服务
Python 3.7
MySQL 服务(MySQL5.7.8 以上版本或 Mariadb 10.5 以上版本)
Redis 服务(4.0版本以上)
Nginx 服务
权限准备
CREATE、ALTER、INDEX、DELETE、LOCK TABLES、SELECT、INSERT、REFERENCES、UPDATE
权限端口使用:需要开放80端口的访问权限(80为TCA平台默认访问端口),或调整 Web 服务默认的访问端口地址
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
安装基础软件与部署 TCA(可根据脚本选项确定是否要安装 Python、MySQL、Redis、Nginx 相关基础软件),执行
$ bash ./quick_install.sh local deploy
+
执行该命令会做以下四个步骤:
Install
:检测本地 Python3.7、Mariadb/MySQL、Redis 与 Nginx,如果不存在会提示安装Init
:部署 TCA Server、Web与Client,并进行初始化Start
:启动 TCA Server、Web与ClientCheck
:检测 TCA 的运行状态注意:在运行过程中,脚本会检测本地是否安装了相关基础软件(Python3.7、MySQL/Mariadb、Redis、Nignx),如果未安装会输出以下类似提示语:
Do you want to install [Redis] by this script?
+Please enter:[Y/N]
+
如果确定通过脚本安装可以输入Y
。
提示
至此,您已完成 TCA 平台部署,请在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可开启您的腾讯云代码分析。
平台内操作指引请查看:快速启动一次代码分析
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
1. 更新代码
2. 执行以下命令
bash ./quick_install.sh local install tca #更新相关配置
+bash ./quick_install.sh local start #启动服务(会自动关闭之前的服务)
+bash ./quick_install.sh local check #检查服务是否启动失败
+
注意:local install
命令行参数说明:
- base
:安装 Python、Mariadb/MySQL、Redis 与 Nginx
- tca
:初始化或更新 TCA Server、Web、Client 相关配置和数据
- server
:初始化或更新 TCA Server 相关配置和数据
- web
:初始化或更新 TCA Web 相关配置和数据
- client
:初始化或更新 TCA Client 相关配置和数据
- 不填参数,默认会执行base
、tca
相关操作
启动所有服务:bash ./quick_install.sh local start
启动Main相关服务:bash ./quick_install.sh local start main
local start
支持启动指定服务,如上述的启动Main服务,还支持mysql/redis/analysis/file/login/scmproxy/nginx/client/all
停止所有服务:bash ./quick_install.sh local stop
停止Main相关服务:bash ./quick_install.sh local stop main
local stop
支持停止指定服务,如上述的停止Main服务,还支持analysis/file/login/scmproxy/nginx/client/all
注意:
启动时会自动关闭之前已经运行的服务
mysql
和redis
默认会使用systemctl
进行启动,如果systemctl
无法使用,则会直接使用nohup
方式运行相关服务
检查服务运行状态:bash ./quick_install.sh local check
打印 TCA Server 各个服务的日志路径: bash ./quick_install.sh local log
系统环境
环境准备
# 源码根目录下执行
+pip3 install -r client/requirements/app_reqs.pip
+
# 源码根目录
+cd client/requirements
+
+# 执行安装脚本
+# Linux/macOS环境
+./install.sh
+# Windows环境
+./install.bat
+
配置 client/config.ini
文件
将 <Server IP地址>
替换成实际的serve ip(可包含端口号)。
配置 client/codedog.ini
文件
必填项:token
、org_sid
、team_name
、source_dir
个人令牌 - token
:从 TCA 页面获取,前往[个人中心]-[个人令牌]-复制Token
团队编号 - org_sid
:进入 TCA 项目概览页,从 URL 中获取
项目名称 - team_name
::进入 TCA 项目概览页,从 URL 中获取
提示
项目概览URL格式:http://{域名}/t/{org_sid}/p/{team_name}/profile
分析路径 - source_dir
: 本地代码目录路径
提示
如果项目代码为编译型语言(比如:C/C++,C#,Go,Java,Kotlin,Objective-C等),且使用的分析方案中配置了编译型工具(如图,使用了OC推荐规则包),需要填写build_cmd
编译命令。
其他可选项按需填写,不填写时按默认配置执行
# 源码根目录
+cd client
+
+# 执行客户端脚本
+python3 codepuppy.py localscan
+
注意
Client 的实现及启动脚本均依赖 Python3 版本为 3.7,可执行 python3 --version
查看版本。若版本有误,可安装版本为3.7的python并软链接到python3命令。
提示
codedog.ini
各项参数可由命令行传入,获取详细参数说明可运行 python3 codepuppy.py localscan -h
使用localscan
命令启动本地单次的代码分析,如需启动分布式并行分析任务,请参考使用分布式节点模式进行配置。
提示
适用于快速上手体验。使用docker运行,可以免去客户端环境依赖的安装,避免环境兼容性问题。
但是由于环境受限于docker,会无法复用本地的编译环境,部分需要编译的工具无法使用。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
提示
同通过源代码使用-配置客户端
docker build -t tca-client .
+
进入client
目录,执行以下命令
# 按照实际情况填写`SOURCE_DIR`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client
+
进入docker容器内的bash终端
# 按照实际情况填写`SOURCE_DIR`环境变量值
+export SOURCE_DIR=需要扫描的代码目录绝对路径
+docker run -it --rm -v $PWD:/workspace/client -v $SOURCE_DIR:/workspace/src --name tca-client tca-client bash
+
通过命令行启动client代码
python3 codepuppy.py localscan
+
系统环境
从发布页面下载与系统相对应的客户端压缩包到本地。
解压缩。
配置 client/config.ini
文件
配置 client/codedog.ini
文件
提示
同通过源代码使用-配置客户端
进入到client
目录下,执行客户端
./codepuppy localscan
+
TCA提供部署脚本,支持一键式快速部署Server、Web、Client。
脚本共提供三种部署方式:Docker部署(推荐)、Docker-Compose部署、源码部署,可根据您的具体使用场景任意选择其一进行部署。
注意
仅适用于Docker部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
提示
tencenttca/tca:latest
镜像.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy
:重新构建并启动tca容器提示
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
成功部署TCA后,请开始您的代码分析。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
提示
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
提示
分析方案是用于对代码库进行分析的一套配置集合。
更多分析方案配置可查阅帮助文档-分析方案
提示
本次部署会默认启动运行环境为「Codedog_Linux」的客户端,若需扩展更多运行环境,详见客户端常驻节点分析
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
提示
在线分析
,您可根据具体使用场景选择其一。在线分析
表示配置代码库链接后,TCA客户端拉取代码后进行分析;客户端分析
在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。在线分析
与客户端分析
具体详情及配置参考TCA客户端配置详情分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
分析结束后,进入分支概览可以查看该分支指定分析方案的概览数据以及 问题列表 等。
注意
Docker部署会包含Mariadb和Redis,如果需要更大规模使用,可以调整配置文件使用运维规范的 MySQL/Mariadb 和 Redis。
Server、Web 与 Client
~/CodeAnalysis
),以下路径均为目录内的相对路径bash ./quick_install.sh docker deploy
+
提示
tencenttca/tca:latest
镜像.docker_temp/logs
:容器内的/var/log/tca/
,存放TCA平台的日输出文件;.docker_temp/data
:容器内的/var/opt/tca/
, 存放TCA平台的服务数据,主要是Mariadb、Redis;.docker_temp/configs
:容器内的/etc/tca
,存放TCA平台的配置文件,主要是config.sh
TCA_IMAGE_BUILD=true ./quick_install.sh docker deploy #重新构建并启动tca容器
+
提示
TCA_IMAGE_BUILD=true
表示从本地构建TCA镜像运行
如果已经在机器上执行过docker deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行TCA
bash ./quick_install.sh docker start
+
如果容器正在运行,希望停止容器,可以运行
bash ./quick_install.sh docker stop
+
至此,您已完成第一个TCA平台部署,请在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可开启您的腾讯云代码分析。
平台内操作指引请查看:快速启动一次代码分析
提示
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
TCA提供部署脚本,支持一键式快速部署 Server、Web、Client。
脚本共提供三种部署方式:Docker部署(平台体验首推)、Docker-Compose部署、源码部署, 可根据您的具体使用场景任意选择其一进行部署。
Server、Web 与 Client
注意
仅适用于 Docker-Compose 部署体验,生产环境建议使用专业的 MySQL、Redis 等服务
进入 CodeAnalysis 工作目录(例如~/CodeAnalysis
),以下路径均为目录内的相对路径
执行命令:
bash ./quick_install.sh docker-compose deploy #启动tca_server容器
+
注意:通过 Docker-Compose 部署默认会在当前根目录下的挂载三个路径:
.docker_data/logs
:存放 TCA 平台的各个服务日志输出目录;.docker_data/mysql
:存放 TCA 平台的 MySQL 数据.docker_data/redis
:存放 TCA 平台的 Redis 数据.docker_data/filedata
:存放 TCA 平台文件服务器的文件提示
完成 TCA 平台部署后,请在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可开启您的腾讯云代码分析。
平台内操作指引请查看:快速启动一次代码分析
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
更新代码
执行以下命令:
bash ./quick_install.sh docker-compose build #重新构建TCA相关镜像
+bash ./quick_install.sh docker-compose stop #停止运行中的TCA容器
+bash ./quick_install.sh docker-compose deploy #重新部署TCA相关容器与初始化(或刷新数据)
+
如果已经在机器上执行过docker-compose deploy
,并保留容器数据的,可以执行以下命令启动容器,继续运行 TCA
bash ./quick_install.sh docker-compose start
+
如果容器正在运行,希望停止容器,可以执行以下命令
bash ./quick_install.sh docker-compose stop
+
如果希望构建镜像,可以执行以下命令
bash ./quick_install.sh docker-compose build
+
TCA 除开集成业界知名的分析工具之外,也有自主研发的独立工具,作为 TCA 的增强分析模块。
TCA 增强分析模块,需要用户额外部署 License 鉴权微服务,并邮件申请 License 。
提示
1. License申请完全免费! 2. 优先企业或高校申请License。
持续更新中……
如果用户平常使用的是 TCA 官网版公共服务,并想在官网版上体验到增强分析模块的分析能力,可以按照这篇帮助文档进行申请配置。
如果用户是在企业内网环境内使用 TCA,并想在内网体验 TCA 的增强分析模块能力,可以参考下面步骤申请。
注意
注意:不能随意删除CLS目录
server/cls
目录下执行以下命令,获取 Server ID
和 Client License
注意
注意:需要在 CLS 目录下执行命令
# 安装 Git LFS
+$ bash ./scripts/base/install_git_lfs.sh
+# 如果在该目录下没有找到 cls 二进制文件,可以执行以下命令进行同步
+$ bash ./scripts/base/install_bin.sh
+$ cd server/cls
+$ ./cls server
+2022-04-13 18:35:29.356510559 +0800 CST [INFO] Version: 20220328.1
+2022-04-13 18:35:29.44083463 +0800 CST [INFO] The client license is:
+xxx
+2022-04-13 18:35:29.454552966 +0800 CST [INFO] License Server ID: xxx
+
Server ID
: 机器码,用于向 TCA 团队申请 License 授权Client License
: 提供给 TCA Client,方便 TCA Client 进行工具鉴权(重要,建议备份留底)config.ini
中配置 CLS 微服务信息,比如[LICENSE_CONFIG]
+; [可选]使用独立工具时,需要填写,默认不需要
+; License服务的域名和端口
+URL=http://<IP或者域名>:<port>
+BASE_PATH=
+LICENSE=<Client License>
+
注意
注意:URL对应值的最后不需要跟斜杆/
.
注意
不同的部署方式可以根据下面方法修改config.ini
配置
client/config.ini
./quick_install.sh local start client
.docker_temp/configs/client/config.ini
,并重启tca-services
容器tca-service
容器后,修改/CodeAnalysis/client/config.ini
,并退出重启tca-services
容器docker restart tca-service
client/config.ini
,并重启client
容器docker-compose restart client
Server ID
,首次登记的机器码Client License
config.yaml
文件中填写License注意
注意:遵从 yaml 格式,比如:
:
后面跟一个空白字符,示例 key: value
。./cls server -d
+
# 查找是否存在CLS进程
+ps aux|grep cls
+
注意
注意:如果以上命令没有发现 CLS 的进程,则说明 CLS 没有正常启动。
请尝试更改 config.yaml
文件中的 port 为其他 port,比如8080,目前默认是80端口,然后重新执行步骤5的命令。
# 查找CLS进程ID
+ps aux|grep cls
+# 重启微服务
+kill -USR2 <pid>
+
如果以上部署步骤已经完成,但是增强功能还是出现 License check failed! Please check the license. License Server is not available!
异常。可以按照以下步骤进行排查:
method(head) call fails on error: <urlopen error [Errno 111] Connection refused>
+
ping <config.ini中填写的 CLS IP或者域名>
+telnet <config.ini中填写的 CLS IP或者域名> <对应端口>
+
背景: 小明以 Docker 方式部署 TCA,并在相同宿主机上部署 CLS 服务,然后在 config.ini 中设置的 URL 中的 IP 为 127.0.0.1
, 重启后启动增强功能任务遇到上述网络不通异常。
原因: 原因是此时的 127.0.0.1
指向的是 TCA Client 容器自身,而不是部署在宿主机上的 CLS 服务。
解决方案: 将 127.0.0.1
改成宿主机自身IP即可。
# 查找CLS进程ID
+ps aux|grep cls
+# 重启微服务
+kill -9 <pid>
+
注意
注意:不能删除原来的 cls 目录,只需要替换其中的 cls 二进制文件即可。
./cls server -d
+
腾讯云代码分析(Tencent Cloud Code Analysis,简称TCA,内部曾用研发代号 CodeDog )是集众多分析工具的云原生、分布式、高性能的代码综合分析跟踪平台,包含服务端、Web端、客户端三个组件,已集成一批自研工具,同时也支持动态集成业界各编程语言的分析工具。
代码分析是通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,对代码进行综合分析,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
使用TCA可以帮助团队用代码分析技术查找代码中的规范性、结构性、安全漏洞等问题,持续监控项目代码质量并进行告警。同时TCA开放API,支持与上下游系统对接,从而集成代码分析能力,为代码质量提供保障,更有益于传承优良的团队代码文化。
拉取 TCA 代码库 后,首次体验推荐您使用 Docker 快速部署方式快速搭建和体验腾讯云代码分析平台。
如您更多环境需求,也可通过以下两种方式部署腾讯云代码分析平台:
成功部署并启动 Server 与 Web 服务后,通过以下步骤创建您的第一个代码分析项目。
在浏览器输入http://部署机器IP/
,点击立即体验,完成登录后即可跳转到团队列表页
提示
默认平台登录账号/密码:CodeDog/admin
如部署过程中,已调整默认账号密码,请按照调整后的账号密码进行登录
完成团队创建
完成项目创建
登记代码库,输入代码库地址以及凭证信息等,完成代码库登记。
提示
分析方案是用于对代码库进行分析的一套配置集合。
更多分析方案配置可查阅帮助文档-分析方案
腾讯云代码分析(Tencent Cloud Code Analysis,简称TCA,内部曾用研发代号 CodeDog )是集众多分析工具的云原生、分布式、高性能的代码综合分析跟踪平台,包含服务端、Web端和客户端三个组件,已集成一批自研工具,同时也支持动态集成业界各编程语言的分析工具。
使用TCA Action,只需要在代码仓库中添加.github/workflows/tca.yml
文件,就可以直接在GitHub工作流中快速体验代码分析。请参考:TCA-action指引
拉取 代码库 后,您可以通过以下三种方式部署腾讯云代码分析平台:
成功部署并启动TCA后,您可以按照 指引 创建您的首个代码分析项目。
提示
默认平台登录账号/密码:CodeDog/admin
TCA客户端支持通过可执行文件进行快速扩展部署,详见通过可执行文件
提示
客户端可在本地执行代码分析,也可以作为在线常驻节点进行在线分析。
更多关于腾讯云代码分析平台的使用指南和配置说明,参见帮助文档。
在完成 Server、Web 和 Client 相关部署和配置后,可通过平台执行代码分析。
初始化创建项目后,可通过 在线分析
或 客户端分析
来启动代码分析。
注:
在线分析
,您可根据具体使用场景选择其一。在线分析
表示配置代码库链接后,TCA客户端拉取代码后进行分析;客户端分析
在配置本地待扫描代码路径后,无需代码拉取直接分析本地代码。在线分析
与客户端分析
具体详情及配置参考TCA客户端配置详情分析结束后,数据会上报到服务端。可进入分析历史页面查看分析记录以及分析结果。
分析结束后,进入分支概览可以查看该分支指定分析方案的概览数据以及 问题列表 等。