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.lib.ConfigConstants;
55 import org.eclipse.jgit.lib.Constants;
56 import org.eclipse.jgit.lib.NullProgressMonitor;
57 import org.eclipse.jgit.lib.ProgressMonitor;
58 import org.eclipse.jgit.lib.Repository;
59 import org.eclipse.jgit.lib.StoredConfig;
60 import org.eclipse.jgit.storage.file.FileBasedConfig;
61 import org.eclipse.jgit.submodule.SubmoduleWalk;
62 import org.eclipse.jgit.treewalk.filter.PathFilter;
63 import org.eclipse.jgit.treewalk.filter.TreeFilter;
64
65
66
67
68
69
70
71
72
73
74
75
76 public class SubmoduleAddCommand extends
77 TransportCommand<SubmoduleAddCommand, Repository> {
78
79 private String path;
80
81 private String uri;
82
83 private ProgressMonitor monitor;
84
85
86
87
88 public SubmoduleAddCommand(final Repository repo) {
89 super(repo);
90 }
91
92
93
94
95
96
97
98
99 public SubmoduleAddCommand setPath(final String path) {
100 this.path = path;
101 return this;
102 }
103
104
105
106
107
108
109
110 public SubmoduleAddCommand setURI(final String uri) {
111 this.uri = uri;
112 return this;
113 }
114
115
116
117
118
119
120
121
122
123 public SubmoduleAddCommand setProgressMonitor(final ProgressMonitor monitor) {
124 this.monitor = monitor;
125 return this;
126 }
127
128
129
130
131
132
133
134 protected boolean submoduleExists() throws IOException {
135 TreeFilter filter = PathFilter.create(path);
136 return SubmoduleWalk.forIndex(repo).setFilter(filter).next();
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public Repository call() throws GitAPIException {
151 checkCallable();
152 if (path == null || path.length() == 0)
153 throw new IllegalArgumentException(JGitText.get().pathNotConfigured);
154 if (uri == null || uri.length() == 0)
155 throw new IllegalArgumentException(JGitText.get().uriNotConfigured);
156
157 try {
158 if (submoduleExists())
159 throw new JGitInternalException(MessageFormat.format(
160 JGitText.get().submoduleExists, path));
161 } catch (IOException e) {
162 throw new JGitInternalException(e.getMessage(), e);
163 }
164
165 final String resolvedUri;
166 try {
167 resolvedUri = SubmoduleWalk.getSubmoduleRemoteUrl(repo, uri);
168 } catch (IOException e) {
169 throw new JGitInternalException(e.getMessage(), e);
170 }
171
172 File moduleDirectory = SubmoduleWalk.getSubmoduleDirectory(repo, path);
173 CloneCommand clone = Git.cloneRepository();
174 configure(clone);
175 clone.setDirectory(moduleDirectory);
176 clone.setURI(resolvedUri);
177 if (monitor != null)
178 clone.setProgressMonitor(monitor);
179 Repository subRepo = clone.call().getRepository();
180
181
182 StoredConfig config = repo.getConfig();
183 config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
184 ConfigConstants.CONFIG_KEY_URL, resolvedUri);
185 try {
186 config.save();
187 } catch (IOException e) {
188 throw new JGitInternalException(e.getMessage(), e);
189 }
190
191
192 FileBasedConfig modulesConfig = new FileBasedConfig(new File(
193 repo.getWorkTree(), Constants.DOT_GIT_MODULES), repo.getFS());
194 try {
195 modulesConfig.load();
196 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
197 path, ConfigConstants.CONFIG_KEY_PATH, path);
198 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
199 path, ConfigConstants.CONFIG_KEY_URL, uri);
200 modulesConfig.save();
201 } catch (IOException e) {
202 throw new JGitInternalException(e.getMessage(), e);
203 } catch (ConfigInvalidException e) {
204 throw new JGitInternalException(e.getMessage(), e);
205 }
206
207 AddCommand add = new AddCommand(repo);
208
209 add.addFilepattern(Constants.DOT_GIT_MODULES);
210
211 add.addFilepattern(path);
212 try {
213 add.call();
214 } catch (NoFilepatternException e) {
215 throw new JGitInternalException(e.getMessage(), e);
216 }
217
218 return subRepo;
219 }
220 }