代码评审是软件质量保证一种活动,由一个或者多个人对一个程序的部分或者全部源代码进阅读理解。一般来说分为作者和评审者两种角色,作者方提供代码逻辑的介绍和代码,评审者则对提供的代码基于设计,功能性和非功能性等方面认知进行阅读并提出问题。常见的评审组织形式是有同行评审(Peer Review)和小组检查 (Team Inspection)两种方式。
在代码评审中,评审的目的在通过代码的评审发现潜在的问题,同时分享和表达是代码评审的重要收获,我们知道人相同在不同的文化下生产力是不同的,代码评审是一个工具,工具受文化的影响的同时也影响着文化,最终朝着我们希望的责任共担、持续改进的方向发展。
4)插件运行调试打包安装
Gradle构建方式进行调试打包安装
运行/调试:runIde 可以选择Debug模式或者是Run模式
打包
安装:可以将打的包发布市场(本地idea配置插件仓库),从Marketplace搜索插件或者是直接从Settings->plugins->Install->Install Plugin from Disk安装
步骤2:研究Gerrit插件源码,搞清楚整理开发流程和模块
步骤3:基于Gerrit插件规划VCR插件模块,增加clone、branch、mergeRequest、VCR模块,并对各组件增强
步骤4:定制原有流程模块push,自动化关联工作项
在使用Git依赖插件之前,先了解一下插件的扩展以及扩展点(Extensions、Extension Points)。
Intellij 平台提供了允许一个插件与其他插件或者 IDE 交互的 extensions 以及 extension points 的概念。
可以在 plugin.xml 中的和块中定义 extensions 以及 extension points。
plugin.xml
<!--依赖插件包--!><depends>Git4Idea</depends><!—idea第一次打开, 实际上就是订阅了应用程序打开的事件--><application-components><component><implementation-class>com.demo.intellij.plugin.vcr.push.VcrPushExtension$Proxy</implementation-class></component></application-components>
上述我们看到依赖的Git4Idea 包,如果我们想修改原生的的Git,先看下push依赖包中如何实现的。
Git4Idea(plugin.xml)
<extensions defaultExtensionNs="com.intellij"><pushSupport implementation="git4idea.push.GitPushSupport"/>...</extensions>
intellij-dvcs.jar(plugin.xml)
<extensionPoints> <extensionPoint name="pushSupport" interface="com.intellij.dvcs.push.PushSupport" area="IDEA_PROJECT" dynamic="true"/>....</extensionPoints>
从上述可看到,Git4Idea 的GitPushSupport扩展实现push的功能点,接下来我们主要对GitPushSupport进行javassist字节码修改以达到扩展git push组件能力。
扩展使用GitPushSupport之前,需要将需要的类进行装载至GitPlugin中,然后再对GitPushSupport进行字节码改造,至此对git Push原生插件页进行改造。
步骤5:使用树状列表模式,展示一次push请求VCR提交内容及多个CR情况
主要是实现JTreeTable,对VCR与CR进行管理。
一次评审请求VCR包含所有CR的提交变更记录,可针对该变更记录进行代码评审,单个CR也可以进行评审。
步骤6:展示变更文件视图及定制评论展示模块,精准定位代码
代码评审主要根据编辑器获取代码行及位置,评论可精准定位到代码行。
1)changeBrowser变更视图展示VCR变更文件信息
2)双击文件,diff视图展示inline和side-by-side两种代码差异
声明扩展,针对扩展类进行定制化改造。
plugin.xml
<diff.DiffTool implementatinotallow="com.demo.intellij.plugin.vcr.ui.diff.VcrCommentsDiffTool$Proxy"/>
3)添加代码块评论,定位代码块
AddCommentAction.java
public class AddCommentAction extends AnAction implements DumbAware {public AddCommentAction(String label, Icon icon, CommentsDiffTool commentsDiffTool, Editor editor, List<CommentInfo> fileComments .... ) { super(label, null, icon);}private CommentInput createComment() {//获取用户选择代码位置位置//行的情况下,默认是开头和行结束 得到光标的位置caretModel.getOffset();/*取到插字光标模式对象 CaretModel caretModel = editor.getCaretModel();得到光标的位置int caretOffset = caretModel.getOffset();//得到一行开始和结束的地方int lineNum = document.getLineNumber(caretOffset);int lineStartOffset = document.getLineStartOffset(lineNum);int lineEndOffset = document.getLineEndOffset(lineNum);获取一行内容String lineContent = document.getText(new TextRange(lineStartOffset, lineEndOffset));*/Document document = editor.getDocument();int lineNum = document.getLineNumber(editor.getCaretModel().getOffset()) ;int lineStartOffset = document.getLineStartOffset(lineNum);int lineEndOffset = document.getLineEndOffset(lineNum);String lineContent = document.getText(new TextRange(lineStartOffset, lineEndOffset));.....}}
所有评论展示列表如何精准定位代码
SafeHtmlHistoryComments.java
public class SafeHtmlHistoryComments extends JPanel { private Iterable<CommentInfo> fileComments; private List<CommentInfo> commentInfos = new ArrayList<>(); private CommentInfo currentCommentInfo; private SelectedComment selectedComment; private SelectedComment operatorSelectedComment; private Editor editor; public SafeHtmlHistoryComments(Editor editor,Iterable<CommentInfo> fileComments, Comment selectedComment) { super(new BorderLayout()); .... HistoryCommentListPanel historyCommentListPanel = new HistoryCommentListPanel(fileComments); //双击table某行触发代码定位 historyCommentListPanel.addTableMouseDoubleHit(new Consumer<CommentInfo>() { @Override public void consume(CommentInfo commentInfo) { codeTextHit(editor,commentInfo); } }); } /** * 定位代码 * @param editor * @param commentInfo */ private static void codeTextHit(Editor editor, CommentInfo commentInfo) { SelectionModel selectionModel = editor.getSelectionModel(); // 优化:如果文件修改过了,则不进行选中操作,换为提示 if (null != commentInfo.startIndex && null != commentInfo.endIndex && commentInfo.startIndex != 0 && commentInfo.endIndex != 0) { editor.getCaretModel().moveToOffset(commentInfo.endIndex); selectionModel.setSelection(commentInfo.startIndex, commentInfo.endIndex); } else if (null != commentInfo.line && commentInfo.line != 0) { int lineNum = commentInfo.line - 1; editor.getCaretModel().moveToOffset(lineNum); CharSequence charsSequence = editor.getMarkupModel().getDocument().getCharsSequence(); if(null!=commentInfo.range) { RangeUtils.Offset offset = RangeUtils.rangeToTextOffset(charsSequence, commentInfo.range); selectionModel.setSelection(offset.start, offset.end); }else{ Document document = editor.getDocument(); int lineStartOffset = document.getLineStartOffset(lineNum); int lineEndOffset = document.getLineEndOffset(lineNum); selectionModel.setSelection(lineStartOffset, lineEndOffset); } } editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); }....}
本文链接:http://www.28at.com/showinfo-26-96989-0.htmlvivo 互联网自研代码评审 VCR 落地实践
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com