注意:本工具是代码无法全自动维护的情况下采用,需要手动操作,只实现了版本半自动化维护。是在上线环境和开发环境无法联网,无法做到全自动维护。

1、我们使用的代码版本管理是SVN,java代码实现了读取SVN服务器,根据上传作者、上传时间、关键词检索svn的变更集,下载变更集到excel

2、java读取excel,excel记录了java的源文件文件位置,和.class文件的位置

3、根据excel变更文件路径复制.class文件和其他相关文件,打成一个和原项目目录结构相同的文件夹

4、把做好的变更文件夹拷贝到上线文件目录进行覆盖

 

jar:poi相关jar

        <dependency>
            <groupId>org.tmatesoft.svnkit</groupId>
            <artifactId>svnkit</artifactId>
            <version>1.9.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.71</version>
        </dependency>


一、java下载svn变更集

package com.cosic;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.junit.Test;
import org.springframework.util.ResourceUtils;
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.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import com.alibaba.fastjson.JSONObject;

/**
 * @desc   获取svn提交记录,并按照筛选条件抓取记录保存到excel
 * @author fengbin
 *
 */
public class SvnToolOnline {
    
    //是否开启svn提交人过滤
    private static boolean isUsersFilter=false;
    //筛选svn提交用户
    private static String svnUsers="fengbin,lizongyao,shijin";
    //是否开启时间过滤
    private static boolean timeFiler=true;
    //开启时间过滤开始时间
    private  static String  startTime="2020-05-13 11:00:00";
    //开启时间过滤结束时间-默认当前时间
    private static String  endTime="";
    //svn提交地址
    //private static String svnUrl="svn://10.152.38.57/kjwoa3.0";
    private static String svnUrl="https://mayday-pc/svn/KJWOA";
    //keyword搜索,多个key使用","分割
    private static String keyWords="";
    //导出Excel的路径
    private static String exportUrl="E:\\ExportSVNLog\\online.xls";
    
    private static List<Object> list=new ArrayList<Object>();
    
