Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/merge-3.2 |
Merge into: | lp:brz |
Diff against target: |
2209 lines (+341/-292) 74 files modified
Makefile (+3/-2) breezy/bzr/inventorytree.py (+3/-0) breezy/bzr/tests/test__dirstate_helpers.py (+5/-5) breezy/bzr/tests/test_bundle.py (+1/-1) breezy/bzr/tests/test_dirstate.py (+1/-1) breezy/bzr/tests/test_testament.py (+1/-1) breezy/bzr/tests/test_transform.py (+6/-6) breezy/bzr/transform.py (+3/-0) breezy/commit.py (+1/-1) breezy/git/tests/test_object_store.py (+1/-1) breezy/git/transform.py (+3/-0) breezy/git/tree.py (+3/-0) breezy/location.py (+2/-1) breezy/osutils.py (+28/-66) breezy/plugins/fastimport/exporter.py (+1/-1) breezy/plugins/fastimport/tests/test_commands.py (+1/-1) breezy/plugins/po_merge/po_merge.py (+3/-3) breezy/plugins/upload/tests/test_upload.py (+2/-2) breezy/smtp_connection.py (+1/-2) breezy/tests/blackbox/test_add.py (+2/-2) breezy/tests/blackbox/test_branch.py (+2/-2) breezy/tests/blackbox/test_checkout.py (+2/-2) breezy/tests/blackbox/test_cp.py (+0/-1) breezy/tests/blackbox/test_link_tree.py (+1/-2) breezy/tests/blackbox/test_merge_directive.py (+1/-0) breezy/tests/blackbox/test_mv.py (+1/-1) breezy/tests/blackbox/test_remove.py (+1/-1) breezy/tests/blackbox/test_revert.py (+1/-1) breezy/tests/blackbox/test_too_much.py (+2/-2) breezy/tests/features.py (+13/-10) breezy/tests/per_branch/test_sprout.py (+1/-1) breezy/tests/per_intertree/test_compare.py (+7/-7) breezy/tests/per_repository/test_commit_builder.py (+7/-7) breezy/tests/per_tree/__init__.py (+1/-1) breezy/tests/per_tree/test_archive.py (+2/-2) breezy/tests/per_tree/test_export.py (+1/-1) breezy/tests/per_tree/test_get_symlink_target.py (+2/-2) breezy/tests/per_tree/test_is_executable.py (+1/-1) breezy/tests/per_tree/test_path_content_summary.py (+3/-3) breezy/tests/per_tree/test_symlinks.py (+1/-2) breezy/tests/per_tree/test_test_trees.py (+1/-1) breezy/tests/per_tree/test_transform.py (+10/-11) breezy/tests/per_tree/test_walkdirs.py (+5/-5) breezy/tests/per_workingtree/test_parents.py (+1/-1) breezy/tests/per_workingtree/test_symlinks.py (+9/-3) breezy/tests/per_workingtree/test_transform.py (+5/-5) breezy/tests/per_workingtree/test_walkdirs.py (+1/-1) breezy/tests/per_workingtree/test_workingtree.py (+4/-4) breezy/tests/test_clean_tree.py (+2/-2) breezy/tests/test_commit.py (+2/-2) breezy/tests/test_commit_merge.py (+1/-1) breezy/tests/test_diff.py (+1/-1) breezy/tests/test_export.py (+1/-1) breezy/tests/test_location.py (+2/-0) breezy/tests/test_merge.py (+6/-6) breezy/tests/test_osutils.py (+10/-10) breezy/tests/test_server.py (+1/-0) breezy/tests/test_shelf.py (+2/-2) breezy/tests/test_shelf_ui.py (+2/-2) breezy/tests/test_smtp_connection.py (+8/-10) breezy/tests/test_transform.py (+6/-7) breezy/tests/test_treeshape.py (+1/-1) breezy/tests/test_workingtree.py (+1/-1) breezy/transform.py (+3/-1) breezy/transport/local.py (+2/-2) breezy/tree.py (+1/-1) breezy/win32utils.py (+11/-18) doc/developers/testing.txt (+5/-4) setup.py (+32/-17) tools/package_mf.py (+45/-16) tools/win32/brz.iss.cog (+19/-7) tools/win32/info.txt (+3/-3) tools/win32/ostools.py (+16/-0) tools/win32/start_brz.bat (+1/-1) |
To merge this branch: | bzr merge lp:~jelmer/brz/merge-3.2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+413480@code.launchpad.net |
Commit message
Merge lp:brz/3.2.
Description of the change
Merge lp:brz/3.2.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2021-11-17 20:30:19 +0000 |
3 | +++ Makefile 2021-12-25 12:35:58 +0000 |
4 | @@ -253,7 +253,7 @@ |
5 | $(PYTHON) setup.py build_ext -i -f $(PYTHON_BUILDFLAGS) |
6 | $(PYTHON) setup.py py2exe > py2exe.log |
7 | $(PYTHON) tools/win32/ostools.py copytodir tools/win32/start_brz.bat win32_brz.exe |
8 | - $(PYTHON) tools/win32/ostools.py copytodir tools/win32/bazaar.url win32_brz.exe |
9 | + $(PYTHON) tools/win32/ostools.py copytodir tools/win32/breezy.url win32_brz.exe |
10 | |
11 | # win32 installer for brz.exe |
12 | installer: exe copy-docs |
13 | @@ -268,7 +268,8 @@ |
14 | |
15 | copy-docs: docs |
16 | $(PYTHON) tools/win32/ostools.py copytodir README win32_brz.exe/doc |
17 | - $(PYTHON) tools/win32/ostools.py copytree $(WEB_DOCS) win32_brz.exe |
18 | + $(PYTHON) tools/win32/ostools.py copydir doc/en/_build/html win32_brz.exe/doc |
19 | + $(PYTHON) tools/win32/ostools.py copydir doc/developers/_build/html win32_brz.exe/doc/developers |
20 | |
21 | # clean on win32 all installer-related files and directories |
22 | clean-win32: clean-docs |
23 | |
24 | === modified file 'breezy/bzr/inventorytree.py' |
25 | --- breezy/bzr/inventorytree.py 2021-11-16 01:24:28 +0000 |
26 | +++ breezy/bzr/inventorytree.py 2021-12-25 12:35:58 +0000 |
27 | @@ -135,6 +135,9 @@ |
28 | private to external API users. |
29 | """ |
30 | |
31 | + def supports_symlinks(self): |
32 | + return True |
33 | + |
34 | def _get_root_inventory(self): |
35 | return self._inventory |
36 | |
37 | |
38 | === modified file 'breezy/bzr/tests/test__dirstate_helpers.py' |
39 | --- breezy/bzr/tests/test__dirstate_helpers.py 2020-06-10 02:56:53 +0000 |
40 | +++ breezy/bzr/tests/test__dirstate_helpers.py 2021-12-25 12:35:58 +0000 |
41 | @@ -952,7 +952,7 @@ |
42 | |
43 | def test_update_entry_symlink(self): |
44 | """Update entry should read symlinks.""" |
45 | - self.requireFeature(features.SymlinkFeature) |
46 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
47 | state, entry = self.get_state_with_a() |
48 | state.save() |
49 | self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED, |
50 | @@ -1149,7 +1149,7 @@ |
51 | |
52 | def test_update_file_to_symlink(self): |
53 | """File becomes a symlink""" |
54 | - self.requireFeature(features.SymlinkFeature) |
55 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
56 | state, entry = self.get_state_with_a() |
57 | # The file sha1 won't be cached unless the file is old |
58 | state.adjust_time(+10) |
59 | @@ -1168,7 +1168,7 @@ |
60 | |
61 | def test_update_dir_to_symlink(self): |
62 | """Directory becomes a symlink""" |
63 | - self.requireFeature(features.SymlinkFeature) |
64 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
65 | state, entry = self.get_state_with_a() |
66 | # The symlink target won't be cached if it isn't old |
67 | state.adjust_time(+10) |
68 | @@ -1178,7 +1178,7 @@ |
69 | |
70 | def test_update_symlink_to_file(self): |
71 | """Symlink becomes a file""" |
72 | - self.requireFeature(features.SymlinkFeature) |
73 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
74 | state, entry = self.get_state_with_a() |
75 | # The symlink and file info won't be cached unless old |
76 | state.adjust_time(+10) |
77 | @@ -1188,7 +1188,7 @@ |
78 | |
79 | def test_update_symlink_to_dir(self): |
80 | """Symlink becomes a directory""" |
81 | - self.requireFeature(features.SymlinkFeature) |
82 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
83 | state, entry = self.get_state_with_a() |
84 | # The symlink target won't be cached if it isn't old |
85 | state.adjust_time(+10) |
86 | |
87 | === modified file 'breezy/bzr/tests/test_bundle.py' |
88 | --- breezy/bzr/tests/test_bundle.py 2020-07-04 12:29:00 +0000 |
89 | +++ breezy/bzr/tests/test_bundle.py 2021-12-25 12:35:58 +0000 |
90 | @@ -670,7 +670,7 @@ |
91 | def _test_symlink_bundle(self, link_name, link_target, new_link_target): |
92 | link_id = b'link-1' |
93 | |
94 | - self.requireFeature(features.SymlinkFeature) |
95 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
96 | self.tree1 = self.make_branch_and_tree('b1') |
97 | self.b1 = self.tree1.branch |
98 | |
99 | |
100 | === modified file 'breezy/bzr/tests/test_dirstate.py' |
101 | --- breezy/bzr/tests/test_dirstate.py 2020-06-10 02:56:53 +0000 |
102 | +++ breezy/bzr/tests/test_dirstate.py 2021-12-25 12:35:58 +0000 |
103 | @@ -1224,7 +1224,7 @@ |
104 | # The most trivial addition of a symlink when there are no parents and |
105 | # its in the root and all data about the file is supplied |
106 | # bzr doesn't support fake symlinks on windows, yet. |
107 | - self.requireFeature(features.SymlinkFeature) |
108 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
109 | os.symlink(target, link_name) |
110 | stat = os.lstat(link_name) |
111 | expected_entries = [ |
112 | |
113 | === modified file 'breezy/bzr/tests/test_testament.py' |
114 | --- breezy/bzr/tests/test_testament.py 2020-07-04 12:29:00 +0000 |
115 | +++ breezy/bzr/tests/test_testament.py 2021-12-25 12:35:58 +0000 |
116 | @@ -103,7 +103,7 @@ |
117 | |
118 | def test_testament_symlinks(self): |
119 | """Testament containing symlink (where possible)""" |
120 | - self.requireFeature(SymlinkFeature) |
121 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
122 | os.symlink('wibble/linktarget', 'link') |
123 | self.wt.add(['link'], [b'link-id']) |
124 | self.wt.commit(message='add symlink', |
125 | |
126 | === modified file 'breezy/bzr/tests/test_transform.py' |
127 | --- breezy/bzr/tests/test_transform.py 2020-09-02 17:00:38 +0000 |
128 | +++ breezy/bzr/tests/test_transform.py 2021-12-25 12:35:58 +0000 |
129 | @@ -62,7 +62,7 @@ |
130 | class TestBuildTree(TestCaseWithTransport): |
131 | |
132 | def test_build_tree_with_symlinks(self): |
133 | - self.requireFeature(features.SymlinkFeature) |
134 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
135 | os.mkdir('a') |
136 | a = ControlDir.create_standalone_workingtree('a') |
137 | os.mkdir('a/foo') |
138 | @@ -113,7 +113,7 @@ |
139 | |
140 | def test_symlink_conflict_handling(self): |
141 | """Ensure that when building trees, conflict handling is done""" |
142 | - self.requireFeature(features.SymlinkFeature) |
143 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
144 | source = self.make_branch_and_tree('source') |
145 | os.symlink('foo', 'source/symlink') |
146 | source.add('symlink', b'new-symlink') |
147 | @@ -272,7 +272,7 @@ |
148 | self.assertEqual([], list(target.iter_changes(revision_tree))) |
149 | |
150 | def test_build_tree_accelerator_wrong_kind(self): |
151 | - self.requireFeature(features.SymlinkFeature) |
152 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
153 | source = self.make_branch_and_tree('source') |
154 | self.build_tree_contents([('source/file1', b'')]) |
155 | self.build_tree_contents([('source/file2', b'')]) |
156 | @@ -300,7 +300,7 @@ |
157 | self.assertEqual([], list(target.iter_changes(revision_tree))) |
158 | |
159 | def test_build_tree_hardlink(self): |
160 | - self.requireFeature(features.HardlinkFeature) |
161 | + self.requireFeature(features.HardlinkFeature(self.test_dir)) |
162 | source = self.create_ab_tree() |
163 | target = self.make_branch_and_tree('target') |
164 | revision_tree = source.basis_tree() |
165 | @@ -342,7 +342,7 @@ |
166 | self.assertEqual([], list(target.iter_changes(revision_tree))) |
167 | |
168 | def test_build_tree_hardlinks_preserve_execute(self): |
169 | - self.requireFeature(features.HardlinkFeature) |
170 | + self.requireFeature(features.HardlinkFeature(self.test_dir)) |
171 | source = self.create_ab_tree() |
172 | tt = source.transform() |
173 | trans_id = tt.trans_id_tree_path('file1') |
174 | @@ -393,7 +393,7 @@ |
175 | applied to them (but will still hardlink other files from the same tree |
176 | if it can). |
177 | """ |
178 | - self.requireFeature(features.HardlinkFeature) |
179 | + self.requireFeature(features.HardlinkFeature(self.test_dir)) |
180 | self.install_rot13_content_filter(b'file1') |
181 | source = self.create_ab_tree() |
182 | target = self.make_branch_and_tree('target') |
183 | |
184 | === modified file 'breezy/bzr/transform.py' |
185 | --- breezy/bzr/transform.py 2021-11-13 13:01:39 +0000 |
186 | +++ breezy/bzr/transform.py 2021-12-25 12:35:58 +0000 |
187 | @@ -1923,6 +1923,9 @@ |
188 | def supports_setting_file_ids(self): |
189 | return True |
190 | |
191 | + def supports_symlinks(self): |
192 | + return self._transform._create_symlinks |
193 | + |
194 | def supports_tree_reference(self): |
195 | # TODO(jelmer): Support tree references in PreviewTree. |
196 | # return self._transform._tree.supports_tree_reference() |
197 | |
198 | === modified file 'breezy/commit.py' |
199 | --- breezy/commit.py 2020-08-10 15:00:17 +0000 |
200 | +++ breezy/commit.py 2021-12-25 12:35:58 +0000 |
201 | @@ -62,7 +62,7 @@ |
202 | StrictCommitFailed |
203 | ) |
204 | from .osutils import (get_user_encoding, |
205 | - has_symlinks, |
206 | + supports_symlinks, |
207 | is_inside_any, |
208 | minimum_path_selection, |
209 | ) |
210 | |
211 | === modified file 'breezy/git/tests/test_object_store.py' |
212 | --- breezy/git/tests/test_object_store.py 2020-02-18 01:57:45 +0000 |
213 | +++ breezy/git/tests/test_object_store.py 2021-12-25 12:35:58 +0000 |
214 | @@ -171,7 +171,7 @@ |
215 | self.assertEqual(b, self.store[b.id]) |
216 | |
217 | def test_directory_converted_to_symlink(self): |
218 | - self.requireFeature(SymlinkFeature) |
219 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
220 | b = Blob() |
221 | b.data = b'trgt' |
222 | self.store.lock_read() |
223 | |
224 | === modified file 'breezy/git/transform.py' |
225 | --- breezy/git/transform.py 2021-11-15 23:21:12 +0000 |
226 | +++ breezy/git/transform.py 2021-12-25 12:35:58 +0000 |
227 | @@ -1582,6 +1582,9 @@ |
228 | def supports_setting_file_ids(self): |
229 | return False |
230 | |
231 | + def supports_symlinks(self): |
232 | + return self._transform._create_symlinks |
233 | + |
234 | def _supports_executable(self): |
235 | return self._transform._limbo_supports_executable() |
236 | |
237 | |
238 | === modified file 'breezy/git/tree.py' |
239 | --- breezy/git/tree.py 2021-11-16 17:49:16 +0000 |
240 | +++ breezy/git/tree.py 2021-12-25 12:35:58 +0000 |
241 | @@ -257,6 +257,9 @@ |
242 | |
243 | supports_file_ids = False |
244 | |
245 | + def supports_symlinks(self): |
246 | + return True |
247 | + |
248 | def iter_git_objects(self): |
249 | """Iterate over all the objects in the tree. |
250 | |
251 | |
252 | === modified file 'breezy/location.py' |
253 | --- breezy/location.py 2021-06-04 19:21:33 +0000 |
254 | +++ breezy/location.py 2021-12-25 12:35:58 +0000 |
255 | @@ -47,7 +47,8 @@ |
256 | :return: A URL, e.g. "ssh://foo/bar" |
257 | :raises ValueError: if this is not a RCP-style URL |
258 | """ |
259 | - m = re.match('^(?P<user>[^@:/]+@)?(?P<host>[^/:]+):(?P<path>.*)$', location) |
260 | + m = re.match('^(?P<user>[^@:/]+@)?(?P<host>[^/:]{2,}):(?P<path>.*)$', |
261 | + location) |
262 | if not m: |
263 | raise ValueError("Not a RCP URL") |
264 | if m.group('path').startswith('//'): |
265 | |
266 | === modified file 'breezy/osutils.py' |
267 | --- breezy/osutils.py 2021-11-13 13:01:39 +0000 |
268 | +++ breezy/osutils.py 2021-12-25 12:35:58 +0000 |
269 | @@ -329,31 +329,37 @@ |
270 | drive, path = ntpath.splitdrive(path) |
271 | return drive.upper() + path |
272 | |
273 | +def _win32_fix_separators(path): |
274 | + """Return path with directory separators changed to forward slashes""" |
275 | + if isinstance(path, bytes): |
276 | + return path.replace(b'\\', b'/') |
277 | + else: |
278 | + return path.replace('\\', '/') |
279 | |
280 | def _win32_abspath(path): |
281 | # Real ntpath.abspath doesn't have a problem with a unicode cwd |
282 | - return _win32_fixdrive(ntpath.abspath(path).replace('\\', '/')) |
283 | + return _win32_fixdrive(_win32_fix_separators(ntpath.abspath(path))) |
284 | |
285 | |
286 | def _win32_realpath(path): |
287 | # Real ntpath.realpath doesn't have a problem with a unicode cwd |
288 | - return _win32_fixdrive(ntpath.realpath(path).replace('\\', '/')) |
289 | + return _win32_fixdrive(_win32_fix_separators(ntpath.realpath(path))) |
290 | |
291 | |
292 | def _win32_pathjoin(*args): |
293 | - return ntpath.join(*args).replace('\\', '/') |
294 | + return _win32_fix_separators(ntpath.join(*args)) |
295 | |
296 | |
297 | def _win32_normpath(path): |
298 | - return _win32_fixdrive(ntpath.normpath(path).replace('\\', '/')) |
299 | + return _win32_fixdrive(_win32_fix_separators(ntpath.normpath(path))) |
300 | |
301 | |
302 | def _win32_getcwd(): |
303 | - return _win32_fixdrive(_getcwd().replace('\\', '/')) |
304 | + return _win32_fixdrive(_win32_fix_separators(_getcwd())) |
305 | |
306 | |
307 | def _win32_mkdtemp(*args, **kwargs): |
308 | - return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/')) |
309 | + return _win32_fixdrive(_win32_fix_separators(tempfile.mkdtemp(*args, **kwargs))) |
310 | |
311 | |
312 | def _win32_rename(old, new): |
313 | @@ -456,7 +462,7 @@ |
314 | Helps to remove files and dirs marked as read-only. |
315 | """ |
316 | exception = excinfo[1] |
317 | - if function in (os.remove, os.rmdir) \ |
318 | + if function in (os.unlink, os.remove, os.rmdir) \ |
319 | and isinstance(exception, OSError) \ |
320 | and exception.errno == errno.EACCES: |
321 | make_writable(path) |
322 | @@ -1139,22 +1145,23 @@ |
323 | os.unlink(path) |
324 | |
325 | |
326 | -def has_symlinks(): |
327 | - if getattr(os, 'symlink', None) is not None: |
328 | - return True |
329 | - else: |
330 | - return False |
331 | - |
332 | - |
333 | -def has_hardlinks(): |
334 | - if getattr(os, 'link', None) is not None: |
335 | - return True |
336 | - else: |
337 | - return False |
338 | +def supports_hardlinks(path): |
339 | + if getattr(os, 'link', None) is None: |
340 | + return False |
341 | + try: |
342 | + fs_type = get_fs_type(path) |
343 | + except errors.DependencyNotPresent as e: |
344 | + trace.mutter('Unable to get fs type for %r: %s', path, e) |
345 | + return True |
346 | + else: |
347 | + if fs_type in ('vfat', 'ntfs'): |
348 | + # filesystems known to not support hardlinks |
349 | + return False |
350 | + return True |
351 | |
352 | |
353 | def host_os_dereferences_symlinks(): |
354 | - return (has_symlinks() |
355 | + return (getattr(os, 'symlink', None) is not None |
356 | and sys.platform not in ('cygwin', 'win32')) |
357 | |
358 | |
359 | @@ -1582,7 +1589,7 @@ |
360 | """Return if the filesystem at path supports the creation of symbolic links. |
361 | |
362 | """ |
363 | - if not has_symlinks(): |
364 | + if getattr(os, 'symlink', None) is None: |
365 | return False |
366 | try: |
367 | fs_type = get_fs_type(path) |
368 | @@ -2327,51 +2334,6 @@ |
369 | data, _ = self.encode(object, self.errors) |
370 | self.stream.write(data) |
371 | |
372 | - |
373 | -if sys.platform == 'win32': |
374 | - def open_file(filename, mode='r', bufsize=-1): |
375 | - """This function is used to override the ``open`` builtin. |
376 | - |
377 | - But it uses O_NOINHERIT flag so the file handle is not inherited by |
378 | - child processes. Deleting or renaming a closed file opened with this |
379 | - function is not blocking child processes. |
380 | - """ |
381 | - writing = 'w' in mode |
382 | - appending = 'a' in mode |
383 | - updating = '+' in mode |
384 | - binary = 'b' in mode |
385 | - |
386 | - flags = O_NOINHERIT |
387 | - # see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx |
388 | - # for flags for each modes. |
389 | - if binary: |
390 | - flags |= O_BINARY |
391 | - else: |
392 | - flags |= O_TEXT |
393 | - |
394 | - if writing: |
395 | - if updating: |
396 | - flags |= os.O_RDWR |
397 | - else: |
398 | - flags |= os.O_WRONLY |
399 | - flags |= os.O_CREAT | os.O_TRUNC |
400 | - elif appending: |
401 | - if updating: |
402 | - flags |= os.O_RDWR |
403 | - else: |
404 | - flags |= os.O_WRONLY |
405 | - flags |= os.O_CREAT | os.O_APPEND |
406 | - else: # reading |
407 | - if updating: |
408 | - flags |= os.O_RDWR |
409 | - else: |
410 | - flags |= os.O_RDONLY |
411 | - |
412 | - return os.fdopen(os.open(filename, flags), mode, bufsize) |
413 | -else: |
414 | - open_file = open |
415 | - |
416 | - |
417 | def available_backup_name(base, exists): |
418 | """Find a non-existing backup file name. |
419 | |
420 | |
421 | === modified file 'breezy/plugins/fastimport/exporter.py' |
422 | --- breezy/plugins/fastimport/exporter.py 2020-07-18 23:14:00 +0000 |
423 | +++ breezy/plugins/fastimport/exporter.py 2021-12-25 12:35:58 +0000 |
424 | @@ -504,7 +504,7 @@ |
425 | # Map kind changes to a delete followed by an add |
426 | for change in changes.kind_changed: |
427 | path = self._adjust_path_for_renames( |
428 | - path, renamed, tree_new.get_revision_id()) |
429 | + change.path[0], renamed, tree_new.get_revision_id()) |
430 | # IGC: I don't understand why a delete is needed here. |
431 | # In fact, it seems harmful? If you uncomment this line, |
432 | # please file a bug explaining why you needed to. |
433 | |
434 | === modified file 'breezy/plugins/fastimport/tests/test_commands.py' |
435 | --- breezy/plugins/fastimport/tests/test_commands.py 2020-02-18 01:57:45 +0000 |
436 | +++ breezy/plugins/fastimport/tests/test_commands.py 2021-12-25 12:35:58 +0000 |
437 | @@ -156,7 +156,7 @@ |
438 | |
439 | def test_symlink(self): |
440 | tree = self.make_branch_and_tree("br") |
441 | - self.requireFeature(features.SymlinkFeature) |
442 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
443 | os.symlink('symlink-target', 'br/symlink') |
444 | tree.add('symlink') |
445 | tree.commit("add a symlink") |
446 | |
447 | === modified file 'breezy/plugins/po_merge/po_merge.py' |
448 | --- breezy/plugins/po_merge/po_merge.py 2020-02-18 01:57:45 +0000 |
449 | +++ breezy/plugins/po_merge/po_merge.py 2021-12-25 12:35:58 +0000 |
450 | @@ -152,13 +152,13 @@ |
451 | env['result'] = osutils.pathjoin(tmpdir, 'result') |
452 | env['pot_file'] = self.pot_file_abspath |
453 | try: |
454 | - with osutils.open_file(env['this'], 'wb') as f: |
455 | + with open(env['this'], 'wb') as f: |
456 | f.writelines(params.this_lines) |
457 | - with osutils.open_file(env['other'], 'wb') as f: |
458 | + with open(env['other'], 'wb') as f: |
459 | f.writelines(params.other_lines) |
460 | command = self.conf.expand_options(self.command, env) |
461 | retcode, out, err = self._invoke(command) |
462 | - with osutils.open_file(env['result'], 'rb') as f: |
463 | + with open(env['result'], 'rb') as f: |
464 | # FIXME: To avoid the list() construct below which means the |
465 | # whole 'result' file is kept in memory, there may be a way to |
466 | # use an iterator that will close the file when it's done, but |
467 | |
468 | === modified file 'breezy/plugins/upload/tests/test_upload.py' |
469 | --- breezy/plugins/upload/tests/test_upload.py 2020-06-21 02:15:25 +0000 |
470 | +++ breezy/plugins/upload/tests/test_upload.py 2021-12-25 12:35:58 +0000 |
471 | @@ -176,13 +176,13 @@ |
472 | self.tree.commit('change %s from file to dir' % path) |
473 | |
474 | def add_symlink(self, path, target, base=branch_dir): |
475 | - self.requireFeature(features.SymlinkFeature) |
476 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
477 | os.symlink(target, osutils.pathjoin(base, path)) |
478 | self.tree.add(path) |
479 | self.tree.commit('add symlink %s -> %s' % (path, target)) |
480 | |
481 | def modify_symlink(self, path, target, base=branch_dir): |
482 | - self.requireFeature(features.SymlinkFeature) |
483 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
484 | full_path = osutils.pathjoin(base, path) |
485 | os.unlink(full_path) |
486 | os.symlink(target, full_path) |
487 | |
488 | === modified file 'breezy/smtp_connection.py' |
489 | --- breezy/smtp_connection.py 2020-02-18 01:57:45 +0000 |
490 | +++ breezy/smtp_connection.py 2021-12-25 12:35:58 +0000 |
491 | @@ -111,9 +111,8 @@ |
492 | |
493 | def _create_connection(self): |
494 | """Create an SMTP connection.""" |
495 | - self._connection = self._smtp_factory() |
496 | try: |
497 | - self._connection.connect(self._smtp_server) |
498 | + self._connection = self._smtp_factory(host=self._smtp_server) |
499 | except socket.error as e: |
500 | if e.args[0] == errno.ECONNREFUSED: |
501 | if self._config_smtp_server is None: |
502 | |
503 | === modified file 'breezy/tests/blackbox/test_add.py' |
504 | --- breezy/tests/blackbox/test_add.py 2018-11-17 18:49:41 +0000 |
505 | +++ breezy/tests/blackbox/test_add.py 2021-12-25 12:35:58 +0000 |
506 | @@ -211,7 +211,7 @@ |
507 | self.assertContainsRe(err, r'ERROR:.*\.bzr.*control file') |
508 | |
509 | def test_add_via_symlink(self): |
510 | - self.requireFeature(features.SymlinkFeature) |
511 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
512 | self.make_branch_and_tree('source') |
513 | self.build_tree(['source/top.txt']) |
514 | os.symlink('source', 'link') |
515 | @@ -219,7 +219,7 @@ |
516 | self.assertEqual(out, 'adding top.txt\n') |
517 | |
518 | def test_add_symlink_to_abspath(self): |
519 | - self.requireFeature(features.SymlinkFeature) |
520 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
521 | self.make_branch_and_tree('tree') |
522 | os.symlink(osutils.abspath('target'), 'tree/link') |
523 | out = self.run_bzr(['add', 'tree/link'])[0] |
524 | |
525 | === modified file 'breezy/tests/blackbox/test_branch.py' |
526 | --- breezy/tests/blackbox/test_branch.py 2020-06-13 02:58:24 +0000 |
527 | +++ breezy/tests/blackbox/test_branch.py 2021-12-25 12:35:58 +0000 |
528 | @@ -251,7 +251,7 @@ |
529 | self.assertTrue(pushed_repo.has_revision(b'b-1')) |
530 | |
531 | def test_branch_hardlink(self): |
532 | - self.requireFeature(HardlinkFeature) |
533 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
534 | source = self.make_branch_and_tree('source') |
535 | self.build_tree(['source/file1']) |
536 | source.add('file1') |
537 | @@ -270,7 +270,7 @@ |
538 | self.assertPathExists('target/file1') |
539 | |
540 | def test_branch_files_from_hardlink(self): |
541 | - self.requireFeature(HardlinkFeature) |
542 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
543 | source = self.make_branch_and_tree('source') |
544 | self.build_tree(['source/file1']) |
545 | source.add('file1') |
546 | |
547 | === modified file 'breezy/tests/blackbox/test_checkout.py' |
548 | --- breezy/tests/blackbox/test_checkout.py 2020-06-13 02:58:24 +0000 |
549 | +++ breezy/tests/blackbox/test_checkout.py 2021-12-25 12:35:58 +0000 |
550 | @@ -157,7 +157,7 @@ |
551 | 'branch']) |
552 | |
553 | def test_checkout_hardlink(self): |
554 | - self.requireFeature(HardlinkFeature) |
555 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
556 | source = self.make_branch_and_tree('source') |
557 | self.build_tree(['source/file1']) |
558 | source.add('file1') |
559 | @@ -168,7 +168,7 @@ |
560 | self.assertEqual(source_stat, target_stat) |
561 | |
562 | def test_checkout_hardlink_files_from(self): |
563 | - self.requireFeature(HardlinkFeature) |
564 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
565 | source = self.make_branch_and_tree('source') |
566 | self.build_tree(['source/file1']) |
567 | source.add('file1') |
568 | |
569 | === modified file 'breezy/tests/blackbox/test_cp.py' |
570 | --- breezy/tests/blackbox/test_cp.py 2018-07-16 22:59:06 +0000 |
571 | +++ breezy/tests/blackbox/test_cp.py 2021-12-25 12:35:58 +0000 |
572 | @@ -29,7 +29,6 @@ |
573 | ) |
574 | from breezy.tests.features import ( |
575 | CaseInsensitiveFilesystemFeature, |
576 | - SymlinkFeature, |
577 | UnicodeFilenameFeature, |
578 | ) |
579 | |
580 | |
581 | === modified file 'breezy/tests/blackbox/test_link_tree.py' |
582 | --- breezy/tests/blackbox/test_link_tree.py 2018-02-18 15:21:06 +0000 |
583 | +++ breezy/tests/blackbox/test_link_tree.py 2021-12-25 12:35:58 +0000 |
584 | @@ -30,10 +30,9 @@ |
585 | |
586 | class TestLinkTreeCommand(tests.TestCaseWithTransport): |
587 | |
588 | - _test_needs_features = [HardlinkFeature] |
589 | - |
590 | def setUp(self): |
591 | tests.TestCaseWithTransport.setUp(self) |
592 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
593 | self.parent_tree = self.make_branch_and_tree('parent') |
594 | self.parent_tree.lock_write() |
595 | self.addCleanup(self.parent_tree.unlock) |
596 | |
597 | === modified file 'breezy/tests/blackbox/test_merge_directive.py' |
598 | --- breezy/tests/blackbox/test_merge_directive.py 2018-11-11 04:08:32 +0000 |
599 | +++ breezy/tests/blackbox/test_merge_directive.py 2021-12-25 12:35:58 +0000 |
600 | @@ -119,6 +119,7 @@ |
601 | |
602 | def connect(self, host='localhost', port=0): |
603 | connect_calls.append((self, host, port)) |
604 | + return (220, 'Ok') |
605 | |
606 | def has_extn(self, extension): |
607 | return False |
608 | |
609 | === modified file 'breezy/tests/blackbox/test_mv.py' |
610 | --- breezy/tests/blackbox/test_mv.py 2018-11-23 19:47:13 +0000 |
611 | +++ breezy/tests/blackbox/test_mv.py 2021-12-25 12:35:58 +0000 |
612 | @@ -192,7 +192,7 @@ |
613 | 'mv . a') |
614 | |
615 | def test_mv_through_symlinks(self): |
616 | - self.requireFeature(SymlinkFeature) |
617 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
618 | tree = self.make_branch_and_tree('.') |
619 | self.build_tree(['a/', 'a/b']) |
620 | os.symlink('a', 'c') |
621 | |
622 | === modified file 'breezy/tests/blackbox/test_remove.py' |
623 | --- breezy/tests/blackbox/test_remove.py 2019-06-29 19:54:32 +0000 |
624 | +++ breezy/tests/blackbox/test_remove.py 2021-12-25 12:35:58 +0000 |
625 | @@ -123,7 +123,7 @@ |
626 | self.assertNotInWorkingTree('bar', tree=tree) |
627 | |
628 | def test_remove_no_files_specified_missing_link(self): |
629 | - self.requireFeature(features.SymlinkFeature) |
630 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
631 | tree = self._make_tree_and_add(['foo']) |
632 | os.symlink('foo', 'linkname') |
633 | tree.add(['linkname']) |
634 | |
635 | === modified file 'breezy/tests/blackbox/test_revert.py' |
636 | --- breezy/tests/blackbox/test_revert.py 2018-11-11 04:08:32 +0000 |
637 | +++ breezy/tests/blackbox/test_revert.py 2021-12-25 12:35:58 +0000 |
638 | @@ -145,7 +145,7 @@ |
639 | os.rmdir('revertdir') |
640 | self.run_bzr('revert') |
641 | |
642 | - if breezy.osutils.has_symlinks(): |
643 | + if breezy.osutils.supports_symlinks(self.test_dir): |
644 | os.symlink('/unlikely/to/exist', 'symlink') |
645 | self.run_bzr('add symlink') |
646 | self.run_bzr('commit -m f') |
647 | |
648 | === modified file 'breezy/tests/blackbox/test_too_much.py' |
649 | --- breezy/tests/blackbox/test_too_much.py 2020-06-21 02:15:25 +0000 |
650 | +++ breezy/tests/blackbox/test_too_much.py 2021-12-25 12:35:58 +0000 |
651 | @@ -85,7 +85,7 @@ |
652 | os.rmdir('revertdir') |
653 | self.run_bzr('revert') |
654 | |
655 | - if osutils.has_symlinks(): |
656 | + if osutils.supports_symlinks(self.test_dir): |
657 | os.symlink('/unlikely/to/exist', 'symlink') |
658 | self.run_bzr('add symlink') |
659 | self.run_bzr('commit -m f') |
660 | @@ -460,7 +460,7 @@ |
661 | |
662 | self.run_bzr('info') |
663 | |
664 | - if osutils.has_symlinks(): |
665 | + if osutils.supports_symlinks(self.test_dir): |
666 | progress("symlinks") |
667 | mkdir('symlinks') |
668 | chdir('symlinks') |
669 | |
670 | === modified file 'breezy/tests/features.py' |
671 | --- breezy/tests/features.py 2021-11-13 13:01:39 +0000 |
672 | +++ breezy/tests/features.py 2021-12-25 12:35:58 +0000 |
673 | @@ -59,30 +59,33 @@ |
674 | return self.__class__.__name__ |
675 | |
676 | |
677 | -class _SymlinkFeature(Feature): |
678 | +class SymlinkFeature(Feature): |
679 | + """Whether symlinks can be created by the current user.""" |
680 | + |
681 | + def __init__(self, path): |
682 | + super(SymlinkFeature, self).__init__() |
683 | + self.path = path |
684 | |
685 | def _probe(self): |
686 | - return osutils.has_symlinks() |
687 | + return osutils.supports_symlinks(self.path) |
688 | |
689 | def feature_name(self): |
690 | return 'symlinks' |
691 | |
692 | |
693 | -SymlinkFeature = _SymlinkFeature() |
694 | - |
695 | - |
696 | -class _HardlinkFeature(Feature): |
697 | +class HardlinkFeature(Feature): |
698 | + |
699 | + def __init__(self, path): |
700 | + super(HardlinkFeature, self).__init__() |
701 | + self.path = path |
702 | |
703 | def _probe(self): |
704 | - return osutils.has_hardlinks() |
705 | + return osutils.supports_hardlinks(self.path) |
706 | |
707 | def feature_name(self): |
708 | return 'hardlinks' |
709 | |
710 | |
711 | -HardlinkFeature = _HardlinkFeature() |
712 | - |
713 | - |
714 | class _OsFifoFeature(Feature): |
715 | |
716 | def _probe(self): |
717 | |
718 | === modified file 'breezy/tests/per_branch/test_sprout.py' |
719 | --- breezy/tests/per_branch/test_sprout.py 2020-01-12 13:56:10 +0000 |
720 | +++ breezy/tests/per_branch/test_sprout.py 2021-12-25 12:35:58 +0000 |
721 | @@ -161,7 +161,7 @@ |
722 | # Since the trigger function seems to be set_parent_trees, there exists |
723 | # also a similar test, with name test_unicode_symlink, in class |
724 | # TestSetParents at file per_workingtree/test_parents.py |
725 | - self.requireFeature(features.SymlinkFeature) |
726 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
727 | self.requireFeature(features.UnicodeFilenameFeature) |
728 | |
729 | tree = self.make_branch_and_tree('tree1') |
730 | |
731 | === modified file 'breezy/tests/per_intertree/test_compare.py' |
732 | --- breezy/tests/per_intertree/test_compare.py 2021-11-13 17:24:04 +0000 |
733 | +++ breezy/tests/per_intertree/test_compare.py 2021-12-25 12:35:58 +0000 |
734 | @@ -25,7 +25,7 @@ |
735 | tests, |
736 | ) |
737 | from breezy.tree import TreeChange |
738 | -from breezy.osutils import has_symlinks |
739 | +from breezy.osutils import supports_symlinks |
740 | from breezy.bzr.inventorytree import InventoryTreeChange |
741 | from breezy.tests.per_intertree import TestCaseWithTwoTrees |
742 | from breezy.tests import ( |
743 | @@ -390,7 +390,7 @@ |
744 | tree2 = self.make_to_branch_and_tree('tree2') |
745 | tree2.set_root_id(tree1.path2id('')) |
746 | self.build_tree(['tree2/file', 'tree2/dir/']) |
747 | - if has_symlinks(): |
748 | + if supports_symlinks(self.test_dir): |
749 | os.symlink('target', 'tree2/link') |
750 | links_supported = True |
751 | else: |
752 | @@ -1267,7 +1267,7 @@ |
753 | tree2 = self.make_to_branch_and_tree('tree2') |
754 | tree2.set_root_id(tree1.path2id('')) |
755 | self.build_tree(['tree2/file', 'tree2/dir/']) |
756 | - if has_symlinks(): |
757 | + if supports_symlinks(self.test_dir): |
758 | os.symlink('target', 'tree2/link') |
759 | links_supported = True |
760 | else: |
761 | @@ -1288,7 +1288,7 @@ |
762 | tree1 = self.make_branch_and_tree('tree1') |
763 | tree2 = self.make_to_branch_and_tree('tree2') |
764 | self.build_tree(['tree2/file', 'tree2/dir/']) |
765 | - if has_symlinks(): |
766 | + if supports_symlinks(self.test_dir): |
767 | os.symlink('target', 'tree2/link') |
768 | links_supported = True |
769 | else: |
770 | @@ -1322,7 +1322,7 @@ |
771 | self.build_tree(['tree2/file', 'tree2/dir/', |
772 | 'tree1/file', 'tree2/movedfile', |
773 | 'tree1/dir/', 'tree2/moveddir/']) |
774 | - if has_symlinks(): |
775 | + if supports_symlinks(self.test_dir): |
776 | os.symlink('target', 'tree1/link') |
777 | os.symlink('target', 'tree2/link') |
778 | os.symlink('target', 'tree2/movedlink') |
779 | @@ -1459,7 +1459,7 @@ |
780 | return self.mutable_trees_to_locked_test_trees(tree1, tree2) |
781 | |
782 | def test_versioned_symlinks(self): |
783 | - self.requireFeature(features.SymlinkFeature) |
784 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
785 | tree1, tree2 = self.make_trees_with_symlinks() |
786 | self.not_applicable_if_cannot_represent_unversioned(tree2) |
787 | root_id = tree1.path2id('') |
788 | @@ -1482,7 +1482,7 @@ |
789 | self.check_has_changes(True, tree1, tree2) |
790 | |
791 | def test_versioned_symlinks_specific_files(self): |
792 | - self.requireFeature(features.SymlinkFeature) |
793 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
794 | tree1, tree2 = self.make_trees_with_symlinks() |
795 | root_id = tree1.path2id('') |
796 | expected = [ |
797 | |
798 | === modified file 'breezy/tests/per_repository/test_commit_builder.py' |
799 | --- breezy/tests/per_repository/test_commit_builder.py 2021-11-16 01:24:28 +0000 |
800 | +++ breezy/tests/per_repository/test_commit_builder.py 2021-12-25 12:35:58 +0000 |
801 | @@ -323,7 +323,7 @@ |
802 | |
803 | def test_last_modified_revision_after_commit_link_unchanged(self): |
804 | # committing without changing a link does not change the last modified. |
805 | - self.requireFeature(features.SymlinkFeature) |
806 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
807 | tree = self.make_branch_and_tree('.') |
808 | os.symlink('target', 'link') |
809 | self._add_commit_check_unchanged(tree, 'link') |
810 | @@ -374,7 +374,7 @@ |
811 | |
812 | def test_last_modified_revision_after_rename_link_changes(self): |
813 | # renaming a link changes the last modified. |
814 | - self.requireFeature(features.SymlinkFeature) |
815 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
816 | tree = self.make_branch_and_tree('.') |
817 | os.symlink('target', 'link') |
818 | self._add_commit_renamed_check_changed(tree, 'link') |
819 | @@ -419,7 +419,7 @@ |
820 | |
821 | def test_last_modified_revision_after_reparent_link_changes(self): |
822 | # reparenting a link changes the last modified. |
823 | - self.requireFeature(features.SymlinkFeature) |
824 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
825 | tree = self.make_branch_and_tree('.') |
826 | os.symlink('target', 'link') |
827 | self._add_commit_reparent_check_changed(tree, 'link') |
828 | @@ -567,7 +567,7 @@ |
829 | def _test_last_mod_rev_after_content_link_changes( |
830 | self, link, target, newtarget): |
831 | # changing a link changes the last modified. |
832 | - self.requireFeature(features.SymlinkFeature) |
833 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
834 | tree = self.make_branch_and_tree('.') |
835 | os.symlink(target, link) |
836 | |
837 | @@ -642,7 +642,7 @@ |
838 | |
839 | def test_last_modified_revision_after_merge_link_changes(self): |
840 | # merge a link changes the last modified. |
841 | - self.requireFeature(features.SymlinkFeature) |
842 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
843 | tree1 = self.make_branch_and_tree('t1') |
844 | os.symlink('target', 't1/link') |
845 | self._commit_sprout_rename_merge(tree1, 'link') |
846 | @@ -720,7 +720,7 @@ |
847 | |
848 | def test_last_modified_revision_after_converged_merge_link_unchanged(self): |
849 | # merge a link that changed preserves the last modified. |
850 | - self.requireFeature(features.SymlinkFeature) |
851 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
852 | tree1 = self.make_branch_and_tree('t1') |
853 | os.symlink('target', 't1/link') |
854 | self._commit_sprout_rename_merge_converged(tree1, 'link') |
855 | @@ -750,7 +750,7 @@ |
856 | self.build_tree([name]) |
857 | |
858 | def make_link(self, name): |
859 | - self.requireFeature(features.SymlinkFeature) |
860 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
861 | os.symlink('target', name) |
862 | |
863 | def make_reference(self, name): |
864 | |
865 | === modified file 'breezy/tests/per_tree/__init__.py' |
866 | --- breezy/tests/per_tree/__init__.py 2020-11-18 22:02:00 +0000 |
867 | +++ breezy/tests/per_tree/__init__.py 2021-12-25 12:35:58 +0000 |
868 | @@ -247,7 +247,7 @@ |
869 | Note: if you wish to automatically set this |
870 | parameters depending on underlying system, |
871 | please use value returned |
872 | - by breezy.osutils.has_symlinks() function. |
873 | + by breezy.osutils.supports_symlinks() function. |
874 | |
875 | The returned tree has the following inventory: |
876 | ['', |
877 | |
878 | === modified file 'breezy/tests/per_tree/test_archive.py' |
879 | --- breezy/tests/per_tree/test_archive.py 2018-11-11 04:08:32 +0000 |
880 | +++ breezy/tests/per_tree/test_archive.py 2021-12-25 12:35:58 +0000 |
881 | @@ -47,7 +47,7 @@ |
882 | self.assertIn('dir', names) |
883 | |
884 | def test_export_symlink(self): |
885 | - self.requireFeature(features.SymlinkFeature) |
886 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
887 | work_a = self.make_branch_and_tree('wta') |
888 | os.symlink('target', 'wta/link') |
889 | work_a.add('link') |
890 | @@ -99,7 +99,7 @@ |
891 | zf.close() |
892 | |
893 | def test_export_symlink(self): |
894 | - self.requireFeature(features.SymlinkFeature) |
895 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
896 | work_a = self.make_branch_and_tree('wta') |
897 | os.symlink('target', 'wta/link') |
898 | work_a.add('link') |
899 | |
900 | === modified file 'breezy/tests/per_tree/test_export.py' |
901 | --- breezy/tests/per_tree/test_export.py 2018-02-18 15:21:06 +0000 |
902 | +++ breezy/tests/per_tree/test_export.py 2021-12-25 12:35:58 +0000 |
903 | @@ -40,7 +40,7 @@ |
904 | export(tree_a, 'output', self.exporter) |
905 | |
906 | def prepare_symlink_export(self): |
907 | - self.requireFeature(features.SymlinkFeature) |
908 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
909 | work_a = self.make_branch_and_tree('wta') |
910 | os.symlink('target', 'wta/link') |
911 | work_a.add('link') |
912 | |
913 | === modified file 'breezy/tests/per_tree/test_get_symlink_target.py' |
914 | --- breezy/tests/per_tree/test_get_symlink_target.py 2021-11-13 13:01:39 +0000 |
915 | +++ breezy/tests/per_tree/test_get_symlink_target.py 2021-12-25 12:35:58 +0000 |
916 | @@ -31,7 +31,7 @@ |
917 | class TestGetSymlinkTarget(per_tree.TestCaseWithTree): |
918 | |
919 | def get_tree_with_symlinks(self): |
920 | - self.requireFeature(features.SymlinkFeature) |
921 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
922 | tree = self.make_branch_and_tree('tree') |
923 | os.symlink('foo', 'tree/link') |
924 | os.symlink('../bar', 'tree/rel_link') |
925 | @@ -53,7 +53,7 @@ |
926 | tree.get_symlink_target('link')) |
927 | |
928 | def test_get_unicode_symlink_target(self): |
929 | - self.requireFeature(features.SymlinkFeature) |
930 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
931 | self.requireFeature(features.UnicodeFilenameFeature) |
932 | tree = self.make_branch_and_tree('tree') |
933 | target = u'targ\N{Euro Sign}t' |
934 | |
935 | === modified file 'breezy/tests/per_tree/test_is_executable.py' |
936 | --- breezy/tests/per_tree/test_is_executable.py 2017-11-12 14:19:13 +0000 |
937 | +++ breezy/tests/per_tree/test_is_executable.py 2021-12-25 12:35:58 +0000 |
938 | @@ -32,7 +32,7 @@ |
939 | self.assertEqual(False, tree.is_executable('1top-dir')) |
940 | |
941 | def test_is_executable_symlink(self): |
942 | - self.requireFeature(SymlinkFeature) |
943 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
944 | tree = self.get_tree_with_subdirs_and_all_content_types() |
945 | tree.lock_read() |
946 | self.addCleanup(tree.unlock) |
947 | |
948 | === modified file 'breezy/tests/per_tree/test_path_content_summary.py' |
949 | --- breezy/tests/per_tree/test_path_content_summary.py 2021-11-13 13:01:39 +0000 |
950 | +++ breezy/tests/per_tree/test_path_content_summary.py 2021-12-25 12:35:58 +0000 |
951 | @@ -56,7 +56,7 @@ |
952 | self.fail("invalid size in summary: %r" % (returned_size,)) |
953 | |
954 | def test_symlink_content_summary(self): |
955 | - self.requireFeature(SymlinkFeature) |
956 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
957 | tree = self.make_branch_and_tree('tree') |
958 | os.symlink('target', 'tree/path') |
959 | tree.add(['path']) |
960 | @@ -64,7 +64,7 @@ |
961 | self.assertEqual(('symlink', None, None, 'target'), summary) |
962 | |
963 | def test_unicode_symlink_content_summary(self): |
964 | - self.requireFeature(features.SymlinkFeature) |
965 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
966 | self.requireFeature(features.UnicodeFilenameFeature) |
967 | tree = self.make_branch_and_tree('tree') |
968 | os.symlink('target', os.fsencode(u'tree/\u03b2-path')) |
969 | @@ -73,7 +73,7 @@ |
970 | self.assertEqual(('symlink', None, None, 'target'), summary) |
971 | |
972 | def test_unicode_symlink_target_summary(self): |
973 | - self.requireFeature(features.SymlinkFeature) |
974 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
975 | self.requireFeature(features.UnicodeFilenameFeature) |
976 | tree = self.make_branch_and_tree('tree') |
977 | os.symlink(os.fsencode(u'tree/\u03b2-path'), 'tree/link') |
978 | |
979 | === modified file 'breezy/tests/per_tree/test_symlinks.py' |
980 | --- breezy/tests/per_tree/test_symlinks.py 2020-07-07 20:32:36 +0000 |
981 | +++ breezy/tests/per_tree/test_symlinks.py 2021-12-25 12:35:58 +0000 |
982 | @@ -46,10 +46,9 @@ |
983 | |
984 | class TestTreeWithSymlinks(per_tree.TestCaseWithTree): |
985 | |
986 | - _test_needs_features = [features.SymlinkFeature] |
987 | - |
988 | def setUp(self): |
989 | super(TestTreeWithSymlinks, self).setUp() |
990 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
991 | self.tree = self.get_tree_with_subdirs_and_all_content_types() |
992 | self.tree.lock_read() |
993 | self.addCleanup(self.tree.unlock) |
994 | |
995 | === modified file 'breezy/tests/per_tree/test_test_trees.py' |
996 | --- breezy/tests/per_tree/test_test_trees.py 2021-11-13 21:30:35 +0000 |
997 | +++ breezy/tests/per_tree/test_test_trees.py 2021-12-25 12:35:58 +0000 |
998 | @@ -204,7 +204,7 @@ |
999 | # currently this test tree requires unicode. It might be good |
1000 | # to have it simply stop having the single unicode file in it |
1001 | # when dealing with a non-unicode filesystem. |
1002 | - self.requireFeature(features.SymlinkFeature) |
1003 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1004 | tree = self.get_tree_with_subdirs_and_all_content_types() |
1005 | tree.lock_read() |
1006 | self.addCleanup(tree.unlock) |
1007 | |
1008 | === modified file 'breezy/tests/per_tree/test_transform.py' |
1009 | --- breezy/tests/per_tree/test_transform.py 2021-11-13 16:17:55 +0000 |
1010 | +++ breezy/tests/per_tree/test_transform.py 2021-12-25 12:35:58 +0000 |
1011 | @@ -38,7 +38,6 @@ |
1012 | |
1013 | |
1014 | from ..features import ( |
1015 | - HardlinkFeature, |
1016 | SymlinkFeature, |
1017 | UnicodeFilenameFeature, |
1018 | ) |
1019 | @@ -96,7 +95,7 @@ |
1020 | self.assertEqual(lines[4], b"+content B") |
1021 | |
1022 | def test_unsupported_symlink_diff(self): |
1023 | - self.requireFeature(SymlinkFeature) |
1024 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1025 | tree = self.make_branch_and_tree('.') |
1026 | self.build_tree_contents([('a', 'content 1')]) |
1027 | tree.add('a') |
1028 | @@ -104,16 +103,16 @@ |
1029 | tree.add('foo') |
1030 | revid1 = tree.commit('rev1') |
1031 | revision_tree = tree.branch.repository.revision_tree(revid1) |
1032 | - preview = revision_tree.preview_transform() |
1033 | - self.addCleanup(preview.finalize) |
1034 | - preview.delete_versioned(preview.trans_id_tree_path('foo')) |
1035 | - preview_tree = preview.get_preview_tree() |
1036 | - out = BytesIO() |
1037 | - log = BytesIO() |
1038 | - trace.push_log_file(log) |
1039 | os_symlink = getattr(os, 'symlink', None) |
1040 | os.symlink = None |
1041 | try: |
1042 | + preview = revision_tree.preview_transform() |
1043 | + self.addCleanup(preview.finalize) |
1044 | + preview.delete_versioned(preview.trans_id_tree_path('foo')) |
1045 | + preview_tree = preview.get_preview_tree() |
1046 | + out = BytesIO() |
1047 | + log = BytesIO() |
1048 | + trace.push_log_file(log) |
1049 | show_diff_trees(revision_tree, preview_tree, out) |
1050 | lines = out.getvalue().splitlines() |
1051 | finally: |
1052 | @@ -253,7 +252,7 @@ |
1053 | self.assertEqual(b'contents', tree_file.read()) |
1054 | |
1055 | def test_get_symlink_target(self): |
1056 | - self.requireFeature(SymlinkFeature) |
1057 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1058 | preview = self.get_empty_preview() |
1059 | preview.new_symlink('symlink', preview.root, 'target', b'symlink-id') |
1060 | preview_tree = preview.get_preview_tree() |
1061 | @@ -391,7 +390,7 @@ |
1062 | self.assertMatchingIterEntries(tt, ['', 'parent/child']) |
1063 | |
1064 | def test_symlink_content_summary(self): |
1065 | - self.requireFeature(SymlinkFeature) |
1066 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1067 | preview = self.get_empty_preview() |
1068 | preview.new_symlink('path', preview.root, 'target', b'path-id') |
1069 | summary = preview.get_preview_tree().path_content_summary('path') |
1070 | |
1071 | === modified file 'breezy/tests/per_tree/test_walkdirs.py' |
1072 | --- breezy/tests/per_tree/test_walkdirs.py 2021-11-13 21:30:35 +0000 |
1073 | +++ breezy/tests/per_tree/test_walkdirs.py 2021-12-25 12:35:58 +0000 |
1074 | @@ -20,7 +20,7 @@ |
1075 | |
1076 | from breezy import tests |
1077 | from breezy.mutabletree import MutableTree |
1078 | -from breezy.osutils import has_symlinks |
1079 | +from breezy.osutils import supports_symlinks |
1080 | from breezy.tests.per_tree import TestCaseWithTree |
1081 | |
1082 | |
1083 | @@ -55,10 +55,10 @@ |
1084 | |
1085 | def test_walkdir_root(self): |
1086 | tree = self.get_tree_with_subdirs_and_all_supported_content_types( |
1087 | - has_symlinks()) |
1088 | + supports_symlinks(self.test_dir)) |
1089 | with tree.lock_read(): |
1090 | expected_dirblocks = self.get_all_subdirs_expected( |
1091 | - tree, has_symlinks()) |
1092 | + tree, supports_symlinks(self.test_dir)) |
1093 | # test that its iterable by iterating |
1094 | result = [] |
1095 | for dirinfo, block in tree.walkdirs(): |
1096 | @@ -76,12 +76,12 @@ |
1097 | |
1098 | def test_walkdir_subtree(self): |
1099 | tree = self.get_tree_with_subdirs_and_all_supported_content_types( |
1100 | - has_symlinks()) |
1101 | + supports_symlinks(self.test_dir)) |
1102 | # test that its iterable by iterating |
1103 | result = [] |
1104 | with tree.lock_read(): |
1105 | expected_dirblocks = self.get_all_subdirs_expected( |
1106 | - tree, has_symlinks())[1:] |
1107 | + tree, supports_symlinks(self.test_dir))[1:] |
1108 | for dirinfo, block in tree.walkdirs('1top-dir'): |
1109 | newblock = [] |
1110 | for row in block: |
1111 | |
1112 | === modified file 'breezy/tests/per_workingtree/test_parents.py' |
1113 | --- breezy/tests/per_workingtree/test_parents.py 2020-02-07 02:14:30 +0000 |
1114 | +++ breezy/tests/per_workingtree/test_parents.py 2021-12-25 12:35:58 +0000 |
1115 | @@ -254,7 +254,7 @@ |
1116 | |
1117 | def test_unicode_symlink(self): |
1118 | # this tests bug #272444 |
1119 | - self.requireFeature(features.SymlinkFeature) |
1120 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1121 | self.requireFeature(features.UnicodeFilenameFeature) |
1122 | |
1123 | tree = self.make_branch_and_tree('tree1') |
1124 | |
1125 | === modified file 'breezy/tests/per_workingtree/test_symlinks.py' |
1126 | --- breezy/tests/per_workingtree/test_symlinks.py 2018-11-11 04:08:32 +0000 |
1127 | +++ breezy/tests/per_workingtree/test_symlinks.py 2021-12-25 12:35:58 +0000 |
1128 | @@ -34,7 +34,9 @@ |
1129 | |
1130 | # See eg <https://bugs.launchpad.net/bzr/+bug/192859> |
1131 | |
1132 | - _test_needs_features = [features.SymlinkFeature] |
1133 | + def setUp(self): |
1134 | + super(TestSmartAddTree, self).setUp() |
1135 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1136 | |
1137 | def test_smart_add_symlink(self): |
1138 | tree = self.make_branch_and_tree('tree') |
1139 | @@ -84,7 +86,9 @@ |
1140 | |
1141 | class TestKindChanges(TestCaseWithWorkingTree): |
1142 | |
1143 | - _test_needs_features = [features.SymlinkFeature] |
1144 | + def setUp(self): |
1145 | + super(TestKindChanges, self).setUp() |
1146 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1147 | |
1148 | def test_symlink_changes_to_dir(self): |
1149 | # <https://bugs.launchpad.net/bzr/+bug/192859>: |
1150 | @@ -134,7 +138,9 @@ |
1151 | |
1152 | class TestOpenTree(TestCaseWithWorkingTree): |
1153 | |
1154 | - _test_needs_features = [features.SymlinkFeature] |
1155 | + def setUp(self): |
1156 | + super(TestOpenTree, self).setUp() |
1157 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1158 | |
1159 | def test_open_containing_through_symlink(self): |
1160 | self.make_test_tree() |
1161 | |
1162 | === modified file 'breezy/tests/per_workingtree/test_transform.py' |
1163 | --- breezy/tests/per_workingtree/test_transform.py 2021-11-16 01:24:28 +0000 |
1164 | +++ breezy/tests/per_workingtree/test_transform.py 2021-12-25 12:35:58 +0000 |
1165 | @@ -380,7 +380,7 @@ |
1166 | self.assertEqual(old_root_id, self.wt.path2id('')) |
1167 | |
1168 | def test_hardlink(self): |
1169 | - self.requireFeature(HardlinkFeature) |
1170 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
1171 | transform, root = self.transform() |
1172 | transform.new_file('file1', root, [b'contents']) |
1173 | transform.apply() |
1174 | @@ -830,7 +830,7 @@ |
1175 | def ozpath(p): |
1176 | return 'oz/' + p |
1177 | |
1178 | - self.requireFeature(SymlinkFeature) |
1179 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1180 | transform, root = self.transform() |
1181 | oz_id = transform.new_directory('oz', root, b'oz-id') |
1182 | transform.new_symlink(link_name1, oz_id, link_target1, b'wizard-id') |
1183 | @@ -1700,7 +1700,7 @@ |
1184 | self.assertFalse(changes.has_changed(), changes) |
1185 | |
1186 | def test_file_to_symlink(self): |
1187 | - self.requireFeature(SymlinkFeature) |
1188 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1189 | wt = self.make_branch_and_tree('.') |
1190 | self.build_tree(['foo']) |
1191 | wt.add(['foo']) |
1192 | @@ -1753,7 +1753,7 @@ |
1193 | self.assertEqual(wt.kind("foo"), "file") |
1194 | |
1195 | def test_dir_to_hardlink(self): |
1196 | - self.requireFeature(HardlinkFeature) |
1197 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
1198 | wt = self.make_branch_and_tree('.') |
1199 | self.build_tree(['foo/', 'foo/bar']) |
1200 | wt.add(['foo', 'foo/bar']) |
1201 | @@ -1807,7 +1807,7 @@ |
1202 | self.assertFileEqual(b'qux', 'tree2/foo') |
1203 | |
1204 | def test_create_from_tree_symlink(self): |
1205 | - self.requireFeature(SymlinkFeature) |
1206 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1207 | tree1 = self.make_branch_and_tree('tree1') |
1208 | os.symlink('bar', 'tree1/foo') |
1209 | tree1.add('foo') |
1210 | |
1211 | === modified file 'breezy/tests/per_workingtree/test_walkdirs.py' |
1212 | --- breezy/tests/per_workingtree/test_walkdirs.py 2020-08-07 18:35:50 +0000 |
1213 | +++ breezy/tests/per_workingtree/test_walkdirs.py 2021-12-25 12:35:58 +0000 |
1214 | @@ -162,7 +162,7 @@ |
1215 | |
1216 | def test_walkdirs_type_changes(self): |
1217 | """Walkdir shows the actual kinds on disk and the recorded kinds.""" |
1218 | - self.requireFeature(SymlinkFeature) |
1219 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1220 | tree = self.make_branch_and_tree('.') |
1221 | paths = ['file1', 'file2', 'dir1/', 'dir2/'] |
1222 | self.build_tree(paths) |
1223 | |
1224 | === modified file 'breezy/tests/per_workingtree/test_workingtree.py' |
1225 | --- breezy/tests/per_workingtree/test_workingtree.py 2021-11-16 17:49:16 +0000 |
1226 | +++ breezy/tests/per_workingtree/test_workingtree.py 2021-12-25 12:35:58 +0000 |
1227 | @@ -41,7 +41,7 @@ |
1228 | ) |
1229 | from ...bzr.inventory import Inventory |
1230 | from ...mutabletree import MutableTree |
1231 | -from ...osutils import pathjoin, getcwd, has_symlinks |
1232 | +from ...osutils import pathjoin, getcwd, supports_symlinks |
1233 | from .. import ( |
1234 | features, |
1235 | TestSkipped, |
1236 | @@ -83,7 +83,7 @@ |
1237 | def test_list_files(self): |
1238 | tree = self.make_branch_and_tree('.') |
1239 | self.build_tree(['dir/', 'file']) |
1240 | - if has_symlinks(): |
1241 | + if supports_symlinks(self.test_dir): |
1242 | os.symlink('target', 'symlink') |
1243 | tree.lock_read() |
1244 | files = list(tree.list_files()) |
1245 | @@ -91,7 +91,7 @@ |
1246 | self.assertEqual( |
1247 | files.pop(0), ('dir', '?', 'directory', TreeDirectory())) |
1248 | self.assertEqual(files.pop(0), ('file', '?', 'file', TreeFile())) |
1249 | - if has_symlinks(): |
1250 | + if supports_symlinks(self.test_dir): |
1251 | self.assertEqual( |
1252 | files.pop(0), ('symlink', '?', 'symlink', TreeLink())) |
1253 | |
1254 | @@ -977,7 +977,7 @@ |
1255 | self.addCleanup(tree.unlock) |
1256 | self.build_tree(['file', 'directory/']) |
1257 | names = ['file', 'directory'] |
1258 | - if has_symlinks(): |
1259 | + if supports_symlinks(self.test_dir): |
1260 | os.symlink('target', 'symlink') |
1261 | names.append('symlink') |
1262 | tree.add(names) |
1263 | |
1264 | === modified file 'breezy/tests/test_clean_tree.py' |
1265 | --- breezy/tests/test_clean_tree.py 2018-11-11 04:08:32 +0000 |
1266 | +++ breezy/tests/test_clean_tree.py 2021-12-25 12:35:58 +0000 |
1267 | @@ -29,7 +29,7 @@ |
1268 | iter_deletables, |
1269 | ) |
1270 | from ..osutils import ( |
1271 | - has_symlinks, |
1272 | + supports_symlinks, |
1273 | ) |
1274 | from . import ( |
1275 | TestCaseInTempDir, |
1276 | @@ -39,7 +39,7 @@ |
1277 | class TestCleanTree(TestCaseInTempDir): |
1278 | |
1279 | def test_symlinks(self): |
1280 | - if has_symlinks() is False: |
1281 | + if supports_symlinks(self.test_dir) is False: |
1282 | return |
1283 | os.mkdir('branch') |
1284 | ControlDir.create_standalone_workingtree('branch') |
1285 | |
1286 | === modified file 'breezy/tests/test_commit.py' |
1287 | --- breezy/tests/test_commit.py 2021-11-13 16:17:55 +0000 |
1288 | +++ breezy/tests/test_commit.py 2021-12-25 12:35:58 +0000 |
1289 | @@ -677,7 +677,7 @@ |
1290 | basis.unlock() |
1291 | |
1292 | def test_unsupported_symlink_commit(self): |
1293 | - self.requireFeature(SymlinkFeature) |
1294 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1295 | tree = self.make_branch_and_tree('.') |
1296 | self.build_tree(['hello']) |
1297 | tree.add('hello') |
1298 | @@ -706,7 +706,7 @@ |
1299 | b'supported on this filesystem\\.') |
1300 | |
1301 | def test_commit_kind_changes(self): |
1302 | - self.requireFeature(SymlinkFeature) |
1303 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1304 | tree = self.make_branch_and_tree('.') |
1305 | os.symlink('target', 'name') |
1306 | tree.add('name', b'a-file-id') |
1307 | |
1308 | === modified file 'breezy/tests/test_commit_merge.py' |
1309 | --- breezy/tests/test_commit_merge.py 2019-06-29 13:16:26 +0000 |
1310 | +++ breezy/tests/test_commit_merge.py 2021-12-25 12:35:58 +0000 |
1311 | @@ -106,7 +106,7 @@ |
1312 | check.check_dwim(by.base, False, True, True) |
1313 | |
1314 | def test_merge_with_symlink(self): |
1315 | - self.requireFeature(SymlinkFeature) |
1316 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1317 | tree_a = self.make_branch_and_tree('tree_a') |
1318 | os.symlink('target', osutils.pathjoin('tree_a', 'link')) |
1319 | tree_a.add('link') |
1320 | |
1321 | === modified file 'breezy/tests/test_diff.py' |
1322 | --- breezy/tests/test_diff.py 2020-07-18 23:14:00 +0000 |
1323 | +++ breezy/tests/test_diff.py 2021-12-25 12:35:58 +0000 |
1324 | @@ -790,7 +790,7 @@ |
1325 | br' \@\@\n-old\n\+new\n\n') |
1326 | |
1327 | def test_diff_kind_change(self): |
1328 | - self.requireFeature(features.SymlinkFeature) |
1329 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1330 | self.build_tree_contents([('old-tree/olddir/',), |
1331 | ('old-tree/olddir/oldfile', b'old\n')]) |
1332 | self.old_tree.add('olddir') |
1333 | |
1334 | === modified file 'breezy/tests/test_export.py' |
1335 | --- breezy/tests/test_export.py 2020-02-07 02:14:30 +0000 |
1336 | +++ breezy/tests/test_export.py 2021-12-25 12:35:58 +0000 |
1337 | @@ -50,7 +50,7 @@ |
1338 | self.assertEqual([], os.listdir("target")) |
1339 | |
1340 | def test_symlink(self): |
1341 | - self.requireFeature(features.SymlinkFeature) |
1342 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1343 | wt = self.make_branch_and_tree('.') |
1344 | os.symlink('source', 'link') |
1345 | wt.add(['link']) |
1346 | |
1347 | === modified file 'breezy/tests/test_location.py' |
1348 | --- breezy/tests/test_location.py 2021-06-04 19:21:33 +0000 |
1349 | +++ breezy/tests/test_location.py 2021-12-25 12:35:58 +0000 |
1350 | @@ -131,3 +131,5 @@ |
1351 | def test_invalid(self): |
1352 | self.assertRaises(ValueError, rcp_location_to_url, "http://srv/git/bar") |
1353 | self.assertRaises(ValueError, rcp_location_to_url, "git/bar") |
1354 | + # rcp host names cannot be shorter than two characters |
1355 | + self.assertRaises(ValueError, rcp_location_to_url, "c:/git/bar") |
1356 | |
1357 | === modified file 'breezy/tests/test_merge.py' |
1358 | --- breezy/tests/test_merge.py 2021-03-22 21:07:08 +0000 |
1359 | +++ breezy/tests/test_merge.py 2021-12-25 12:35:58 +0000 |
1360 | @@ -2290,7 +2290,7 @@ |
1361 | self.assertTrue(wt.is_executable('foo')) |
1362 | |
1363 | def test_create_symlink(self): |
1364 | - self.requireFeature(features.SymlinkFeature) |
1365 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1366 | # A |
1367 | # / \ |
1368 | # B C |
1369 | @@ -2361,7 +2361,7 @@ |
1370 | wt.get_file_text('foo')) |
1371 | |
1372 | def test_modified_symlink(self): |
1373 | - self.requireFeature(features.SymlinkFeature) |
1374 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1375 | # A Create symlink foo => bar |
1376 | # / \ |
1377 | # B C B relinks foo => baz |
1378 | @@ -2406,7 +2406,7 @@ |
1379 | self.assertEqual('bing', wt.get_symlink_target('foo')) |
1380 | |
1381 | def test_renamed_symlink(self): |
1382 | - self.requireFeature(features.SymlinkFeature) |
1383 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1384 | # A Create symlink foo => bar |
1385 | # / \ |
1386 | # B C B renames foo => barry |
1387 | @@ -2463,7 +2463,7 @@ |
1388 | self.assertEqual('blah', wt.id2path(b'foo-id')) |
1389 | |
1390 | def test_symlink_no_content_change(self): |
1391 | - self.requireFeature(features.SymlinkFeature) |
1392 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1393 | # A Create symlink foo => bar |
1394 | # / \ |
1395 | # B C B relinks foo => baz |
1396 | @@ -2513,7 +2513,7 @@ |
1397 | self.assertEqual('bing', wt.get_symlink_target('foo')) |
1398 | |
1399 | def test_symlink_this_changed_kind(self): |
1400 | - self.requireFeature(features.SymlinkFeature) |
1401 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1402 | # A Nothing |
1403 | # / \ |
1404 | # B C B creates symlink foo => bar |
1405 | @@ -2567,7 +2567,7 @@ |
1406 | |
1407 | def test_symlink_all_wt(self): |
1408 | """Check behavior if all trees are Working Trees.""" |
1409 | - self.requireFeature(features.SymlinkFeature) |
1410 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1411 | # The big issue is that entry.symlink_target is None for WorkingTrees. |
1412 | # So we need to make sure we handle that case correctly. |
1413 | # A foo => bar |
1414 | |
1415 | === modified file 'breezy/tests/test_osutils.py' |
1416 | --- breezy/tests/test_osutils.py 2021-11-13 13:01:39 +0000 |
1417 | +++ breezy/tests/test_osutils.py 2021-12-25 12:35:58 +0000 |
1418 | @@ -294,7 +294,7 @@ |
1419 | self.build_tree(['file', 'dir/']) |
1420 | self.assertEqual('file', osutils.file_kind('file')) |
1421 | self.assertEqual('directory', osutils.file_kind('dir/')) |
1422 | - if osutils.has_symlinks(): |
1423 | + if osutils.supports_symlinks(self.test_dir): |
1424 | os.symlink('symlink', 'symlink') |
1425 | self.assertEqual('symlink', osutils.file_kind('symlink')) |
1426 | |
1427 | @@ -479,7 +479,7 @@ |
1428 | class TestLinks(tests.TestCaseInTempDir): |
1429 | |
1430 | def test_dereference_path(self): |
1431 | - self.requireFeature(features.SymlinkFeature) |
1432 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1433 | cwd = osutils.realpath('.') |
1434 | os.mkdir('bar') |
1435 | bar_path = osutils.pathjoin(cwd, 'bar') |
1436 | @@ -519,7 +519,7 @@ |
1437 | mode = os.lstat('file').st_mode |
1438 | self.assertEqual(mode, mode | 0o200) |
1439 | |
1440 | - if osutils.has_symlinks(): |
1441 | + if osutils.supports_symlinks(self.test_dir): |
1442 | # should not error when handed a symlink |
1443 | os.symlink('nonexistent', 'dangling') |
1444 | osutils.make_readonly('dangling') |
1445 | @@ -1603,7 +1603,7 @@ |
1446 | self.assertEqual(['c'], os.listdir('target/b')) |
1447 | |
1448 | def test_copy_tree_symlinks(self): |
1449 | - self.requireFeature(features.SymlinkFeature) |
1450 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1451 | self.build_tree(['source/']) |
1452 | os.symlink('a/generic/path', 'source/lnk') |
1453 | osutils.copy_tree('source', 'target') |
1454 | @@ -1628,7 +1628,7 @@ |
1455 | } |
1456 | |
1457 | self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c']) |
1458 | - if osutils.has_symlinks(): |
1459 | + if osutils.supports_symlinks(self.test_dir): |
1460 | os.symlink('a/generic/path', 'source/lnk') |
1461 | osutils.copy_tree('source', 'target', handlers=handlers) |
1462 | |
1463 | @@ -1638,7 +1638,7 @@ |
1464 | ('f', 'source/b/c', 'target/b/c'), |
1465 | ], processed_files) |
1466 | self.assertPathDoesNotExist('target') |
1467 | - if osutils.has_symlinks(): |
1468 | + if osutils.supports_symlinks(self.test_dir): |
1469 | self.assertEqual([('source/lnk', 'target/lnk')], processed_links) |
1470 | |
1471 | |
1472 | @@ -1860,7 +1860,7 @@ |
1473 | self.assertEqual(expected_dirblocks, self._filter_out(result)) |
1474 | |
1475 | def test_symlink(self): |
1476 | - self.requireFeature(features.SymlinkFeature) |
1477 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1478 | self.requireFeature(features.UnicodeFilenameFeature) |
1479 | target = u'target\N{Euro Sign}' |
1480 | link_name = u'l\N{Euro Sign}nk' |
1481 | @@ -1884,11 +1884,11 @@ |
1482 | But prior python versions failed to properly encode the passed unicode |
1483 | string. |
1484 | """ |
1485 | - _test_needs_features = [features.SymlinkFeature, |
1486 | - features.UnicodeFilenameFeature] |
1487 | + _test_needs_features = [features.UnicodeFilenameFeature] |
1488 | |
1489 | def setUp(self): |
1490 | super(tests.TestCaseInTempDir, self).setUp() |
1491 | + self._test_needs_features.append(features.SymlinkFeature(self.test_dir)) |
1492 | self.link = u'l\N{Euro Sign}ink' |
1493 | self.target = u'targe\N{Euro Sign}t' |
1494 | os.symlink(self.target, self.link) |
1495 | @@ -2121,7 +2121,7 @@ |
1496 | def envvar_to_override(self): |
1497 | if sys.platform == "win32": |
1498 | # Disable use of platform calls on windows so envvar is used |
1499 | - self.overrideAttr(win32utils, 'has_ctypes', False) |
1500 | + self.overrideAttr(win32utils.ctypes, 'windll', None) |
1501 | return 'USERNAME' # only variable used on windows |
1502 | return 'LOGNAME' # first variable checked by getpass.getuser() |
1503 | |
1504 | |
1505 | === modified file 'breezy/tests/test_server.py' |
1506 | --- breezy/tests/test_server.py 2020-06-10 23:47:24 +0000 |
1507 | +++ breezy/tests/test_server.py 2021-12-25 12:35:58 +0000 |
1508 | @@ -350,6 +350,7 @@ |
1509 | accepted_errnos = [errno.EBADF, |
1510 | errno.EPIPE, |
1511 | errno.WSAEBADF, |
1512 | + errno.WSAENOTSOCK, |
1513 | errno.WSAECONNRESET, |
1514 | errno.WSAENOTCONN, |
1515 | errno.WSAESHUTDOWN, |
1516 | |
1517 | === modified file 'breezy/tests/test_shelf.py' |
1518 | --- breezy/tests/test_shelf.py 2020-07-04 12:29:00 +0000 |
1519 | +++ breezy/tests/test_shelf.py 2021-12-25 12:35:58 +0000 |
1520 | @@ -257,7 +257,7 @@ |
1521 | |
1522 | def _test_shelve_symlink_creation(self, link_name, link_target, |
1523 | shelve_change=False): |
1524 | - self.requireFeature(features.SymlinkFeature) |
1525 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1526 | tree = self.make_branch_and_tree('.') |
1527 | tree.lock_write() |
1528 | self.addCleanup(tree.unlock) |
1529 | @@ -297,7 +297,7 @@ |
1530 | def _test_shelve_symlink_target_change(self, link_name, |
1531 | old_target, new_target, |
1532 | shelve_change=False): |
1533 | - self.requireFeature(features.SymlinkFeature) |
1534 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1535 | tree = self.make_branch_and_tree('.') |
1536 | tree.lock_write() |
1537 | self.addCleanup(tree.unlock) |
1538 | |
1539 | === modified file 'breezy/tests/test_shelf_ui.py' |
1540 | --- breezy/tests/test_shelf_ui.py 2020-02-07 02:14:30 +0000 |
1541 | +++ breezy/tests/test_shelf_ui.py 2021-12-25 12:35:58 +0000 |
1542 | @@ -214,7 +214,7 @@ |
1543 | shelver.expect('Shelve 1 change(s)?', 0) |
1544 | |
1545 | def test_shelve_modify_target(self): |
1546 | - self.requireFeature(features.SymlinkFeature) |
1547 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1548 | tree = self.create_shelvable_tree() |
1549 | os.symlink('bar', 'tree/baz') |
1550 | tree.add('baz', b'baz-id') |
1551 | @@ -443,7 +443,7 @@ |
1552 | shelver.expect('Apply 1 change(s)?', 0) |
1553 | |
1554 | def test_shelve_modify_target(self): |
1555 | - self.requireFeature(features.SymlinkFeature) |
1556 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1557 | tree = self.create_shelvable_tree() |
1558 | os.symlink('bar', 'tree/baz') |
1559 | tree.add('baz', b'baz-id') |
1560 | |
1561 | === modified file 'breezy/tests/test_smtp_connection.py' |
1562 | --- breezy/tests/test_smtp_connection.py 2020-02-07 02:14:30 +0000 |
1563 | +++ breezy/tests/test_smtp_connection.py 2021-12-25 12:35:58 +0000 |
1564 | @@ -28,12 +28,8 @@ |
1565 | ) |
1566 | |
1567 | |
1568 | -def connection_refuser(): |
1569 | - def connect(server): |
1570 | - raise socket.error(errno.ECONNREFUSED, 'Connection Refused') |
1571 | - smtp = smtplib.SMTP() |
1572 | - smtp.connect = connect |
1573 | - return smtp |
1574 | +def connection_refuser(host): |
1575 | + raise socket.error(errno.ECONNREFUSED, 'Connection Refused') |
1576 | |
1577 | |
1578 | class StubSMTPFactory(object): |
1579 | @@ -45,12 +41,13 @@ |
1580 | self._smtp_features = smtp_features or [] |
1581 | self._ehlo_called = False |
1582 | |
1583 | - def __call__(self): |
1584 | + def __call__(self, host='localhost'): |
1585 | + self._calls.append(('connect', host)) |
1586 | # The factory pretends to be a connection |
1587 | return self |
1588 | |
1589 | def connect(self, server): |
1590 | - self._calls.append(('connect', server)) |
1591 | + raise NotImplementedError |
1592 | |
1593 | def helo(self): |
1594 | self._calls.append(('helo',)) |
1595 | @@ -218,8 +215,9 @@ |
1596 | def test_create_connection_starttls_fails(self): |
1597 | # Check that we raise an exception if the server claims to |
1598 | # support STARTTLS, but then fails when we try to activate it. |
1599 | - factory = StubSMTPFactory(fail_on=['starttls'], |
1600 | - smtp_features=['starttls']) |
1601 | + factory = StubSMTPFactory( |
1602 | + fail_on=['starttls'], |
1603 | + smtp_features=['starttls']) |
1604 | conn = self.get_connection(b'', smtp_factory=factory) |
1605 | self.assertRaises(smtp_connection.SMTPError, conn._create_connection) |
1606 | self.assertEqual([('connect', 'localhost'), |
1607 | |
1608 | === modified file 'breezy/tests/test_transform.py' |
1609 | --- breezy/tests/test_transform.py 2021-08-18 22:38:08 +0000 |
1610 | +++ breezy/tests/test_transform.py 2021-12-25 12:35:58 +0000 |
1611 | @@ -184,7 +184,7 @@ |
1612 | this.wt.revert() |
1613 | |
1614 | def test_file_merge(self): |
1615 | - self.requireFeature(SymlinkFeature) |
1616 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1617 | root_id = generate_ids.gen_root_id() |
1618 | base = TransformGroup("BASE", root_id) |
1619 | this = TransformGroup("THIS", root_id) |
1620 | @@ -358,14 +358,14 @@ |
1621 | branch, tt = self.get_branch_and_transform() |
1622 | tt.new_file('file', tt.root, [b'contents'], b'file-id') |
1623 | trans_id = tt.new_directory('dir', tt.root, b'dir-id') |
1624 | - if SymlinkFeature.available(): |
1625 | + if SymlinkFeature(self.test_dir).available(): |
1626 | tt.new_symlink('symlink', trans_id, 'target', b'symlink-id') |
1627 | tt.commit(branch, 'message') |
1628 | tree = branch.basis_tree() |
1629 | self.assertEqual('file', tree.id2path(b'file-id')) |
1630 | self.assertEqual(b'contents', tree.get_file_text('file')) |
1631 | self.assertEqual('dir', tree.id2path(b'dir-id')) |
1632 | - if SymlinkFeature.available(): |
1633 | + if SymlinkFeature(self.test_dir).available(): |
1634 | self.assertEqual('dir/symlink', tree.id2path(b'symlink-id')) |
1635 | self.assertEqual('target', tree.get_symlink_target('dir/symlink')) |
1636 | |
1637 | @@ -802,13 +802,13 @@ |
1638 | return self.make_records(attribs, contents) |
1639 | |
1640 | def test_serialize_symlink_creation(self): |
1641 | - self.requireFeature(features.SymlinkFeature) |
1642 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1643 | tt = self.get_preview() |
1644 | tt.new_symlink(u'foo\u1234', tt.root, u'bar\u1234') |
1645 | self.assertSerializesTo(self.symlink_creation_records(), tt) |
1646 | |
1647 | def test_deserialize_symlink_creation(self): |
1648 | - self.requireFeature(features.SymlinkFeature) |
1649 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1650 | tt = self.get_preview() |
1651 | tt.deserialize(iter(self.symlink_creation_records())) |
1652 | abspath = tt._limbo_name('new-1') |
1653 | @@ -1115,10 +1115,9 @@ |
1654 | |
1655 | class TestLinkTree(tests.TestCaseWithTransport): |
1656 | |
1657 | - _test_needs_features = [HardlinkFeature] |
1658 | - |
1659 | def setUp(self): |
1660 | tests.TestCaseWithTransport.setUp(self) |
1661 | + self.requireFeature(HardlinkFeature(self.test_dir)) |
1662 | self.parent_tree = self.make_branch_and_tree('parent') |
1663 | self.parent_tree.lock_write() |
1664 | self.addCleanup(self.parent_tree.unlock) |
1665 | |
1666 | === modified file 'breezy/tests/test_treeshape.py' |
1667 | --- breezy/tests/test_treeshape.py 2018-11-11 04:08:32 +0000 |
1668 | +++ breezy/tests/test_treeshape.py 2021-12-25 12:35:58 +0000 |
1669 | @@ -38,7 +38,7 @@ |
1670 | self.assertFileEqual(b'hello', '.bzr/README') |
1671 | |
1672 | def test_build_tree_symlink(self): |
1673 | - self.requireFeature(features.SymlinkFeature) |
1674 | + self.requireFeature(features.SymlinkFeature(self.test_dir)) |
1675 | self.build_tree_contents([('link@', 'target')]) |
1676 | self.assertEqual('target', |
1677 | os.readlink('link')) |
1678 | |
1679 | === modified file 'breezy/tests/test_workingtree.py' |
1680 | --- breezy/tests/test_workingtree.py 2020-08-09 18:10:01 +0000 |
1681 | +++ breezy/tests/test_workingtree.py 2021-12-25 12:35:58 +0000 |
1682 | @@ -457,7 +457,7 @@ |
1683 | self.assertPathDoesNotExist('this/hello.BASE') |
1684 | |
1685 | def test_unsupported_symlink_auto_resolve(self): |
1686 | - self.requireFeature(SymlinkFeature) |
1687 | + self.requireFeature(SymlinkFeature(self.test_dir)) |
1688 | base = self.make_branch_and_tree('base') |
1689 | self.build_tree_contents([('base/hello', 'Hello')]) |
1690 | base.add('hello', b'hello_id') |
1691 | |
1692 | === modified file 'breezy/transform.py' |
1693 | --- breezy/transform.py 2021-11-13 16:17:01 +0000 |
1694 | +++ breezy/transform.py 2021-12-25 12:35:58 +0000 |
1695 | @@ -50,7 +50,6 @@ |
1696 | pathjoin, |
1697 | sha_file, |
1698 | splitpath, |
1699 | - supports_symlinks, |
1700 | ) |
1701 | from .progress import ProgressPhase |
1702 | from .tree import ( |
1703 | @@ -1132,6 +1131,9 @@ |
1704 | def supports_setting_file_ids(self): |
1705 | raise NotImplementedError(self.supports_setting_file_ids) |
1706 | |
1707 | + def supports_symlinks(self): |
1708 | + return self._transform._tree.supports_symlinks() |
1709 | + |
1710 | @property |
1711 | def _by_parent(self): |
1712 | if self.__by_parent is None: |
1713 | |
1714 | === modified file 'breezy/transport/local.py' |
1715 | --- breezy/transport/local.py 2020-02-18 01:57:45 +0000 |
1716 | +++ breezy/transport/local.py 2021-12-25 12:35:58 +0000 |
1717 | @@ -152,7 +152,7 @@ |
1718 | transport._file_streams[canonical_url].flush() |
1719 | try: |
1720 | path = self._abspath(relpath) |
1721 | - return osutils.open_file(path, 'rb') |
1722 | + return open(path, 'rb') |
1723 | except (IOError, OSError) as e: |
1724 | if e.errno == errno.EISDIR: |
1725 | return LateReadError(relpath) |
1726 | @@ -323,7 +323,7 @@ |
1727 | """See Transport.open_write_stream.""" |
1728 | abspath = self._abspath(relpath) |
1729 | try: |
1730 | - handle = osutils.open_file(abspath, 'wb') |
1731 | + handle = open(abspath, 'wb') |
1732 | except (IOError, OSError) as e: |
1733 | self._translate_error(e, abspath) |
1734 | handle.truncate() |
1735 | |
1736 | === modified file 'breezy/tree.py' |
1737 | --- breezy/tree.py 2021-11-16 01:24:28 +0000 |
1738 | +++ breezy/tree.py 2021-12-25 12:35:58 +0000 |
1739 | @@ -203,7 +203,7 @@ |
1740 | def supports_symlinks(self): |
1741 | """Does this tree support symbolic links? |
1742 | """ |
1743 | - return osutils.has_symlinks() |
1744 | + return True |
1745 | |
1746 | @property |
1747 | def supports_file_ids(self): |
1748 | |
1749 | === modified file 'breezy/win32utils.py' |
1750 | --- breezy/win32utils.py 2020-05-24 00:42:36 +0000 |
1751 | +++ breezy/win32utils.py 2021-12-25 12:35:58 +0000 |
1752 | @@ -14,11 +14,9 @@ |
1753 | # along with this program; if not, write to the Free Software |
1754 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1755 | |
1756 | -"""Win32-specific helper functions |
1757 | - |
1758 | -Only one dependency: ctypes should be installed. |
1759 | -""" |
1760 | - |
1761 | +"""Win32-specific helper functions""" |
1762 | + |
1763 | +import ctypes |
1764 | import glob |
1765 | import os |
1766 | import struct |
1767 | @@ -54,7 +52,6 @@ |
1768 | |
1769 | def debug_memory_win32api(message='', short=True): |
1770 | """Use trace.note() to dump the running memory info.""" |
1771 | - import ctypes |
1772 | from breezy import trace |
1773 | class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure): |
1774 | """Used by GetProcessMemoryInfo""" |
1775 | @@ -119,7 +116,6 @@ |
1776 | console window and return tuple (sizex, sizey) if success, |
1777 | or default size (defaultx, defaulty) otherwise. |
1778 | """ |
1779 | - import ctypes |
1780 | # To avoid problem with redirecting output via pipe |
1781 | # we need to use stderr instead of stdout |
1782 | h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE) |
1783 | @@ -142,7 +138,6 @@ |
1784 | |
1785 | Result is always unicode (or None). |
1786 | """ |
1787 | - import ctypes |
1788 | try: |
1789 | SHGetSpecialFolderPath = \ |
1790 | ctypes.windll.shell32.SHGetSpecialFolderPathW |
1791 | @@ -242,7 +237,6 @@ |
1792 | |
1793 | :return: A unicode string representing the host name. |
1794 | """ |
1795 | - import ctypes |
1796 | buf = ctypes.create_unicode_buffer(MAX_COMPUTERNAME_LENGTH + 1) |
1797 | n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1) |
1798 | |
1799 | @@ -320,26 +314,26 @@ |
1800 | :return: full path to aplication executable from registry, |
1801 | or appname itself if nothing found. |
1802 | """ |
1803 | - import _winreg |
1804 | + import winreg |
1805 | |
1806 | basename = appname |
1807 | if not os.path.splitext(basename)[1]: |
1808 | basename = appname + '.exe' |
1809 | |
1810 | try: |
1811 | - hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, |
1812 | - 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' + |
1813 | - basename) |
1814 | + hkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, |
1815 | + 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' |
1816 | + + basename) |
1817 | except EnvironmentError: |
1818 | return appname |
1819 | |
1820 | try: |
1821 | try: |
1822 | - path, type_id = _winreg.QueryValueEx(hkey, '') |
1823 | + path, type_id = winreg.QueryValueEx(hkey, '') |
1824 | except WindowsError: |
1825 | return appname |
1826 | finally: |
1827 | - _winreg.CloseKey(hkey) |
1828 | + winreg.CloseKey(hkey) |
1829 | |
1830 | if type_id == REG_SZ: |
1831 | return path |
1832 | @@ -404,8 +398,7 @@ |
1833 | |
1834 | |
1835 | def _ctypes_is_local_pid_dead(pid): |
1836 | - import ctypes |
1837 | - kernel32 = ctypes.wintypes.windll.kernel32 |
1838 | + kernel32 = ctypes.windll.kernel32 |
1839 | """True if pid doesn't correspond to live process on this machine""" |
1840 | handle = kernel32.OpenProcess(1, False, pid) |
1841 | if not handle: |
1842 | @@ -416,7 +409,7 @@ |
1843 | elif errorcode == 87: # ERROR_INVALID_PARAMETER |
1844 | return True |
1845 | raise ctypes.WinError(errorcode) |
1846 | - Kernel32.CloseHandle(handle) |
1847 | + kernel32.CloseHandle(handle) |
1848 | return False |
1849 | |
1850 | is_local_pid_dead = _ctypes_is_local_pid_dead |
1851 | |
1852 | === modified file 'doc/developers/testing.txt' |
1853 | --- doc/developers/testing.txt 2017-07-30 16:59:50 +0000 |
1854 | +++ doc/developers/testing.txt 2021-12-25 12:35:58 +0000 |
1855 | @@ -710,16 +710,17 @@ |
1856 | are defined by subclassing ``breezy.tests.Feature`` and overriding the |
1857 | ``_probe`` and ``feature_name`` methods. For example:: |
1858 | |
1859 | - class _SymlinkFeature(Feature): |
1860 | + class SymlinkFeature(Feature): |
1861 | + |
1862 | + def __init__(self, path): |
1863 | + self.path = path |
1864 | |
1865 | def _probe(self): |
1866 | - return osutils.has_symlinks() |
1867 | + return osutils.supports_symlinks(self.path) |
1868 | |
1869 | def feature_name(self): |
1870 | return 'symlinks' |
1871 | |
1872 | - SymlinkFeature = _SymlinkFeature() |
1873 | - |
1874 | A helper for handling running tests based on whether a python |
1875 | module is available. This can handle 3rd-party dependencies (is |
1876 | ``paramiko`` available?) as well as stdlib (``termios``) or |
1877 | |
1878 | === modified file 'setup.py' |
1879 | --- setup.py 2021-08-20 15:32:58 +0000 |
1880 | +++ setup.py 2021-12-25 12:35:58 +0000 |
1881 | @@ -376,7 +376,8 @@ |
1882 | ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources') |
1883 | icos = [] # list of (path_root, relative_ico_path) |
1884 | # First always brz's icon and its in the root of the brz tree. |
1885 | - icos.append(('', 'brz.ico')) |
1886 | + # FIXME: There's no such thing as brz.ico |
1887 | + #icos.append(('', 'brz.ico')) |
1888 | for root, dirs, files in os.walk(ico_root): |
1889 | icos.extend([(ico_root, os.path.join(root, f)[len(ico_root) + 1:]) |
1890 | for f in files if f.endswith('.ico')]) |
1891 | @@ -534,7 +535,7 @@ |
1892 | |
1893 | elif 'py2exe' in sys.argv: |
1894 | # py2exe setup |
1895 | - import py2exe |
1896 | + from py2exe import distutils_buildexe as py2exe |
1897 | |
1898 | # pick real brz version |
1899 | import breezy |
1900 | @@ -578,15 +579,17 @@ |
1901 | self.outfiles.extend([f + 'o' for f in compile_names]) |
1902 | # end of class install_data_with_bytecompile |
1903 | |
1904 | - target = py2exe.build_exe.Target( |
1905 | + target = py2exe.runtime.Target( |
1906 | script="brz", |
1907 | dest_base="brz", |
1908 | - icon_resources=[(0, 'brz.ico')], |
1909 | + # FIXME: There's no such thing as brz.ico |
1910 | + #icon_resources=[(0, 'brz.ico')], |
1911 | name=META_INFO['name'], |
1912 | version=version_str, |
1913 | description=META_INFO['description'], |
1914 | - author=META_INFO['author'], |
1915 | - copyright="(c) Canonical Ltd, 2005-2010", |
1916 | + maintainer=META_INFO['maintainer'], |
1917 | + copyright="Copyright 2005-2012 Canonical Ltd.\n" |
1918 | + "Copyright 2017-2021 Breezy developers", |
1919 | company_name="Canonical Ltd.", |
1920 | comments=META_INFO['description'], |
1921 | ) |
1922 | @@ -647,6 +650,14 @@ |
1923 | # rest of the svn plugin wasn't. So we tell py2exe to leave the |
1924 | # plugins out of the .zip file |
1925 | excludes.extend(["breezy.plugins." + d for d in dirs]) |
1926 | + # svn plugin requires subvertpy, |
1927 | + # and pip cannot install it on Windows. |
1928 | + # When subvertpy is not available, remove svn from plugins |
1929 | + if "svn" in dirs: |
1930 | + try: |
1931 | + import subvertpy |
1932 | + except ImportError: |
1933 | + dirs.remove("svn") |
1934 | x = [] |
1935 | for i in files: |
1936 | # Throw away files we don't want packaged. Note that plugins may |
1937 | @@ -661,16 +672,20 @@ |
1938 | if x: |
1939 | target_dir = root[len('breezy/'):] # install to 'plugins/...' |
1940 | plugins_files.append((target_dir, x)) |
1941 | - # find modules for built-in plugins |
1942 | + # find modules required by built-in plugins |
1943 | import tools.package_mf |
1944 | - mf = tools.package_mf.CustomModuleFinder() |
1945 | - mf.run_package('breezy/plugins') |
1946 | - packs, mods = mf.get_result() |
1947 | - additional_packages.update(packs) |
1948 | - includes.extend(mods) |
1949 | + mf = tools.package_mf.CustomModuleFinder('.') |
1950 | + mf.load_package_recursive('breezy.plugins') |
1951 | + (packs, mods) = mf.get_result() |
1952 | + # Don't add the plugins packages and modules, |
1953 | + # as they are listed in excluded |
1954 | + additional_packages.update(pack for pack in packs |
1955 | + if not (pack.startswith('breezy.plugins.') or pack in excludes)) |
1956 | + includes.extend(mod for mod in mods |
1957 | + if not (mod.startswith('breezy.plugins.') or mod in excludes)) |
1958 | |
1959 | console_targets = [target, |
1960 | - 'tools/win32/bzr_postinstall.py', |
1961 | + 'tools/win32/brz_postinstall.py', |
1962 | ] |
1963 | gui_targets = [gui_target] |
1964 | data_files = topics_files + plugins_files + I18N_FILES |
1965 | @@ -725,7 +740,7 @@ |
1966 | "includes": includes, |
1967 | "excludes": excludes, |
1968 | "dll_excludes": dll_excludes, |
1969 | - "dist_dir": "win32_bzr.exe", |
1970 | + "dist_dir": "win32_brz.exe", |
1971 | "optimize": 2, |
1972 | "custom_boot_script": |
1973 | "tools/win32/py2exe_boot_common.py", |
1974 | @@ -735,10 +750,10 @@ |
1975 | # We want the libaray.zip to have optimize = 2, but the exe to have |
1976 | # optimize = 1, so that .py files that get compilied at run time |
1977 | # (e.g. user installed plugins) dont have their doc strings removed. |
1978 | - class py2exe_no_oo_exe(py2exe.build_exe.py2exe): |
1979 | - def build_executable(self, *args, **kwargs): |
1980 | + class py2exe_no_oo_exe(py2exe.py2exe): |
1981 | + def run(self, *args, **kwargs): |
1982 | self.optimize = 1 |
1983 | - py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs) |
1984 | + super(py2exe_no_oo_exe, self).run(*args, **kwargs) |
1985 | self.optimize = 2 |
1986 | |
1987 | if __name__ == '__main__': |
1988 | |
1989 | === modified file 'tools/package_mf.py' |
1990 | --- tools/package_mf.py 2018-11-16 12:25:18 +0000 |
1991 | +++ tools/package_mf.py 2021-12-25 12:35:58 +0000 |
1992 | @@ -16,10 +16,12 @@ |
1993 | |
1994 | """Custom module finder for entire package""" |
1995 | |
1996 | -import modulefinder |
1997 | import os |
1998 | import sys |
1999 | |
2000 | +# At present, this is only used on Windows (see setup.py) |
2001 | +from py2exe import mf310 as modulefinder |
2002 | + |
2003 | |
2004 | class CustomModuleFinder(modulefinder.ModuleFinder): |
2005 | """Custom module finder for processing python packages, |
2006 | @@ -35,27 +37,54 @@ |
2007 | modulefinder.ModuleFinder.__init__( |
2008 | self, path, debug, excludes, replace_paths) |
2009 | |
2010 | - def run_package(self, package_path): |
2011 | - """Recursively process each module in package with run_script method. |
2012 | + def load_package_recursive(self, fqname): |
2013 | + """Recursively process each module in package |
2014 | |
2015 | - :param package_path: path to package directory. |
2016 | + :param fqname: name of the package. |
2017 | """ |
2018 | - stack = [package_path] |
2019 | + # Load all the parents |
2020 | + parent = None |
2021 | + path = [] |
2022 | + for partname in fqname.split("."): |
2023 | + parent_path = ".".join(path) |
2024 | + path.append(partname) |
2025 | + # import_module works recursively, |
2026 | + # and some of the dependencies may try |
2027 | + # to import modules not present on the system. |
2028 | + # (The actual error is |
2029 | + # AttributeError: 'NoneType' object has no attribute 'is_package') |
2030 | + # Ignore errors here and bail out in the collection loop. |
2031 | + try: |
2032 | + self.import_module(partname, ".".join(path), |
2033 | + self.modules.get(parent_path, None)) |
2034 | + except: |
2035 | + pass |
2036 | + stack = [(fqname, parent_path)] |
2037 | while stack: |
2038 | - curdir = stack.pop(0) |
2039 | - py = os.listdir(curdir) |
2040 | - for i in py: |
2041 | - full = os.path.join(curdir, i) |
2042 | + (package, parent_path) = stack.pop(0) |
2043 | + # Here we assume that all parents have already been imported. |
2044 | + # Abort when a parent is missing. |
2045 | + parent = self.modules[parent_path] |
2046 | + pkg_module = self.import_module(package, package, parent) |
2047 | + curdir = pkg_module.__file__ |
2048 | + dirlist = os.listdir(curdir) |
2049 | + for filename in dirlist: |
2050 | + full = os.path.join(curdir, filename) |
2051 | if os.path.isdir(full): |
2052 | + if filename == "tests": |
2053 | + continue |
2054 | init = os.path.join(full, '__init__.py') |
2055 | if os.path.isfile(init): |
2056 | - stack.append(full) |
2057 | - continue |
2058 | - if not i.endswith('.py'): |
2059 | - continue |
2060 | - if i == 'setup.py': # skip |
2061 | - continue |
2062 | - self.run_script(full) |
2063 | + stack.append((".".join((package, filename)), package)) |
2064 | + continue |
2065 | + if not filename.endswith('.py'): |
2066 | + continue |
2067 | + if filename == 'setup.py': # skip |
2068 | + continue |
2069 | + # We only accept .py files, so could use [:-3] too - faster... |
2070 | + partname = os.path.splitext(filename)[0] |
2071 | + self.import_module(partname, |
2072 | + ".".join((package, partname)), pkg_module) |
2073 | |
2074 | def get_result(self): |
2075 | """Return 2-tuple: (list of packages, list of modules)""" |
2076 | |
2077 | === modified file 'tools/win32/brz.iss.cog' |
2078 | --- tools/win32/brz.iss.cog 2021-12-20 23:40:21 +0000 |
2079 | +++ tools/win32/brz.iss.cog 2021-12-25 12:35:58 +0000 |
2080 | @@ -78,6 +78,14 @@ |
2081 | ; [[[cog cog.outl('AppVersion=%s' % VERSION) ]]] |
2082 | ; [[[end]]] |
2083 | |
2084 | +; [[[cog |
2085 | +; import platform |
2086 | +; |
2087 | +; if platform.machine().endswith("64"): |
2088 | +; cog.outl('ArchitecturesAllowed=x64') |
2089 | +; cog.outl('ArchitecturesInstallIn64BitMode=x64') |
2090 | +; ]]] |
2091 | +; [[[end]]] |
2092 | ChangesEnvironment=yes |
2093 | ; MARKH: PrivilegesRequired=none means it can't be installed by a non-admin |
2094 | ; user - but sadly we still need admin - eg, tortoise overlays, installing |
2095 | @@ -115,8 +123,12 @@ |
2096 | Source: "plugins\*.*"; DestDir: "{app}\\plugins"; Flags: createallsubdirs ignoreversion recursesubdirs restartreplace uninsrestartdelete; Components: plugins |
2097 | Source: "*.bat"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2098 | Source: "*.url"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2099 | -Source: "msvc*.dll"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2100 | -Source: "bz*.exe"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2101 | +; Python3 includes vcruntime*.dll which is not packed in by py2exe. |
2102 | +; I'm not sure if the installer has to contain it. |
2103 | +; It looks like the binaries work OK without vcruntime dll. |
2104 | +; Delete this dll line when we're sure. |
2105 | +;Source: "msvc*.dll"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2106 | +Source: "brz*.exe"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2107 | Source: "Python*.dll"; DestDir: "{app}"; Flags: ignoreversion restartreplace uninsrestartdelete; |
2108 | Source: "lib\*.*"; DestDir: "{app}\lib"; Flags: createallsubdirs ignoreversion recursesubdirs restartreplace uninsrestartdelete; |
2109 | Source: "doc\*.*"; DestDir: "{app}\doc"; Flags: createallsubdirs ignoreversion recursesubdirs restartreplace uninsrestartdelete; |
2110 | @@ -141,7 +153,7 @@ |
2111 | ; imageformats plugins for PyQt4 |
2112 | ; [[[cog |
2113 | ; plug_dir = os.path.join(os.path.dirname(cog.inFile), # $(bzr_src_root)/tools/win32 |
2114 | -; '..', '..', 'win32_bzr.exe', 'imageformats') |
2115 | +; '..', '..', 'win32_brz.exe', 'imageformats') |
2116 | ; if os.path.isdir(plug_dir): |
2117 | ; cog.outl('Source: "imageformats\\*.*"; DestDir: "{app}\\imageformats"; ' |
2118 | ; 'Flags: createallsubdirs ignoreversion recursesubdirs restartreplace uninsrestartdelete;') |
2119 | @@ -179,9 +191,9 @@ |
2120 | [Icons] |
2121 | Name: "{group}\Documentation index"; Filename: "{app}\doc\index.html"; WorkingDir: "{app}\doc"; |
2122 | Name: "{group}\Breezy Home Page"; Filename: "{app}\breezy.url"; Comment: "https://www.breezy-vcs.org/"; |
2123 | -Name: "{group}\Start Bzr in cmd shell"; Filename: "{cmd}"; Parameters: "/K start_bzr.bat"; WorkingDir: "{app}"; IconFilename: "{app}\bzr.exe"; Comment: "Open new Bzr session"; |
2124 | +Name: "{group}\Start Bzr in cmd shell"; Filename: "{cmd}"; Parameters: "/K start_brz.bat"; WorkingDir: "{app}"; IconFilename: "{app}\brz.exe"; Comment: "Open new Bzr session"; |
2125 | ; NOTE: Intent is to change the log file location - the line below will need to change to reflect that. |
2126 | -Name: "{group}\Open Bzr log file"; Filename: "notepad.exe"; Parameters: "{userdocs}\.bzr.log"; Comment: "Launch notepad to view the bzr log file"; |
2127 | +Name: "{group}\Open Bzr log file"; Filename: "notepad.exe"; Parameters: "{userdocs}\.brz.log"; Comment: "Launch notepad to view the brz log file"; |
2128 | |
2129 | ; [[[cog |
2130 | ; if "TBZR" in os.environ: |
2131 | @@ -224,7 +236,7 @@ |
2132 | |
2133 | |
2134 | [UninstallRun] |
2135 | -Filename: "{app}\bzr_postinstall.exe"; Parameters: "--delete-path --delete-shell-menu --silent"; Flags: skipifdoesntexist runhidden; |
2136 | +Filename: "{app}\brz_postinstall.exe"; Parameters: "--delete-path --delete-shell-menu --silent"; Flags: skipifdoesntexist runhidden; |
2137 | ; [[[cog |
2138 | ; if "TBZR" in os.environ: |
2139 | ; cog.outl('Filename: "regsvr32.exe"; Parameters: "/u /s /i: tbzrshellext_x86.dll"; WorkingDir: "{app}"; Components: tortoise; StatusMsg: "Unregistering Tortoise"; Flags: skipifdoesntexist') |
2140 | @@ -320,7 +332,7 @@ |
2141 | ewWaitUntilTerminated, ErrorCode) then |
2142 | MsgBox('Failed to install TortoiseOverlays: ' + SysErrorMessage(ErrorCode), |
2143 | mbInformation, MB_OK); |
2144 | - // Ideally we could be bzr_postinstall.exe this way too, but |
2145 | + // Ideally we could be brz_postinstall.exe this way too, but |
2146 | // its needed at uninstall time. |
2147 | end; |
2148 | // cause explorer to re-fetch handlers. |
2149 | |
2150 | === modified file 'tools/win32/info.txt' |
2151 | --- tools/win32/info.txt 2010-03-30 20:13:52 +0000 |
2152 | +++ tools/win32/info.txt 2021-12-25 12:35:58 +0000 |
2153 | @@ -1,6 +1,6 @@ |
2154 | -Bazaar is free software; you can redistribute and/or modify it under |
2155 | -the terms of the GNU General Public License version 2. |
2156 | +Breezy is free software; you can redistribute and/or modify it |
2157 | +under the terms of the GNU General Public License version 2. |
2158 | |
2159 | See: http://www.gnu.org/copyleft/gpl.html |
2160 | |
2161 | -Managing source code in Bazaar does not make it subject to the GPL. |
2162 | +Managing source code in Breezy does not make it subject to the GPL. |
2163 | |
2164 | === modified file 'tools/win32/ostools.py' |
2165 | --- tools/win32/ostools.py 2020-01-31 17:43:44 +0000 |
2166 | +++ tools/win32/ostools.py 2021-12-25 12:35:58 +0000 |
2167 | @@ -12,6 +12,9 @@ |
2168 | ostools.py copytree FILES... DIR |
2169 | copy files to specified directory keeping relative paths |
2170 | |
2171 | + ostools.py copydir SOURCE TARGET |
2172 | + recursively copy SOURCE directory tree to TARGET directory |
2173 | + |
2174 | ostools.py remove [FILES...] [DIRS...] |
2175 | remove files or directories (recursive) |
2176 | """ |
2177 | @@ -89,6 +92,19 @@ |
2178 | |
2179 | return 0 |
2180 | |
2181 | + if cmd == 'copydir': |
2182 | + if len(argv) != 2: |
2183 | + print("Usage: ostools.py copydir SOURCE TARGET") |
2184 | + return 1 |
2185 | + |
2186 | + def _copy(src, dest, follow_symlinks=True): |
2187 | + shutil.copy(src, dest, follow_symlinks=follow_symlinks) |
2188 | + print("Copied:", src, "=>", dest) |
2189 | + shutil.copytree(argv[0], argv[1], |
2190 | + copy_function=_copy, dirs_exist_ok=True) |
2191 | + |
2192 | + return 0 |
2193 | + |
2194 | if cmd == 'remove': |
2195 | if len(argv) == 0: |
2196 | print("Usage: ostools.py remove [FILES...] [DIRS...]") |
2197 | |
2198 | === modified file 'tools/win32/start_brz.bat' |
2199 | --- tools/win32/start_brz.bat 2017-05-21 14:47:52 +0000 |
2200 | +++ tools/win32/start_brz.bat 2021-12-25 12:35:58 +0000 |
2201 | @@ -6,7 +6,7 @@ |
2202 | REM ****************************************************** |
2203 | |
2204 | REM Add the Brz directory to system-wide PATH environment variable |
2205 | -SET PATH=C:\Program Files\Bazaar;%PATH% |
2206 | +SET PATH=C:\Program Files\Breezy;%PATH% |
2207 | |
2208 | REM Change next line to set-up e-mail to identify yourself in brz |
2209 | REM SET BZREMAIL= |