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 		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 		Repository repo = command.call();
133 		assertNotNull(repo);
134 		ObjectId subCommit = repo.resolve(Constants.HEAD);
135 		repo.close();
136 
137 		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
138 		assertTrue(generator.next());
139 		assertEquals(path, generator.getPath());
140 		assertEquals(commit, generator.getObjectId());
141 		assertEquals(uri, generator.getModulesUrl());
142 		assertEquals(path, generator.getModulesPath());
143 		assertEquals(uri, generator.getConfigUrl());
144 		Repository subModRepo = generator.getRepository();
145 		assertNotNull(subModRepo);
146 		assertEquals(subCommit, commit);
147 		subModRepo.close();
148 
149 		Status status = Git.wrap(db).status().call();
150 		assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
151 		assertTrue(status.getAdded().contains(path));
152 	}
153 
154 	@Test
155 	public void addExistentSubmodule() throws Exception {
156 		final ObjectId id = ObjectId
157 				.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234");
158 		final String path = "sub";
159 		DirCache cache = db.lockDirCache();
160 		DirCacheEditor editor = cache.editor();
161 		editor.add(new PathEdit(path) {
162 
163 			public void apply(DirCacheEntry ent) {
164 				ent.setFileMode(FileMode.GITLINK);
165 				ent.setObjectId(id);
166 			}
167 		});
168 		editor.commit();
169 
170 		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
171 		command.setPath(path);
172 		command.setURI("git://server/repo.git");
173 		try {
174 			command.call().close();
175 			fail("Exception not thrown");
176 		} catch (JGitInternalException e) {
177 			assertEquals(
178 					MessageFormat.format(JGitText.get().submoduleExists, path),
179 					e.getMessage());
180 		}
181 	}
182 
183 	@Test
184 	public void addSubmoduleWithRelativeUri() throws Exception {
185 		Git git = new Git(db);
186 		writeTrashFile("file.txt", "content");
187 		git.add().addFilepattern("file.txt").call();
188 		RevCommit commit = git.commit().setMessage("create file").call();
189 
190 		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
191 		String path = "sub";
192 		String uri = "./.git";
193 		command.setPath(path);
194 		command.setURI(uri);
195 		Repository repo = command.call();
196 		assertNotNull(repo);
197 		addRepoToClose(repo);
198 
199 		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
200 		assertTrue(generator.next());
201 		assertEquals(path, generator.getPath());
202 		assertEquals(commit, generator.getObjectId());
203 		assertEquals(uri, generator.getModulesUrl());
204 		assertEquals(path, generator.getModulesPath());
205 		String fullUri = db.getDirectory().getAbsolutePath();
206 		if (File.separatorChar == '\\')
207 			fullUri = fullUri.replace('\\', '/');
208 		assertEquals(fullUri, generator.getConfigUrl());
209 		Repository subModRepo = generator.getRepository();
210 		assertNotNull(subModRepo);
211 		assertEquals(
212 				fullUri,
213 				subModRepo
214 						.getConfig()
215 						.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
216 								Constants.DEFAULT_REMOTE_NAME,
217 								ConfigConstants.CONFIG_KEY_URL));
218 		subModRepo.close();
219 		assertEquals(commit, repo.resolve(Constants.HEAD));
220 
221 		Status status = Git.wrap(db).status().call();
222 		assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
223 		assertTrue(status.getAdded().contains(path));
224 	}
225 
226 	@Test
227 	public void addSubmoduleWithExistingSubmoduleDefined() throws Exception {
228 		String path1 = "sub1";
229 		String url1 = "git://server/repo1.git";
230 		String path2 = "sub2";
231 
232 		FileBasedConfig modulesConfig = new FileBasedConfig(new File(
233 				db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
234 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
235 				path1, ConfigConstants.CONFIG_KEY_PATH, path1);
236 		modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
237 				path1, ConfigConstants.CONFIG_KEY_URL, url1);
238 		modulesConfig.save();
239 
240 		Git git = new Git(db);
241 		writeTrashFile("file.txt", "content");
242 		git.add().addFilepattern("file.txt").call();
243 		assertNotNull(git.commit().setMessage("create file").call());
244 
245 		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
246 		command.setPath(path2);
247 		String url2 = db.getDirectory().toURI().toString();
248 		command.setURI(url2);
249 		Repository r = command.call();
250 		assertNotNull(r);
251 		addRepoToClose(r);
252 
253 		modulesConfig.load();
254 		assertEquals(path1, modulesConfig.getString(
255 				ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
256 				ConfigConstants.CONFIG_KEY_PATH));
257 		assertEquals(url1, modulesConfig.getString(
258 				ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
259 				ConfigConstants.CONFIG_KEY_URL));
260 		assertEquals(path2, modulesConfig.getString(
261 				ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
262 				ConfigConstants.CONFIG_KEY_PATH));
263 		assertEquals(url2, modulesConfig.getString(
264 				ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
265 				ConfigConstants.CONFIG_KEY_URL));
266 	}
267 }