1 package org.cyclopsgroup.gitcon.jgit;
2
3 import java.io.File;
4 import java.io.IOException;
5 import org.apache.commons.io.FileUtils;
6 import org.apache.commons.lang.StringUtils;
7 import org.apache.commons.lang.SystemUtils;
8 import org.apache.commons.lang.Validate;
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.cyclopsgroup.gitcon.FileSystemSource;
12 import org.eclipse.jgit.api.CloneCommand;
13 import org.eclipse.jgit.api.Git;
14 import org.eclipse.jgit.api.PullResult;
15 import org.eclipse.jgit.api.errors.GitAPIException;
16 import org.eclipse.jgit.lib.Ref;
17 import org.eclipse.jgit.transport.CredentialsProvider;
18 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class JGitSource implements FileSystemSource {
42 private static final Log LOG = LogFactory.getLog(JGitSource.class);
43
44 private volatile String branchOrCommit;
45
46 private String sshIdentity;
47
48 private Boolean buildInSshIdentityUsed;
49
50 private CredentialsProvider credentialsProvider;
51
52 private JGitCallExecutor executor;
53
54 private Git git;
55
56 private final String repoUri;
57
58
59
60
61
62
63 public JGitSource(String repoUri) {
64 Validate.notNull(repoUri, "Git repository URI can not be NULL");
65 this.repoUri = repoUri;
66 }
67
68 public String getBranchOrCommmit() {
69 return branchOrCommit;
70 }
71
72 @Override
73 public File initWorkingDirectory(File workingDirectory) throws GitAPIException, IOException {
74
75 File sourceDirectory =
76 new File(workingDirectory.getAbsolutePath() + SystemUtils.FILE_SEPARATOR + "gitrepo");
77 if (sourceDirectory.mkdirs()) {
78 LOG.info("Created GIT repo directory " + sourceDirectory);
79 }
80
81
82 File sshKey = null;
83 if (buildInSshIdentityUsed == Boolean.TRUE
84 || StringUtils.equalsIgnoreCase(sshIdentity, "buildin")) {
85 sshKey =
86 new File(
87 workingDirectory.getAbsolutePath()
88 + SystemUtils.FILE_SEPARATOR
89 + "gitconreader-ssh.key");
90 FileUtils.copyURLToFile(
91 getClass().getClassLoader().getResource("META-INF/gitcon/gitconreader-ssh.key"), sshKey);
92 LOG.info("Build-in SSH private key is copied into " + sshKey);
93
94 } else if (sshIdentity != null && !sshIdentity.equalsIgnoreCase("default")) {
95 sshKey = new File(sshIdentity);
96 LOG.info("About to use specified SSH key " + sshIdentity);
97 } else {
98 LOG.info("Default system SSH key will apply");
99 }
100
101 if (sshKey == null) {
102 executor = JGitCallExecutor.synchronize(JGitCallExecutor.direct());
103 } else if (!sshKey.canRead()) {
104 throw new IllegalStateException(
105 "Configured SSH private key " + sshKey + " is not accessible");
106 } else {
107 executor = JGitCallExecutor.withSshPrivateKey(sshKey.getAbsolutePath());
108 LOG.info("JGit executor is set with build-in SSH key " + sshKey);
109 }
110
111
112 final CloneCommand clone = Git.cloneRepository().setDirectory(sourceDirectory).setURI(repoUri);
113 if (credentialsProvider != null) {
114 clone.setCredentialsProvider(credentialsProvider);
115 }
116 LOG.info("Running git clone " + repoUri + " against " + sourceDirectory);
117 git = executor.invokeCall(clone::call);
118
119
120 if (branchOrCommit != null) {
121 LOG.info("Calling git checkout " + branchOrCommit + " ...");
122 Ref result = executor.invokeCall(() -> git.checkout().setName(branchOrCommit).call());
123 LOG.info("Git checkout returned " + result);
124 }
125 return sourceDirectory;
126 }
127
128
129
130
131
132
133
134
135 public void setBranchOrCommit(String branch) {
136 this.branchOrCommit = branch;
137 }
138
139
140
141
142
143
144
145 public void setBuildInSshIdentityUsed(boolean buildInSshIdentityUsed) {
146 this.buildInSshIdentityUsed = buildInSshIdentityUsed;
147 }
148
149
150
151
152
153
154
155
156
157
158 public void setSshIdentity(String privateKeyPath) {
159 this.sshIdentity = privateKeyPath;
160 }
161
162
163
164
165
166
167
168 public void setSshIdentityFile(File privateKeyFile) {
169 setSshIdentity(privateKeyFile == null ? null : privateKeyFile.getAbsolutePath());
170 }
171
172
173
174
175
176
177
178 public void setUserPassword(String userAndPassword) {
179 int position = userAndPassword.indexOf(':');
180 Validate.isTrue(
181 position > 0 && position < userAndPassword.length() - 1,
182 "Input must be <username>:<password>, but it is " + userAndPassword);
183 setUserPassword(
184 userAndPassword.substring(0, position), userAndPassword.substring(position + 1));
185 }
186
187
188
189
190
191
192
193
194 public void setUserPassword(String user, String password) {
195 Validate.notNull(user, "User name must be supplied");
196 Validate.notNull(password, "Password must be supplied");
197
198 if (credentialsProvider != null) {
199 throw new IllegalStateException(
200 "Credentials provider can only be set for once. It's already " + credentialsProvider);
201 }
202
203 this.credentialsProvider = new UsernamePasswordCredentialsProvider(user, password);
204 LOG.info("Credentials provider is set to user/password instance");
205 }
206
207
208
209
210
211
212 @Override
213 public void updateWorkingDirectory(File workingDirectory) throws GitAPIException {
214 LOG.info("Running a git pull command ... ");
215 PullResult result = executor.invokeCall(() -> git.pull().call());
216 LOG.info("Pull command returned " + result);
217 }
218 }