    public static void main( String[] args ) throws ParseException, IOException, EncryptedDocumentException, InvalidFormatException {
        DAVRepositoryFactory.setup();
        //String url = "http://svn.svnkit.com/repos/svnkit/trunk/doc";
        String name = "shijin";
        String password = "123";
        long startRevision = 0;
        long endRevision = -1; //HEAD (the latest) revision
        SVNRepository repository = null;
        char[] password1=password.toCharArray();
        Date startDate = null;
        Date endDate =null;
        if(timeFiler){
            startDate = parseStrTime(startTime);
            if("".equals(endTime)){
                endDate = new Date();
            }else{
                endDate = parseStrTime(endTime);
            }
        }
        
        List<Map<String, Object>> dataList=new ArrayList<>();
        try {
            repository = SVNRepositoryFactory.create( SVNURL.parseURIEncoded(svnUrl));
            ISVNAuthenticationManager authManager=SVNWCUtil.createDefaultAuthenticationManager(name, password1);
            //ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name,password);
            repository.setAuthenticationManager(authManager);
            Collection<?> logEntries = null;
            logEntries = repository.log(new String[] { "" } , null , startRevision , endRevision , true , true );
            for (Iterator<?> entries = logEntries.iterator( ); entries.hasNext( ); ) {
                SVNLogEntry logEntry = ( SVNLogEntry ) entries.next( );
                Date date = logEntry.getDate();
                if(date.after(startDate)  && date.before(endDate)){
                    Map<String, Object> dataMap=createLog(logEntry);
                    //System.err.println(dataMap.get("revision"));
                    //System.err.println(dataMap.get("paths"));
                    dataList.add(dataMap);
                }
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        
        
        String sheetTitle="kjwoa";
        String[] title={"序号","所属系统","变更形式","变更文件","注释","提交时间","变更原文件路径"};
        File file = new File(exportUrl);
        
        if (!file.exists()) {
            boolean createNewFile = file.createNewFile();
        }
        Workbook wb = WorkbookFactory.create(new FileInputStream(file));
        //XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));//创建excel表
        Sheet sheet = wb.createSheet();
        wb.setSheetName(1, sheetTitle);
        //删除多余的sheet页,并把自己导出的sheet放在表格第一位
        int sheetIndex=wb.getSheetIndex(sheet);//获取当前的sheet页下标
        int sheets=wb.getNumberOfSheets();//获取表格中所有的sheet
        for (int i = sheets-1; i > -1; i--) {
            if (i!=sheetIndex) {
                wb.removeSheetAt(i);//删除sheet
            }
            wb.setActiveSheet(0);//设置当前的sheet为第一位
        }
        
        //sheet.setDefaultColumnWidth(20);//设置默认行宽
        sheet.setColumnWidth(0, 8*256);
        sheet.setColumnWidth(1, 12*256);
        sheet.setColumnWidth(2, 12*256);
        sheet.setColumnWidth(3, 100*256);
        sheet.setColumnWidth(4, 50*256);
        sheet.setColumnWidth(5, 20*256);
        sheet.setColumnWidth(6, 100*256);

        //表头样式(加粗,水平居中,垂直居中)
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
        //设置边框样式
        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框

        Font fontStyle = wb.createFont();
        fontStyle.setFontHeightInPoints((short)20);        
        fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        cellStyle.setFont(fontStyle);

        //标题样式(加粗,垂直居中)
        CellStyle cellStyle2 = wb.createCellStyle();
        cellStyle2.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
        cellStyle2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
        cellStyle2.setFont(fontStyle);

        //设置边框样式
        cellStyle2.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle2.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        cellStyle2.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        cellStyle2.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        Font fontStyle2 = wb.createFont();
        fontStyle2.setFontHeightInPoints((short)14);        
        fontStyle2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        cellStyle2.setFont(fontStyle2);
        
        //字段样式(垂直居中)
        CellStyle cellStyle3 = wb.createCellStyle();
        cellStyle3.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
        cellStyle3.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
        //设置边框样式
        cellStyle3.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle3.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        cellStyle3.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        cellStyle3.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        //message的样式
        CellStyle messageStyle = wb.createCellStyle();
        messageStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
        messageStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);//文字靠左
        messageStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        messageStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        messageStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        messageStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        
        //创建标题
        Row rowTitle = sheet.createRow(0);
        rowTitle.setHeightInPoints(25);

        Cell hc;
        for (int i = 0; i < title.length; i++) {
            hc = rowTitle.createCell(i);
            hc.setCellValue(title[i]);
            hc.setCellStyle(cellStyle2);
        }
        byte result[] = null;
        ByteArrayOutputStream out = null;
        try {
            
        int rowNum=1;//表格从哪一行开始
        int index=1;//序号
        for (Object obj : dataList) {
            Map map = (Map) obj;
            System.out.println(map.get("revision"));
            System.out.println(map.get("author"));
            System.out.println(map.get("date"));
            System.out.println(map.get("message")==null?"":map.get("message"));
            List<String> urlList=(List<String>) map.get("urlList");
            
            for (String str:urlList) {
                System.out.println("type="+str.split("-")[0]+" "+"path="+str.split("-")[1]);
                System.out.println("index="+index);
                //System.out.println(index+" "+"kjwoa"+" "+);
                String absolutPath = str.split("-")[1];
                absolutPath=absolutPath.substring(1);
                absolutPath=absolutPath.replace("kjwoa3.0/", "");
                String compilePth="";
                if (absolutPath.indexOf(".")==-1) {//说明是一个文件夹,不必记录
                    continue;
                }
                if (absolutPath.endsWith(".java")) {
                    compilePth="defaultroot/WEB-INF/classes"+absolutPath.substring(absolutPath.indexOf("/src/")+4, absolutPath.lastIndexOf("."))+".class";
                }else if(absolutPath.endsWith(".properties") && absolutPath.indexOf("/src/")!=-1){
                    compilePth="defaultroot/WEB-INF/classes"+absolutPath.substring(absolutPath.indexOf("/src/")+4, absolutPath.lastIndexOf("."))+".properties";
                }else {
                    compilePth=absolutPath;
                }
                    Row rowBody = sheet.createRow(rowNum);
                    rowBody.setHeightInPoints(20);
                    for (int j =0;j<7;j++) {
                        hc = rowBody.createCell(j);
                        hc.setCellStyle(cellStyle3);
                        switch (j) {
                            case 0:
                                hc.setCellValue(index);
                                break;
                            case 1:
                                hc.setCellValue("kjwoa");
                                hc.setCellStyle(cellStyle3);
                                break;
                            case 2:
                                hc.setCellValue(str.split("-")[0]);
                                hc.setCellStyle(cellStyle3);
                                break;
                            case 3:
                                hc.setCellValue(compilePth);
                                hc.setCellStyle(messageStyle);
                                break;
                            case 4:
                                hc.setCellValue(map.get("message")==null?"":map.get("message").toString());
                                hc.setCellStyle(messageStyle);
                                break;
                            case 5:
                                hc.setCellValue(map.get("date").toString());
                                hc.setCellStyle(cellStyle3);
                                break;
                            case 6:
                                hc.setCellValue(absolutPath);
                                hc.setCellStyle(messageStyle);
                                break;
                            default:
                               break;
                        }
                    }
                    rowNum++;
                    index++;
                }
            System.out.println("---------------------------------------------");
        }
       
             out = new ByteArrayOutputStream();
                result =  out.toByteArray();
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                wb.write(fileOutputStream);
              }catch(Exception e){
                  e.printStackTrace();
              }finally{
                  try {
                      if(null != out){
                          out.close();
                      }
                  } catch (IOException ex) {
                      ex.printStackTrace();          
                      } finally{
                      try {
                          wb.close();
                      } catch (IOException ex) {
                          ex.printStackTrace();
                          }
                  }
              }
                
        
    }
    
    /**
     * @desc 时间转换
     * @param time
     * @return
     * @throws ParseException
     */
    public static Date parseStrTime(String time) throws ParseException{
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = df.parse(time);
        return date;
    }
    
    @SuppressWarnings("deprecation")
    public static Map<String, Object> createLog(SVNLogEntry logEntry){
        Map<String, Object> map=new HashMap();
        System.out.println( "***************************************");
        System.out.println ("revision: " + logEntry.getRevision( ) );
        System.out.println( "author: " + logEntry.getAuthor( ) );
        System.out.println( "date: " + logEntry.getDate().toLocaleString());
        System.out.println( "message: " + logEntry.getMessage( ) );
        map.put("revision", logEntry.getRevision( ));
        map.put("author", logEntry.getAuthor( ));
        map.put("date", logEntry.getDate().toLocaleString());
        map.put("message", logEntry.getMessage( ) );
        
        
        List<String> urlList=new ArrayList<>();
        if ( logEntry.getChangedPaths().size() > 0 ) {
            System.out.println( "changed paths:" );
            Set<?> changedPathsSet = logEntry.getChangedPaths( ).keySet();
            for ( Iterator<?> changedPaths = changedPathsSet.iterator( ); changedPaths.hasNext( ); ) {
                
                SVNLogEntryPath entryPath = ( SVNLogEntryPath ) logEntry.getChangedPaths( ).get( changedPaths.next( ) );
                //A新增 C冲突 D删除 M修改 G本地文件修改并且和服务器合并 U从服务器更新 R从服务器替换 I忽略
                
                System.out.println(getSVNEnum(entryPath.getType())
                        + "-"
                        + entryPath.getPath()
                        + (( entryPath.getCopyPath() != null ) ? " (from "
                                + entryPath.getCopyPath() + " revision "
                                + entryPath.getCopyRevision() + ")" : "" ));
                urlList.add( getSVNEnum(entryPath.getType())
                        + "-"
                        + entryPath.getPath()
                        + (( entryPath.getCopyPath() != null ) ? " (from "
                                + entryPath.getCopyPath() + " revision "
                                + entryPath.getCopyRevision() + ")" : "" ));
            }
        }
        map.put("urlList", urlList);
        return map;
    }
    
    //读取项目工程的json文件
    public static String readSVNJson(String fileName){
        FileReader fileReader=null;
        Reader reader=null;
        try {
            File jsonFile=ResourceUtils.getFile("classpath:"+"com/cosic/"+fileName);
            fileReader=new FileReader(jsonFile);
            reader=new InputStreamReader(new FileInputStream(jsonFile),"gbk");
            int ch=0;
            StringBuffer sb=new StringBuffer();
            while ((ch=reader.read())!=-1) {
                sb.append((char)ch);
            }
            fileReader.close();
            reader.close();
            return sb.toString();
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
            return null;
        }
    }
    //解析度读取到的json文件
    public static String getSVNEnum(char ch){
        String jsonString=readSVNJson("svn.json");
        //String jsonString="{\"svn\":{\"A\":\"新增\",\"C\":\"冲突\",\"D\":\"删除\",\"M\":\"修改\",\"G\":\"本地文件修改并且和服务器合并\",\"U\":\"从服务器更新 \",\"R\":\"从服务器替换\",\"I\":\"忽略\"}}";
        JSONObject jsonObject=JSONObject.parseObject(jsonString);
        JSONObject svnObject=jsonObject.getJSONObject("svn");
        return svnObject.getString(String.valueOf(ch));
    }
    
    @Test
    public void shwow(){
        System.out.println(getSVNEnum('A'));
    }
}
 


二、根据文件变更路径复制项目变更文件

package com.cosic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;


/**
 * @desc:上线抽取包工具类
 * @author fengbin
 * @注意:路径最好不要有中文,如果要把所有文件抽取到一个目录下,文件名称要不相同
 *
 */
public class CodeManager {

