diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13bbe5b9112f9828a4f0eae28e0eb34e5fdb58d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ + diff --git a/AcessScan/.keep b/AcessScan/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AcessScan/README.md b/AcessScan/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7216b9b2a1c7804775e13c4ff9e74e6a5fc191c --- /dev/null +++ b/AcessScan/README.md @@ -0,0 +1,157 @@ +- [AcessScan门禁扫描工具使用说明](#AcessScan门禁扫描工具使用说明.md) + +- 门禁扫描checklist: + + 1、license扫描:.py/.cpp文件中需要添加license,若未添加,结果返回失败; + + 2、垃圾文件扫描:若后缀为.so/.log/.h5/.event/.log/.pbtxt/.zip/.tar/.tar.gz/.swp/.ipynp/.pyc及文件名称中含有.ckpt,则视为垃圾文件,结果返回失败; + + 3、首层目录必要文件扫描:首层目录下必须存在LINCENSE,README.md,modelzoo_level.txt 三个文件,否则,结果返回失败;不可以存在00-access目录,否则,结果返回失 + + 败;(注:README.md可以命名为其他名称,如README.*/Readme.*/ReadMe.*/readme.*,*代表任意字符) + + 4、大文件扫描:若文件大小超过2M,则视为大文件,结果返回失败; + + 5、内部链接扫描:文件中不可存在蓝驱无法访问的地址,如http://3ms.huawei.com,否则结果返回失败;(README.md不在扫描范围内) + + 6、敏感信息扫描:如工号,文件中的目录内容包含:wx+6/7/8/9位数字或00+6/7/8位数字的组合(扫描范围:所有文件); 如IP:文件中不可存在IP,如: + + http://10.137.54.150/data,否则,结果返回失败(README.md不在扫描范围内); + + 7、网络功能、性能、精度扫描:网络首层目录下必须配置modelzoo_level.txt文件,且文件内容包含三个关键字段:FuncStatus(功能是否OK,值可填写OK/NOK); + + PerfStatus(性能是否OK或达到极致PERFECT,值可填OK/NOK/PERFECT);PrecisionStatus(精度是否OK,值可填写OK/NOK);若网络功能、性能、精度均通过,内容格式如 + + 下所示: + + +``` + FuncStatus:OK + PerfStatus:OK + PrecisionStatus:OK +``` + 注:“:”两侧无需空格,英文格式; + + 校验规则: + + a、FuncStatus:OK,PerfStatus:OK,PrecisionStatus:OK,表示网络功能、性能、精度均通过,网络代码必须放置在Official领域目录下; + + b、FuncStatus:OK,PerfStatus:PERFENCT,PrecisionStatus:OK,表示网络功能、精度均通过、性能达到极致,网络代码必须放置在Benchmark领域目录下; + + c、FuncStatus:OK,PerfStatus:NOK,PrecisionStatus:OK,表示网络功能通过、性能不通过、精度通过,网络代码必须放置在Research领域目录下; + + d、FuncStatus:OK,PerfStatus:OK,PrecisionStatus:NOK,表示网络功能通过、性能通过、精度不通过,网络代码必须放置在Research领域目录下; + + e、FuncStatus:OK,PerfStatus:NOK,PrecisionStatus:NOK,表示网络功能通过、性能不通过、精度不通过,网络代码必须放置在Research领域目录下; + + f、FuncStatus:NOK,表示网络功能不通过,网络代码不允许放置主仓内; + + +- 代码结构: + + +``` + ├── run_upline.sh //开始扫描执行脚本 + ├── access_upline.py //实现门禁扫描规则的代码脚本 + ├── link_list.txt //进行内部链接扫描时,内部链接关键字的配置脚本 +``` + + +- 重要参数: + + - run_upline.sh重要参数如下: + + --id_dir //pr_filelist.txt 及modelzoo代码存放文件存放的路径 + + - access_upline.py重要参数如下: + + --pr_filelist_dir //需要上传仓上的所有文件名称及其路径(build-in开始的路径,例如:built-in/MindSpore/Benchmark/cv/detection/Mask_R_CNN_for_MindSpore/eval.py) + + --linklisttxt //配置文件link_list.txt所在路径 + + --FileSizeLimit //配置大文件的大小,默认为2 + +- 操作步骤:(以AlexNet_for_TensorFlow为例) + + 1、获取代码:run_upline.sh、access_upline.py、link_list.txt脚本,下载脚本放置同一目录下,例如:/home 目录; + + +``` + ├── /home + ├──├──run_upline.sh + ├──├──access_upline.py + ├──├──link_list.txt +``` + + + 2、数据准备: + + a、将需提交pr的代码放置在id_dir(可自定义),例如:/home: + + + ├── /home + ├──├──run_upline.sh + ├──├──access_upline.py + ├──├──link_list.txt + ├──├──modelzoo/build-in/... .../AlexNet_for_TensorFlow + + + + b、pr_filelist.txt配置文件准备,pr_filelist.txt内容应该为AlexNet_for_TensorFlow目录下所有文件的路径如下所示: + + built-in/TensorFlow/Official/cv/image_classification/AlexNet_for_TensorFlow/train.py + built-in/TensorFlow/Official/cv/image_classification/AlexNet_for_TensorFlow/README.md + built-in/TensorFlow/Official/cv/image_classification/AlexNet_for_TensorFlow/scripts/train_alexnet_1p.sh + built-in/TensorFlow/Official/cv/image_classification/AlexNet_for_TensorFlow/alexnet/alexnet.py + ...依次同理 + + 注意:路径是从build-in开始,且只需配置需要上传仓的文件,确保文件真实存在对应的路径下; + + c、将pr_filelist.txt文件放置在modelzoo/目录同级,如下: + + + ├── /home + ├──├──run_upline.sh + ├──├──access_upline.py + ├──├──link_list.txt + ├──├──modelzoo/build-in/... .../AlexNet_for_TensorFlow + ├──├──pr_filelist.txt + + + 3、开始扫描 + + a、配置run_upline.sh脚本,将id_dir配置为实际路径,即/home id_dir='/home' + + b、执行如下指令: bash run_upline.sh + + 4、扫描结果分析 + + a、若check success,则表示扫描通过,如下所示: + + +``` + =================Start to Check License ================= + =================Start to Check Size of File ================= + =================Start to Check funk file ================= + =================Start to Check file of First Directory ================= + =================Start to Check Internal Link ================= + =================Start to Check Sensitive Information ================= + =================Start to Check modelzoo level ================= + check success +``` + + + b、若结果返回 check fail,则表示失败,如下所示,失败原因请查看wiki门禁校验规则。 + + +``` + =================Start to Check License ================= + =================Start to Check Size of File ================= + =================Start to Check funk file ================= + =================Start to Check file of First Directory ================= + =================Start to Check Internal Link ================= + =================Start to Check Sensitive Information ================= + =================Start to Check modelzoo level ================= + PerfStatus is not OK or PERFECT or PrecisionStatus is not OK ,You should put the code under the Research directory! + check fail +``` diff --git a/AcessScan/access_upline.py b/AcessScan/access_upline.py new file mode 100644 index 0000000000000000000000000000000000000000..23ee2b8ca919e27152b42d5b39555329e5484b85 --- /dev/null +++ b/AcessScan/access_upline.py @@ -0,0 +1,279 @@ +import re +import os +import sys +import json +import math +import glob +import argparse + +class AccessCodeCheck(object): + """ModelZoo 门禁代码检查""" + def __init__(self): + # self.modelzoo_dir = "ModelZoo-PyTorch" + self.modelzoo_dir = "modelzoo" + self.args = self.init_args() + self.prListFile = self.args.pr_filelist_dir + self.fram_str = self.prListFile[:self.prListFile.index('pr_filelist.txt')] + self.pr_filelist = self.get_result_dict() + self.succResultList = [] + self.failResultList = [] + self.errorResultList = [] + # self.fileNameList = self.get_file_name_list() + # self.fullPathList = self.get_full_path_list() + + def init_args(self): + """功能:读取通用参数""" + parser = argparse.ArgumentParser() + parser.add_argument('--pr_filelist_dir', type=str, default="./pr_filelist0.txt", + help='model dirrectory of the pr_filelist') + parser.add_argument('--linklisttxt', type=str, default="./link_list.txt", + help='model dirrectory of the link_list') + return parser.parse_args() + + def get_result_dict(self): + """ + 功能:生成检查文件列表 + """ + with open(self.prListFile, 'r') as f: + content = f.read() + content = content.split('\n') + prfilelist = [] + for filename in content: + fullname = os.path.join(self.fram_str, self.modelzoo_dir, filename) + if os.path.exists(fullname): + prfilelist.append(filename.strip('\n')) + prfilelist = self.check_rawcode(prfilelist) + return prfilelist + + def check_rawcode(self,filelist): + """ + 功能:判断文件是否属于开源源码,开源源码不做检查 + """ + no_raw_filelist = [] + raw_filelist = [] + for f in filelist: + path_list = f.split("/")[:-1] + for i, p in enumerate(path_list): + file_path = os.path.join(self.fram_str, self.modelzoo_dir, *path_list[:i]) + path_list_files = os.listdir(file_path) + if ".gitrawcode" in path_list_files: + raw_filelist.append(f) + break + for f in filelist: + if f not in raw_filelist: + no_raw_filelist.append(f) + return no_raw_filelist + + def file_size_check(self, prfile): + """ + 功能:扫描文件大小,小于1M + 备注:暂时按照小于1M处理,后续细化,不同文件类型不同大小限制。 + """ + prfilename = os.path.join(self.fram_str, self.modelzoo_dir, prfile) + prfilesize = os.path.getsize(prfilename) / math.pow(1024, 2) + if prfilesize < 1: + self.succResultList.append("{}: filesize less than 1M, check succ!".format(prfile)) + else: + self.failResultList.append("{}: filesize less than 1M, check fail!".format(prfile)) + + def license_check(self, prfile): + """ + 功能:判断.py/.cpp文件是否存在关键字LICENSE/license + """ + prfilename = os.path.join(self.fram_str, self.modelzoo_dir, prfile) + if (prfilename[-3:] == ".py") or (prfilename[-4:] == ".cpp"): + if prfilename[-11:] == "__init__.py": + self.succResultList.append("{}: is __init__.py, no need to check license!".format(prfile)) + else: + with open(prfilename, 'r') as f: + content = f.read() + content = content.lower() + if ("license" in content) or ("licence" in content): + self.succResultList.append("{}: contain LICENCE/licence, check succ!".format(prfile)) + else: + self.failResultList.append("{}: not contain LICENCE/licence, check fail!".format(prfile)) + else: + self.succResultList.append("{}: is not *.py/*.cpp, no need to check license!".format(prfile)) + + def get_model_root(self, pr_file_str): + """ + 功能:获取网络框架根目录 + """ + modelRoot = "" + if "/" not in pr_file_str: + return modelRoot + path_list = pr_file_str.split('/') + path_list_len = len(path_list) + model_parent_file = '.modelparant' + while path_list_len > 1: + tmp_path = os.path.join(modelRoot, *path_list[:path_list_len]) + path_list_len -= 1 + if os.path.isfile(os.path.join(self.fram_str, self.modelzoo_dir, tmp_path)): + continue + if model_parent_file in os.listdir(os.path.join(self.fram_str, self.modelzoo_dir, tmp_path)): + return os.path.join(modelRoot, *path_list[:path_list_len]) + return "" + + def firstlevel_file_check(self, prfile): + """ + 功能:判断网络框架根目录下是否包含必要的文件 + LICENCE,requirements.txt,modelzoo_level.txt, readme.md + """ + model_root = self.get_model_root(prfile) + check_list = ["requirements.txt", "modelzoo_level.txt", "readme.md"] + if model_root == "": + self.succResultList.append("{}: at root path,no need to check, check succ!".format(prfile)) + if model_root != "": + print("model_root: ",model_root) + model_root_filelist_tmp = os.listdir(os.path.join(self.fram_str, self.modelzoo_dir, model_root)) + model_root_filelist = [] + for model_root_file in model_root_filelist_tmp: + model_root_filelist.append(model_root_file.lower()) + for check_file in check_list: + if check_file not in model_root_filelist: + self.failResultList.append("{}: at model root path, does not contain {}, check fail!".format(model_root, check_file)) + else: + self.succResultList.append("{}: at model root path, contain {}, check succ!".format(model_root, check_file)) + if ("license" in model_root_filelist) or ("licence" in model_root_filelist): + self.succResultList.append("{}: at model root path, contain {}, check succ!".format(model_root, check_file)) + else: + self.failResultList.append("{}: at model root path, does not contain {}, check fail!".format(model_root, check_file)) + + def link_check(self, prfile): + """ + 功能:检测文件内部是否包含内部链接 + """ + prfilename = os.path.join(self.fram_str, self.modelzoo_dir, prfile) + with open(self.args.linklisttxt, 'r') as f: + content = f.read() + linklist = content.split('\n') + if ('readme' not in prfilename.lower()): + with open(prfilename, 'r') as f: + content = f.read() + for link in linklist: + if link in content: + self.failResultList.append("{}: contain link[{}], check fail!".format(prfile, link)) + else: + self.succResultList.append("{}: not contain link[{}], check succ!".format(prfile, link)) + else: + self.succResultList.append("{}: is readme file, no need to check link, check succ!".format(prfile)) + + + def sensitive_content_check(self, prfile): + """ + 功能:检测文件内部是否包含敏感信息(工号,http链接,黑名单) + """ + prfilename = os.path.join(self.fram_str, self.modelzoo_dir, prfile) + with open(prfilename, 'r') as f: + content = f.read() + code_line_list = content.split('\n') + with open(os.path.join(os.getcwd(),"upline_access_black_http.json"), 'r') as f: + load_dict = json.load(f) + blackhttp_list = load_dict["blackhttp"].split(',') + for code_line in code_line_list: + # 检查工号 + if ('0.00' not in code_line) or ('0.' not in code_line): + if re.findall(r'[A-Za-z]00[1-9][\d]{4, 9}', code_line) or \ + re.findall(r'[A-Za-z]wx[1-9][\d]{4, 9}', code_line) or \ + re.findall(r'00[1-9][\d]{4, 9}', code_line): + self.failResultList.append("{}: contain sensitive message in [{}], check fail!".format(prfile, code_line)) + # 检查http链接 + # if 'readme' not in prfile.lower(): + # if ('device_ip' in code_line) or ('server_id' in code_line): + # continue + # elif re.findall(r'http://\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b', + # code_line) or \ + # re.findall(r'https://\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b', + # code_line): + # self.failResultList.append("{}: contain sensitive message in [{}], check fail!".format(prfile, code_line)) + # 检查黑名单 + else: + for black_key in blackhttp_list: + if 'contrib/' in str(prfile) and black_key == "pan.baidu.com": + pass + elif black_key in code_line: + self.failResultList.append("{}: contain sensitive message in [{}], check fail!".format(prfile, code_line)) + + def modelzoo_level_check(self, prfile): + """ + 功能:检测modelzoo_level.txt文件 + 1.是否存在 + 2.文件内容是否合规 + """ + level_dict = {} + statuslist = ['FuncStatus', 'PerfStatus', 'PrecisionStatus'] + model_root = self.get_model_root(prfile) + if model_root != '': + model_dir = os.path.join(self.fram_str, self.modelzoo_dir, model_root) + modelzoo_level_file = os.path.join(model_dir, 'modelzoo_level.txt') + prlevelfile = os.path.join(model_root, 'modelzoo_level.txt') + if os.path.exists(modelzoo_level_file): + try: + with open(modelzoo_level_file, 'r') as f: + content = f.read() + content = content.split('\n') + for line in content: + level_dict[line.split(':')[0]] = line.split(':')[1] + except: + print('The file modelzoo_level.txt in ' + model_root + 'can not open, please check it!') + for status in statuslist: + if status not in level_dict: + self.failResultList.append("{}: The keyword of the[{}] is not exist in the level file, please check and add it, check fail!".format(prlevelfile, status)) + if level_dict[status] == '': + self.failResultList.append("{}: The keyword of the[{}] is not null in the level file, please check and ehter the correct value, check fail!".format(prlevelfile, status)) + else: + self.failResultList.append("{}: The level file is not exist, please check and add it, check fail!".format(prlevelfile)) + + def file_word_ehck(self, prfile): + """ + 功能:检查网络框架下test目录是否包含必要的train_full(1p or 8p)文件 + 只检查pytorch下,acl下不检查 + """ + model_root = self.get_model_root(prfile) + if (model_root != '') and (model_root.startswith("PyTorch")): + model_dir = os.path.join(self.fram_str, self.modelzoo_dir, model_root) + test_dir = os.path.join(model_dir, 'test') + if os.path.exists(test_dir): + train_full = glob.glob(os.path.join(test_dir, "train*full*")) + train_performance = glob.glob(os.path.join(test_dir, "train*performance*")) + if not train_performance: + self.failResultList.append("{}/test/: not contain the train_performance(1p or 8p) file, check fail!".format(model_root)) + if not train_full: + self.failResultList.append("{}/test/: not contain the train_full(1p or 8p) file, check fail!".format(model_root)) + + def check_result(self): + """ + 功能:检查结果汇总输出 + """ + print("++++++++++++++++++++ check pass log ++++++++++++++++++++") + for l in self.succResultList: + print(l) + print("++++++++++++++++++++ check remove file log ++++++++++++++++++++") + for l in self.errorResultList: + print(l) + print("++++++++++++++++++++ check no pass log ++++++++++++++++++++") + for l in self.failResultList: + print(l) + + def check_entrance(self): + self.__init__() + for pr_file in self.pr_filelist: + filename = os.path.join(self.fram_str,self.modelzoo_dir,pr_file) + if os.path.exists(filename) and os.path.isfile(filename): + self.file_size_check(pr_file) + self.license_check(pr_file) + self.firstlevel_file_check(pr_file) + self.link_check(pr_file) + self.sensitive_content_check(pr_file) + self.modelzoo_level_check(pr_file) + self.file_word_ehck(pr_file) + else: + self.errorResultList.append("{}: The file does not exsist, please check if you remove this file!".format(pr_file)) + self.check_result() + +def main(): + codeCheck = AccessCodeCheck() + codeCheck.check_entrance() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/AcessScan/core_binding_config.json b/AcessScan/core_binding_config.json new file mode 100644 index 0000000000000000000000000000000000000000..7f2ef165181ffff57fd1054c5011da639b3c9592 --- /dev/null +++ b/AcessScan/core_binding_config.json @@ -0,0 +1,6 @@ +{ + "taskset -c": { + "need": "taskset -c $", + "not need": "taskset -c $a-$c" + } +} diff --git a/AcessScan/link_list.txt b/AcessScan/link_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..ee944f64e6369509aa2ab52e9805a2aa7a4ca42e --- /dev/null +++ b/AcessScan/link_list.txt @@ -0,0 +1 @@ +w3.huawei.com \ No newline at end of file diff --git a/AcessScan/run_upline.sh b/AcessScan/run_upline.sh new file mode 100644 index 0000000000000000000000000000000000000000..e33c33bba5407d6e62fd0050eeaf67d31675034e --- /dev/null +++ b/AcessScan/run_upline.sh @@ -0,0 +1,41 @@ +#!/bin/bash +id_dir='/home/jenkins/share-data/gitee/ascend/modelzoo/code/compile/20_bak' +file_log='log1/py_train.log' +dir_log='log1' +if [ -d $dir_log ]; +then + if [ -f $file_log ]; + then + rm -f $file_log + fi +else + mkdir $dir_log +fi +#=========功能列表============= +#1、py/cpp文件中license检查 +#2、垃圾文件检查,后缀为so/log/h5/event +#3、首层目录必要文件检查:LINCENSE,README.md,requirements.txt +#4、文件大小检查,不超过2M +#5、内部链接扫描 +#6、敏感信息扫描,如wx/00开头的工号 +#7、网络功能、性能、精度扫描; +#py功能实现 +python3 access_upline.py --pr_filelist_dir=$id_dir/pr_filelist.txt >$file_log 2>&1 +#结果呈现 +license_check=`grep -ri "license_check=1" ${file_log} | wc -l` +filesize_check=`grep -ri "filesize_check=1" ${file_log} | wc -l` +firstlevel_check=`grep -ri "firstlevel_check=1" ${file_log} | wc -l` +funkfile_check=`grep -ri "funkfile_check=1" ${file_log} | wc -l` +internal_link_check=`grep -ri "internal_link_check=1" ${file_log} | wc -l` +sensitive_check=`grep -ri "sensitive_check=1" ${file_log} | wc -l` +modelzoo_level_check=`grep -ri "modelzoo_level_check=1" ${file_log} | wc -l` +#echo "========== $sensitive_check" +cat $file_log | grep -v "check=1" | grep -v "check=0" +if [[ $license_check -ge 1 || $filesize_check -ge 1 || $firstlevel_check -ge 1 || $funkfile_check -ge 1 || $internal_link_check -ge 1 || $sensitive_check -ge 1 || modelzoo_level_check -ge 1 ]]; +then + echo "check fail" + exit 1 +else + echo "check success" +fi + diff --git a/AcessScan/startRun.sh b/AcessScan/startRun.sh new file mode 100644 index 0000000000000000000000000000000000000000..4e1ffaebd2d0d8bb854cc4c9af7fbfd5327dc024 --- /dev/null +++ b/AcessScan/startRun.sh @@ -0,0 +1,311 @@ +#!/bin/bash + +echo "####################################################################" +echo "# Start Modelzoo Network Test.... " +echo "####################################################################" + +top_dir=`pwd` + +hostname="worker-121-36-69-71" +config_dir=/root/lava_workspace/$hostname +log_dir=/root/lava_workspace/$hostname/log +test_dir=/root/lava_workspace/$hostname/git +modelzoo_dir=$1/modelzoo +ascend310_ip="183.129.213.69" +ascend910_ip="218.2.129.25" + +if [ -f $top_dir/result.xml ] +then + #echo "clear $top_dir/result.xml" + rm -rf $top_dir/result.xml +fi + +if [ -f $top_dir/result.txt ] +then + #echo "clear $top_dir/result.txt" + rm -rf $top_dir/result.txt +fi + +if [ -f $top_dir/result.bak ] +then + #echo "clear $top_dir/result.bak" + rm -rf $top_dir/result.bak +fi + +if [ -d $top_dir/log ] +then + #echo "clear $top_dir/log/*" + rm -rf $top_dir/log/* +fi + +echo "=================Modified files in this PR: =================" +cat $1/pr_filelist.txt + + + +#如果PR只涉及到.MD文件的修改,则无需执行用例,直接返回OK +if [[ `grep -ciE ".MD|.txt|.doc|.docx|LICENSE" "$1/pr_filelist.txt"` -ne '0' && `grep -cE ".py|.sh|.cpp" "$1/pr_filelist.txt"` -eq '0' ]] ;then + echo "Only .MD|.txt|.doc|.docx|LICENSE in pr_filelist, No need to run testcases!" + exit 0 +fi +#=========功能列表============= +#1、py/cpp文件中license检查 +#2、垃圾文件检查,后缀为so/log/h5/event +#3、首层目录必要文件检查:LINCENSE,README.md,requirements.txt +#4、文件大小检查,不超过2M +#5、内部链接扫描 +file_log='log1/py_train.log' +dir_log='log1' +if [ -d $dir_log ]; +then + if [ -f $file_log ]; + then + rm -f $file_log + fi +else + mkdir $dir_log +fi +python3 access_upline.py --pr_filelist_dir=$1/pr_filelist.txt >$file_log 2>&1 +license_check=`grep -ri "license_check=1" ${file_log} | wc -l` +filesize_check=`grep -ri "filesize_check=1" ${file_log} | wc -l` +firstlevel_check=`grep -ri "firstlevel_check=1" ${file_log} | wc -l` +funkfile_check=`grep -ri "funkfile_check=1" ${file_log} | wc -l` +internal_link_check=`grep -ri "internal_link_check=1" ${file_log} | wc -l` +sensitive_check=`grep -ri "sensitive_check=1" ${file_log} | wc -l` +cat $file_log | grep -v "check=1" | grep -v "check=0" +if [[ $license_check -ge 1 || $filesize_check -ge 1 || $firstlevel_check -ge 1 || $funkfile_check -ge 1 || $internal_link_check -ge 1 || sensitive_check -ge 1 ]]; +then + echo "check fail" + exit 1 +else + echo "check success" +fi +#exit $status + + +echo "=================Start to Check License =================" +#license检查 +lincense_check=0 +while read line +do + a=`echo $line |awk -F "_for_" '{print $1}' | awk -F "/" '{print $NF}'` + b=`echo $line |awk -F "_for_" '{print $2}' | awk -F "/" '{print $1}'` + result=`echo $a`_for_`echo $b` + lise_dir=$(echo ${line%$result*}/$result/LICENSE) + directory=$(echo ${line%$result*}/$result/) + if [ -n "$b" ] && [ -d $1/modelzoo/$directory ]; + then + if [ -f $1/modelzoo/$lise_dir ]; + then + true + else + echo "$result license is not exist!" + let lincense_check=1 + fi + else + true + #echo "$result name -ERROR" + fi +done < $1/pr_filelist.txt + + +#py/cpp文件检查 +while read line +do + function checkfile() + { + result=$(echo $1 | grep -E "\.py|\.cpp" | grep -v "__init__.py") + if [ -n "$result" ]; + then + Hw_result=`cat $1 | grep -i "License"` + if [ -n "$Hw_result" ]; + then + true + else + echo "$1 license check fail!" + let lincense_check=1 + fi + else + #echo "$1 no need check" + true + fi + } + function getAllFiles() + { + for fileName in `ls $1`; + do + dir_or_file=$1"/"$fileName + if [ -d $dir_or_file ] + then + getAllFiles $dir_or_file + else + checkfile $dir_or_file + fi + done + } + if [ -f $1/modelzoo/$line ]; + then + #echo $line + checkfile $1/modelzoo/$line + else + getAllFiles $1/modelzoo/$line + fi + +done < $1/pr_filelist.txt + +if [ $lincense_check -eq '1' ] ;then + echo "License check failed, Please follow the guide to add License:" + echo "https://gitee.com/ascend/modelzoo/blob/master/contrib/CONTRIBUTING.md" + exit 1 +fi + +#如果新增的都是目录,则无需执行用例,直接返回OK +check_res=0 +while read line +do + if [[ ! $line =~ ".keep" ]]; + then + let check_res=1 + fi +done < $1/pr_filelist.txt + +if [ $check_res -eq '0' ] ;then + echo "Add directorys in contrib/Research, No need to run testcases!" + exit 0 +fi + +#代码安全检查模块 +while read line +do + if [ -d $1/modelzoo/$line ]; + then + rmresult=`grep -rn -w "rm " $1/modelzoo/$line/*.sh | wc -l` + cpresult=`grep -rn -w "cp " $1/modelzoo/$line/*.sh | wc -l` + toresult=`grep -rn -w "touch " $1/modelzoo/$line/*.sh | wc -l` + if [ $rmresult -gt 0 ] || [ $cpresult -gt 0 ] || [ $toresult -gt 0 ] ; + then + echo "Please do not use rm/cp/touch in .sh, tks!" + fi + elif [[ $1/modelzoo/$line =~ ".sh" ]]; + then + rmresult=`cat $1/modelzoo/$line | grep -w "rm " | wc -l` + cpresult=`cat $1/modelzoo/$line | grep -w "cp " | wc -l` + toresult=`cat $1/modelzoo/$line | grep -w "touch " | wc -l` + if [ $rmresult -gt 0 ] || [ $cpresult -gt 0 ] || [ $toresult -gt 0 ] ; + then + echo "Please do not use rm/cp/touch in .sh, tks!" + fi + fi +done < $1/pr_filelist.txt + +#文件大小检查模块,超过10M则报错 +filesize_check=0 +maxsize=$((1024*1024*2)) +while read line +do + if [ -d $1/modelzoo/$line ]; + then + #PR提交里面不存在目录,如果是空目录,则为.keep + echo "directory" + else + filesize=`ls -l $1/modelzoo/$line | awk '{ print $5 }'` + if [[ $filesize -gt $maxsize ]]; + then + echo "File size of $1/modelzoo/$line greater than 2M, Please remove it!" + let filesize_check=1 + fi + fi +done < $1/pr_filelist.txt + +if [ $filesize_check -eq '1' ] ;then + echo "File size check failed, exit!" + exit 1 +fi + +#如果PR不涉及contrib/TensorFlow/Research目录,则无需执行用例,直接返回OK +if [ `grep -c "contrib/TensorFlow/Research" "$1/pr_filelist.txt"` -eq '0' ] ;then + echo "This pr dosn't have changes in contrib/TensorFlow/Research, No need to run testcases!" + exit 0 +fi + +date_time=`date +%Y%m%d`"."`date +%H%M%S` +echo "====================================================================" +echo "$date_time : start run test case , please wait ..." +echo "====================================================================" + +python3 createCases.py $1/pr_filelist.txt $modelzoo_dir + +#如果case.txt中没有生成用例,则报错退出 +if [ `grep -c ".sh" "$top_dir/cases.txt"` -eq '0' ] ;then + echo "No testcases was found, Please check your PR!" + exit 1 +fi + +date_time=`date +%Y%m%d`"."`date +%H%M%S` +echo "====================================================================" +echo "$date_time : copy source code to Ascend310&Ascend910 , please wait ..." +echo "====================================================================" + +if [ `grep -c "_offline_inference" "$top_dir/cases.txt"` -ne '0' ] ;then + ./auto_scp.sh "$modelzoo_dir/contrib" "$ascend310_ip" "/home/HwHiAiUser/modelzoo" "Root@123" "22" >/dev/null 2>&1 +fi +if [[ `grep -c "_online_inference" "$top_dir/cases.txt"` -ne '0' || `grep -c "_train" "$top_dir/cases.txt"` -ne '0' ]] ;then + ./auto_scp.sh "$modelzoo_dir/contrib" "$ascend910_ip" "/home/HwHiAiUser/modelzoo" "Root@123" "7745" >/dev/null 2>&1 +fi + +date_time=`date +%Y%m%d`"."`date +%H%M%S` +echo "====================================================================" +echo "$date_time : cat testcase info" +echo "====================================================================" +cat cases.txt + +echo "====================================================================" +num=1 +cat cases.txt | while read line +do + date_time=`date +%Y%m%d`"."`date +%H%M%S` + echo "$date_time : start run test case num [ $num ] : [ $line ]" + echo "====================================================================" + array=(${line//,/ }) + case=${array[0]} + echo $case + + if [ -f "$test_dir/$case" ] + then + chmod +x $test_dir/$case + sleep 1 + $test_dir/$line + date_time=`date +%Y%m%d`"."`date +%H%M%S` + echo "$date_time : finished test case num [ $num ] : [ $line ]" + wc -l $top_dir/result.txt + let num=num+1 + if [ -s $top_dir/result.txt ] + then + cp -rf $top_dir/result.txt $top_dir/result.bak + else + echo "####################################################################" + echo "$date_time ERROR : Check Test Result FAIL" + echo "ERROR INFO : $top_dir/result.txt is empty , please check..." + echo "####################################################################" + fi + echo "====================================================================" + else + echo "####################################################################" + echo "$date_time ERROR : Run Testcase FAIL" + echo "ERROR INFO : Could not find testcase [ $test_dir/$case ]" + echo "####################################################################" + fi +done + +cp -r $top_dir/log $1/modelzoo_log + +date_time=`date +%Y%m%d`"."`date +%H%M%S` +echo "####################################################################" +echo "# Modelzoo Network Test Finished! " +echo "####################################################################" + +if [ `grep -c "fail" "$top_dir/result.txt"` -ne '0' ] ;then + exit 1 +else + exit 0 +fi \ No newline at end of file diff --git a/AcessScan/upline_access_black_http.json b/AcessScan/upline_access_black_http.json new file mode 100644 index 0000000000000000000000000000000000000000..d72791aa358775c6c051f106ae30c79488169d28 --- /dev/null +++ b/AcessScan/upline_access_black_http.json @@ -0,0 +1,4 @@ +{ + "blackhttp": "pan.baidu.com,cocodataset.org,storage.googleapis.com,www.image-net.org,drive.google.com,share.weiyun.com,dl.fbaipublicfiles.com,cloud.google.com,colab.research.google.com,gluebenchmark.com,rajpurkar.github.io,worksheets.codalab.org,dumps.wikimedia.org,commoncrawl.org,www.liangzheng.org,ai.googleblog.com,download.tensorflow.org,download.osgeo.org,www.cluebenchmarks.com,mp.weixin.qq.com,download.pytorch.org,yann.lecun.com,polyp.grand-challenge.org,tiny-imagenet.herokuapp.com,huggingface.co,rrc.cvc.uab.es,ftp.tugraz.at,www.vision.ee.ethz.ch,press.liacs.nl,vision.ee.ethz.ch,en.wikipedia.org,www.statmt.org,pjreddie.com,bcsiriuschen.github.io,host.robots.ox.ac.uk,lmb.informatik.uni-freiburg.de,files.is.tue.mpg.de,visualqa.org,download.openmmlab.com,youtube-vos.org,image-net.org,1drv.ms,www.cs.toronto.edu,acsweb.ucsd.edu,brainiac2.mit.edu,nvidia.com,arvrjourney.com,hfl-rc.github.io,cloudygo.com", + "whitehttp": "stackoverflow.com/questions/tagged/tensorflow,sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html,www.sphinx-doc.org,www.pylint.org,opensource.google.com/conduct,cla.developers.google.com,gitee.com,images.gitee,arxiv.org,www.mindspore.cn,github.com,support.huawei,ascendhub.huawei,ascend.huawei,myhuaweicloud.com,.pdf,raw.githubusercontent.com,pypi.python.org,ieeexplore.ieee.org,www.hiascend.com,img.shields.io,openaccess.thecvf.com,tensorlayer.readthedocs.io,mindspore,paperswithcode.com,pytorch.org,user-images.githubusercontent.com,openreview.net,docs.opencv.org,mega.nz,sites.google.com,colah.github.io,gvv.mpi-inf.mpg.de,jany.st,zzutk.github.io,competitions.codalab.org,www.nature.com" +} \ No newline at end of file diff --git a/LicenseTool/LicenseTool.py b/LicenseTool/LicenseTool.py new file mode 100644 index 0000000000000000000000000000000000000000..78cd5c0daf2ad05cfb08dc447c9cd812a3a64b95 --- /dev/null +++ b/LicenseTool/LicenseTool.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- +import os,shutil,re +import argparse +import sys + +def Get_FileList(file_path): + """ + # param file_path: the path to the file folder + # return: number of LICENSE file, all LICENSE files, all py files, all cpp files + """ + LICENSE_Count = 0 + LICENSE_Filelist = [] + py_Filelist = [] + cpp_Filelist = [] + # traverse folders, return: current path, current path name, current path files name + for presentdir, dirnames, filenames in os.walk(file_path): + for filename in filenames: + # files with path + file_with_path = os.path.join(presentdir, filename) + if filename == 'LICENSE' : + LICENSE_Count = LICENSE_Count + 1 + LICENSE_Filelist.append(file_with_path) + if file_with_path.split('.')[-1] == 'py': + py_Filelist.append(file_with_path) + if file_with_path.split('.')[-1] == 'cpp': + cpp_Filelist.append(file_with_path) + return LICENSE_Count, LICENSE_Filelist, py_Filelist, cpp_Filelist + +def Read_File(file): + """ + # param file + # return: read file by lines + """ + file_list = [] + # gb18030 encode and ignore errors + for line in open(file, encoding='gb18030', errors='ignore'): + file_list.append(line) + return file_list + +def Get_SearchArea(file): + """ + # param file + # return: search area: line0 to end_line (line of the first import) + """ + file_list = Read_File(file) + # search line of the first import + flag_import = 0 + for t in range(len(file_list)): + # check 'import' + if re.search("import", file_list[t]): + flag_import = 1 + import_line = t + break + # search area + if flag_import == 0: + # not found import, so the search area is total file + End_line = len(file_list) + else: + End_line = import_line + return End_line + +def NEW_File(license_file, old_file, insert_line): + """ + # param license_file: path to License file + # param old_file: path to old file + # param insert_line: insertion position (line) + """ + # read License file + License_list = Read_File(license_file) + License_list.append("\n") + # read old file + old_list = Read_File(old_file) + # the insert position depend on the insert_line + # if insert_line=-1 , then insert begins on the top of the file + if insert_line == -1: + for k in range(len(old_list)): + License_list.append(old_list[k]) + # remove old file + os.unlink(old_file) + # new file (the same name to the old file) + with open(old_file,'w') as F: + F.writelines(License_list) + F.close() + else: + # new_file text with License + text_with_License = [] + # add old file : 0 to insert_line + for k in range(insert_line + 1): + text_with_License.append(old_list[k]) + # add License + for k in range(len(License_list)): + text_with_License.append(License_list[k]) + # add old file : insert_line to end + for k in range(insert_line + 1, len(old_list)): + text_with_License.append(old_list[k]) + # remove old file + os.unlink(old_file) + # new file (the same name to the old file) + with open(old_file, 'w') as F: + F.writelines(text_with_License) + F.close() + print(old_file + " : License has been added !") + +def LICENSE_File(Model_type, Input_path, Data_path, LICENSE_FileCount, LICENSE_FileList): + """ + # param Model_type + # param Input_path + # param Data_path: some usefull files, like LICENSE file and so on + # param LICENSE_FileCount: numbers of LICENSE file + # param LICENSE_FileList: all LICENSE files + """ + if Model_type == "TensorFlow": + file_from = Data_path + "/LICENSE_TF/LICENSE" + if Model_type == "PyTorch": + file_from = Data_path + "/LICENSE_Pytorch/LICENSE" + + if LICENSE_FileCount == 0: + # copy LICENSE file to input path + shutil.copy(file_from, Input_path) + print("LICENSE file has been added !") + else: + cache_path = Data_path + "/cache" + cache_path_file = cache_path + "/LICENSE" + # copy old LICENSE file to cache + shutil.copy(LICENSE_FileList[0], cache_path) + # remove all old LICENSE file + for f in LICENSE_FileList: + os.unlink(f) + # copy LICENSE from cache to input path + shutil.copy(cache_path_file, Input_path) + # remove LICENSE file of cache + os.unlink(cache_path_file) + print("LICENSE file has been finished ! Excess LICENSE files have been deleted !") + +def Add_License_Py(Model_type, Data_path, py_Filelist): + """ + # param Model_type: + # param Data_path: some usefull files, like LICENSE file and so on + # param py_Filelist: all py files + """ + tf_all = Data_path + "/py_license_tf_all.txt" + tf_huawei = Data_path + "/py_license_tf_huawei.txt" + py_all = Data_path + "/py_license_py_all.txt" + + if Model_type == "TensorFlow": + License_all = tf_all + License_huawei = tf_huawei + elif Model_type == "PyTorch": + License_all = py_all + License_huawei = py_all + + # add License for each file in py_Filelist + for oldfile in py_Filelist: + # if file is empty, insert at the top of the file + if os.path.getsize(oldfile) == 0: + NEW_File(License_all, oldfile, -1) + else: + # read old file + oldfile_list = Read_File(oldfile) + # search area + end_line = Get_SearchArea(oldfile) + # check 'License' (License_line is the line of the last 'License') + flag_License = 0 + for t in range(end_line): + if re.search("License", oldfile_list[t]): + flag_License = 1 + License_line = t + # not found License then copy all License + if flag_License == 0: + # insert position + # line0 to end_line check 'coding: utf-8' and '#!python' + flag_utf = 0 + for t in range(end_line): + if re.search("utf-8", oldfile_list[t]): + flag_utf = 1 + utf_line = t + # not found 'coding: utf-8', then check line0 '#!' + if flag_utf == 0: + flag_python = 0 + if re.search("#!", oldfile_list[0]): + flag_python = 1 + #not found '#!' insert at the top of the file + if flag_python == 0: + NEW_File(License_all, oldfile, -1) + # found '#!', insert after line0 + if flag_python == 1: + NEW_File(License_all, oldfile, 0) + # found 'coding: utf-8', insert after line of 'utf-8' (utf_line) + if flag_utf == 1: + NEW_File(License_all, oldfile, utf_line) + # found License, then search area check 'Huawei' + if flag_License == 1: + flag_Huawei = 0 + for t in range(end_line): + if re.search("Huawei", oldfile_list[t]): + flag_Huawei = 1 + break + # not found 'Huawei' insert License_huawei after the line of the last 'License' (License_line) + if flag_Huawei == 0: + NEW_File(License_huawei, oldfile, License_line) + # found 'Huawei', do nothing + if flag_Huawei == 1: + print(oldfile + " : No need to make changes ! ") + print("All py files have been processed !") + +def Add_License_Cpp(Model_type, Data_path, cpp_Filelist): + """ + # param Model_type + # param Data_path: some usefull files, like LICENSE file and so on + # param cpp_Filelist: all cpp files + """ + tf_all = Data_path + "/cpp_license_tf_all.txt" + tf_huawei = Data_path + "/cpp_license_tf_huawei.txt" + py_all = Data_path + "/cpp_license_py_all.txt" + + if Model_type == "TensorFlow": + License_all = tf_all + License_huawei = tf_huawei + elif Model_type == "PyTorch": + License_all = py_all + License_huawei = py_all + + # add License for each file in cpp_Filelist + for oldfile in cpp_Filelist: + # if file is empty, insert at the top of the file + if os.path.getsize(oldfile) == 0: + NEW_File(License_all, oldfile, -1) + else: + # read old file + oldfile_list = Read_File(oldfile) + # search area + end_line = Get_SearchArea(oldfile) + # check 'License' (License_line is the line of the last 'License') + flag_License = 0 + for t in range(end_line): + if re.search("License", oldfile_list[t]): + flag_License = 1 + License_line = t + # not found License then copy all License + if flag_License == 0: + # insert at the top of the file + NEW_File(License_all, oldfile, -1) + # found License, then search area check 'Huawei' + if flag_License == 1: + flag_Huawei = 0 + for t in range(end_line): + if re.search("Huawei", oldfile_list[t]): + flag_Huawei = 1 + break + # not found 'Huawei' insert License_huawei after the line of the last 'License' (License_line) + if flag_Huawei == 0: + NEW_File(License_huawei, oldfile, License_line) + # found 'Huawei', do nothing + if flag_Huawei == 1: + print(oldfile + " : No need to make changes ! ") + print("All cpp files have been processed !") + +def parse_args(args): + """ + Parse the arguments. + """ + parser = argparse.ArgumentParser(description='Check License file and Add License for py/cpp files') + parser.add_argument('--input_path', type=str, + help='Enter the path to the network folder') + return parser.parse_args(args) + +def main(args=None): + # parse arguments + args = parse_args(args) + if args.input_path is None: + print("Please enter a input_path before running the program !") + sys.exit() + elif not re.search("for_TensorFlow", args.input_path) and not re.search("for_PyTorch", args.input_path): + print("The name is unstandard ! Please use name like **_for_TensorFlow or **_for_PyTorch !") + sys.exit() + else: + # get data path (current .py file path) + data_path = os.path.split(os.path.realpath(__file__))[0] + "/data" + # get information of the input path + LICENSE_filecount, LICENSE_filelist, py_filelist, cpp_filelist = Get_FileList(args.input_path) + # get model type + if re.search("for_TensorFlow", args.input_path): + model_type = "TensorFlow" + elif re.search("for_PyTorch", args.input_path): + model_type = "PyTorch" + ''' LICENSE file ''' + LICENSE_File(model_type, args.input_path, data_path, LICENSE_filecount, LICENSE_filelist) + ''' add License for all py files ''' + if len(py_filelist) == 0: + print("There has no py files in current input path !") + else: + Add_License_Py(model_type, data_path, py_filelist) + ''' add License for all cpp files ''' + if len(cpp_filelist) == 0: + print("There has no cpp files in current input path !") + else: + Add_License_Cpp(model_type, data_path, cpp_filelist) + # finished! + print("Work finished !") + + +if __name__ == '__main__': + main() + + diff --git a/LicenseTool/README.md b/LicenseTool/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3bf0bb256815306c925f590e2a0df35ff5577293 --- /dev/null +++ b/LicenseTool/README.md @@ -0,0 +1,44 @@ +## License添加工具使用说明: + +#### 工具功能说明: + +##### LICENSE文件添加: + +1、网络根目录下若不存在LICENSE文件,会自行添加LICENSE文件。 + +2、若子目录存在多余LICENSE文件,会自行删除。 + +##### 脚本添加license注释: + +1、在.py文件和.cpp文件开头自动判断是否存在license注释;若不存在,则会添加对应框架的license注释。 + +##### 注: + +该工具当前仅支持tensorflow和pytorch两个框架下的迁移网络,mindspore和acl正在开发中。 + + + +#### 使用方法: + +```shell +python3 LicenseTool.py --input_path XXXX路径 +``` + +使用示例: + +```shell +python3 LicenseTool.py --input_path /home/Bert-qa_ID0369_for_TensorFlow +``` + + + +注意事项: + +1、因仓库统一格式,路径必须以`_for_TensorFlow`或`_for_PyTorch`结尾。 + +否则会出现报错: + +`The name is unstandard ! Please use name like **_for_TensorFlow or **_for_PyTorch !` + +2、`LicenseTool/data`目录为程序运行必须目录,请勿更改。 + diff --git a/LicenseTool/data/LICENSE_Pytorch/LICENSE b/LicenseTool/data/LICENSE_Pytorch/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..09d493bf1fc257505c1336f3f87425568ab9da3c --- /dev/null +++ b/LicenseTool/data/LICENSE_Pytorch/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LicenseTool/data/LICENSE_TF/LICENSE b/LicenseTool/data/LICENSE_TF/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..e63e4f7ad633ce2491f84eebbe1f55b836749e15 --- /dev/null +++ b/LicenseTool/data/LICENSE_TF/LICENSE @@ -0,0 +1,284 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------ +Files: third_party/compute_library/... + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------ +Files: ACKNOWLEDGEMENTS +LICENSE + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------ +Files: third_party/hexagon + +Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted (subject to the limitations in the +disclaimer below) provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT +HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LicenseTool/data/cache/.keep b/LicenseTool/data/cache/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/LicenseTool/data/cpp_license_py_all.txt b/LicenseTool/data/cpp_license_py_all.txt new file mode 100644 index 0000000000000000000000000000000000000000..5663310d61574c8f7d06ecded2f733f994345ee2 --- /dev/null +++ b/LicenseTool/data/cpp_license_py_all.txt @@ -0,0 +1,33 @@ +/* +* BSD 3-Clause License +* +* Copyright (c) 2017 xxxx +* All rights reserved. +* Copyright 2021 Huawei Technologies Co., Ltd +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* * Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* ============================================================================ +*/ \ No newline at end of file diff --git a/LicenseTool/data/cpp_license_tf_all.txt b/LicenseTool/data/cpp_license_tf_all.txt new file mode 100644 index 0000000000000000000000000000000000000000..35e01a0048bb71e9a3bff7fc5f9ba563e03a15b4 --- /dev/null +++ b/LicenseTool/data/cpp_license_tf_all.txt @@ -0,0 +1,29 @@ +/* +* Copyright 2017 The TensorFlow Authors. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============================================================================ +* Copyright 2021 Huawei Technologies Co., Ltd +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ \ No newline at end of file diff --git a/LicenseTool/data/cpp_license_tf_huawei.txt b/LicenseTool/data/cpp_license_tf_huawei.txt new file mode 100644 index 0000000000000000000000000000000000000000..e4874f026c989ffe172d8aa2a7e5f1ea9afc5842 --- /dev/null +++ b/LicenseTool/data/cpp_license_tf_huawei.txt @@ -0,0 +1,16 @@ +/* +* ============================================================================ +* Copyright 2021 Huawei Technologies Co., Ltd +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ \ No newline at end of file diff --git a/LicenseTool/data/py_license_py_all.txt b/LicenseTool/data/py_license_py_all.txt new file mode 100644 index 0000000000000000000000000000000000000000..2fcb3d2f55c539cb2454a25da4a272a83e3faa44 --- /dev/null +++ b/LicenseTool/data/py_license_py_all.txt @@ -0,0 +1,33 @@ +# +# BSD 3-Clause License +# +# Copyright (c) 2017 xxxx +# All rights reserved. +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ============================================================================ +# \ No newline at end of file diff --git a/LicenseTool/data/py_license_tf_all.txt b/LicenseTool/data/py_license_tf_all.txt new file mode 100644 index 0000000000000000000000000000000000000000..993e70e38ae1eea6fd12b3ef2d907a6bf5e6f175 --- /dev/null +++ b/LicenseTool/data/py_license_tf_all.txt @@ -0,0 +1,29 @@ +# +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/LicenseTool/data/py_license_tf_huawei.txt b/LicenseTool/data/py_license_tf_huawei.txt new file mode 100644 index 0000000000000000000000000000000000000000..dede7339f625477d3b922d79192d3771a00274aa --- /dev/null +++ b/LicenseTool/data/py_license_tf_huawei.txt @@ -0,0 +1,16 @@ +# +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 91170f8ed7e26946880ec772256b81ef1df53323..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# ModelZoo-PyTorch - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index cf52c85e968251b0fde4638881dd491ff1264f7a..c008648980c46836addd2d884e698169101a9100 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,4 @@ # ModelZoo-PyTorch -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +This branch is only used for ci-pipeline.. -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)