• Matt Glazar's avatar
    Reuse old build dir on Windows · 78ee6b85
    Matt Glazar authored
    Summary:
    getdeps.py's find_existing_win32_subst_for_path function tries to reuse an existing build directory alias. (On Windows, the build directory is aliased to a drive letter to shorten paths.) If this function does not find and existing build directory alias, getdeps.py invalidates many of its caches.
    
    On my Windows machine, find_existing_win32_subst_for_path always fails, so all of my builds are super slow. This happens because find_existing_win32_subst_for_path is given a path with a lower-case drive letter ("c:\users\..."), but the subst command returns paths with an upper-case drive letter ("C:\users\...").
    
    When comparing paths, use ntpath.normpath. This makes the comparison case-insensitive for drive letters. (It also makes the comparison case-insensitive for other path components.)
    
    On Linux and macOS, this diff should not change behavior.
    
    Reviewed By: wez
    
    Differential Revision: D15466096
    
    fbshipit-source-id: 1669aa0a6eaeb6012154f3a9e24eba3f835262c6
    78ee6b85
scratch_test.py 2.85 KB
#!/usr/bin/env python
# Copyright (c) 2019-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

from __future__ import absolute_import, division, print_function, unicode_literals

import unittest

from ..buildopts import find_existing_win32_subst_for_path


class Win32SubstTest(unittest.TestCase):
    def test_no_existing_subst(self):
        self.assertIsNone(
            find_existing_win32_subst_for_path(
                r"C:\users\alice\appdata\local\temp\fbcode_builder_getdeps",
                subst_mapping={},
            )
        )
        self.assertIsNone(
            find_existing_win32_subst_for_path(
                r"C:\users\alice\appdata\local\temp\fbcode_builder_getdeps",
                subst_mapping={"X:\\": r"C:\users\alice\appdata\local\temp\other"},
            )
        )

    def test_exact_match_returns_drive_path(self):
        self.assertEqual(
            find_existing_win32_subst_for_path(
                r"C:\temp\fbcode_builder_getdeps",
                subst_mapping={"X:\\": r"C:\temp\fbcode_builder_getdeps"},
            ),
            "X:\\",
        )
        self.assertEqual(
            find_existing_win32_subst_for_path(
                r"C:/temp/fbcode_builder_getdeps",
                subst_mapping={"X:\\": r"C:/temp/fbcode_builder_getdeps"},
            ),
            "X:\\",
        )

    def test_multiple_exact_matches_returns_arbitrary_drive_path(self):
        self.assertIn(
            find_existing_win32_subst_for_path(
                r"C:\temp\fbcode_builder_getdeps",
                subst_mapping={
                    "X:\\": r"C:\temp\fbcode_builder_getdeps",
                    "Y:\\": r"C:\temp\fbcode_builder_getdeps",
                    "Z:\\": r"C:\temp\fbcode_builder_getdeps",
                },
            ),
            ("X:\\", "Y:\\", "Z:\\"),
        )

    def test_drive_letter_is_case_insensitive(self):
        self.assertEqual(
            find_existing_win32_subst_for_path(
                r"C:\temp\fbcode_builder_getdeps",
                subst_mapping={"X:\\": r"c:\temp\fbcode_builder_getdeps"},
            ),
            "X:\\",
        )

    def test_path_components_are_case_insensitive(self):
        self.assertEqual(
            find_existing_win32_subst_for_path(
                r"C:\TEMP\FBCODE_builder_getdeps",
                subst_mapping={"X:\\": r"C:\temp\fbcode_builder_getdeps"},
            ),
            "X:\\",
        )
        self.assertEqual(
            find_existing_win32_subst_for_path(
                r"C:\temp\fbcode_builder_getdeps",
                subst_mapping={"X:\\": r"C:\TEMP\FBCODE_builder_getdeps"},
            ),
            "X:\\",
        )