    /**
     * 抽取变更的文件存放位置
     */
    private static String desDir="C:/Users/j01054941/Desktop/code";
    /**
     * 存放变更集的exce位置,excel样板文件codeChange.xlsx
     */
    private static String excelPath="C:/Users/j01054941/Desktop/code/excel/codeChange.xlsx"; 
    /**
     * 文件变更记录excel
     */
    private static String changedExcelName="codeChange.xlsx";
    /**
     * 文件变更记录xml
     */
    private static String cahngedXmlName="codeChange.xml";
    
    
    public static void main(String[] args) throws Exception {
        //eclipse项目工作目录
        String workspace ="D:/kjwworkspace/KJWOA/";    
        readExcel(excelPath,workspace);
        System.exit(0);
    }
    
    /**
     * @desc:解析excel
     * @param excelPath
     * @param workspace
     * @throws IOException
     */
    public static void readExcel(String excelPath,String workspace) throws IOException {
        FileInputStream fis=null;
        Document document = DocumentHelper.createDocument(); //把excel解析成xml,方便shell解析
        try {
            //String encoding = "GBK";   //读取文件默认的字符集
            File excel = new File(excelPath);
            if (excel.isFile() && excel.exists()) {   //判断文件是否存在
                String[] split = excel.getName().split("\\.");  //.是特殊字符,需要转义!!!!!
                Workbook wb;
                //根据文件后缀(xls/xlsx)进行判断
                fis = new FileInputStream(excel);   //文件流对象
                if ( "xls".equals(split[1])){
                    wb = new HSSFWorkbook(fis);
                }else if ("xlsx".equals(split[1])){
                     wb=new XSSFWorkbook(fis);
                }else {
                    System.out.println("文件类型错误!");
                    return;
                }
                //开始解析
                Sheet sheet = wb.getSheetAt(0);     //读取sheet 0 kjwoa变更的classes
                int firstRowIndex = sheet.getFirstRowNum();   //第一行是列名,所以不读
                int lastRowIndex = sheet.getLastRowNum();
                System.out.println("firstRowIndex: "+firstRowIndex);
                System.out.println("lastRowIndex: "+lastRowIndex);

                Element table = document.addElement("table");
                boolean isRead=false;
                for(int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) {   //遍历行
                    System.out.println();
                    Row row = sheet.getRow(rIndex);
                    if(isRead) {
                        break;
                    }
                    Element tr =null;
                    if(rIndex>0) {
                          tr = table.addElement("tr");
                    }
                    if (row != null) {
                        int firstCellIndex = row.getFirstCellNum();
                        int lastCellIndex = row.getLastCellNum();
                        for (int cIndex = firstCellIndex; cIndex < lastCellIndex; cIndex++) {   //遍历列
                            Cell cell = row.getCell(cIndex);
                            if("".equals(row.getCell(firstCellIndex).toString().trim())) {
                                isRead=true;
                                break;
                            }
                            if(cell == null || "".equals(cell.toString().trim())) {
                                continue;
                            }
                            if (cell != null && !"".equals(row.getCell(firstCellIndex).toString().trim())) {
                                System.out.print(cell);
                                System.out.print("\t");
                            }
                            if(rIndex>0 && cIndex==3) {  //复制文件
                                String filePath=workspace+"/"+cell;
                                String copyFilePath=desDir+"/"+cell;   //这个会把文件的名称路径带上
//                                if(cell.toString().contains("class")){
//                                    filePath="";
//                                    filePath=workspace+"defaultroot/WEB-INF/"+cell;
//                                    copyFilePath=desDir+"/"+"defaultroot/WEB-INF/"+cell;   //这个会把文件的名称路径带上
//                                }
                                String fileName = cell.toString().substring(cell.toString().lastIndexOf("/")); 
                                //String copyFilePath=desDir+"/"+fileName; //把文件抽取到一各位置,不同包下同文件名称会有问题
                                File oldFile = new File(filePath);
                                File newFile = new File(copyFilePath);
                                if(!newFile.exists()) {
                                    /*getParentFile返回此抽象路径名的父路径名的抽象路径名,如果直接使用f.mkdirs则会将234.txt也创建成目录*/
                                    newFile.getParentFile().mkdirs();
                                    newFile.createNewFile();
                                }
                                copyFileUsingFileStreams(oldFile,newFile);
                            }
                            if(rIndex>0 ) {
                                Element td = tr.addElement("td");
                                td.addText(cell.toString());
                                if(cIndex==0) {
                                    td.addAttribute("name", "id");
                                }else if(cIndex==1) {
                                    td.addAttribute("name", "system");
                                }else if(cIndex==2) {
                                    td.addAttribute("name", "changeType");
                                }else {
                                    td.addAttribute("name", "filePath");
                                }
                            }
                        }
                    }
                }
                OutputFormat format = OutputFormat.createPrettyPrint();
                //创建变更xml文件,方便后续shell解析,shell对excel文件支持性不好
                File file = new File(desDir+"/"+cahngedXmlName);
                XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
                writer.write(document);  
                //复制改变的excel到变更目录
                File changedExcel = new File(desDir+"/"+changedExcelName);
                if(!changedExcel.exists()) {
                    /*getParentFile返回此抽象路径名的父路径名的抽象路径名,如果直接使用f.mkdirs则会将234.txt也创建成目录*/
                    changedExcel.getParentFile().mkdirs();
                    changedExcel.createNewFile();
                }
                changedExcel.delete();
                copyFileUsingFileStreams(excel, changedExcel);
            } else {
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(null!=fis) {
                fis.close();
            }
            
        }

    }
    
    /**
     * @desc:复制文件
     * @param source
     * @param dest
     * @throws IOException
     */
    public  static void copyFileUsingFileStreams(File source, File dest)throws IOException {    
        InputStream input = null;    
        OutputStream output = null;    
        try {
               input = new FileInputStream(source);
               output = new FileOutputStream(dest);        
               byte[] buf = new byte[1024];        
               int bytesRead; 
               while ((bytesRead = input.read(buf))!=-1) {
                   output.write(buf, 0, bytesRead);
               }
        } finally {
            input.close();
            output.close();
        }
    }        
}
 


三、上线替换文件(小心谨慎,好好测试代码的可靠性,我很少使用)

package com.cosic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @desc:增量项目更新
 * @author fengbin
 *
 */
public class CodeUpdate {
    
