通過gitlab Api自動下載gitLab上的所有項目
背景
現在越來越多的公司採用gitlab來管理代碼。但是公司越來越大,項目越來越多,一個個clone比較麻煩,於是寫個java程序批量clone
思路
gitlab有提供api來獲取git數據,利用這些信息clone項目
參考文檔:https://docs.gitlab.com/ee/api/projects.html#list-all-projects
步驟:
1、申請gitlab token
進入gitlab Settings頁面, 點擊Access Tokens標籤
2 、實現邏輯
-
1、通過API獲取分組列表
-
2、遍歷分組列表
-
3、通過指定分組名稱獲取項目列表
-
4、遍歷項目列表
-
5、通過指定項目ID獲取最近修改的分支名稱
-
6、克隆指定分支的項目到指定目錄
核心代碼如下
/**
* 通過gitlab Api自動下載gitLab上的所有項目
*/
@Service
public class GitlabProjectCloneService {
@Value("${git.gitlabUrl}")
private String gitlabUrl;
@Value("${git.privateToken}")
private String privateToken;
@Value("${git.projectDir}")
private String projectDir;
ObjectMapper objectMapper = new ObjectMapper();
@Autowired
RestTemplate restTemplate;
@PostConstruct
private void start() {
File execDir = new File(projectDir);
System.out.println("start get gitlab projects");
List<GitGroup> groups = getGroups();
try {
System.out.println(objectMapper.writeValueAsString(groups));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
for (GitGroup group : groups) {
List<GitProject> projects = getProjectsByGroup(group.getName());
for (GitProject project : projects) {
String lastActivityBranchName = getLastActivityBranchName(project.getId());
if (StringUtils.isEmpty(lastActivityBranchName)) {
System.out.println("branches is empty, break project...");
continue;
}
clone(lastActivityBranchName, project, execDir);
}
}
System.out.println("end get gitlab projects");
}
/**
* 獲取所有項目
*
* @return
*/
private List<GitProject> getAllProjects() {
String url = gitlabUrl + "/api/v3/projects?per_page={per_page}&private_token={private_token}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("per_page", "100");
uriVariables.put("private_token", privateToken);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity<>(headers);
ParameterizedTypeReference<List<GitProject>> responseType = new ParameterizedTypeReference<List<GitProject>>() {
};
ResponseEntity<List<GitProject>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
if (HttpStatus.OK == responseEntity.getStatusCode()) {
return responseEntity.getBody();
}
return null;
}
/**
* 獲取指定分組下的項目
*
* @param group
* @return
*/
private List<GitProject> getProjectsByGroup(String group) {
String url = gitlabUrl + "/api/v3/groups/{group}/projects?per_page={per_page}&private_token={private_token}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("group", group);
uriVariables.put("per_page", "100");
uriVariables.put("private_token", privateToken);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity<>(headers);
ParameterizedTypeReference<List<GitProject>> responseType = new ParameterizedTypeReference<List<GitProject>>() {
};
ResponseEntity<List<GitProject>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
if (HttpStatus.OK == responseEntity.getStatusCode()) {
return responseEntity.getBody();
}
return null;
}
/**
* 獲取分組列表
*
* @return
*/
private List<GitGroup> getGroups() {
String url = gitlabUrl + "/api/v3/groups?private_token={private_token}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("private_token", privateToken);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity<>(headers);
ParameterizedTypeReference<List<GitGroup>> responseType = new ParameterizedTypeReference<List<GitGroup>>() {
};
ResponseEntity<List<GitGroup>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
if (HttpStatus.OK == responseEntity.getStatusCode()) {
return responseEntity.getBody();
}
return null;
}
/**
* 獲取最近修改的分支名稱
*
* @param projectId 項目ID
* @return
*/
private String getLastActivityBranchName(Long projectId) {
List<GitBranch> branches = getBranches(projectId);
if (CollectionUtils.isEmpty(branches)) {
return "";
}
GitBranch gitBranch = getLastActivityBranch(branches);
return gitBranch.getName();
}
/**
* 獲取指定項目的分支列表
* https://docs.gitlab.com/ee/api/branches.html#branches-api
*
* @param projectId 項目ID
* @return
*/
private List<GitBranch> getBranches(Long projectId) {
String url = gitlabUrl + "/api/v3/projects/{projectId}/repository/branches?private_token={privateToken}";
Map<String, Object> uriVariables = new HashMap<>();
uriVariables.put("projectId", projectId);
uriVariables.put("privateToken", privateToken);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity<>(headers);
ParameterizedTypeReference<List<GitBranch>> responseType = new ParameterizedTypeReference<List<GitBranch>>() {
};
ResponseEntity<List<GitBranch>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
if (HttpStatus.OK == responseEntity.getStatusCode()) {
return responseEntity.getBody();
}
return null;
}
/**
* 獲取最近修改的分支
*
* @param gitBranches 分支列表
* @return
*/
private GitBranch getLastActivityBranch(final List<GitBranch> gitBranches) {
GitBranch lastActivityBranch = gitBranches.get(0);
for (GitBranch gitBranch : gitBranches) {
if (gitBranch.getCommit().getCommittedDate().getTime() > lastActivityBranch.getCommit().getCommittedDate().getTime()) {
lastActivityBranch = gitBranch;
}
}
return lastActivityBranch;
}
private void clone(String branchName, GitProject gitProject, File execDir) {
String command = String.format("git clone -b %s %s %s", branchName, gitProject.getHttpUrlToRepo(), gitProject.getPathWithNamespace());
System.out.println("start exec command : " + command);
try {
Process exec = Runtime.getRuntime().exec(command, null, execDir);
exec.waitFor();
String successResult = inputStreamToString(exec.getInputStream());
String errorResult = inputStreamToString(exec.getErrorStream());
System.out.println("successResult: " + successResult);
System.out.println("errorResult: " + errorResult);
System.out.println("================================");
} catch (Exception e) {
e.printStackTrace();
}
}
private String inputStreamToString(final InputStream input) {
StringBuilder result = new StringBuilder();
Reader reader = new InputStreamReader(input);
BufferedReader bf = new BufferedReader(reader);
String line;
try {
while ((line = bf.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
}
代碼github地址:https://github.com/huchao1009/gitlab-projects-clone