Merge lp:~jelmer/brz/merge-3.2 into lp:brz

Proposed by Jelmer Vernooij
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
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=

Subscribers

People subscribed via source and target branches