55from pathlib import Path
66import sys
77from tempfile import TemporaryDirectory
8+ from unittest .mock import patch
89
910from colcon_core import shell
11+ from colcon_core .location import get_relative_package_index_path
1012from colcon_core .plugin_system import SkipExtensionException
13+ from colcon_core .shell import get_environment_variables
1114from colcon_core .shell .bat import BatShell
15+ from colcon_core .shell .dsv import DsvShell
1216import pytest
1317
1418from .run_until_complete import run_until_complete
@@ -20,6 +24,7 @@ def test_extension():
2024 try :
2125 with TemporaryDirectory (prefix = 'test_colcon_' ) as prefix_path :
2226 _test_extension (Path (prefix_path ))
27+ _test_prefix_script (Path (prefix_path ))
2328 finally :
2429 shell .use_all_shell_extensions = use_all_shell_extensions
2530
@@ -39,33 +44,36 @@ def _test_extension(prefix_path):
3944 extension .create_prefix_script (prefix_path , False )
4045 assert (prefix_path / 'local_setup.bat' ).exists ()
4146
47+ # create_hook_append_value
48+ append_hook_path = extension .create_hook_append_value (
49+ 'append_env_hook_name' , prefix_path , 'pkg_name' ,
50+ 'APPEND_NAME' , 'subdirectory' )
51+ assert append_hook_path .exists ()
52+ assert append_hook_path .name == 'append_env_hook_name.bat'
53+ content = append_hook_path .read_text ()
54+ assert 'APPEND_NAME' in content
55+
56+ # create_hook_prepend_value
57+ prepend_hook_path = extension .create_hook_prepend_value (
58+ 'prepend_env_hook_name' , prefix_path , 'pkg_name' ,
59+ 'PREPEND_NAME' , 'subdirectory' )
60+ assert prepend_hook_path .exists ()
61+ assert prepend_hook_path .name == 'prepend_env_hook_name.bat'
62+ content = prepend_hook_path .read_text ()
63+ assert 'PREPEND_NAME' in content
64+
4265 # create_package_script
4366 extension .create_package_script (
4467 prefix_path , 'pkg_name' , [
45- ('hookA.bat' , '/some/path/hookA.bat' ),
68+ (append_hook_path .relative_to (prefix_path ), ()),
69+ (prepend_hook_path .relative_to (prefix_path ), ()),
4670 ('hookB.other' , '/some/path/hookB.other' )])
4771 assert (prefix_path / 'share' / 'pkg_name' / 'package.bat' ).exists ()
4872 content = (prefix_path / 'share' / 'pkg_name' / 'package.bat' ).read_text ()
49- assert 'hookA' in content
73+ assert append_hook_path .name in content
74+ assert prepend_hook_path .name in content
5075 assert 'hookB' not in content
5176
52- # create_hook_append_value
53- hook_path = extension .create_hook_append_value (
54- 'append_env_hook_name' , prefix_path , 'pkg_name' ,
55- 'APPEND_NAME' , 'append_subdirectory' )
56- assert hook_path .exists ()
57- assert hook_path .name == 'append_env_hook_name.bat'
58- content = hook_path .read_text ()
59- assert 'APPEND_NAME' in content
60-
61- # create_hook_prepend_value
62- hook_path = extension .create_hook_prepend_value (
63- 'env_hook_name' , prefix_path , 'pkg_name' , 'NAME' , 'subdirectory' )
64- assert hook_path .exists ()
65- assert hook_path .name == 'env_hook_name.bat'
66- content = hook_path .read_text ()
67- assert 'NAME' in content
68-
6977 # generate_command_environment
7078 if sys .platform != 'win32' :
7179 with pytest .raises (SkipExtensionException ) as e :
@@ -93,3 +101,153 @@ def _test_extension(prefix_path):
93101 'task_name' , prefix_path , {'dep' : str (prefix_path )})
94102 env = run_until_complete (coroutine )
95103 assert isinstance (env , dict )
104+
105+ subdirectory_path = str (prefix_path / 'subdirectory' )
106+
107+ # validate appending/prepending without existing values
108+ with patch .dict (os .environ ) as env_patch :
109+ env_patch .pop ('APPEND_NAME' , None )
110+ env_patch .pop ('PREPEND_NAME' , None )
111+ coroutine = extension .generate_command_environment (
112+ 'task_name' , prefix_path , {'pkg_name' : str (prefix_path )})
113+ env = run_until_complete (coroutine )
114+ assert env .get ('APPEND_NAME' ) == subdirectory_path
115+ assert env .get ('PREPEND_NAME' ) == subdirectory_path
116+
117+ # validate appending/prepending with existing values
118+ with patch .dict (os .environ , {
119+ 'APPEND_NAME' : 'control' ,
120+ 'PREPEND_NAME' : 'control' ,
121+ }):
122+ coroutine = extension .generate_command_environment (
123+ 'task_name' , prefix_path , {'pkg_name' : str (prefix_path )})
124+ env = run_until_complete (coroutine )
125+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
126+ 'control' ,
127+ subdirectory_path ,
128+ ))
129+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
130+ subdirectory_path ,
131+ 'control' ,
132+ ))
133+
134+ # validate appending/prepending unique values
135+ with patch .dict (os .environ , {
136+ 'APPEND_NAME' : os .pathsep .join ((subdirectory_path , 'control' )),
137+ 'PREPEND_NAME' : os .pathsep .join (('control' , subdirectory_path )),
138+ }):
139+ coroutine = extension .generate_command_environment (
140+ 'task_name' , prefix_path , {'pkg_name' : str (prefix_path )})
141+ env = run_until_complete (coroutine )
142+ # Expect no change, value already appears earlier in the list
143+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
144+ subdirectory_path ,
145+ 'control' ,
146+ ))
147+ # Expect value to be *moved* to the front of the list
148+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
149+ subdirectory_path ,
150+ 'control' ,
151+ ))
152+
153+
154+ async def _run_prefix_script (prefix_script ):
155+ return await get_environment_variables ([
156+ str (prefix_script ),
157+ '&&' ,
158+ 'set' ,
159+ ])
160+
161+
162+ def _test_prefix_script (prefix_path ):
163+ extension = BatShell ()
164+
165+ # BatShell requires the (non-primary) DsvShell extension as well
166+ dsv_extension = DsvShell ()
167+
168+ # create_hook_append_value
169+ append_hook_path = dsv_extension .create_hook_append_value (
170+ 'append_env_hook_name' , prefix_path , 'pkg_name' ,
171+ 'APPEND_NAME' , 'subdirectory' )
172+ assert append_hook_path .exists ()
173+ assert append_hook_path .name == 'append_env_hook_name.dsv'
174+ content = append_hook_path .read_text ()
175+ assert 'APPEND_NAME' in content
176+
177+ # create_hook_prepend_value
178+ prepend_hook_path = dsv_extension .create_hook_prepend_value (
179+ 'prepend_env_hook_name' , prefix_path , 'pkg_name' ,
180+ 'PREPEND_NAME' , 'subdirectory' )
181+ assert prepend_hook_path .exists ()
182+ assert prepend_hook_path .name == 'prepend_env_hook_name.dsv'
183+ content = prepend_hook_path .read_text ()
184+ assert 'PREPEND_NAME' in content
185+
186+ # mark package as installed
187+ package_index = prefix_path / get_relative_package_index_path ()
188+ package_index .mkdir (parents = True )
189+ (package_index / 'pkg_name' ).write_text ('' )
190+
191+ # create_package_script
192+ dsv_extension .create_package_script (
193+ prefix_path , 'pkg_name' , [
194+ (append_hook_path .relative_to (prefix_path ), ()),
195+ (prepend_hook_path .relative_to (prefix_path ), ())])
196+ assert (prefix_path / 'share' / 'pkg_name' / 'package.dsv' ).exists ()
197+ content = (prefix_path / 'share' / 'pkg_name' / 'package.dsv' ).read_text ()
198+ assert append_hook_path .name in content
199+ assert prepend_hook_path .name in content
200+
201+ # create_prefix_script
202+ extension .create_prefix_script (prefix_path , True )
203+ prefix_script = prefix_path / 'local_setup.bat'
204+ assert prefix_script .exists ()
205+ assert (prefix_path / '_local_setup_util_bat.py' ).exists ()
206+
207+ if sys .platform == 'win32' :
208+ subdirectory_path = str (prefix_path / 'subdirectory' )
209+
210+ # validate appending/prepending without existing values
211+ with patch .dict (os .environ ) as env_patch :
212+ env_patch .pop ('APPEND_NAME' , None )
213+ env_patch .pop ('PREPEND_NAME' , None )
214+
215+ coroutine = _run_prefix_script (prefix_script )
216+ env = run_until_complete (coroutine )
217+ assert env .get ('APPEND_NAME' ) == subdirectory_path
218+ assert env .get ('PREPEND_NAME' ) == subdirectory_path
219+
220+ # validate appending/prepending with existing values
221+ with patch .dict (os .environ , {
222+ 'APPEND_NAME' : 'control' ,
223+ 'PREPEND_NAME' : 'control' ,
224+ }):
225+ coroutine = _run_prefix_script (prefix_script )
226+ env = run_until_complete (coroutine )
227+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
228+ 'control' ,
229+ subdirectory_path ,
230+ ))
231+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
232+ subdirectory_path ,
233+ 'control' ,
234+ ))
235+
236+ # validate appending/prepending unique values
237+ with patch .dict (os .environ , {
238+ 'APPEND_NAME' : os .pathsep .join ((subdirectory_path , 'control' )),
239+ 'PREPEND_NAME' : os .pathsep .join (('control' , subdirectory_path )),
240+ }):
241+ coroutine = _run_prefix_script (prefix_script )
242+ env = run_until_complete (coroutine )
243+ # Expect no change, value already appears earlier in the list
244+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
245+ subdirectory_path ,
246+ 'control' ,
247+ ))
248+ # TODO: The DsvShell behavior doesn't align with BatShell!
249+ # ~~Expect value to be *moved* to the front of the list~~
250+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
251+ 'control' ,
252+ subdirectory_path ,
253+ ))
0 commit comments