@@ -22,6 +22,7 @@ class Cmd:
2222 default_platform = "-64"
2323
2424 def __init__ (self , platform = None ):
25+ self .scratch = {}
2526 if platform :
2627 self .default_platform = platform
2728
@@ -81,19 +82,19 @@ def check_warm64(self, cmd, tag, name):
8182
8283
8384def test_write_alias_tag_with_platform (alias_checker ):
84- alias_checker .check_32 (alias_checker .Cmd , "1.0-32" , "testA" )
85- alias_checker .check_w32 (alias_checker .Cmd , "1.0-32" , "testB" )
86- alias_checker .check_64 (alias_checker .Cmd , "1.0-64" , "testC" )
87- alias_checker .check_w64 (alias_checker .Cmd , "1.0-64" , "testD" )
88- alias_checker .check_arm64 (alias_checker .Cmd , "1.0-arm64" , "testE" )
89- alias_checker .check_warm64 (alias_checker .Cmd , "1.0-arm64" , "testF" )
85+ alias_checker .check_32 (alias_checker .Cmd () , "1.0-32" , "testA" )
86+ alias_checker .check_w32 (alias_checker .Cmd () , "1.0-32" , "testB" )
87+ alias_checker .check_64 (alias_checker .Cmd () , "1.0-64" , "testC" )
88+ alias_checker .check_w64 (alias_checker .Cmd () , "1.0-64" , "testD" )
89+ alias_checker .check_arm64 (alias_checker .Cmd () , "1.0-arm64" , "testE" )
90+ alias_checker .check_warm64 (alias_checker .Cmd () , "1.0-arm64" , "testF" )
9091
9192
9293def test_write_alias_default_platform (alias_checker ):
9394 alias_checker .check_32 (alias_checker .Cmd ("-32" ), "1.0" , "testA" )
9495 alias_checker .check_w32 (alias_checker .Cmd ("-32" ), "1.0" , "testB" )
95- alias_checker .check_64 (alias_checker .Cmd , "1.0" , "testC" )
96- alias_checker .check_w64 (alias_checker .Cmd , "1.0" , "testD" )
96+ alias_checker .check_64 (alias_checker .Cmd () , "1.0" , "testC" )
97+ alias_checker .check_w64 (alias_checker .Cmd () , "1.0" , "testD" )
9798 alias_checker .check_arm64 (alias_checker .Cmd ("-arm64" ), "1.0" , "testE" )
9899 alias_checker .check_warm64 (alias_checker .Cmd ("-arm64" ), "1.0" , "testF" )
99100
@@ -103,13 +104,128 @@ def test_write_alias_fallback_platform(alias_checker):
103104 alias_checker .check_w64 (alias_checker .Cmd ("-spam" ), "1.0" , "testB" )
104105
105106
107+ def test_write_alias_launcher_missing (fake_config , assert_log , tmp_path ):
108+ fake_config .launcher_exe = tmp_path / "non-existent.exe"
109+ fake_config .default_platform = '-32'
110+ fake_config .global_dir = tmp_path / "bin"
111+ IC ._write_alias (
112+ fake_config ,
113+ {"tag" : "test" },
114+ {"name" : "test.exe" },
115+ tmp_path / "target.exe" ,
116+ )
117+ assert_log (
118+ "Checking for launcher.*" ,
119+ "Checking for launcher.*" ,
120+ "Checking for launcher.*" ,
121+ "Create %s linking to %s" ,
122+ "Skipping %s alias because the launcher template was not found." ,
123+ assert_log .end_of_log (),
124+ )
125+
126+
127+ def test_write_alias_launcher_unreadable (fake_config , assert_log , tmp_path ):
128+ class FakeLauncherPath :
129+ stem = "test"
130+ suffix = ".exe"
131+ parent = tmp_path
132+
133+ @staticmethod
134+ def is_file ():
135+ return True
136+
137+ @staticmethod
138+ def read_bytes ():
139+ raise OSError ("no reading for the test" )
140+
141+ fake_config .scratch = {}
142+ fake_config .launcher_exe = FakeLauncherPath
143+ fake_config .default_platform = '-32'
144+ fake_config .global_dir = tmp_path / "bin"
145+ IC ._write_alias (
146+ fake_config ,
147+ {"tag" : "test" },
148+ {"name" : "test.exe" },
149+ tmp_path / "target.exe" ,
150+ )
151+ assert_log (
152+ "Checking for launcher.*" ,
153+ "Create %s linking to %s" ,
154+ "Failed to read launcher template at %s\\ ." ,
155+ "Failed to read %s" ,
156+ assert_log .end_of_log (),
157+ )
158+
159+
160+ def test_write_alias_launcher_unlinkable (fake_config , assert_log , tmp_path ):
161+ def fake_link (x , y ):
162+ raise OSError ("Error for testing" )
163+
164+ fake_config .scratch = {}
165+ fake_config .launcher_exe = tmp_path / "launcher.txt"
166+ fake_config .launcher_exe .write_bytes (b'Arbitrary contents' )
167+ fake_config .default_platform = '-32'
168+ fake_config .global_dir = tmp_path / "bin"
169+ IC ._write_alias (
170+ fake_config ,
171+ {"tag" : "test" },
172+ {"name" : "test.exe" },
173+ tmp_path / "target.exe" ,
174+ _link = fake_link
175+ )
176+ assert_log (
177+ "Checking for launcher.*" ,
178+ "Create %s linking to %s" ,
179+ "Failed to create hard link.+" ,
180+ "Created %s as copy of %s" ,
181+ assert_log .end_of_log (),
182+ )
183+
184+
185+ def test_write_alias_launcher_unlinkable_remap (fake_config , assert_log , tmp_path ):
186+ # This is for the fairly expected case of the PyManager install being on one
187+ # drive, but the global commands directory being on another. In this
188+ # situation, we can't hard link directly into the app files, and will need
189+ # to copy. But we only need to copy once, so if a launcher_remap has been
190+ # set (in the current process), then we have an available copy already and
191+ # can link to that.
192+
193+ def fake_link (x , y ):
194+ if x .match ("launcher.txt" ):
195+ raise OSError (17 , "Error for testing" )
196+
197+ fake_config .scratch = {
198+ "install_command._write_alias.launcher_remap" : {"launcher.txt" : tmp_path / "actual_launcher.txt" },
199+ }
200+ fake_config .launcher_exe = tmp_path / "launcher.txt"
201+ fake_config .launcher_exe .write_bytes (b'Arbitrary contents' )
202+ (tmp_path / "actual_launcher.txt" ).write_bytes (b'Arbitrary contents' )
203+ fake_config .default_platform = '-32'
204+ fake_config .global_dir = tmp_path / "bin"
205+ IC ._write_alias (
206+ fake_config ,
207+ {"tag" : "test" },
208+ {"name" : "test.exe" },
209+ tmp_path / "target.exe" ,
210+ _link = fake_link
211+ )
212+ assert_log (
213+ "Checking for launcher.*" ,
214+ "Create %s linking to %s" ,
215+ "Failed to create hard link.+" ,
216+ ("Created %s as hard link to %s" , ("test.exe" , "actual_launcher.txt" )),
217+ assert_log .end_of_log (),
218+ )
219+
220+
106221@pytest .mark .parametrize ("default" , [1 , 0 ])
107222def test_write_alias_default (alias_checker , monkeypatch , tmp_path , default ):
108223 prefix = Path (tmp_path ) / "runtime"
109224
110225 class Cmd :
111226 global_dir = Path (tmp_path ) / "bin"
112227 launcher_exe = None
228+ scratch = {}
113229 def get_installs (self ):
114230 return [
115231 {
@@ -146,6 +262,7 @@ def write_alias(*a):
146262
147263def test_print_cli_shortcuts (patched_installs , assert_log , monkeypatch , tmp_path ):
148264 class Cmd :
265+ scratch = {}
149266 global_dir = Path (tmp_path )
150267 def get_installs (self ):
151268 return installs .get_installs (None )
@@ -163,6 +280,7 @@ def get_installs(self):
163280
164281def test_print_path_warning (patched_installs , assert_log , tmp_path ):
165282 class Cmd :
283+ scratch = {}
166284 global_dir = Path (tmp_path )
167285 def get_installs (self ):
168286 return installs .get_installs (None )
0 commit comments