在维护公司 Sonarqube平台时 从旧的4.5升级到支持LTS 5.6.x 时 导致原来的plugin不能 兼容,特别是扫描代码时我需要生成新的 service代码文件。
在5.6之前 Sonar-runner调用plugin扫描代码开始execute时都是通过扫描项目路径 所以不存在扫描不到新文件的问题,但是5.6之后 都是在execute scan之前 将所有的file 进行了index处理,这样就导致 动态新文件无法被index,所以无法被扫描,翻了很多官网资料都无解决方案 。
我开始的想法是在execute之后动态增加inputfile ,模拟scanner服务端 add defaultinputfile ,但是不work,由于 sonar scanner服务端采用了cache和其他复杂的设计,我新增的file 总是 不能被有效添加index中,缺少这样或者那样的 初始化值。 无奈放弃。
通过调试插件发现 plugin入口类define方法 是可以在sonar-scanner file indexed之前触发的,于是从这入手 ,先把需要生成的文件生成好,这样后面就能正常file index了。
但是这样我们我们无法获取部分项目属性和参数比如项目路径,但是我们可以用File directory = new File("");获取到。
@Override public void define(Context context) { context.addExtensions(FlowLanguage.class, FlowRules.class, Profile.class, PagesProfile.class, DocumentationMetrics.class, WebMethodsSensor.class, PagesLanguage.class, PagesRules.class); context.addExtension(PropertyDefinition.builder(WebMethodsPlugin.PROPERTY_WM_HOME) .name("Directory of webMethods installation") .description( "Directory of webMethods installation; used for building the inital set of service specifications.") .defaultValue(System.getenv("WM_HOME")).onQualifiers(Qualifiers.PROJECT).category(FLOW_CATEGORY) .build()); File directory = new File(""); File packagePath = directory.getAbsoluteFile(); //File f2 = new File(this.getClass().getResource("").getPath()); LOG.debug("Plugin start ...."); LOG.info("project path: " + packagePath.getAbsolutePath()); if (packagePath.getAbsolutePath().toString().contains("Rb")) { LOG.debug("Scan start preprocess: " + packagePath.getAbsolutePath()); PrepareLoad.preprocess(packagePath); } // LOG.info("System path: "+System.getProperty("java.class.path")); // LOG.info("Current project path: "+f2.getAbsolutePath().toString()); }
但是这样有个问题,sensor类 是scan执行类,plugin 方法define 会被触发三次。看api注释 :
/** * This method is executed at runtime when: **
*/ void define(Context context);- Web Server starts
*- Compute Engine starts
*- Scanner starts
*
我们真正需要的是第三次 scanner starts 才是执行扫描 项目包的 真正开始时,所以需要想法屏蔽掉之前的两次执行。我此处是根据自己业务 检测 包含rb字样才执行生成新文件方法
packagePath.getAbsolutePath().toString().contains("Rb")
这样解决了 问题,通过执行 测试
INFO: Scanner configuration file: D:\sonar-scanner-3.0.3.778-windows\bin\..\conf\sonar-scanner.properties INFO: Project root configuration file: C:\Users\xxxxx\Desktop\projectname\sonar-project.properties INFO: SonarQube Scanner 3.0.3.778 INFO: Java 1.8.0_121 Oracle Corporation (64-bit) INFO: Windows Server 2008 R2 6.1 amd64 INFO: User cache: C:\Users\xxxxxx\.sonar\cache INFO: Load global repositories INFO: Load global repositories (done) | time=218ms INFO: User cache: C:\Users\LUM9SZH\.sonar\cache INFO: Load plugins index INFO: Load plugins index (done) | time=16ms INFO: Download sonar-plugin-xxx-webmethods-1.0.0.jar INFO: SonarQube server 5.6.7 INFO: Default locale: "en_US", source code encoding: "UTF-8" INFO: project path: C:\Users\xxxxxx\Desktop\projectname INFO: Found manifest: C:\Users\xxxx\Desktop\projectname\manifest.v3 INFO: Process project properties INFO: project path: C:\Users\xxxx\Desktop\projectname INFO: Found manifest: C:\Users\xxx\Desktop\projectname\manifest.v3 INFO: Load project repositories INFO: Load project repositories (done) | time=187ms INFO: Load quality profiles INFO: Load quality profiles (done) | time=62ms INFO: Load active rules INFO: Load active rules (done) | time=639ms INFO: Publish mode INFO: ------------- Scan xxxxxxx INFO: project path: C:\Users\xxxxxx\Desktop\projectname INFO: Found manifest: C:\Users\LUM9SZH\Desktop\projectname\manifest.v3 INFO: Load server rules INFO: Load server rules (done) | time=156ms INFO: Base dir: C:\Users\LUM9SZH\Desktop\projectname INFO: Working dir: C:\Users\xxxx\Desktop\projectname\.scannerwork INFO: Source paths: config, ns, code, pub, web INFO: Source encoding: UTF-8, default locale: en_US INFO: Index files INFO: 7 files indexed INFO: Quality profile for flow: XXXX Flow Language Profile INFO: print start... INFO: Setting: com.xxx.webmethods.sonar.pkgclassifile=/opt/sonar-runner-2.3/conf/packages.xlsx INFO: Setting: sonar.projectName=RbKrDesadvToDesadv INFO: Setting: sonar.host.url=http://localhost:9567/sonarqube/ INFO: Setting: 。。。。。
请注意 ------------- Scan xxxxxxx
下面才是 扫描代码的开始。 可以看到 7 files indexed(其中6个是在plugin方法中 动态生成的 )
Quality profile for flow: XXXX Flow Language Profile...之后才是检测代码执行,之前index是在scanner服务端处理。
Jenkins测试也是正常,有一点需要注意的是,jenkin在配置参数时 路径一定要包含在项目文件xia 不要放在不相关的目录,这样便于监测 是否决定根据自己业务规则执行新增文件。