View Javadoc
1   /*
2    * Copyright (C) 2011, GitHub Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  package org.eclipse.jgit.submodule;
44  
45  import static org.junit.Assert.assertEquals;
46  import static org.junit.Assert.assertNotNull;
47  import static org.junit.Assert.assertTrue;
48  import static org.junit.Assert.fail;
49  
50  import java.io.File;
51  import java.text.MessageFormat;
52  
53  import org.eclipse.jgit.api.Git;
54  import org.eclipse.jgit.api.Status;
55  import org.eclipse.jgit.api.SubmoduleAddCommand;
56  import org.eclipse.jgit.api.errors.GitAPIException;
57  import org.eclipse.jgit.api.errors.JGitInternalException;
58  import org.eclipse.jgit.dircache.DirCache;
59  import org.eclipse.jgit.dircache.DirCacheEditor;
60  import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
61  import org.eclipse.jgit.dircache.DirCacheEntry;
62  import org.eclipse.jgit.internal.JGitText;
63  import org.eclipse.jgit.junit.RepositoryTestCase;
64  import org.eclipse.jgit.lib.ConfigConstants;
65  import org.eclipse.jgit.lib.Constants;
66  import org.eclipse.jgit.lib.FileMode;
67  import org.eclipse.jgit.lib.ObjectId;
68  import org.eclipse.jgit.lib.Repository;
69  import org.eclipse.jgit.revwalk.RevCommit;
70  import org.eclipse.jgit.storage.file.FileBasedConfig;
71  import org.junit.Test;
72  
73  /**
74   * Unit tests of {@link org.eclipse.jgit.api.SubmoduleAddCommand}
75   */
76  public class SubmoduleAddTest extends RepositoryTestCase {
77  
78  	@Test
79  	public void commandWithNullPath() throws GitAPIException {
80  		try {
81  			new SubmoduleAddCommand(db).setURI("uri").call().close();
82  			fail("Exception not thrown");
83  		} catch (IllegalArgumentException e) {
84  			assertEquals(JGitText.get().pathNotConfigured, e.getMessage());
85  		}
86  	}
87  
88  	@Test
89  	public void commandWithEmptyPath() throws GitAPIException {
90  		try {
91  			new SubmoduleAddCommand(db).setPath("").setURI("uri").call()
92  					.close();
93  			fail("Exception not thrown");
94  		} catch (IllegalArgumentException e) {
95  			assertEquals(JGitText.get().pathNotConfigured, e.getMessage());
96  		}
97  	}
98  
99  	@Test
100 	public void commandWithNullUri() throws GitAPIException {
101 		try {
102 			new SubmoduleAddCommand(db).setPath("sub").call().close();
103 			fail("Exception not thrown");
104 		} catch (IllegalArgumentException e) {
105 			assertEquals(JGitText.get().uriNotConfigured, e.getMessage());
106 		}
107 	}
108 
109 	@Test
110 	public void commandWithEmptyUri() throws GitAPIException {
111 		try {
112 			new SubmoduleAddCommand(db).setPath("sub").setURI("").call()
113 					.close();
114 			fail("Exception not thrown");
115 		} catch (IllegalArgumentException e) {
116 			assertEquals(JGitText.get().uriNotConfigured, e.getMessage());
117 		}
118 	}
119 
120 	@Test
121 	public void addSubmodule() throws Exception {
122 		try (Git git = new Git(db)) {
123 			writeTrashFile("file.txt", "content");
124 			git.add().addFilepattern("file.txt").call();
125 			RevCommit commit = git.commit().setMessage("create file").call();
126 
127 			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
128 			String path = "sub";
129 			command.setPath(path);
130 			String uri = db.getDirectory().toURI().toString();
131 			command.setURI(uri);
132 			ObjectId subCommit;
133 			try (Repository repo = command.call()) {
134 				assertNotNull(repo);
135 				subCommit = repo.resolve(Constants.HEAD);
136 			}
137 
138 			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
139 			assertTrue(generator.next());
140 			assertEquals(path, generator.getPath());
141 			assertEquals(commit, generator.getObjectId());
142 			assertEquals(uri, generator.getModulesUrl());
143 			assertEquals(path, generator.getModulesPath());
144 			assertEquals(uri, generator.getConfigUrl());
145 			try (Repository subModRepo = generator.getRepository()) {
146 				assertNotNull(subModRepo);
147 				assertEquals(subCommit, commit);
148 			}
149 
150 			Status status = Git.wrap(db).status().call();
151 			assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
152 			assertTrue(status.getAdded().contains(path));
153 		}
154 	}
155 
156 	@Test
157 	public void addExistentSubmodule() throws Exception {
158 		final ObjectId id = ObjectId
159 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
160 		final String path = "sub";
161 		DirCache cache = db.lockDirCache();
162 		DirCacheEditor editor = cache.editor();
163 		editor.add(new PathEdit(path) {
164 
165 			@Override
166 			public void apply(DirCacheEntry ent) {
167 				ent.setFileMode(FileMode.GITLINK);
168 				ent.setObjectId(id);
169 			}
170 		});
171 		editor.commit();
172 
173 		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
174 		command.setPath(path);
175 		command.setURI("git://server/repo.git");
176 		try {
177 			command.call().close();
178 			fail("Exception not thrown");
179 		} catch (JGitInternalException e) {
180 			assertEquals(
181 					MessageFormat.format(JGitText.get().submoduleExists, path),
182 					e.getMessage());
183 		}
184 	}
185 
186 	@Test
187 	public void addSubmoduleWithRelativeUri() throws Exception {
188 		try (Git git = new Git(db)) {
189 			writeTrashFile("file.txt", "content");
190 			git.add().addFilepattern("file.txt").call();
191 			RevCommit commit = git.commit().setMessage("create file").call();
192 
193 			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
194 			String path = "sub";
195 			String uri = "./.git";
196 			command.setPath(path);
197 			command.setURI(uri);
198 			Repository repo = command.call();
199 			assertNotNull(repo);
200 			addRepoToClose(repo);
201 
202 			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
203 			assertTrue(generator.next());
204 			assertEquals(path, generator.getPath());
205 			assertEquals(commit, generator.getObjectId());
206 			assertEquals(uri, generator.getModulesUrl());
207 			assertEquals(path, generator.getModulesPath());
208 			String fullUri = db.getDirectory().getAbsolutePath();
209 			if (File.separatorChar == '\\') {
210 				fullUri = fullUri.replace('\\', '/');
211 			}
212 			assertEquals(fullUri, generator.getConfigUrl());
213 			try (Repository subModRepo = generator.getRepository()) {
214 				assertNotNull(subModRepo);
215 				assertEquals(fullUri,
216 						subModRepo.getConfig().getString(
217 								ConfigConstants.CONFIG_REMOTE_SECTION,
218 								Constants.DEFAULT_REMOTE_NAME,
219 								ConfigConstants.CONFIG_KEY_URL));
220 			}
221 			assertEquals(commit, repo.resolve(Constants.HEAD));
222 
223 			Status status = Git.wrap(db).status().call();
224 			assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
225 			assertTrue(status.getAdded().contains(path));
226 		}
227 	}
228 
229 	@Test
230 	public void addSubmoduleWithExistingSubmoduleDefined() throws Exception {
231 		String path1 = "sub1";
232 		String url1 = "git://server/repo1.git";
233 		String path2 = "sub2";
234 
235 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
236 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
237 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
238 				path1, ConfigConstants.CONFIG_KEY_PATH, path1);
239 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
240 				path1, ConfigConstants.CONFIG_KEY_URL, url1);
241 		modulesConfig.save();
242 
243 		try (Git git = new Git(db)) {
244 			writeTrashFile("file.txt", "content");
245 			git.add().addFilepattern("file.txt").call();
246 			assertNotNull(git.commit().setMessage("create file").call());
247 
248 			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
249 			command.setPath(path2);
250 			String url2 = db.getDirectory().toURI().toString();
251 			command.setURI(url2);
252 			Repository r = command.call();
253 			assertNotNull(r);
254 			addRepoToClose(r);
255 
256 			modulesConfig.load();
257 			assertEquals(path1, modulesConfig.getString(
258 					ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
259 					ConfigConstants.CONFIG_KEY_PATH));
260 			assertEquals(url1, modulesConfig.getString(
261 					ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
262 					ConfigConstants.CONFIG_KEY_URL));
263 			assertEquals(path2, modulesConfig.getString(
264 					ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
265 					ConfigConstants.CONFIG_KEY_PATH));
266 			assertEquals(url2, modulesConfig.getString(
267 					ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
268 					ConfigConstants.CONFIG_KEY_URL));
269 		}
270 	}
271 }