ps:首先要講一下前提包蓝。用的是gitlab驶社。然后因?yàn)樾枨笤颍M麑?shí)現(xiàn)的是用戶的某個(gè)操作自動(dòng)創(chuàng)建一個(gè)git的工作空間测萎,然后用戶可以配置一些東西亡电,會(huì)用代碼的形式以文件的形式push到git。最終可以通過某種方式直接將這個(gè)項(xiàng)目再k8s中運(yùn)行起來硅瞧。
另外希望可以將git項(xiàng)目中的文件和最后修改時(shí)間以列表的形式返回(因?yàn)橛行┤瞬幌虢ogit權(quán)限逊抡,但是給提供查看文件更新時(shí)間的功能)。
我負(fù)責(zé)的是簡(jiǎn)單的創(chuàng)建項(xiàng)目和push,展示文件列表冒嫡。因?yàn)槠鋵?shí)這個(gè)功能不是很常見拇勃,所以寫的時(shí)候沒有拿來主義,自己調(diào)試了好久孝凌,所以這里簡(jiǎn)單記錄下:
一共分為三個(gè)接口:
create空git項(xiàng)目
push項(xiàng)目
拉取項(xiàng)目所有文件并獲取最后修改時(shí)間
假設(shè)我有了有權(quán)限的token,申請(qǐng)方式是這樣的:
注意一點(diǎn)方咆,不是在git中可以crud就是有權(quán)限,可能git頁(yè)面和接口的權(quán)限是不一樣的蟀架,所以要在接口中有這個(gè)setting的賬號(hào)申請(qǐng)的token才生效瓣赂。
然后有了token以后,進(jìn)行創(chuàng)建(注意projectName是要?jiǎng)?chuàng)建的名稱片拍,apiUrl 是git地址煌集,namespace_id是想要?jiǎng)?chuàng)建的目錄的id):
private static String token = "xx";
public static void createProject(String projectName){
try {
HttpClient httpClient = HttpClients.createDefault();
// 構(gòu)建 API 請(qǐng)求 URL
String apiUrl = "https://gitlab.xx.xxx.com/api/v4/projects";
// 構(gòu)建請(qǐng)求體 JSON 數(shù)據(jù)
String requestBody = "{\"name\": \"" + projectName + "\",\"namespace_id\": 62296}";
// 創(chuàng)建 POST 請(qǐng)求
HttpPost httpPost = new HttpPost(apiUrl);
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Private-Token", token);
httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
// 發(fā)送請(qǐng)求并獲取響應(yīng)
HttpResponse response = httpClient.execute(httpPost);
System.out.println(response);
HttpEntity entity = response.getEntity();
// 處理響應(yīng)
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 "推送失敗";
}
}
最后一個(gè)方法比較麻煩,我直接附上完整的代碼:
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;
}
}
}
最后這個(gè)方法因?yàn)椴襟E比較多苫纤,我全貼出來修改敏感詞的,所以如果跑不通自己調(diào)試下就行了
本篇筆記就記到這里纲缓,如果稍微幫到你了記得點(diǎn)個(gè)喜歡點(diǎn)個(gè)關(guān)注~