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  						return b;
89  					}
90  					out.write(prefix);
91  					out.write(b);
92  					return 1;
93  				}
94  			};
95  			return cmd;
96  		}
97  	}
98  
99  	@Override
100 	@Before
101 	public void setUp() throws Exception {
102 		super.setUp();
103 		git = new Git(db);
104 		// commit something
105 		writeTrashFile("Test.txt", "Hello world");
106 		git.add().addFilepattern("Test.txt").call();
107 		initialCommit = git.commit().setMessage("Initial commit").call();
108 
109 		// create a master branch and switch to it
110 		git.branchCreate().setName("test").call();
111 		RefUpdate rup = db.updateRef(Constants.HEAD);
112 		rup.link("refs/heads/test");
113 
114 		// commit something on the test branch
115 		writeTrashFile("Test.txt", "Some change");
116 		git.add().addFilepattern("Test.txt").call();
117 		secondCommit = git.commit().setMessage("Second commit").call();
118 	}
119 
120 	@Test
121 	public void testBuiltinCleanFilter()
122 			throws IOException, GitAPIException {
123 		String builtinCommandName = "jgit://builtin/test/clean";
124 		FilterCommandRegistry.register(builtinCommandName,
125 				new TestCommandFactory('c'));
126 		StoredConfig config = git.getRepository().getConfig();
127 		config.setString("filter", "test", "clean", builtinCommandName);
128 		config.save();
129 
130 		writeTrashFile(".gitattributes", "*.txt filter=test");
131 		git.add().addFilepattern(".gitattributes").call();
132 		git.commit().setMessage("add filter").call();
133 
134 		writeTrashFile("Test.txt", "Hello again");
135 		git.add().addFilepattern("Test.txt").call();
136 		assertEquals(
137 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
138 				indexState(CONTENT));
139 
140 		writeTrashFile("Test.bin", "Hello again");
141 		git.add().addFilepattern("Test.bin").call();
142 		assertEquals(
143 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
144 				indexState(CONTENT));
145 
146 		config.setString("filter", "test", "clean", null);
147 		config.save();
148 
149 		git.add().addFilepattern("Test.txt").call();
150 		assertEquals(
151 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]",
152 				indexState(CONTENT));
153 
154 		config.setString("filter", "test", "clean", null);
155 		config.save();
156 	}
157 
158 	@Test
159 	public void testBuiltinSmudgeFilter() throws IOException, GitAPIException {
160 		String builtinCommandName = "jgit://builtin/test/smudge";
161 		FilterCommandRegistry.register(builtinCommandName,
162 				new TestCommandFactory('s'));
163 		StoredConfig config = git.getRepository().getConfig();
164 		config.setString("filter", "test", "smudge", builtinCommandName);
165 		config.save();
166 
167 		writeTrashFile(".gitattributes", "*.txt filter=test");
168 		git.add().addFilepattern(".gitattributes").call();
169 		git.commit().setMessage("add filter").call();
170 
171 		writeTrashFile("Test.txt", "Hello again");
172 		git.add().addFilepattern("Test.txt").call();
173 		assertEquals(
174 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:Hello again]",
175 				indexState(CONTENT));
176 		assertEquals("Hello again", read("Test.txt"));
177 		deleteTrashFile("Test.txt");
178 		git.checkout().addPath("Test.txt").call();
179 		assertEquals("sHseslslsos sasgsasisn", read("Test.txt"));
180 
181 		writeTrashFile("Test.bin", "Hello again");
182 		git.add().addFilepattern("Test.bin").call();
183 		assertEquals(
184 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]",
185 				indexState(CONTENT));
186 		deleteTrashFile("Test.bin");
187 		git.checkout().addPath("Test.bin").call();
188 		assertEquals("Hello again", read("Test.bin"));
189 
190 		config.setString("filter", "test", "clean", null);
191 		config.save();
192 
193 		git.add().addFilepattern("Test.txt").call();
194 		assertEquals(
195 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:sHseslslsos sasgsasisn]",
196 				indexState(CONTENT));
197 
198 		config.setString("filter", "test", "clean", null);
199 		config.save();
200 	}
201 
202 	@Test
203 	public void testBuiltinCleanAndSmudgeFilter() throws IOException, GitAPIException {
204 		String builtinCommandPrefix = "jgit://builtin/test/";
205 		FilterCommandRegistry.register(builtinCommandPrefix + "smudge",
206 				new TestCommandFactory('s'));
207 		FilterCommandRegistry.register(builtinCommandPrefix + "clean",
208 				new TestCommandFactory('c'));
209 		StoredConfig config = git.getRepository().getConfig();
210 		config.setString("filter", "test", "smudge", builtinCommandPrefix+"smudge");
211 		config.setString("filter", "test", "clean",
212 				builtinCommandPrefix + "clean");
213 		config.save();
214 
215 		writeTrashFile(".gitattributes", "*.txt filter=test");
216 		git.add().addFilepattern(".gitattributes").call();
217 		git.commit().setMessage("add filter").call();
218 
219 		writeTrashFile("Test.txt", "Hello again");
220 		git.add().addFilepattern("Test.txt").call();
221 		assertEquals(
222 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
223 				indexState(CONTENT));
224 		assertEquals("Hello again", read("Test.txt"));
225 		deleteTrashFile("Test.txt");
226 		git.checkout().addPath("Test.txt").call();
227 		assertEquals("scsHscsescslscslscsoscs scsascsgscsascsiscsn",
228 				read("Test.txt"));
229 
230 		writeTrashFile("Test.bin", "Hello again");
231 		git.add().addFilepattern("Test.bin").call();
232 		assertEquals(
233 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]",
234 				indexState(CONTENT));
235 		deleteTrashFile("Test.bin");
236 		git.checkout().addPath("Test.bin").call();
237 		assertEquals("Hello again", read("Test.bin"));
238 
239 		config.setString("filter", "test", "clean", null);
240 		config.save();
241 
242 		git.add().addFilepattern("Test.txt").call();
243 		assertEquals(
244 				"[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:scsHscsescslscslscsoscs scsascsgscsascsiscsn]",
245 				indexState(CONTENT));
246 
247 		config.setString("filter", "test", "clean", null);
248 		config.save();
249 	}
250 
251 }