美文网首页
java通过代码实现创建项目,提交项目等功能

java通过代码实现创建项目,提交项目等功能

作者: 唯有努力不欺人丶 | 来源:发表于2023-09-24 11:16 被阅读0次

    ps:首先要讲一下前提。用的是gitlab。然后因为需求原因,希望实现的是用户的某个操作自动创建一个git的工作空间,然后用户可以配置一些东西,会用代码的形式以文件的形式push到git。最终可以通过某种方式直接将这个项目再k8s中运行起来。
    另外希望可以将git项目中的文件和最后修改时间以列表的形式返回(因为有些人不想给git权限,但是给提供查看文件更新时间的功能)。

    我负责的是简单的创建项目和push,展示文件列表。因为其实这个功能不是很常见,所以写的时候没有拿来主义,自己调试了好久,所以这里简单记录下:
    一共分为三个接口:
    create空git项目
    push项目
    拉取项目所有文件并获取最后修改时间

    假设我有了有权限的token,申请方式是这样的:
    注意一点,不是在git中可以crud就是有权限,可能git页面和接口的权限是不一样的,所以要在接口中有这个setting的账号申请的token才生效。


    有权限的账号

    然后有了token以后,进行创建(注意projectName是要创建的名称,apiUrl 是git地址,namespace_id是想要创建的目录的id):

        private static String token = "xx";
        public static void createProject(String projectName){
            try {
                HttpClient httpClient = HttpClients.createDefault();
                // 构建 API 请求 URL
                String apiUrl = "https://gitlab.xx.xxx.com/api/v4/projects";
                // 构建请求体 JSON 数据
                String requestBody = "{\"name\": \"" + projectName + "\",\"namespace_id\": 62296}";
    
                // 创建 POST 请求
                HttpPost httpPost = new HttpPost(apiUrl);
                httpPost.setHeader("Content-Type", "application/json");
                httpPost.setHeader("Private-Token", token);
                httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
    
                // 发送请求并获取响应
                HttpResponse response = httpClient.execute(httpPost);
                System.out.println(response);
                HttpEntity entity = response.getEntity();
                // 处理响应
                if (entity != null) {
                    String responseString = entity.toString();
                    System.out.println(responseString);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    

    提交文件:

    public static String createAndAddFileToGitRepo(CamelProjectEntity camelProjectEntity,List<CamelDataEntity> list) {
            try {
                // Clone the Git repository
                File localPath = File.createTempFile("temp-git-repo", "");
                localPath.delete();
                CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider("userName", "password");
                Git git = Git.cloneRepository()
                        .setURI(camelProjectEntity.getGitAddress())
                        .setCredentialsProvider(credentialsProvider)
                        .setDirectory(localPath)
                        .call();
                // Create the file
                for (CamelDataEntity c : list) {
                    String fileName = c.getName()+".yml";
                    String content = c.getYml();
                    // Create the file
                    File file = new File(localPath.getPath() + File.separator + fileName);
                    FileWriter writer = new FileWriter(file);
                    writer.write(content);
                    writer.close();
                    // Add the file to the Git repository
                    git.add()
                            .addFilepattern(fileName)
                            .call();
                }
                // Commit the changes
                git.commit()
                        .setMessage("Add files")
                        .call();
    
                // Push the changes to the remote repository
                git.push()
                        .setCredentialsProvider(credentialsProvider)
                        .call();
                // Clean up
                git.close();
                localPath.deleteOnExit();
                return "推送成功";
            }catch (Exception e){
                e.printStackTrace();
                return "推送失败";
            }
    
        }
    

    最后一个方法比较麻烦,我直接附上完整的代码:

    package com.lenovo.common.utils;
    
    import org.eclipse.jgit.api.Git;
    import org.eclipse.jgit.api.errors.GitAPIException;
    import org.eclipse.jgit.diff.DiffEntry;
    import org.eclipse.jgit.diff.DiffFormatter;
    import org.eclipse.jgit.lib.Repository;
    import org.eclipse.jgit.lib.RepositoryBuilder;
    import org.eclipse.jgit.revwalk.RevCommit;
    import org.eclipse.jgit.revwalk.RevWalk;
    import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
    import org.eclipse.jgit.util.io.DisabledOutputStream;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    public class GitLastCommitTime {
    
        public static boolean deleteFile(String path) {
            File file = new File(path);
            if (!file.exists()) {
                System.out.println("File or directory does not exist.");
                return false;
            }
            if (file.isDirectory()) {
                // 如果是目录,则递归删除其中的文件和子目录
                File[] files = file.listFiles();
                if (files != null) {
                    for (File subFile : files) {
                        deleteFile(subFile.getAbsolutePath());
                    }
                }
            }
            // 删除文件或空目录
            return file.delete();
        }
    
        public static   Map<String, Object>  git(String gitRepoUrl){
            String username = "username ";
            String password = "password ";
            String name = gitRepoUrl;
            deleteFile(name);
            try (Git git = cloneRepository(gitRepoUrl, username, password)) {
                Repository repo = createRepository(git.getRepository());
                Map<String, Date> fileLastCommitTimeMap = getFileLastCommitTimeMap(repo);
                Iterator<Map.Entry<String, Date>> iterator = fileLastCommitTimeMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Date> entry = iterator.next();
                    if (entry.getKey().contains(".git")) {
                        iterator.remove();
                    }
                }
                Map<String, String> folderContentMap = readFolderContents(name);
                Map<String, Object> res = convertToTree(fileLastCommitTimeMap,name);
                return res;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private static Map<String, String> readFolderContents(String folderPath) {
            Map<String, String> folderContentMap = new HashMap<>();
            File folder = new File(folderPath);
    
            if (!folder.isDirectory()) {
                throw new IllegalArgumentException("Specified path is not a valid folder.");
            }
    
            File[] files = folder.listFiles();
    
            for (File file : files) {
                if (file.isFile() && (file.getName().endsWith("xslt") || file.getName().endsWith("dfdl"))) {
                    try {
                        String content = new String(Files.readAllBytes(file.toPath()));
                        folderContentMap.put(file.getName(), content);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else if (file.isDirectory()) {
                    folderContentMap.putAll(readFolderContents(file.getPath()));
                }
            }
            return folderContentMap;
        }
    
        public static Map<String, Object> convertToTree(Map<String, Date> fileLastModifiedMap,String name) {
            Map<String, Object> root = new HashMap<>();
            root.put("files", new HashMap<>());
            root.put("name", name);
            root.put("subfolders", new ArrayList<>());
    
            for (String filePath : fileLastModifiedMap.keySet()) {
                String[] folders = filePath.split("/");
    
                Map<String, Object> currentNode = root;
                for (int i = 0; i < folders.length - 1; i++) {
                    String folder = folders[i];
                    List<Map<String, Object>> subfolders = (List<Map<String, Object>>) currentNode.get("subfolders");
                    Optional<Map<String, Object>> optionalFolder = subfolders.stream()
                            .filter(f -> f.get("name").equals(folder))
                            .findFirst();
    
                    if (optionalFolder.isPresent()) {
                        currentNode = optionalFolder.get();
                    } else {
                        Map<String, Object> newFolder = new HashMap<>();
                        newFolder.put("files", new HashMap<>());
                        newFolder.put("name", folder);
                        newFolder.put("subfolders", new ArrayList<>());
    
                        subfolders.add(newFolder);
                        currentNode = newFolder;
                    }
                }
    
                String file = folders[folders.length - 1];
                Map<String,String> files = (Map<String,String>) currentNode.get("files");
                files.put(file,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileLastModifiedMap.get(filePath)));
            }
    
            return root;
        }
    
        private static Git cloneRepository(String gitRepoUrl, String username, String password) throws GitAPIException {
            return Git.cloneRepository()
                    .setURI(gitRepoUrl)
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password))
                    .call();
        }
        private static Repository createRepository(org.eclipse.jgit.lib.Repository jGitRepo) throws Exception {
            RepositoryBuilder builder = new RepositoryBuilder();
            builder.setGitDir(jGitRepo.getDirectory());
            builder.readEnvironment();
    
            return builder.build();
        }
    
        private static Map<String, Date> getFileLastCommitTimeMap(Repository repository) throws IOException {
            Map<String, Date> fileLastCommitTimeMap = new HashMap<>();
    
            try {
                org.eclipse.jgit.api.Git git = new org.eclipse.jgit.api.Git(repository);
                RevWalk revWalk = new RevWalk(repository);
                Iterable<RevCommit> commits = git.log().all().call();
    
                for (RevCommit commit : commits) {
                    RevCommit parentCommit = null;
    
                    if (commit.getParentCount() > 0) {
                        parentCommit = revWalk.parseCommit(commit.getParent(0).getId());
                    }
    
                    List<DiffEntry> diffs = getDiffEntries(repository, parentCommit, commit);
    
                    for (DiffEntry diff : diffs) {
                        String filePath = diff.getNewPath();
                        Date lastCommitTime = fileLastCommitTimeMap.getOrDefault(filePath, new Date(0));
                        Date commitTime = new Date(commit.getCommitTime() * 1000L);
    
                        if (commitTime.after(lastCommitTime)) {
                            fileLastCommitTimeMap.put(filePath, commitTime);
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
    
            return fileLastCommitTimeMap;
        }
        private static List<DiffEntry> getDiffEntries(Repository repository, RevCommit parentCommit, RevCommit commit) throws IOException {
            DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE);
            diffFormatter.setRepository(repository);
            diffFormatter.setDetectRenames(true);
    
            return diffFormatter.scan(parentCommit != null ? parentCommit.getTree() : null, commit.getTree());
        }
    
        class FileCommitInfo {
            private String filePath;
            private Date lastCommitTime;
    
            public FileCommitInfo(String filePath, Date lastCommitTime) {
                this.filePath = filePath;
                this.lastCommitTime = lastCommitTime;
            }
    
            public String getFilePath() {
                return filePath;
            }
    
            public Date getLastCommitTime() {
                return lastCommitTime;
            }
        }
    }
    

    最后这个方法因为步骤比较多,我全贴出来修改敏感词的,所以如果跑不通自己调试下就行了

    本篇笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注~

    相关文章

      网友评论

          本文标题:java通过代码实现创建项目,提交项目等功能

          本文链接:https://www.haomeiwen.com/subject/xjuzvdtx.html