-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-63519] Create a better mechanism to detect node-specific git implementations #949
Changes from 8 commits
f921410
719f284
1ceed4d
26eb95e
193b7e5
34093c3
25239d1
43c3094
7bc2b84
cfa0661
2f985e3
c82a734
34a146d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
import hudson.ExtensionList; | ||
import hudson.ExtensionPoint; | ||
import hudson.model.Item; | ||
import hudson.model.Node; | ||
import hudson.model.TaskListener; | ||
import hudson.plugins.git.GitTool; | ||
import hudson.plugins.git.util.GitUtils; | ||
|
@@ -16,6 +17,7 @@ | |
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.logging.Level; | ||
|
@@ -31,6 +33,8 @@ public class GitToolChooser { | |
private long sizeOfRepo = 0L; | ||
private String implementation; | ||
private String gitTool; | ||
private TaskListener listener; | ||
private Node currentNode; | ||
/** | ||
* Size to switch implementation in KiB | ||
*/ | ||
|
@@ -43,17 +47,21 @@ public class GitToolChooser { | |
* @param remoteName the repository url | ||
* @param projectContext the context where repository size is being estimated | ||
* @param credentialsId credential used to access the repository or null if no credential is required | ||
* @param gitExe name of the git tool ('git', 'jgit', 'jgitapache') to be used as the default tool | ||
* @param gitExe Git tool ('git', 'jgit', 'jgitapache') to be used as the default tool | ||
* @param n A Jenkins agent used to check validity of git installation | ||
* @param listener TaskListener required by GitUtils.resolveGitTool() | ||
* @param useJGit if true the JGit is allowed as an implementation | ||
* @throws IOException on error | ||
* @throws InterruptedException on error | ||
*/ | ||
public GitToolChooser(String remoteName, Item projectContext, String credentialsId, String gitExe, Boolean useJGit) throws IOException, InterruptedException { | ||
public GitToolChooser(String remoteName, Item projectContext, String credentialsId, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add javadoc comments for the new parameters. That will resolve the javadoc warnings below and keep the javadoc clean There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
GitTool gitExe, Node n, TaskListener listener, Boolean useJGit) throws IOException, InterruptedException { | ||
boolean useCache = false; | ||
if (useJGit != null) { | ||
JGIT_SUPPORTED = useJGit; | ||
} | ||
|
||
currentNode = n; | ||
this.listener = listener; | ||
implementation = "NONE"; | ||
useCache = decideAndUseCache(remoteName); | ||
|
||
|
@@ -62,7 +70,11 @@ public GitToolChooser(String remoteName, Item projectContext, String credentials | |
} else { | ||
decideAndUseAPI(remoteName, projectContext, credentialsId, gitExe); | ||
} | ||
determineGitTool(implementation, gitExe); | ||
gitTool = implementation; | ||
} | ||
|
||
public void addListener(TaskListener listener) { | ||
this.listener = listener; | ||
} | ||
|
||
/** | ||
|
@@ -88,7 +100,7 @@ private boolean decideAndUseCache(String remoteName) throws IOException, Interru | |
return useCache; | ||
} | ||
|
||
private void decideAndUseAPI(String remoteName, Item context, String credentialsId, String gitExe) { | ||
private void decideAndUseAPI(String remoteName, Item context, String credentialsId, GitTool gitExe) { | ||
if (setSizeFromAPI(remoteName, context, credentialsId)) { | ||
implementation = determineSwitchOnSize(sizeOfRepo, gitExe); | ||
} | ||
|
@@ -126,35 +138,73 @@ private boolean setSizeFromAPI(String repoUrl, Item context, String credentialsI | |
* @param sizeOfRepo: Size of a repository (in KiBs) | ||
* @return a git implementation, "git" or "jgit" | ||
*/ | ||
String determineSwitchOnSize(Long sizeOfRepo, String gitExe) { | ||
String determineSwitchOnSize(Long sizeOfRepo, GitTool tool) { | ||
if (sizeOfRepo != 0L) { | ||
if (sizeOfRepo < SIZE_TO_SWITCH) { | ||
if (!JGIT_SUPPORTED) { | ||
return "NONE"; | ||
} | ||
return determineToolName(gitExe, JGitTool.MAGIC_EXENAME); | ||
GitTool rTool = resolveGitToolForRecommendation(tool, JGitTool.MAGIC_EXENAME); | ||
if (rTool == null) { | ||
return "NONE"; | ||
} | ||
return rTool.getGitExe(); | ||
} else { | ||
return determineToolName(gitExe, "git"); | ||
GitTool rTool = resolveGitToolForRecommendation(tool, "git"); | ||
return rTool.getGitExe(); | ||
} | ||
} | ||
return "NONE"; | ||
} | ||
|
||
/** | ||
* For a given recommended git implementation, validate if the installation exists and provide no suggestion if | ||
* implementation doesn't exist. | ||
* @param gitImplementation: The recommended git implementation, "git" or "jgit" on the basis of the heuristics. | ||
*/ | ||
private void determineGitTool(String gitImplementation, String gitExe) { | ||
if (gitImplementation.equals("NONE")) { | ||
gitTool = "NONE"; | ||
return; // Recommend nothing (GitToolRecommendation = NONE) | ||
private GitTool resolveGitToolForRecommendation(GitTool userChoice, String recommendation) { | ||
GitTool tool; | ||
if (recommendation.equals(JGitTool.MAGIC_EXENAME)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For repository size < 5MiB, the recommendation should be |
||
if (userChoice.getGitExe().equals(JGitApacheTool.MAGIC_EXENAME)) { | ||
recommendation = JGitApacheTool.MAGIC_EXENAME; | ||
} | ||
// check if jgit or jgitapache is enabled | ||
tool = getResolvedGitTool(recommendation); | ||
if (tool.getName().equals(recommendation)) { | ||
return tool; | ||
} else { | ||
return null; | ||
} | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This branch of logic is designed for repo size > 5M.
|
||
if (!userChoice.getName().equals(JGitTool.MAGIC_EXENAME) && !userChoice.getName().equals(JGitApacheTool.MAGIC_EXENAME)) { | ||
return userChoice; | ||
} | ||
else { | ||
return recommendGitToolOnAgent(userChoice); | ||
} | ||
} | ||
final Jenkins jenkins = Jenkins.get(); | ||
GitTool tool = GitUtils.resolveGitTool(gitImplementation, jenkins, null, TaskListener.NULL); | ||
if (tool != null) { | ||
gitTool = tool.getGitExe(); | ||
} | ||
|
||
public GitTool recommendGitToolOnAgent(GitTool userChoice) { | ||
List<GitTool> preferredToolList = new ArrayList<>(); | ||
GitTool correctTool = GitTool.getDefaultInstallation(); | ||
String toolName = userChoice.getName(); | ||
if (toolName.equals(JGitTool.MAGIC_EXENAME) || toolName.equals(JGitApacheTool.MAGIC_EXENAME)) { | ||
GitTool[] toolList = Jenkins.get().getDescriptorByType(GitTool.DescriptorImpl.class).getInstallations(); | ||
for (GitTool tool : toolList) { | ||
if (!tool.getProperties().isEmpty()) { | ||
preferredToolList.add(tool); | ||
} | ||
} | ||
for (GitTool tool: preferredToolList) { | ||
if (tool.getName().equals(getResolvedGitTool(tool.getName()).getName())) { | ||
correctTool = getResolvedGitTool(tool.getName()); | ||
} | ||
} | ||
} | ||
return correctTool; | ||
} | ||
|
||
private GitTool getResolvedGitTool(String recommendation) { | ||
if (currentNode == null) { | ||
currentNode = Jenkins.get(); | ||
} | ||
return GitUtils.resolveGitTool(recommendation, currentNode, null, listener); | ||
} | ||
|
||
/** | ||
|
@@ -165,18 +215,6 @@ public String getGitTool() { | |
return gitTool; | ||
} | ||
|
||
private String determineToolName(String gitExe, String recommendation) { | ||
if (gitExe.contains(recommendation) && !gitExe.equals(JGitTool.MAGIC_EXENAME) && !gitExe.equals(JGitApacheTool.MAGIC_EXENAME)) { | ||
return gitExe; | ||
} | ||
if (!recommendation.equals(gitExe)) { | ||
if (gitExe.equals(JGitApacheTool.MAGIC_EXENAME) && recommendation.equals(JGitTool.MAGIC_EXENAME)) { | ||
return gitExe; | ||
} | ||
} | ||
return recommendation; | ||
} | ||
|
||
/** | ||
* Other plugins can estimate the size of repository using this extension point | ||
* The size is assumed to be in KiBs | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was added to access the
GitTool
chosen by the system instead of the git executable path for GitToolChooser.