    //文件总数
    private static int fileCount=0;
    //新增总数
    private static int addCount=0;
    //修改总数
    private static int updateCount=0;
    //项目路径
    private static String newpath="";
    //文件备份
    private static String backPath="";
    
    private static String time="";
    
    /**
     * @desc:复制文件
     * @param source
     * @param dest
     * @throws IOException
     */
    public  static void copyFileUsingFileStreams(File source, File dest)throws IOException {    
        InputStream input = null;    
        OutputStream output = null;    
        try {
               input = new FileInputStream(source);
               output = new FileOutputStream(dest);        
               byte[] buf = new byte[1024];        
               int bytesRead; 
               while ((bytesRead = input.read(buf))!=-1) {
                   output.write(buf, 0, bytesRead);
               }
        } finally {
            input.close();
            output.close();
        }
    }
    
    /**
     * @desc  遍历文件夹读取需要更改的文件,先去备份
     * @author fengbin
     * @param path
     * @throws IOException 
     */
    public static void backFiles(String path) throws IOException {
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            if (null==files||files.length==0) {
                System.err.println(file.getAbsolutePath()+"文件夹为空");
                return;
            }else {
                for (int i = 0; i < files.length; i++) {//备份文件
                    File file2 = files[i];
                    if (file2.isDirectory()) {
                        backFiles(file2.getAbsolutePath());
                    }else {
                        String absolutePath = file2.getAbsolutePath();
                        String tempPath = absolutePath.substring(absolutePath.indexOf("defaultroot")+17, absolutePath.length());
                        fileCount = fileCount+1;
                        File newFile = new File(newpath+tempPath);
                        if (newFile.exists()) {//如果原来项目中存在该文件需要备份
                            //新建备份文件
                            File backFile = new File(backPath+tempPath);
                            updateCount=updateCount+1;
                            if(!backFile.exists()) {
                                /*getParentFile返回此抽象路径名的父路径名的抽象路径名,如果直接使用f.mkdirs则会将234.txt也创建成目录*/
                                backFile.getParentFile().mkdirs();
                                backFile.createNewFile();
                            }
                            System.out.println("备份文件:"+newpath+tempPath);
                            copyFileUsingFileStreams(newFile,backFile);
                        }        
                    }
                }
            }
            
        }
    }
    /**
     * @desc  更新文件
     * @author fengbin
     * @param path
     * @throws IOException 
     */
    public static void updateFiles(String path) throws IOException {
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            if (null==files||files.length==0) {
                System.err.println(file.getAbsolutePath()+"文件夹为空");
                return;
            }else {
                for (int i = 0; i < files.length; i++) {//更新文件
                    File file2 = files[i];
                    if (file2.isDirectory()) {
                        updateFiles(file2.getAbsolutePath());
                    }else {
                        String absolutePath = file2.getAbsolutePath();
                        String tempPath = absolutePath.substring(absolutePath.indexOf("defaultroot")+17, absolutePath.length());
                        File newFile = new File(newpath+tempPath);
                        if(!newFile.exists()) {
                            /*getParentFile返回此抽象路径名的父路径名的抽象路径名,如果直接使用f.mkdirs则会将234.txt也创建成目录*/
                            newFile.getParentFile().mkdirs();
                            newFile.createNewFile();
                        }
                        System.err.println("更新文件:"+newpath+tempPath);
                        copyFileUsingFileStreams(file2,newFile);
                    }
                }
            }
            
        }
    }
    
    
    public static void main(String[] args) throws IOException {
        String  path = "C:\\Users\\j01054941\\Desktop\\code\\defaultrootUpdate";
        if (!path.endsWith("defaultrootUpdate")) {
            System.err.println("参数1必须以defaultrootUpdate结尾。。。");
            return;
        }
        if (args.length<2) {
            System.err.println("缺少执行参数:参数1:变更文件目录绝对路径 参数2:项目的绝对路径");
            System.err.println("执行eg: java -jar C:\\Users\\j01054941\\Desktop\\code\\defaultrootUpdate C:\\Users\\j01054941\\Desktop\\code\\defaultroot");
            return;
        }
        newpath = "C:\\Users\\j01054941\\Desktop\\code\\defaultroot";
        path = args[0];
        newpath=args[1];
        time=getTime();
        System.out.println("备份时间:"+time);
        backPath=newpath+"_back"+time;
        backFiles(path);
        System.out.println("---------------更新文件-------------------");
        updateFiles(path);
        System.out.println("---------------更新文件结束---------------");
        addCount=fileCount-updateCount;
        System.out.println("变更文件个数:"+fileCount+";修改文件个数:"+updateCount+";新增文件个数:"+addCount);
    }
    
