View Javadoc
1   /*
2    * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.com>
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.util;
44  
45  import static org.junit.Assert.assertEquals;
46  
47  import java.io.IOException;
48  import java.io.InputStream;
49  import java.io.OutputStream;
50  
51  import org.eclipse.jgit.api.Git;
52  import org.eclipse.jgit.api.errors.GitAPIException;
53  import org.eclipse.jgit.attributes.FilterCommand;
54  import org.eclipse.jgit.attributes.FilterCommandFactory;
55  import org.eclipse.jgit.attributes.FilterCommandRegistry;
56  import org.eclipse.jgit.junit.RepositoryTestCase;
57  import org.eclipse.jgit.lib.Constants;
58  import org.eclipse.jgit.lib.RefUpdate;
59  import org.eclipse.jgit.lib.Repository;
60  import org.eclipse.jgit.lib.StoredConfig;
61  import org.eclipse.jgit.revwalk.RevCommit;
62  import org.junit.Before;
63  import org.junit.Test;
64  
65  public class FilterCommandsTest extends RepositoryTestCase {
66  	private Git git;
67  
68  	RevCommit initialCommit;
69  
70  	RevCommit secondCommit;
71  
72  	class TestCommandFactory implements FilterCommandFactory {
73  		private int prefix;
74  
75  		public TestCommandFactory(int prefix) {
76  			this.prefix = prefix;
77  		}
78  
79  		@Override
80  		public FilterCommand create(Repository repo, InputStream in,
81  				final OutputStream out) {
82  			FilterCommand cmd = new FilterCommand(in, out) {
83  
84  				@Override
85  				public int run() throws IOException {
86  					int b = in.read();
87  					if (b == -1) {
88  						in.close();
89  						out.close();
90  						return b;
91  					}
92  					out.write(prefix);
93  					out.write(b);
94  					return 1;
95  				}
96  			};
97  			return cmd;
98  		}
99  	}
100 
101 	@Override
102 	@Before
103 	public void setUp() throws Exception {
104 		super.setUp();
105 		git = new Git(db);
106 		// commit something
107 		writeTrashFile("Test.txt", "Hello world");
108 		git.add().addFilepattern("Test.txt").call();
109 		initialCommit = git.commit().setMessage("Initial commit").call();
110 
111 		// create a master branch and switch to it
112 		git.branchCreate().setName("test").call();
113 		RefUpdate rup = db.updateRef(Constants.HEAD);
114 		rup.link("refs/heads/test");
115 
116 		// commit something on the test branch
117 		writeTrashFile("Test.txt", "Some change");
118 		git.add().addFilepattern("Test.txt").call();
119 		secondCommit = git.commit().setMessage("Second commit").call();
120 	}
121 
122 	@Test
123 	public void testBuiltinCleanFilter()
124 			throws IOException, GitAPIException {
125 		String builtinCommandName = "jgit://builtin/test/clean";
126 		FilterCommandRegistry.register(builtinCommandName,
127 				new TestCommandFactory('c'));
128 		StoredConfig config = git.getRepository().getConfig();
129 		config.setString("filter", "test", "clean", builtinCommandName);
130 		config.save();
131 
132 		writeTrashFile(".gitattributes", "*.txt filter=test");
133 		git.add().addFilepattern(".gitattributes").call();
134 		git.commit().setMessage("add filter").call();
135 
136 		writeTrashFile("Test.txt", "Hello again");
137 		git.add().addFilepattern("Test.txt").call();
138 		assertEquals(
139 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
140 				indexState(CONTENT));
141 
142 		writeTrashFile("Test.bin", "Hello again");
143 		git.add().addFilepattern("Test.bin").call();
144 		assertEquals(
145 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
146 				indexState(CONTENT));
147 
148 		config.setString("filter", "test", "clean", null);
149 		config.save();
150 
151 		git.add().addFilepattern("Test.txt").call();
152 		assertEquals(
153 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]",
154 				indexState(CONTENT));
155 
156 		config.setString("filter", "test", "clean", null);
157 		config.save();
158 	}
159 
160 	@Test
161 	public void testBuiltinSmudgeFilter() throws IOException, GitAPIException {
162 		String builtinCommandName = "jgit://builtin/test/smudge";
163 		FilterCommandRegistry.register(builtinCommandName,
164 				new TestCommandFactory('s'));
165 		StoredConfig config = git.getRepository().getConfig();
166 		config.setString("filter", "test", "smudge", builtinCommandName);
167 		config.save();
168 
169 		writeTrashFile(".gitattributes", "*.txt filter=test");
170 		git.add().addFilepattern(".gitattributes").call();
171 		git.commit().setMessage("add filter").call();
172 
173 		writeTrashFile("Test.txt", "Hello again");
174 		git.add().addFilepattern("Test.txt").call();
175 		assertEquals(
176 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:Hello again]",
177 				indexState(CONTENT));
178 		assertEquals("Hello again", read("Test.txt"));
179 		deleteTrashFile("Test.txt");
180 		git.checkout().addPath("Test.txt").call();
181 		assertEquals("sHseslslsos sasgsasisn", read("Test.txt"));
182 
183 		writeTrashFile("Test.bin", "Hello again");
184 		git.add().addFilepattern("Test.bin").call();
185 		assertEquals(
186 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]",
187 				indexState(CONTENT));
188 		deleteTrashFile("Test.bin");
189 		git.checkout().addPath("Test.bin").call();
190 		assertEquals("Hello again", read("Test.bin"));
191 
192 		config.setString("filter", "test", "clean", null);
193 		config.save();
194 
195 		git.add().addFilepattern("Test.txt").call();
196 		assertEquals(
197 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:sHseslslsos sasgsasisn]",
198 				indexState(CONTENT));
199 
200 		config.setString("filter", "test", "clean", null);
201 		config.save();
202 	}
203 
204 	@Test
205 	public void testBuiltinCleanAndSmudgeFilter() throws IOException, GitAPIException {
206 		String builtinCommandPrefix = "jgit://builtin/test/";
207 		FilterCommandRegistry.register(builtinCommandPrefix + "smudge",
208 				new TestCommandFactory('s'));
209 		FilterCommandRegistry.register(builtinCommandPrefix + "clean",
210 				new TestCommandFactory('c'));
211 		StoredConfig config = git.getRepository().getConfig();
212 		config.setString("filter", "test", "smudge", builtinCommandPrefix+"smudge");
213 		config.setString("filter", "test", "clean",
214 				builtinCommandPrefix + "clean");
215 		config.save();
216 
217 		writeTrashFile(".gitattributes", "*.txt filter=test");
218 		git.add().addFilepattern(".gitattributes").call();
219 		git.commit().setMessage("add filter").call();
220 
221 		writeTrashFile("Test.txt", "Hello again");
222 		git.add().addFilepattern("Test.txt").call();
223 		assertEquals(
224 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
225 				indexState(CONTENT));
226 		assertEquals("Hello again", read("Test.txt"));
227 		deleteTrashFile("Test.txt");
228 		git.checkout().addPath("Test.txt").call();
229 		assertEquals("scsHscsescslscslscsoscs scsascsgscsascsiscsn",
230 				read("Test.txt"));
231 
232 		writeTrashFile("Test.bin", "Hello again");
233 		git.add().addFilepattern("Test.bin").call();
234 		assertEquals(
235 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
236 				indexState(CONTENT));
237 		deleteTrashFile("Test.bin");
238 		git.checkout().addPath("Test.bin").call();
239 		assertEquals("Hello again", read("Test.bin"));
240 
241 		config.setString("filter", "test", "clean", null);
242 		config.save();
243 
244 		git.add().addFilepattern("Test.txt").call();
245 		assertEquals(
246 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:scsHscsescslscslscsoscs scsascsgscsascsiscsn]",
247 				indexState(CONTENT));
248 
249 		config.setString("filter", "test", "clean", null);
250 		config.save();
251 	}
252 
253 }