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,145 @@ 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+ def _test_prefix_script (prefix_path ):
155+ extension = BatShell ()
156+
157+ # BatShell requires the (non-primary) DsvShell extension as well
158+ dsv_extension = DsvShell ()
159+
160+ # create_hook_append_value
161+ append_hook_path = dsv_extension .create_hook_append_value (
162+ 'append_env_hook_name' , prefix_path , 'pkg_name' ,
163+ 'APPEND_NAME' , 'subdirectory' )
164+ assert append_hook_path .exists ()
165+ assert append_hook_path .name == 'append_env_hook_name.dsv'
166+ content = append_hook_path .read_text ()
167+ assert 'APPEND_NAME' in content
168+
169+ # create_hook_prepend_value
170+ prepend_hook_path = dsv_extension .create_hook_prepend_value (
171+ 'prepend_env_hook_name' , prefix_path , 'pkg_name' ,
172+ 'PREPEND_NAME' , 'subdirectory' )
173+ assert prepend_hook_path .exists ()
174+ assert prepend_hook_path .name == 'prepend_env_hook_name.dsv'
175+ content = prepend_hook_path .read_text ()
176+ assert 'PREPEND_NAME' in content
177+
178+ # mark package as installed
179+ package_index = prefix_path / get_relative_package_index_path ()
180+ package_index .mkdir (parents = True )
181+ (package_index / 'pkg_name' ).write_text ('' )
182+
183+ # create_package_script
184+ dsv_extension .create_package_script (
185+ prefix_path , 'pkg_name' , [
186+ (append_hook_path .relative_to (prefix_path ), ()),
187+ (prepend_hook_path .relative_to (prefix_path ), ())])
188+ assert (prefix_path / 'share' / 'pkg_name' / 'package.dsv' ).exists ()
189+ content = (prefix_path / 'share' / 'pkg_name' / 'package.dsv' ).read_text ()
190+ assert append_hook_path .name in content
191+ assert prepend_hook_path .name in content
192+
193+ # create_prefix_script
194+ extension .create_prefix_script (prefix_path , True )
195+ prefix_script = prefix_path / 'local_setup.bat'
196+ prefix_script .exists ()
197+ assert (prefix_path / '_local_setup_util_bat.py' ).exists ()
198+
199+ if sys .platform == 'win32' :
200+ subdirectory_path = str (prefix_path / 'subdirectory' )
201+
202+ # validate appending/prepending without existing values
203+ with patch .dict (os .environ , {
204+ 'APPEND_NAME' : '' ,
205+ 'PREPEND_NAME' : '' ,
206+ }):
207+ coroutine = get_environment_variables ([prefix_script , '&&' , 'set' ])
208+ env = run_until_complete (coroutine )
209+ assert env .get ('APPEND_NAME' ) == subdirectory_path
210+ assert env .get ('PREPEND_NAME' ) == subdirectory_path
211+
212+ # validate appending/prepending with existing values
213+ with patch .dict (os .environ , {
214+ 'APPEND_NAME' : 'control' ,
215+ 'PREPEND_NAME' : 'control' ,
216+ }):
217+ coroutine = get_environment_variables ([prefix_script , '&&' , 'set' ])
218+ env = run_until_complete (coroutine )
219+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
220+ 'control' ,
221+ subdirectory_path ,
222+ ))
223+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
224+ subdirectory_path ,
225+ 'control' ,
226+ ))
227+
228+ # validate appending/prepending unique values
229+ with patch .dict (os .environ , {
230+ 'APPEND_NAME' : os .pathsep .join ((subdirectory_path , 'control' )),
231+ 'PREPEND_NAME' : os .pathsep .join (('control' , subdirectory_path )),
232+ }):
233+ coroutine = get_environment_variables ([prefix_script , '&&' , 'set' ])
234+ env = run_until_complete (coroutine )
235+ # Expect no change, value already appears earlier in the list
236+ assert env .get ('APPEND_NAME' ) == os .pathsep .join ((
237+ subdirectory_path ,
238+ 'control' ,
239+ ))
240+ # TODO: The DsvShell behavior doesn't align with BatShell!
241+ # ~~Expect value to be *moved* to the front of the list~~
242+ assert env .get ('PREPEND_NAME' ) == os .pathsep .join ((
243+ 'control' ,
244+ subdirectory_path ,
245+ ))
0 commit comments