通用技术 简易接口定位(三)

大林 · 2022年12月26日 · 2955 次阅读

前面的对比数据源已经弄好了,接下来就是具体操作流程。

流程如下

1、项目选择

2、开发分支选择

3、选择 svn 的版本

4、对比后显示变更影响的接口

1-3 的项目分支和 svn 版本具体实现如下,4 在后面的章节具体说明

项目选择

实现逻辑:简单的新增和列表显示功能

  public Response insertSelective(Project record) {
      ProjectMapper.insertSelective(record);
      return Response.success();
  }

public Response selectProjectGroup(int page, int limit, String search) {
      PageHelper.startPage(page, limit);
      List<Project> list = projectMapper.selectProjectGroup(search);
      return Response.success(list);
  }

项目 svn 分支

实现逻辑:根据远程仓库路径,新增分支、解析分支名称、同步分支代码 (svn 命令)
新增分支

分支列表

public Response insertSelective(ProjectSubversion record) {
    String svnStore = record.getSvnStore();
    int projectId = record.getProjectId();
    int len = svnStore.split("/").length;
    String svnName = svnStore.split("/")[len - 1];//解析分支名称
    record.setSvnName(svnName);
    ProjectSubversionExample ps = new ProjectSubversionExample();
    ps.createCriteria().andProjectIdEqualTo(projectId).andSvnNameEqualTo(svnName);
    if (projectSubversionMapper.selectOneByExample(ps) != null) {
        return Response.error("svn版本已存在");
    }
    String projectname = projectMapper.selectByPrimaryKey(projectId).getName();
    String res = commandService.executeCmd("cd " + testSvnPath + "&&mkdir " + projectname); //创建目录
    String res2 = commandService.executeCmd("cd " + testSvnPath + projectname + "&&svn co " + svnStore); //同步分支代码
    if (res2.contains("exec cmd error")) {
        return Response.error(res2);
    }
    record.setCreateTime(LocalDateTime.now());
    record.setSvnLocalPath(testSvnPath + projectname + File.separator + svnName);
    projectSubversionMapper.insertSelective(record);
    return Response.success();
}
public Response selectSvnByProjectId(int projectId) {
    List<ProjectSubversion> list = projectSubversionMapper.selectSvnByProjectId(projectId);
    return Response.success(list);
}

svn 的版本

实现逻辑:更新分支 svn 代码 (svn 命令),获取最近 20 条记录并解析 (svn 命令),前端展示

