Skip to content

Commit

Permalink
bugfix: Fix windows path case sensitivity
Browse files Browse the repository at this point in the history
This commit fixes an issue where paths on Windows are case insensitive, for instance when setting the build folder its name would be converted to lowercase.

The culprit is our realpath() function, that was calling os.path.normcase() internally, since we are removing that call it makes sense to just remove the function entirely and call os.path.realpath() wherever necessary.

Closes #10282
  • Loading branch information
DNedic committed Jan 17, 2023
1 parent 490f9eb commit 17d1e9a
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 24 deletions.
12 changes: 6 additions & 6 deletions tools/idf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
try:
from idf_py_actions.errors import FatalError # noqa: E402
from idf_py_actions.tools import (PROG, SHELL_COMPLETE_RUN, SHELL_COMPLETE_VAR, PropertyDict, # noqa: E402
debug_print_idf_version, get_target, merge_action_lists, print_warning, realpath)
debug_print_idf_version, get_target, merge_action_lists, print_warning)
if os.getenv('IDF_COMPONENT_MANAGER') != '0':
from idf_component_manager import idf_extensions
except ImportError:
Expand All @@ -64,9 +64,9 @@ def check_environment() -> List:

# verify that IDF_PATH env variable is set
# find the directory idf.py is in, then the parent directory of this, and assume this is IDF_PATH
detected_idf_path = realpath(os.path.join(os.path.dirname(__file__), '..'))
detected_idf_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
if 'IDF_PATH' in os.environ:
set_idf_path = realpath(os.environ['IDF_PATH'])
set_idf_path = os.path.realpath(os.environ['IDF_PATH'])
if set_idf_path != detected_idf_path:
print_warning(
'WARNING: IDF_PATH environment variable is set to %s but %s path indicates IDF directory %s. '
Expand Down Expand Up @@ -621,19 +621,19 @@ def execute_tasks(self, tasks: List, **kwargs: str) -> OrderedDict:
)
@click.option('-C', '--project-dir', default=os.getcwd(), type=click.Path())
def parse_project_dir(project_dir: str) -> Any:
return realpath(project_dir)
return os.path.realpath(project_dir)

# Set `complete_var` to not existing environment variable name to prevent early cmd completion
project_dir = parse_project_dir(standalone_mode=False, complete_var='_IDF.PY_COMPLETE_NOT_EXISTING')

all_actions: Dict = {}
# Load extensions from components dir
idf_py_extensions_path = os.path.join(os.environ['IDF_PATH'], 'tools', 'idf_py_actions')
extension_dirs = [realpath(idf_py_extensions_path)]
extension_dirs = [os.path.realpath(idf_py_extensions_path)]
extra_paths = os.environ.get('IDF_EXTRA_ACTIONS_PATH')
if extra_paths is not None:
for path in extra_paths.split(';'):
path = realpath(path)
path = os.path.realpath(path)
if path not in extension_dirs:
extension_dirs.append(path)

Expand Down
10 changes: 5 additions & 5 deletions tools/idf_py_actions/core_ext.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import fnmatch
import json
Expand All @@ -19,7 +19,7 @@
from idf_py_actions.errors import FatalError
from idf_py_actions.global_options import global_options
from idf_py_actions.tools import (PropertyDict, TargetChoice, ensure_build_directory, generate_hints, get_target,
idf_version, merge_action_lists, realpath, run_target, yellow_print)
idf_version, merge_action_lists, run_target, yellow_print)


def action_extensions(base_actions: Dict, project_path: str) -> Any:
Expand Down Expand Up @@ -168,14 +168,14 @@ def reconfigure(action: str, ctx: Context, args: PropertyDict) -> None:
ensure_build_directory(args, ctx.info_name, True)

def validate_root_options(ctx: Context, args: PropertyDict, tasks: List) -> None:
args.project_dir = realpath(args.project_dir)
if args.build_dir is not None and args.project_dir == realpath(args.build_dir):
args.project_dir = os.path.realpath(args.project_dir)
if args.build_dir is not None and args.project_dir == os.path.realpath(args.build_dir):
raise FatalError(
'Setting the build directory to the project directory is not supported. Suggest dropping '
"--build-dir option, the default is a 'build' subdirectory inside the project directory.")
if args.build_dir is None:
args.build_dir = os.path.join(args.project_dir, 'build')
args.build_dir = realpath(args.build_dir)
args.build_dir = os.path.realpath(args.build_dir)

def idf_version_callback(ctx: Context, param: str, value: str) -> None:
if not value or ctx.resilient_parsing:
Expand Down
16 changes: 3 additions & 13 deletions tools/idf_py_actions/tools.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import asyncio
import os
Expand Down Expand Up @@ -37,16 +37,6 @@ def executable_exists(args: List) -> bool:
return False


def realpath(path: str) -> str:
"""
Return the cannonical path with normalized case.
It is useful on Windows to comparision paths in case-insensitive manner.
On Unix and Mac OS X it works as `os.path.realpath()` only.
"""
return os.path.normcase(os.path.realpath(path))


def _idf_version_from_cmake() -> Optional[str]:
version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake')
regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)')
Expand Down Expand Up @@ -502,10 +492,10 @@ def ensure_build_directory(args: 'PropertyDict', prog_name: str, always_run_cmak

try:
home_dir = cache['CMAKE_HOME_DIRECTORY']
if realpath(home_dir) != realpath(project_dir):
if os.path.realpath(home_dir) != os.path.realpath(project_dir):
raise FatalError(
"Build directory '%s' configured for project '%s' not '%s'. Run '%s fullclean' to start again." %
(build_dir, realpath(home_dir), realpath(project_dir), prog_name))
(build_dir, os.path.realpath(home_dir), os.path.realpath(project_dir), prog_name))
except KeyError:
pass # if cmake failed part way, CMAKE_HOME_DIRECTORY may not be set yet

Expand Down
5 changes: 5 additions & 0 deletions tools/test_build_system/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,8 @@ def test_efuse_symmary_cmake_functions(
output = idf_py('efuse-summary')
assert 'FROM_CMAKE: MAC: 00:00:00:00:00:00' in output.stdout
assert 'FROM_CMAKE: WR_DIS: 0' in output.stdout


def test_custom_build_folder(test_app_copy: Path, idf_py: IdfPyFunc) -> None:
idf_py('-BBuiLDdiR', 'build')
assert (test_app_copy / 'BuiLDdiR').is_dir()

0 comments on commit 17d1e9a

Please sign in to comment.