    public static String getTime() {
        Date date =new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-hhmmss");
        String format = df.format(date);
        return format;
    }
    
}
 


svn.json

{
"svn":{
"A":"新增",
"C":"冲突",
"D":"删除",
"M":"修改",
"G":"本地文件修改并且和服务器合并",
"U":"从服务器更新 ",
"R":"从服务器替换",
"I":"忽略"
}
}


svn模板:

序号 所属系统 变更形式 变更文件
1 KJWOA 修改 defaultroot/htoa/_config/hbm/htoa/allot/HtoaDocAllotNumber.hbm.xml
2 KJWOA 修改 defaultroot/htoa/_config/web/htoa/allot/HtoaDocAllotNumber.biz.xml
3 KJWOA 修改 defaultroot/htoa/_config/web/htoa/allot/HtoaDocNumSequence.biz.xml
4 KJWOA 修改 defaultroot/WEB-INF/classes/htoa/allot/HtoaDocAllotNumber.class
5 KJWOA 修改 defaultroot/htoa/_config/ds/orm/htoa/allot/HtoaDocAllotNumber.meta.xml

 

抽取包成功的样子:

代码变更维护(SVN+Java)-代码增量上线

代码变更维护(SVN+Java)-代码增量上线

代码变更维护(SVN+Java)-代码增量上线

相关文章:

  • 2022-12-23
  • 2022-01-01
  • 2021-11-29
  • 2021-11-29
  • 2021-08-29
猜你喜欢
  • 2021-04-06
  • 2021-07-05
  • 2021-05-02
  • 2021-10-29
  • 2021-12-18
相关资源
相似解决方案