diff --git a/NEWS b/NEWS index d92fb5d484..c1abc48d48 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,15 @@ UNRELEASED CHANGES versioned directories, now use "bzr inventory --kind directory". (Johan Rydberg) + * 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 @@ -74,6 +83,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. @@ -81,6 +93,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, @@ -119,6 +144,7 @@ UNRELEASED CHANGES * Branch.commit() has moved to WorkingTree.commit(). (Robert Collins) + bzr 0.6 2005-10-28 IMPROVEMENTS: diff --git a/bzrlib/config.py b/bzrlib/config.py index 8bf8325052..f23d9b078b 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 @@ -414,7 +415,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/plugin.py b/bzrlib/plugin.py index 012ff696ce..9c8891d4c6 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 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. diff --git a/bzrlib/selftest/__init__.py b/bzrlib/selftest/__init__.py index 1bb9fa88f9..7f5d9c3ae4 100644 --- a/bzrlib/selftest/__init__.py +++ b/bzrlib/selftest/__init__.py @@ -35,6 +35,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 = [] @@ -251,26 +252,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: + if name in os.environ: + del os.environ[name] + else: + os.environ[name] = value def _restoreEnvironment(self): - os.environ['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): self._runCleanups() @@ -471,13 +484,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: @@ -485,7 +502,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 f1683f37df..2420db1a6e 100644 --- a/bzrlib/selftest/blackbox.py +++ b/bzrlib/selftest/blackbox.py @@ -352,12 +352,12 @@ def test_diff(self): self.runbzr('diff') 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.working_tree().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.working_tree().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 38b913930b..c0714cc787 100644 --- a/bzrlib/selftest/test_commit.py +++ b/bzrlib/selftest/test_commit.py @@ -145,7 +145,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.working_tree().commit(message='one', rev_id='test@rev-1', allow_pointless=False) diff --git a/bzrlib/selftest/test_merge_core.py b/bzrlib/selftest/test_merge_core.py index 95f366354b..789aeabd30 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) self.assert_(file(builder.this.full_path("1"), "rb").read() == "text4" ) self.assert_(file(builder.this.full_path("2"), "rb").read() == "text2" ) - self.assert_(os.stat(builder.this.full_path("1")).st_mode &0777 == 0755) - self.assert_(os.stat(builder.this.full_path("2")).st_mode &0777 == 0655) - self.assert_(os.stat(builder.this.full_path("3")).st_mode &0777 == 0744) + if sys.platform != "win32": + self.assert_(os.stat(builder.this.full_path("1")).st_mode &0777 == 0755) + self.assert_(os.stat(builder.this.full_path("2")).st_mode &0777 == 0655) + self.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") - self.assertNotEqual(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") + self.assertNotEqual(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): self.assert_(isinstance(cset.entries["2"].metadata_change, ExecFlagMerge)) self.assert_(cset.entries["3"].is_boring()) builder.apply_changeset(cset) - self.assert_(os.lstat(builder.this.full_path("1")).st_mode &0100 == 0000) - self.assert_(os.lstat(builder.this.full_path("2")).st_mode &0100 == 0100) - self.assert_(os.lstat(builder.this.full_path("3")).st_mode &0100 == 0000) + if sys.platform != "win32": + self.assert_(os.lstat(builder.this.full_path("1")).st_mode &0100 == 0000) + self.assert_(os.lstat(builder.this.full_path("2")).st_mode &0100 == 0100) + self.assert_(os.lstat(builder.this.full_path("3")).st_mode &0100 == 0000) builder.cleanup(); diff --git a/bzrlib/selftest/testconfig.py b/bzrlib/selftest/testconfig.py index 4ddfab4b04..0bbfe7d7d3 100644 --- a/bzrlib/selftest/testconfig.py +++ b/bzrlib/selftest/testconfig.py @@ -175,23 +175,45 @@ class TestConfigPath(TestCase): def setUp(self): super(TestConfigPath, self).setUp() - self.oldenv = os.environ.get('HOME', 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 + 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): - 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): 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 diff --git a/bzrlib/selftest/testinv.py b/bzrlib/selftest/testinv.py index 9f6623f11a..d4d756867b 100644 --- a/bzrlib/selftest/testinv.py +++ b/bzrlib/selftest/testinv.py @@ -241,7 +241,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