public Response selectSvnLog(int projectId, String svnName) throws IOException {
        String projectname = projectMapper.selectByPrimaryKey(projectId).getName();
        String command = "cd " + testSvnPath + projectname + File.separator + svnName + "&&svn update";
        log.info(command);
        String res1 = commandService.executeCmd("cd " + testSvnPath + projectname + File.separator + svnName + "&&svn update");
        if (res1.contains("error")) {
            return null;
        }
        String res = commandService.executeCmd("cd " + testSvnPath + projectname + File.separator + svnName + "&&svn log -v -l 20");//获取最近20条记录
        log.info(res);
        if (res.contains("exec cmd error")) {
            return Response.error(res);
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(res.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
        String line;
        List<LogBean> listLog = new ArrayList<>();
        int index = -1;
        while ((line = br.readLine()) != null) {
            if (line.trim().contains(" 行") || line.trim().contains(" line")) {
                index++;
                LogBean log = new LogBean();
                String logNum = line.split("\\|")[0].split("r")[1].trim();//每行可以做加工
                String logTime = line.split("\\+")[0].split("\\|", 3)[2].trim();
                log.setLogNum(Integer.parseInt(logNum));
                log.setLogTime(logTime);

                listLog.add(log);
            }
            if (line.trim().length() != 0) {
                if (line.trim().substring(0, 1).equals("A")) {
                    LogFile logfile = new LogFile();
                    logfile.setFile(line.trim());
                    logfile.setType(1);
                    LogBean nlogBean = listLog.get(index);
                    List<LogFile> logFiles = nlogBean.getLogfiles();
                    if (logFiles == null) {
                        logFiles = new ArrayList<>();
                    }
                    logFiles.add(logfile);
                    nlogBean.setLogfiles(logFiles);
                    listLog.set(index, nlogBean);
                    continue;
                }
                if (line.trim().substring(0, 1).equals("M")) {
                    LogFile logfile = new LogFile();
                    logfile.setFile(line.trim());
                    logfile.setType(2);
                    LogBean nlogBean = listLog.get(index);
                    List<LogFile> logFiles = nlogBean.getLogfiles();
                    if (logFiles == null) {
                        logFiles = new ArrayList<>();
                    }
                    logFiles.add(logfile);
                    nlogBean.setLogfiles(logFiles);
                    listLog.set(index, nlogBean);
                    continue;
                }
                if (line.trim().substring(0, 1).equals("D")) {
                    LogFile logfile = new LogFile();
                    logfile.setFile(line.trim());
                    logfile.setType(3);
                    LogBean nlogBean = listLog.get(index);
                    List<LogFile> logFiles = nlogBean.getLogfiles();
                    if (logFiles == null) {
                        logFiles = new ArrayList<>();
                    }
                    logFiles.add(logfile);
                    nlogBean.setLogfiles(logFiles);
                    listLog.set(index, nlogBean);
                }
            }

        }
        return Response.success(listLog);
    }

后续重点说明如何进行修改文件的对比!

附:java 执行 svn 命令工具代码

package com.jp.core.tools.shell;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author wl
 */
@Slf4j
@Service
public class CommandServiceImpl implements CommandService, InitializingBean {
    @Value("${cmd.threadname:cmd-executor}")
    private String threadName;

    @Value("${cmd.taskQueueMaxStorage:20}")
    private Integer taskQueueMaxStorage;

    @Value("${cmd.corePoolSize:4}")
    private Integer corePoolSize;

    @Value("${cmd.maximumPoolSize:8}")
    private Integer maximumPoolSize;

    @Value("${cmd.keepAliveSeconds:15}")
    private Integer keepAliveSeconds;
    private ThreadPoolExecutor executor;
    private static final String BASH = "sh";
    private static final String BASH_PARAM = "-c";
    private static final String BASH_win = "cmd.exe";
    private static final String BASH_PARAM_win = "/c";

    // use thread pool to read streams
    @Override
    public void afterPropertiesSet() {
        executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveSeconds, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(taskQueueMaxStorage),
                new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        return new Thread(r, threadName + r.hashCode());
                    }
                },
                new ThreadPoolExecutor.AbortPolicy());
    }

    @Override
    public String executeCmd(String cmd) {
        boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
        Process p = null;
        String res;
        log.debug("CommandService cmd info : {}", cmd);
        try {
            // need to pass command as bash's param,
            // so that we can compatible with commands: "echo a >> b.txt" or "bash a && bash b"
            List<String> cmds = new ArrayList<>();
            if(isWindows){
                cmds.add(BASH_win);
                cmds.add(BASH_PARAM_win);
            }
            else{
                cmds.add(BASH);
                cmds.add(BASH_PARAM);
            }
            cmds.add(cmd);
            ProcessBuilder pb = new ProcessBuilder(cmds);
            p = pb.start();
            Future<String> errorFuture = executor.submit(new ReadTask(p.getErrorStream()));
            Future<String> resFuture = executor.submit(new ReadTask(p.getInputStream()));
            int exitValue = p.waitFor();
            if (exitValue > 0) {
                log.info("exec cmd error: {} ", errorFuture.get());
                res = "exec cmd error:"+errorFuture.get();
                //throw new RuntimeException(errorFuture.get());
            } else {
                res = resFuture.get();
            }
        } catch (Exception e) {
            log.info("exec cmd error: {} ", e.getMessage());
            res = "exec cmd error:"+e.getMessage();
            //throw new RuntimeException(e);
        } finally {
            if (p != null) {
                p.destroy();
            }
        }
        // remove System.lineSeparator() (actually it's '\n') in the end of res if exists
        if (StringUtils.isNotBlank(res) && res.endsWith(System.lineSeparator())) {
            res = res.substring(0, res.lastIndexOf(System.lineSeparator()));
        }
        return res;
    }

    class ReadTask implements Callable<String> {
        InputStream is;

        ReadTask(InputStream is) {
            this.is = is;
        }

        @Override
        public String call() throws Exception {
            BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n"); //这里加\n,就是正常的按行输出
            }
            return sb.toString();
        }
    }
}


暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册