From 8ee3bd2ae2252be8210c326377e5d7189f1be750 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:15:01 -0600 Subject: [PATCH 01/11] Adding my win32 patch for moving the home directory. --- bzrlib/config.py | 16 +++++++++++++++- bzrlib/selftest/testconfig.py | 26 +++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/bzrlib/config.py b/bzrlib/config.py index 578a43cd00..7a446c3559 100644 --- a/bzrlib/config.py +++ b/bzrlib/config.py @@ -54,6 +54,7 @@ import errno import os +import sys from fnmatch import fnmatch import re @@ -402,7 +403,20 @@ def config_dir(): TODO: Global option --config-dir to override this. """ - return os.path.join(os.path.expanduser("~"), ".bazaar") + base = os.environ.get('BZR_HOME', None) + if sys.platform == 'win32': + if base is None: + base = os.environ.get('APPDATA', None) + if base is None: + base = os.environ.get('HOME', None) + if base is None: + raise BzrError('You must have one of BZR_HOME, APPDATA, or HOME set') + return os.path.join(base, 'bazaar', '2.0') + else: + # cygwin, linux, and darwin all have a $HOME directory + if base is None: + base = os.path.expanduser("~") + return os.path.join(base, ".bazaar") def config_filename(): diff --git a/bzrlib/selftest/testconfig.py b/bzrlib/selftest/testconfig.py index 84123aa616..0a5ec83e9b 100644 --- a/bzrlib/selftest/testconfig.py +++ b/bzrlib/selftest/testconfig.py @@ -162,22 +162,38 @@ class TestConfigPath(TestCase): def setUp(self): super(TestConfigPath, self).setUp() self.oldenv = os.environ.get('HOME', None) + self.oldappdata = os.environ.get('APPDATA', None) os.environ['HOME'] = '/home/bogus' + os.environ['APPDATA'] = \ + r'C:\Documents and Settings\bogus\Application Data' def tearDown(self): os.environ['HOME'] = self.oldenv + os.environ['APPDATA'] = self.oldappdata super(TestConfigPath, self).tearDown() def test_config_dir(self): - self.assertEqual(config.config_dir(), '/home/bogus/.bazaar') + if sys.platform == 'win32': + self.assertEqual(config.config_dir(), + r'C:\Documents and Settings\bogus\Application Data\bazaar\2.0') + else: + self.assertEqual(config.config_dir(), '/home/bogus/.bazaar') def test_config_filename(self): - self.assertEqual(config.config_filename(), - '/home/bogus/.bazaar/bazaar.conf') + if sys.platform == 'win32': + self.assertEqual(config.config_filename(), + r'C:\Documents and Settings\bogus\Application Data\bazaar\2.0\bazaar.conf') + else: + self.assertEqual(config.config_filename(), + '/home/bogus/.bazaar/bazaar.conf') def test_branches_config_filename(self): - self.assertEqual(config.branches_config_filename(), - '/home/bogus/.bazaar/branches.conf') + if sys.platform == 'win32': + self.assertEqual(config.branches_config_filename(), + r'C:\Documents and Settings\bogus\Application Data\bazaar\2.0\branches.conf') + else: + self.assertEqual(config.branches_config_filename(), + '/home/bogus/.bazaar/branches.conf') class TestIniConfig(TestCase): From 8869995fef14ea14443d7abbb5b6c2ce319b95e9 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:16:53 -0600 Subject: [PATCH 02/11] [patch] Aaron Bentley's HOME fix. --- bzrlib/selftest/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bzrlib/selftest/__init__.py b/bzrlib/selftest/__init__.py index cc5801cf28..898240e19e 100644 --- a/bzrlib/selftest/__init__.py +++ b/bzrlib/selftest/__init__.py @@ -265,8 +265,15 @@ def _cleanEnvironment(self): del os.environ['EMAIL'] self.addCleanup(self._restoreEnvironment) + @staticmethod + def _restoreVar(name, value): + if value is None: + del os.environ[name] + else: + os.environ[name] = value + def _restoreEnvironment(self): - os.environ['HOME'] = self.oldenv + self._restoreVar('HOME', self.oldenv) if os.environ.get('BZREMAIL') is not None: del os.environ['BZREMAIL'] if self.bzr_email is not None: From 934968119315315c33d7befa72d86f8851de26bc Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:26:29 -0600 Subject: [PATCH 03/11] Refactored environment cleaning code --- bzrlib/selftest/__init__.py | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/bzrlib/selftest/__init__.py b/bzrlib/selftest/__init__.py index 898240e19e..8827ac625b 100644 --- a/bzrlib/selftest/__init__.py +++ b/bzrlib/selftest/__init__.py @@ -255,33 +255,38 @@ def addCleanup(self, callable): self._cleanups.append(callable) def _cleanEnvironment(self): - self.oldenv = os.environ.get('HOME', None) - os.environ['HOME'] = os.getcwd() - self.bzr_email = os.environ.get('BZREMAIL') - if self.bzr_email is not None: - del os.environ['BZREMAIL'] - self.email = os.environ.get('EMAIL') - if self.email is not None: - del os.environ['EMAIL'] + new_env = { + 'HOME': os.getcwd(), + 'APPDATA': os.getcwd(), + 'BZREMAIL': None, + 'EMAIL': None, + } + self.old_env = {} self.addCleanup(self._restoreEnvironment) + for name, value in new_env.iteritems(): + self._captureVar(name, value) + + + def _captureVar(self, name, newvalue): + """Set an environment variable, preparing it to be reset when finished.""" + self.old_env[name] = os.environ.get(name, None) + if newvalue is None: + if name in os.environ: + del os.environ[name] + else: + os.environ[name] = newvalue @staticmethod def _restoreVar(name, value): if value is None: - del os.environ[name] + if name in os.environ: + del os.environ[name] else: os.environ[name] = value def _restoreEnvironment(self): - self._restoreVar('HOME', self.oldenv) - if os.environ.get('BZREMAIL') is not None: - del os.environ['BZREMAIL'] - if self.bzr_email is not None: - os.environ['BZREMAIL'] = self.bzr_email - if os.environ.get('EMAIL') is not None: - del os.environ['EMAIL'] - if self.email is not None: - os.environ['EMAIL'] = self.email + for name, value in self.old_env.iteritems(): + self._restoreVar(name, value) def tearDown(self): logging.getLogger('').removeHandler(self._log_hdlr) From 66beaba697bcb10884883b1c377162bc44251c54 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:32:06 -0600 Subject: [PATCH 04/11] Making old_env a private member --- bzrlib/selftest/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bzrlib/selftest/__init__.py b/bzrlib/selftest/__init__.py index 8827ac625b..2cbc8b54b6 100644 --- a/bzrlib/selftest/__init__.py +++ b/bzrlib/selftest/__init__.py @@ -261,7 +261,7 @@ def _cleanEnvironment(self): 'BZREMAIL': None, 'EMAIL': None, } - self.old_env = {} + self.__old_env = {} self.addCleanup(self._restoreEnvironment) for name, value in new_env.iteritems(): self._captureVar(name, value) @@ -269,7 +269,7 @@ def _cleanEnvironment(self): def _captureVar(self, name, newvalue): """Set an environment variable, preparing it to be reset when finished.""" - self.old_env[name] = os.environ.get(name, None) + self.__old_env[name] = os.environ.get(name, None) if newvalue is None: if name in os.environ: del os.environ[name] @@ -285,7 +285,7 @@ def _restoreVar(name, value): os.environ[name] = value def _restoreEnvironment(self): - for name, value in self.old_env.iteritems(): + for name, value in self.__old_env.iteritems(): self._restoreVar(name, value) def tearDown(self): From e9207d85e7d7e049f7931fadf6122f8d2960aa7e Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:32:46 -0600 Subject: [PATCH 05/11] Updating testconfig to handle missing environment variables --- bzrlib/selftest/testconfig.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bzrlib/selftest/testconfig.py b/bzrlib/selftest/testconfig.py index 0a5ec83e9b..938c319832 100644 --- a/bzrlib/selftest/testconfig.py +++ b/bzrlib/selftest/testconfig.py @@ -161,15 +161,21 @@ class TestConfigPath(TestCase): def setUp(self): super(TestConfigPath, self).setUp() - self.oldenv = os.environ.get('HOME', None) - self.oldappdata = os.environ.get('APPDATA', None) + self.old_home = os.environ.get('HOME', None) + self.old_appdata = os.environ.get('APPDATA', None) os.environ['HOME'] = '/home/bogus' os.environ['APPDATA'] = \ r'C:\Documents and Settings\bogus\Application Data' def tearDown(self): - os.environ['HOME'] = self.oldenv - os.environ['APPDATA'] = self.oldappdata + if self.old_home is None: + del os.environ['HOME'] + else: + os.environ['HOME'] = self.old_home + if self.old_appdata is None: + del os.environ['APPDATA'] + else: + os.environ['APPDATA'] = self.old_appdata super(TestConfigPath, self).tearDown() def test_config_dir(self): From dbf8b1ed60d90396e01ccbba673751f9a70b5a93 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 13:38:52 -0600 Subject: [PATCH 06/11] Applying fix for EWOULDBLOCK under win32 --- bzrlib/selftest/HTTPTestUtil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bzrlib/selftest/HTTPTestUtil.py b/bzrlib/selftest/HTTPTestUtil.py index de2c9e1a0a..ed152e3b65 100644 --- a/bzrlib/selftest/HTTPTestUtil.py +++ b/bzrlib/selftest/HTTPTestUtil.py @@ -44,7 +44,7 @@ def handle_one_request(self): try: self.raw_requestline = self.rfile.readline() except socket.error, e: - if e.args[0] == errno.EAGAIN: + if e.args[0] in (errno.EAGAIN, errno.EWOULDBLOCK): # omitted for now because some tests look at the log of # the server and expect to see no errors. see recent # email thread. -- mbp 20051021. From 709b1263fe082163c45adb9b927e39c7eb120a92 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 14:16:05 -0600 Subject: [PATCH 07/11] Updated build_tree to use fixed line-endings for tests which read the file contents and compare --- bzrlib/selftest/__init__.py | 14 ++++++++++++-- bzrlib/selftest/blackbox.py | 4 ++-- bzrlib/selftest/test_commit.py | 2 +- bzrlib/selftest/testinv.py | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/bzrlib/selftest/__init__.py b/bzrlib/selftest/__init__.py index 2cbc8b54b6..b22d70112d 100644 --- a/bzrlib/selftest/__init__.py +++ b/bzrlib/selftest/__init__.py @@ -34,6 +34,7 @@ from bzrlib.selftest import TestUtil from bzrlib.selftest.TestUtil import TestLoader, TestSuite from bzrlib.selftest.treeshape import build_tree_contents +from bzrlib.errors import BzrError MODULES_TO_TEST = [] MODULES_TO_DOCTEST = [] @@ -489,13 +490,17 @@ def _leaveDirectory(): os.chdir(_currentdir) self.addCleanup(_leaveDirectory) - def build_tree(self, shape): + def build_tree(self, shape, line_endings='native'): """Build a test tree according to a pattern. shape is a sequence of file specifications. If the final character is '/', a directory is created. This doesn't add anything to a branch. + :param line_endings: Either 'binary' or 'native' + in binary mode, exact contents are written + in native mode, the line endings match the + default platform endings. """ # XXX: It's OK to just create them using forward slashes on windows? for name in shape: @@ -503,7 +508,12 @@ def build_tree(self, shape): if name[-1] == '/': os.mkdir(name[:-1]) else: - f = file(name, 'wt') + if line_endings == 'binary': + f = file(name, 'wb') + elif line_endings == 'native': + f = file(name, 'wt') + else: + raise BzrError('Invalid line ending request %r' % (line_endings,)) print >>f, "contents of", name f.close() diff --git a/bzrlib/selftest/blackbox.py b/bzrlib/selftest/blackbox.py index 30feee356b..7708addc1f 100644 --- a/bzrlib/selftest/blackbox.py +++ b/bzrlib/selftest/blackbox.py @@ -294,12 +294,12 @@ def test_diff(self): self.assert_('\n+baz' in output) def test_diff_branches(self): - self.build_tree(['branch1/', 'branch1/file', 'branch2/']) + self.build_tree(['branch1/', 'branch1/file', 'branch2/'], line_endings='binary') branch = Branch.initialize('branch1') branch.add(['file']) branch.commit('add file') copy_branch(branch, 'branch2') - print >> open('branch2/file', 'w'), 'new content' + print >> open('branch2/file', 'wb'), 'new content' branch2 = Branch.open('branch2') branch2.commit('update file') # should open branch1 and diff against branch2, diff --git a/bzrlib/selftest/test_commit.py b/bzrlib/selftest/test_commit.py index 9072aebb4b..2885b59620 100644 --- a/bzrlib/selftest/test_commit.py +++ b/bzrlib/selftest/test_commit.py @@ -148,7 +148,7 @@ def test_selective_delete(self): def test_commit_rename(self): """Test commit of a revision where a file is renamed.""" b = Branch.initialize('.') - self.build_tree(['hello']) + self.build_tree(['hello'], line_endings='binary') b.add(['hello'], ['hello-id']) b.commit(message='one', rev_id='test@rev-1', allow_pointless=False) diff --git a/bzrlib/selftest/testinv.py b/bzrlib/selftest/testinv.py index dfa3b45cc9..177a1ffd1c 100644 --- a/bzrlib/selftest/testinv.py +++ b/bzrlib/selftest/testinv.py @@ -240,7 +240,7 @@ def setUp(self): # with fake parent entries. super(TestSnapshot, self).setUp() self.branch = Branch.initialize('.') - self.build_tree(['subdir/', 'subdir/file']) + self.build_tree(['subdir/', 'subdir/file'], line_endings='binary') self.branch.add(['subdir', 'subdir/file'], ['dirid', 'fileid']) if has_symlinks(): pass From 36ee72aa35280f8bf5263cfac5672ea73526c81e Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 14:17:38 -0600 Subject: [PATCH 08/11] [patch] testhashcache delay for win32 and cygwin --- bzrlib/selftest/testhashcache.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bzrlib/selftest/testhashcache.py b/bzrlib/selftest/testhashcache.py index 5c70349572..db0feabfdf 100644 --- a/bzrlib/selftest/testhashcache.py +++ b/bzrlib/selftest/testhashcache.py @@ -15,6 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os +import sys import time from bzrlib.selftest import TestCaseInTempDir @@ -28,7 +29,7 @@ def sha1(t): def pause(): if False: return - if os.name == 'nt': + if sys.platform in ('win32', 'cygwin'): time.sleep(3) return # allow it to stabilize From d13abe8970a4489a50d69ec08ed78275c8d6a1f0 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 14:28:07 -0600 Subject: [PATCH 09/11] [patch] Alexander Belchenko patch #9, skip stat tests for win32 --- bzrlib/selftest/test_merge_core.py | 59 ++++++++++++++++-------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/bzrlib/selftest/test_merge_core.py b/bzrlib/selftest/test_merge_core.py index 7394bf15a4..4d8f684259 100644 --- a/bzrlib/selftest/test_merge_core.py +++ b/bzrlib/selftest/test_merge_core.py @@ -3,6 +3,7 @@ import tempfile import unittest import stat +import sys from bzrlib.selftest import TestCaseInTempDir, TestCase from bzrlib.branch import ScratchBranch, Branch @@ -467,9 +468,10 @@ def contents_test_success(self, merge_factory): builder.apply_changeset(cset) assert(file(builder.this.full_path("1"), "rb").read() == "text4" ) assert(file(builder.this.full_path("2"), "rb").read() == "text2" ) - assert(os.stat(builder.this.full_path("1")).st_mode &0777 == 0755) - assert(os.stat(builder.this.full_path("2")).st_mode &0777 == 0655) - assert(os.stat(builder.this.full_path("3")).st_mode &0777 == 0744) + if sys.platform != "win32": + assert(os.stat(builder.this.full_path("1")).st_mode &0777 == 0755) + assert(os.stat(builder.this.full_path("2")).st_mode &0777 == 0655) + assert(os.stat(builder.this.full_path("3")).st_mode &0777 == 0744) return builder def contents_test_conflicts(self, merge_factory): @@ -482,29 +484,31 @@ def contents_test_conflicts(self, merge_factory): builder.cleanup() def test_symlink_conflicts(self): - builder = MergeBuilder() - builder.add_symlink("2", "0", "name2", "target1") - builder.change_target("2", other="target4", base="text3") - self.assertRaises(changeset.ThreewayContentsConflict, - builder.merge_changeset, ApplyMerge3) - builder.cleanup() + if sys.platform != "win32": + builder = MergeBuilder() + builder.add_symlink("2", "0", "name2", "target1") + builder.change_target("2", other="target4", base="text3") + self.assertRaises(changeset.ThreewayContentsConflict, + builder.merge_changeset, ApplyMerge3) + builder.cleanup() def test_symlink_merge(self): - builder = MergeBuilder() - builder.add_symlink("1", "0", "name1", "target1") - builder.add_symlink("2", "0", "name2", "target1") - builder.add_symlink("3", "0", "name3", "target1") - builder.change_target("1", this="target2") - builder.change_target("2", base="target2") - builder.change_target("3", other="target2") - assert builder.cset.entries['2'].contents_change !=\ - builder.cset.entries['3'].contents_change - cset = builder.merge_changeset(ApplyMerge3) - builder.apply_changeset(cset) - self.assertEqual(builder.this.get_symlink_target("1"), "target2") - self.assertEqual(builder.this.get_symlink_target("2"), "target1") - self.assertEqual(builder.this.get_symlink_target("3"), "target2") - builder.cleanup() + if sys.platform != "win32": + builder = MergeBuilder() + builder.add_symlink("1", "0", "name1", "target1") + builder.add_symlink("2", "0", "name2", "target1") + builder.add_symlink("3", "0", "name3", "target1") + builder.change_target("1", this="target2") + builder.change_target("2", base="target2") + builder.change_target("3", other="target2") + assert builder.cset.entries['2'].contents_change !=\ + builder.cset.entries['3'].contents_change + cset = builder.merge_changeset(ApplyMerge3) + builder.apply_changeset(cset) + self.assertEqual(builder.this.get_symlink_target("1"), "target2") + self.assertEqual(builder.this.get_symlink_target("2"), "target1") + self.assertEqual(builder.this.get_symlink_target("3"), "target2") + builder.cleanup() def test_perms_merge(self): builder = MergeBuilder() @@ -520,9 +524,10 @@ def test_perms_merge(self): assert(isinstance(cset.entries["2"].metadata_change, ExecFlagMerge)) assert(cset.entries["3"].is_boring()) builder.apply_changeset(cset) - assert(os.lstat(builder.this.full_path("1")).st_mode &0100 == 0000) - assert(os.lstat(builder.this.full_path("2")).st_mode &0100 == 0100) - assert(os.lstat(builder.this.full_path("3")).st_mode &0100 == 0000) + if sys.platform != "win32": + assert(os.lstat(builder.this.full_path("1")).st_mode &0100 == 0000) + assert(os.lstat(builder.this.full_path("2")).st_mode &0100 == 0100) + assert(os.lstat(builder.this.full_path("3")).st_mode &0100 == 0000) builder.cleanup(); From 1902380b728352ab5dc38b603ff470d42b52fd16 Mon Sep 17 00:00:00 2001 From: John Arbash Meinel Date: Fri, 28 Oct 2005 14:29:16 -0600 Subject: [PATCH 10/11] [patch] Alexander Belchenko patch #12: use os.pathsep for BZR_PLUGIN_PATH --- bzrlib/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bzrlib/plugin.py b/bzrlib/plugin.py index 96675c0e0a..8918f5713b 100644 --- a/bzrlib/plugin.py +++ b/bzrlib/plugin.py @@ -79,7 +79,7 @@ def load_plugins(): #raise BzrError("plugins already initialized") _loaded = True - dirs = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH).split(":") + dirs = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH).split(os.pathsep) dirs.insert(0, os.path.dirname(plugins.__file__)) # The problem with imp.get_suffixes() is that it doesn't include From 758fcf031d539f67f51774bbf5adba5e6e5fea6a Mon Sep 17 00:00:00 2001 From: Alexey Shamrin Date: Mon, 21 Nov 2005 04:22:52 -0500 Subject: [PATCH 11/11] updated NEWS to include forgotten changes --- NEWS | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/NEWS b/NEWS index 79298173a7..32cef2f61a 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,15 @@ UNRELEASED CHANGES * .bzrignore is excluded from exports, on the grounds that it's a bzr internal-use file and may not be wanted. (Jamie Wilkinson) + * Under Windows configuration directory is now %APPDATA%\bazaar\2.0 + by default. (John Arbash Meinel) + + * The parent of Bzr configuration directory can be set by BZR_HOME + environment variable. Now the path for it is searched in BZR_HOME, then + in HOME. Under Windows the order is: BZR_HOME, APPDATA (usually + points to C:\Documents and Settings\User Name\Application Data), HOME. + (John Arbash Meinel) + IMPROVEMENTS: * "bzr INIT dir" now initializes the specified directory, and creates @@ -69,6 +78,9 @@ UNRELEASED CHANGES * Fix representation of tab characters in commit messages. (Harald Meland) + * List of plugin directories in BZR_PLUGIN_PASS environment variable is + now parsed properly under Windows. (Alexander Belchenko) + TESTING: * Fix selftest asking for passwords when there are no SFTP keys. @@ -76,6 +88,19 @@ UNRELEASED CHANGES * Fix selftest run with 'python -O'. (Martin Pool) + * Fix HTTP tests under Windows. (John Arbash Meinel) + + * Make tests work even if HOME is not set (Aaron Bentley) + + * Updated build_tree to use fixed line-endings for tests which read + the file cotents and compare. Make some tests use this to pass under + Windows. (John Arbash Meinel) + + * Skip stat and symlink tests under Windows. (Alexander Belchenko) + + * Delay in selftest/testhashcash is now issued under win32 and Cygwin. + (John Arbash Meinel) + INTERNALS: * WorkingTree.pull has been split across Branch and WorkingTree, @@ -114,6 +139,7 @@ UNRELEASED CHANGES * Branch.commit() has moved to WorkingTree.commit(). (Robert Collins) + bzr 0.6 2005-10-28 IMPROVEMENTS: