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 static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertNull;
47
48 import java.beans.Statement;
49 import java.io.IOException;
50 import java.io.OutputStream;
51 import java.util.Arrays;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56
57 import org.eclipse.jgit.api.errors.GitAPIException;
58 import org.eclipse.jgit.junit.RepositoryTestCase;
59 import org.eclipse.jgit.lib.FileMode;
60 import org.eclipse.jgit.lib.ObjectId;
61 import org.eclipse.jgit.lib.ObjectLoader;
62 import org.eclipse.jgit.revwalk.RevCommit;
63 import org.eclipse.jgit.util.StringUtils;
64 import org.junit.After;
65 import org.junit.Before;
66 import org.junit.Test;
67
68 public class ArchiveCommandTest extends RepositoryTestCase {
69
70 private static final String UNEXPECTED_ARCHIVE_SIZE = "Unexpected archive size";
71 private static final String UNEXPECTED_FILE_CONTENTS = "Unexpected file contents";
72 private static final String UNEXPECTED_TREE_CONTENTS = "Unexpected tree contents";
73
74 private MockFormat format = null;
75
76 @Before
77 public void setup() {
78 format = new MockFormat();
79 ArchiveCommand.registerFormat(format.SUFFIXES.get(0), format);
80 }
81
82 @Override
83 @After
84 public void tearDown() {
85 ArchiveCommand.unregisterFormat(format.SUFFIXES.get(0));
86 }
87
88 @Test
89 public void archiveHeadAllFiles() throws IOException, GitAPIException {
90 try (Git git = new Git(db)) {
91 writeTrashFile("file_1.txt", "content_1_1");
92 git.add().addFilepattern("file_1.txt").call();
93 git.commit().setMessage("create file").call();
94
95 writeTrashFile("file_1.txt", "content_1_2");
96 writeTrashFile("file_2.txt", "content_2_2");
97 git.add().addFilepattern(".").call();
98 git.commit().setMessage("updated file").call();
99
100 git.archive().setOutputStream(new MockOutputStream())
101 .setFormat(format.SUFFIXES.get(0))
102 .setTree(git.getRepository().resolve("HEAD")).call();
103
104 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, format.size());
105 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_2", format.getByPath("file_1.txt"));
106 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath("file_2.txt"));
107 }
108 }
109
110 @Test
111 public void archiveHeadSpecificPath() throws IOException, GitAPIException {
112 try (Git git = new Git(db)) {
113 writeTrashFile("file_1.txt", "content_1_1");
114 git.add().addFilepattern("file_1.txt").call();
115 git.commit().setMessage("create file").call();
116
117 writeTrashFile("file_1.txt", "content_1_2");
118 String expectedFilePath = "some_directory/file_2.txt";
119 writeTrashFile(expectedFilePath, "content_2_2");
120 git.add().addFilepattern(".").call();
121 git.commit().setMessage("updated file").call();
122
123 git.archive().setOutputStream(new MockOutputStream())
124 .setFormat(format.SUFFIXES.get(0))
125 .setTree(git.getRepository().resolve("HEAD"))
126 .setPaths(expectedFilePath).call();
127
128 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, format.size());
129 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath));
130 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
131 }
132 }
133
134 @Test
135 public void archiveByIdSpecificFile() throws IOException, GitAPIException {
136 try (Git git = new Git(db)) {
137 writeTrashFile("file_1.txt", "content_1_1");
138 git.add().addFilepattern("file_1.txt").call();
139 RevCommit first = git.commit().setMessage("create file").call();
140
141 writeTrashFile("file_1.txt", "content_1_2");
142 String expectedFilePath = "some_directory/file_2.txt";
143 writeTrashFile(expectedFilePath, "content_2_2");
144 git.add().addFilepattern(".").call();
145 git.commit().setMessage("updated file").call();
146
147 Map<String, Object> options = new HashMap<>();
148 Integer opt = Integer.valueOf(42);
149 options.put("foo", opt);
150 MockOutputStream out = new MockOutputStream();
151 git.archive().setOutputStream(out)
152 .setFormat(format.SUFFIXES.get(0))
153 .setFormatOptions(options)
154 .setTree(first)
155 .setPaths("file_1.txt").call();
156
157 assertEquals(opt.intValue(), out.getFoo());
158 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 1, format.size());
159 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_1", format.getByPath("file_1.txt"));
160 }
161 }
162
163 @Test
164 public void archiveByDirectoryPath() throws GitAPIException, IOException {
165 try (Git git = new Git(db)) {
166 writeTrashFile("file_0.txt", "content_0_1");
167 git.add().addFilepattern("file_0.txt").call();
168 git.commit().setMessage("commit_1").call();
169
170 writeTrashFile("file_0.txt", "content_0_2");
171 String expectedFilePath1 = "some_directory/file_1.txt";
172 writeTrashFile(expectedFilePath1, "content_1_2");
173 String expectedFilePath2 = "some_directory/file_2.txt";
174 writeTrashFile(expectedFilePath2, "content_2_2");
175 String expectedFilePath3 = "some_directory/nested_directory/file_3.txt";
176 writeTrashFile(expectedFilePath3, "content_3_2");
177 git.add().addFilepattern(".").call();
178 git.commit().setMessage("commit_2").call();
179 git.archive().setOutputStream(new MockOutputStream())
180 .setFormat(format.SUFFIXES.get(0))
181 .setTree(git.getRepository().resolve("HEAD"))
182 .setPaths("some_directory/").call();
183
184 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 5, format.size());
185 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_2", format.getByPath(expectedFilePath1));
186 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath2));
187 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_3_2", format.getByPath(expectedFilePath3));
188 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
189 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory/nested_directory"));
190 }
191 }
192
193 private class MockFormat implements ArchiveCommand.Format<MockOutputStream> {
194
195 private Map<String, String> entries = new HashMap<>();
196
197 private int size() {
198 return entries.size();
199 }
200
201 private String getByPath(String path) {
202 return entries.get(path);
203 }
204
205 private final List<String> SUFFIXES = Collections
206 .unmodifiableList(Arrays.asList(".mck"));
207
208 @Override
209 public MockOutputStream createArchiveOutputStream(OutputStream s)
210 throws IOException {
211 return createArchiveOutputStream(s,
212 Collections.<String, Object> emptyMap());
213 }
214
215 @Override
216 public MockOutputStream createArchiveOutputStream(OutputStream s,
217 Map<String, Object> o) throws IOException {
218 for (Map.Entry<String, Object> p : o.entrySet()) {
219 try {
220 String methodName = "set"
221 + StringUtils.capitalize(p.getKey());
222 new Statement(s, methodName, new Object[] { p.getValue() })
223 .execute();
224 } catch (Exception e) {
225 throw new IOException("cannot set option: " + p.getKey(), e);
226 }
227 }
228 return new MockOutputStream();
229 }
230
231 @Override
232 public void putEntry(MockOutputStream out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) {
233 String content = mode != FileMode.TREE ? new String(loader.getBytes()) : null;
234 entries.put(path, content);
235 }
236
237 @Override
238 public Iterable<String> suffixes() {
239 return SUFFIXES;
240 }
241 }
242
243 public class MockOutputStream extends OutputStream {
244
245 private int foo;
246
247 public void setFoo(int foo) {
248 this.foo = foo;
249 }
250
251 public int getFoo() {
252 return foo;
253 }
254
255 @Override
256 public void write(int b) throws IOException {
257
258 }
259 }
260 }