1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.api;
44
45 import java.io.File;
46 import java.io.IOException;
47 import java.text.MessageFormat;
48
49 import org.eclipse.jgit.api.errors.GitAPIException;
50 import org.eclipse.jgit.api.errors.JGitInternalException;
51 import org.eclipse.jgit.api.errors.NoFilepatternException;
52 import org.eclipse.jgit.errors.ConfigInvalidException;
53 import org.eclipse.jgit.internal.JGitText;
54 import org.eclipse.jgit.internal.submodule.SubmoduleValidator;
55 import org.eclipse.jgit.lib.ConfigConstants;
56 import org.eclipse.jgit.lib.Constants;
57 import org.eclipse.jgit.lib.NullProgressMonitor;
58 import org.eclipse.jgit.lib.ProgressMonitor;
59 import org.eclipse.jgit.lib.Repository;
60 import org.eclipse.jgit.lib.StoredConfig;
61 import org.eclipse.jgit.storage.file.FileBasedConfig;
62 import org.eclipse.jgit.submodule.SubmoduleWalk;
63 import org.eclipse.jgit.treewalk.filter.PathFilter;
64 import org.eclipse.jgit.treewalk.filter.TreeFilter;
65
66
67
68
69
70
71
72
73
74
75
76
77 public class SubmoduleAddCommand extends
78 TransportCommand<SubmoduleAddCommand, Repository> {
79
80 private String path;
81
82 private String uri;
83
84 private ProgressMonitor monitor;
85
86
87
88
89
90
91
92 public SubmoduleAddCommand(final Repository repo) {
93 super(repo);
94 }
95
96
97
98
99
100
101
102
103 public SubmoduleAddCommand setPath(final String path) {
104 this.path = path;
105 return this;
106 }
107
108
109
110
111
112
113
114
115 public SubmoduleAddCommand setURI(final String uri) {
116 this.uri = uri;
117 return this;
118 }
119
120
121
122
123
124
125
126
127
128
129 public SubmoduleAddCommand setProgressMonitor(final ProgressMonitor monitor) {
130 this.monitor = monitor;
131 return this;
132 }
133
134
135
136
137
138
139
140 protected boolean submoduleExists() throws IOException {
141 TreeFilter filter = PathFilter.create(path);
142 try (SubmoduleWalk w = SubmoduleWalk.forIndex(repo)) {
143 return w.setFilter(filter).next();
144 }
145 }
146
147
148
149
150
151
152
153
154
155
156
157 @Override
158 public Repository call() throws GitAPIException {
159 checkCallable();
160 if (path == null || path.length() == 0)
161 throw new IllegalArgumentException(JGitText.get().pathNotConfigured);
162 if (uri == null || uri.length() == 0)
163 throw new IllegalArgumentException(JGitText.get().uriNotConfigured);
164
165 try {
166 SubmoduleValidator.assertValidSubmoduleName(path);
167 SubmoduleValidator.assertValidSubmodulePath(path);
168 SubmoduleValidator.assertValidSubmoduleUri(uri);
169 } catch (SubmoduleValidator.SubmoduleValidationException e) {
170 throw new IllegalArgumentException(e.getMessage());
171 }
172
173 try {
174 if (submoduleExists())
175 throw new JGitInternalException(MessageFormat.format(
176 JGitText.get().submoduleExists, path));
177 } catch (IOException e) {
178 throw new JGitInternalException(e.getMessage(), e);
179 }
180
181 final String resolvedUri;
182 try {
183 resolvedUri = SubmoduleWalk.getSubmoduleRemoteUrl(repo, uri);
184 } catch (IOException e) {
185 throw new JGitInternalException(e.getMessage(), e);
186 }
187
188 File moduleDirectory = SubmoduleWalk.getSubmoduleDirectory(repo, path);
189 CloneCommand clone = Git.cloneRepository();
190 configure(clone);
191 clone.setDirectory(moduleDirectory);
192 clone.setGitDir(new File(new File(repo.getDirectory(),
193 Constants.MODULES), path));
194 clone.setURI(resolvedUri);
195 if (monitor != null)
196 clone.setProgressMonitor(monitor);
197 Repository subRepo = null;
198 try (Git git = clone.call()) {
199 subRepo = git.getRepository();
200 subRepo.incrementOpen();
201 }
202
203
204 StoredConfig config = repo.getConfig();
205 config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
206 ConfigConstants.CONFIG_KEY_URL, resolvedUri);
207 try {
208 config.save();
209 } catch (IOException e) {
210 throw new JGitInternalException(e.getMessage(), e);
211 }
212
213
214 FileBasedConfig modulesConfig = new FileBasedConfig(new File(
215 repo.getWorkTree(), Constants.DOT_GIT_MODULES), repo.getFS());
216 try {
217 modulesConfig.load();
218 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
219 path, ConfigConstants.CONFIG_KEY_PATH, path);
220 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
221 path, ConfigConstants.CONFIG_KEY_URL, uri);
222 modulesConfig.save();
223 } catch (IOException e) {
224 throw new JGitInternalException(e.getMessage(), e);
225 } catch (ConfigInvalidException e) {
226 throw new JGitInternalException(e.getMessage(), e);
227 }
228
229 AddCommand add = new AddCommand(repo);
230
231 add.addFilepattern(Constants.DOT_GIT_MODULES);
232
233 add.addFilepattern(path);
234 try {
235 add.call();
236 } catch (NoFilepatternException e) {
237 throw new JGitInternalException(e.getMessage(), e);
238 }
239
240 return subRepo;
241 }
242 }