基于SVN提交历史筛选作者并修改文件内容
笔者最近开发的项目中,是通过SVN做为版本管理工具的,因为需要创建的文件太多,所以有许多文件是在原有文件基础上拷贝过来修改的,这里就涉及到一个问题,原有文件中注释里填的JAVA类名、作者工号、创建时间等,都是需要修改成我自己的,因为文件太多,一个个修改起来太麻烦,所以我写了一个程序来自动扫描这些文件并替换文件中指定注释。
1.需要从项目中筛选出我创建的文件:
这个就通过SVN提交日志来筛选吧,因为SVN提交历史中有提交人的工号,我通过筛选自己的工号就可以查出哪些文件是我的(当然需要注意的一点就是如果你改了别人的文件并提交,也会被筛选出,所以你可以对筛选出的文件做进一步的筛选,我这里就通过类名命名规则又筛了一次)。
查询SVN提交历史需要使用svnkit包,svnkit下载路径:svnkit
这部分的实现类在后面提到的CheckSVNComment类中。
2.替换文件中信息
文件筛选出来后,就需要检查该文件中注释信息是否正确,如果不正确的话,就需要替换成指定信息,我这里对注释中的文件名,作者,创建时间进行了检查(创建时间必须是有作者不正确的前提下才会检查)。
这部分的实现类在后面提到的ModifyFileContent类中。
import java.io.File; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNLogEntry; import org.tmatesoft.svn.core.SVNLogEntryPath; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import org.tmatesoft.svn.core.wc.SVNWCUtil; @SuppressWarnings("all") public class CheckSVNComment { private static void setupLibrary() { DAVRepositoryFactory.setup(); SVNRepositoryFactoryImpl.setup(); FSRepositoryFactory.setup(); } public static Set<String> svnFileList(String authorID) { String url = "项目SVN路径"; String name = "svn帐号"; String password = "svn密码"; long startRevision = 0; long endRevision = -1; setupLibrary(); SVNRepository repository = null; try { repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url)); } catch (SVNException svne) { svne.printStackTrace(); System.err.println( "error while creating an SVNRepository for the location \'" + url + "\': " + svne.getMessage()); System.exit(1); } ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password); repository.setAuthenticationManager(authManager); try { endRevision = repository.getLatestRevision(); } catch (SVNException svne) { System.err.println("error while fetching the latest repository revision: " + svne.getMessage()); System.exit(1); } Collection logEntries = null; try { logEntries = repository.log(new String[] { "" }, null, startRevision, endRevision, true, true); } catch (SVNException svne) { System.out.println("error while collecting log information for \'" + url + "\': " + svne.getMessage()); System.exit(1); } Set<String> svnHistory = new HashSet<String>(); for (Iterator entries = logEntries.iterator(); entries.hasNext();) { SVNLogEntry logEntry = (SVNLogEntry) entries.next(); // 指定作者 if (!authorID.equals(logEntry.getAuthor())) { continue; } if (logEntry.getChangedPaths().size() > 0) { Set changedPathsSet = logEntry.getChangedPaths().keySet(); for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext();) { SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next()); String filePath = entryPath.getPath(); if (filePath.endsWith("java")) { svnHistory.add(filePath); } } } } System.out.println("检查出当前作者提交的文件数:" + svnHistory.size()); return svnHistory; } public static void checkFileComment(String path, String authorID) { ModifyFileContent f = new ModifyFileContent(); File file = new File(path); String target = " * FileName"; String newContent = " * FileName: " + file.getName(); f.operationFile(file, target, newContent, authorID); } public static void main(String[] args) { String authorID = "工号ID"; Set<String> svnHistory = CheckSVNComment.svnFileList(authorID); for (String filePath : svnHistory) { // if (filePath.toLowerCase().indexOf("message")>=0 || filePath.toLowerCase().indexOf("singlewithdraw")>=0) // { // System.out.println(filePath); String newFilePath = filePath.replace("/branches/", "D:\\project\\").replace("/", "\\"); // 检查文件中注释信息 checkFileComment(newFilePath, authorID); // } } } }
package zz.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public class ModifyFileContent { private String target; private String newContent; private static final Map<String, String> necessaryMap = new HashMap<String, String>(); private static final Map<String, String> choiceMap = new HashMap<String, String>(); static { choiceMap.put(" * Date", " * Date: 2017/7/17 15:26"); choiceMap.put(" * @DATE", " * @DATE 2017/7/17 15:26"); } public ModifyFileContent() { } private String checkLine(String originalLine, boolean flag) { if (originalLine.startsWith(this.target) && !originalLine.equals(this.newContent)) { return newContent; } for (Entry<String, String> entry : necessaryMap.entrySet()) { if (originalLine.startsWith(entry.getKey()) && !originalLine.equals(entry.getValue())) { return entry.getValue(); } } if (!flag) { return null; } for (Entry<String, String> entry : choiceMap.entrySet()) { if (originalLine.startsWith(entry.getKey()) && !originalLine.equals(entry.getValue())) { return entry.getValue(); } } return null; } public void operationFile(File file, String target, String newContent, String authorID) { this.target = target; this.newContent = newContent; necessaryMap.put(" * Author", " * Author: " + authorID); necessaryMap.put(" * @USER", " * @USER " + authorID); try { InputStream is = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String filename = file.getName(); // tmpfile为缓存文件,代码运行完毕后此文件将重命名为源文件名字。 File tmpfile = new File(file.getParentFile().getAbsolutePath() + "\\" + filename + ".tmp"); BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile)); boolean flag = false; String str = null; while (true) { str = reader.readLine(); if (str == null) break; String newLine = checkLine(str, flag); if (newLine != null) { writer.write(newLine + "\n"); flag = true; } else { writer.write(str + "\n"); } } is.close(); writer.flush(); writer.close(); if (flag) { file.delete(); tmpfile.renameTo(new File(file.getAbsolutePath())); } else { tmpfile.delete(); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { System.out.println("+++++++++ start"); ModifyFileContent f = new ModifyFileContent(); File file = new File("C:\\Users\\XXXXXX\\Desktop\\MessageNoticeJob.java"); String target = " * FileName"; String newContent = " * FileName: " + file.getName(); String authorID = "工号ID"; f.operationFile(file, target, newContent, authorID); System.out.println("+++++++++ end"); } }
如:
/*
* Copyright (C), 2002-2015, XXXXXX公司
* FileName: RechargeSuccessCallBackHandler.java
* Author: 11111111
* Date: 2017/3/6 11:31
* Description: //模块目的、功能描述
* History: //修改记录
* <author> <time> <version> <desc>
* 修改人姓名 修改时间 版本号 描述
*/
package xxxxxx;
import xxxxxx;
/**
* 〈一句话功能简述〉
* 〈出款处理器〉
*
* @USER 11111111
* @DATE 2017/3/6 11:31
* @SEE [相关类/方法](可选)
* @SINCE [产品/模块版本] (可选)
*/
修改后:
/*
* Copyright (C), 2002-2015, XXXXXX公司
* FileName: SingleWithdrawRefundTicketCallBackHandler.java
* Author: 12345678
* Date: 2017/7/17 15:26
* Description: //模块目的、功能描述
* History: //修改记录
* <author> <time> <version> <desc>
* 修改人姓名 修改时间 版本号 描述
*/
package XXXXXX;
import XXXXXX;
/**
* 〈一句话功能简述〉
* 〈出款处理器〉
*
* @USER 12345678
* @DATE 2017/7/17 15:26
* @SEE [相关类/方法](可选)
* @SINCE [产品/模块版本] (可选)
*/