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;
}
}
}
最后这个方法因为步骤比较多,我全贴出来修改敏感词的,所以如果跑不通自己调试下就行了
本篇笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注~