项目上线需要生成上线源码清单
需要的列
源码名称,源码路径,类型,SVN版本号,提交日期,开发人员
工具:
Setup-Subversion-1.6.23.msi 对应 TortoiseSVN 1.6
Setup-Subversion-1.7.22.msi 对应 TortoiseSVN 1.7
Setup-Subversion-1.8.14.msi 对应 TortoiseSVN 1.8
下载地址:
http://happyqing.iteye.com/blog/2270112
如果Subversion版本低会报错:
svn: 警告: “D:\subversion\PRO\trunk\sourcecode\projectName”不是工作副本
svn: 路径 'D:\subversion\PRO\trunk\sourcecode\projectName' 好像是 Subversion 1.7 或更高版本的工作
副本。请升级你的 Subversion客户端,以使用此工作副本。
命令:
安装好后,先配置环境变量。
svn stauts:从本地副本统计信息
svn status -v D:\subversion\PRO\trunk\sourcecode\projectName> projectNameManifest.txt
此命令没能列出提交时间
生成这样的文本
3 3 happyqing D:\subversion\PRO\trunk\sourcecode\projectName\src\org\jeecgframework\core\annotation M 3 3 happyqing D:\subversion\PRO\trunk\sourcecode\projectName\src\org\jeecgframework\core\annotation\Ehcache.java ? 3 3 happyqing D:\subversion\PRO\trunk\sourcecode\projectName\src\org\jeecgframework\core\annotation\JeecgEntityTitle.java
第1列 第2列 第3列 第4列 第5列
状态 ? 版本号 用户名 源文件
状态是?的是本地新增的,M本地修改,还有其他的需要先处理
整理
生成的文本文件虽然可用,但是用起来太麻烦,需要整理
用程序整理后的效果:
Ehcache.java projectName\src\org\jeecgframework\core\annotation\Ehcache.java 3 2016/1/6 赵一 JeecgEntityTitle.java projectName\src\org\jeecgframework\core\annotation\JeecgEntityTitle.java 3 2016/1/6 赵一
往excel里粘贴时,右键 粘贴选项 A (只保留文本)
工具类
package util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * SVN源码清单 * 第一步 用svn命令生成原始清单 * svn status -v D:\subversion\PRO\trunk\sourcecode\projectName > projectNameManifest.txt * @author happyqing * @Since 2016.1.13 */ public class SVNManifest { private static String pathPrefix; private static Map<String, String> userNameMap = new HashMap<String, String>(); private static Map<String, String> directoryDateMap = new HashMap<String, String>(); /** * 读写txt文件 * @param sourceFilePath * @param destFilePath */ public static void readWriteTxt(String sourceFilePath, String destFilePath){ try { File file = new File(sourceFilePath); File dest = new File(destFilePath); //BufferedReader reader = new BufferedReader(new FileReader(file)); //乱码 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"GBK")); // 考虑到编码格式 BufferedWriter writer = new BufferedWriter(new FileWriter(dest)); String line = reader.readLine(); int readLines = 0; int writeLines = 0; while ((line = reader.readLine()) != null) { readLines++; if(validateProcess(line)){ line = processLine(line); writer.write(line); writeLines++; } } System.out.println("读入行:"+readLines); System.out.println("写入行:"+writeLines); writer.flush(); reader.close(); writer.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 判断一行是否需要处理 * @param line * @return */ public static boolean validateProcess(String line){ //?号开头的不要 if(line.startsWith("?")){ return false; } //是目录的不要 if(line.indexOf(".") < 0){ return false; } //只要resources、src、WebContent下的 // if(!(txt.indexOf("projectName\\resources\\") > -1 || txt.indexOf("projectName\\src\\") > -1 || txt.indexOf("projectName\\WebContent\\") > -1)){ // return false; // } boolean needProcess = false; //Map<String, String> map = new HashMap <String, String>(); Iterator<Map.Entry<String, String>> entries = directoryDateMap.entrySet().iterator(); while(entries.hasNext()){ Map.Entry<String, String> entry = entries.next(); if(line.indexOf(entry.getKey())> 0){ needProcess = true; } } if(!needProcess){ return false; } return true; } /** * 处理一行文本 * @param line * @return */ public static String processLine(String line){ //把空格替换为tab String str1 = line.substring(0, line.indexOf(pathPrefix)); //前半截 String str2 = line.substring(line.indexOf(pathPrefix)); //后半截,文件名中可能会有空格 line = str1.replaceAll(" +", "\t") + str2; //添加文件名列 String filePath = line.substring(line.lastIndexOf("\t")+1); String fileName = filePath.substring(filePath.lastIndexOf("\\")+1); line = line + "\t" + fileName; // + "\r\n"; //把英文用户名替换为中文 Iterator<Map.Entry<String, String>> entries = userNameMap.entrySet().iterator(); while(entries.hasNext()){ Map.Entry<String, String> entry = entries.next(); if(line.indexOf(entry.getKey()) > -1){ line = line.replaceAll(entry.getKey(), entry.getValue()); } } //添加日期列(自定义日期) Iterator<Map.Entry<String, String>> entries2 = directoryDateMap.entrySet().iterator(); while(entries2.hasNext()){ Map.Entry<String, String> entry = entries2.next(); if(line.indexOf(entry.getKey()) > -1){ line = line + "\t" + entry.getValue(); } } //换列的顺序(看需要) String[] columnArr = line.split("\t"); line = columnArr[5] + "\t" + columnArr[4] + "\t" + columnArr[2] + "\\t" + columnArr[6] + "\t" + columnArr[3]; line+="\r\n"; //去掉文件路径前缀 String pathPrefixRegex = pathPrefix.replaceAll("\\\\", "\\\\\\\\"); //System.out.println(pathPrefix); line = line.replaceAll(pathPrefixRegex, ""); return line; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //文件路径前缀,会被替换为空字符串 pathPrefix = "D:\\subversion\\PRO\\trunk\\sourcecode\\"; //用户名替换为中文(也可以用Sting[][]) userNameMap.put("\tzhaoyi\t", "\t赵一\t"); userNameMap.put("\tqianer\t", "\t钱二\t"); //自定义目录的更新日期,用TortoiseSVN版本库浏览器查看 directoryDateMap.put("projectName\\resources\\", "2016/1/11"); directoryDateMap.put("projectName\\src", "2016/1/6"); directoryDateMap.put("projectName\\WebContent\\", "2015/12/30"); SVNManifest.readWriteTxt("D:\\project\\document\\projectNameManifest.txt","D:\\project\\document\\projectNameManifestFormat.txt"); } }