1+ from __future__ import annotations
2+
13import os
24import platform
35import sys
46import zipfile
7+ from typing import TYPE_CHECKING
58
69import pytest
710from packaging .tags import sys_tags
1215from hatchling .metadata .spec import DEFAULT_METADATA_VERSION , get_core_metadata_constructors
1316from hatchling .utils .constants import DEFAULT_BUILD_SCRIPT
1417
18+ if TYPE_CHECKING :
19+ from hatch .utils .fs import Path
20+
1521# https://github.com/python/cpython/pull/26184
1622fixed_pathlib_resolution = pytest .mark .skipif (
1723 sys .platform == 'win32' and (sys .version_info < (3 , 8 ) or sys .implementation .name == 'pypy' ),
@@ -23,6 +29,17 @@ def get_python_versions_tag():
2329 return '.' .join (f'py{ major_version } ' for major_version in get_known_python_major_versions ())
2430
2531
32+ def extract_zip (zip_path : Path , target : Path ) -> None :
33+ with zipfile .ZipFile (zip_path , 'r' ) as z :
34+ for name in z .namelist ():
35+ member = z .getinfo (name )
36+ path = z .extract (member , target )
37+ if member .is_dir ():
38+ os .chmod (path , 0o755 )
39+ else :
40+ os .chmod (path , member .external_attr >> 16 )
41+
42+
2643def test_class ():
2744 assert issubclass (WheelBuilder , BuilderInterface )
2845
@@ -1996,7 +2013,7 @@ def initialize(self, version, build_data):
19962013 )
19972014 helpers .assert_files (extraction_directory , expected_files )
19982015
1999- def test_default_shared_scripts (self , hatch , helpers , temp_dir , config_file ):
2016+ def test_default_shared_scripts (self , hatch , platform , helpers , temp_dir , config_file ):
20002017 config_file .model .template .plugins ['default' ]['src-layout' ] = False
20012018 config_file .save ()
20022019
@@ -2013,7 +2030,12 @@ def test_default_shared_scripts(self, hatch, helpers, temp_dir, config_file):
20132030 shared_data_path .ensure_dir_exists ()
20142031
20152032 binary_contents = os .urandom (1024 )
2016- (shared_data_path / 'binary' ).write_bytes (binary_contents )
2033+ binary_file = shared_data_path / 'binary'
2034+ binary_file .write_bytes (binary_contents )
2035+ if not platform .windows :
2036+ expected_mode = 0o755
2037+ binary_file .chmod (expected_mode )
2038+
20172039 (shared_data_path / 'other_script.sh' ).write_text (
20182040 helpers .dedent (
20192041 """
@@ -2085,10 +2107,7 @@ def test_default_shared_scripts(self, hatch, helpers, temp_dir, config_file):
20852107 assert expected_artifact == str (build_artifacts [0 ])
20862108
20872109 extraction_directory = temp_dir / '_archive'
2088- extraction_directory .mkdir ()
2089-
2090- with zipfile .ZipFile (str (expected_artifact ), 'r' ) as zip_archive :
2091- zip_archive .extractall (str (extraction_directory ))
2110+ extract_zip (expected_artifact , extraction_directory )
20922111
20932112 metadata_directory = f'{ builder .project_id } .dist-info'
20942113 shared_data_directory = f'{ builder .project_id } .data'
@@ -2101,7 +2120,11 @@ def test_default_shared_scripts(self, hatch, helpers, temp_dir, config_file):
21012120 )
21022121 helpers .assert_files (extraction_directory , expected_files )
21032122
2104- def test_default_shared_scripts_from_build_data (self , hatch , helpers , temp_dir , config_file ):
2123+ if not platform .windows :
2124+ extracted_binary = extraction_directory / shared_data_directory / 'scripts' / 'binary'
2125+ assert extracted_binary .stat ().st_mode & 0o777 == expected_mode
2126+
2127+ def test_default_shared_scripts_from_build_data (self , hatch , platform , helpers , temp_dir , config_file ):
21052128 config_file .model .template .plugins ['default' ]['src-layout' ] = False
21062129 config_file .save ()
21072130
@@ -2118,7 +2141,12 @@ def test_default_shared_scripts_from_build_data(self, hatch, helpers, temp_dir,
21182141 shared_data_path .ensure_dir_exists ()
21192142
21202143 binary_contents = os .urandom (1024 )
2121- (shared_data_path / 'binary' ).write_bytes (binary_contents )
2144+ binary_file = shared_data_path / 'binary'
2145+ binary_file .write_bytes (binary_contents )
2146+ if not platform .windows :
2147+ expected_mode = 0o755
2148+ binary_file .chmod (expected_mode )
2149+
21222150 (shared_data_path / 'other_script.sh' ).write_text (
21232151 helpers .dedent (
21242152 """
@@ -2205,10 +2233,7 @@ def initialize(self, version, build_data):
22052233 assert expected_artifact == str (build_artifacts [0 ])
22062234
22072235 extraction_directory = temp_dir / '_archive'
2208- extraction_directory .mkdir ()
2209-
2210- with zipfile .ZipFile (str (expected_artifact ), 'r' ) as zip_archive :
2211- zip_archive .extractall (str (extraction_directory ))
2236+ extract_zip (expected_artifact , extraction_directory )
22122237
22132238 metadata_directory = f'{ builder .project_id } .dist-info'
22142239 shared_data_directory = f'{ builder .project_id } .data'
@@ -2221,6 +2246,10 @@ def initialize(self, version, build_data):
22212246 )
22222247 helpers .assert_files (extraction_directory , expected_files )
22232248
2249+ if not platform .windows :
2250+ extracted_binary = extraction_directory / shared_data_directory / 'scripts' / 'binary'
2251+ assert extracted_binary .stat ().st_mode & 0o777 == expected_mode
2252+
22242253 def test_default_extra_metadata (self , hatch , helpers , temp_dir , config_file ):
22252254 config_file .model .template .plugins ['default' ]['src-layout' ] = False
22262255 config_file .save ()
0 commit comments