Command line runner: For loops, functions, and variable expansion. False positives for undefined variables.

We're using TeamCity Pro 7.1.1.

TeamCity checks that the contents of a command line runner script are good before it lets your run. If you have references to variables that don't exist, it won't let you run. However, it seems to make mistakes about what variables are defined when the reference is inside a loop or function.

This code results in "MyVar <value is required> undeletable" in configuration parameters, which prevents the build from running:

SET MyVar=MyValue
FOR /L %%%A IN (1,1,3) DO (
     ECHO %%MyVar%% %%%A
)


This change fixes it:

setlocal EnableDelayedExpansion
SET MyVar=MyValue
FOR /L %%%A IN (1,1,3) DO (
     ECHO !MyVar! %%%A
)


This results in "MyVar2 <value is required> undeletable"

SET MyVar=MyValue
call:MyFunction MyArgument
GOTO:eof

:MyFunction
     SET MyVar2=MyValue2
     ECHO %%MyVar%% %1
     ECHO %%MyVar2%%
GOTO:eof


This change fixes it:

setlocal EnableDelayedExpansion
SET MyVar=MyValue
call:MyFunction MyArgument
GOTO:eof

:MyFunction
     SET MyVar2=MyValue2
     ECHO %%MyVar%% %1
     ECHO !MyVar2!
GOTO:eof


While there seem to be some work arounds, my fear is they are unstable. While analyzing this, I even found cases where the presence of a comment that contained a reference to a variable would actually fix the problem. How long until a comment breaks something else?

Are these problems solved in TeamCity Pro 8+?

3 comments
Comment actions Permalink

Here's an example where the presence of a comment actually causes an error.

This code is fine:

set currdate=%%date:~10,4%%-%%date:~4,2%%-%%date:~7,2%%
set version=%%currdate%% #%system.build.vcs.number.NextGen_Metamorphosis_Perforce%.%autoinc.BuildRevAutoinc%
set xcopy=c:\windows\system32\xcopy

if not "%DEMO_BUILD%" == "true" (
     echo call %%xcopy%% /E /Y /i Bin64\*.* "destination\%%version%%\Bin64"
)


But this code with the comments results in "version <value is required> undeletable" and "xcopy <value is required> undeletable".

set currdate=%%date:~10,4%%-%%date:~4,2%%-%%date:~7,2%%
set version=%%currdate%% #%system.build.vcs.number.NextGen_Metamorphosis_Perforce%.%autoinc.BuildRevAutoinc%
set xcopy=c:\windows\system32\xcopy

if not "%DEMO_BUILD%" == "true" (
     REM for /L %%%A in (1,1,3) do (
     REM     call %%xcopy%% /E /Y /i source\%%%A\*.* "destination\%%version%%\%%%A"
     REM )
     echo call %%xcopy%% /E /Y /i Bin64\*.* "destination\%%version%%\Bin64"
)

0
Comment actions Permalink

I've found another error case. This one is the most frightening so far, as this build is allowed to execute, but during execution, some configuration parameters go in and out of existence.

The job has a configuration parameter called DEMO_BUILD set to true.

Here is the script:

setlocal EnableDelayedExpansion

set currdate=!date:~10,4!-!date:~4,2!-!date:~7,2!
set version=!currdate! #%system.build.vcs.number.NextGen_Metamorphosis_Perforce%.%autoinc.BuildRevAutoinc%
set xcopy=c:\windows\system32\xcopy

echo DEMO_BUILD: "%DEMO_BUILD%"

for /L %%%A in (1,1,3) do (
     echo call !xcopy! %%%A\*.* "\!version!\%%%A" DEMO_BUILD: "%DEMO_BUILD%"
)

echo DEMO_BUILD: "%DEMO_BUILD%"

for /L %%%A in (1,1,3) do (
     echo call !xcopy! %%%A\*.* "!version!\%%%A" DEMO_BUILD: "%DEMO_BUILD%"
)

echo DEMO_BUILD: "%DEMO_BUILD%"


Here is the log:

[Step 1/1] DEMO_BUILD: "true"
[Step 1/1] call c:\windows\system32\xcopy 1\*.* "\2013-09-25 #80341.38212\1" DEMO_BUILD: ""
[Step 1/1] call c:\windows\system32\xcopy 2\*.* "\2013-09-25 #80341.38212\2" DEMO_BUILD: ""
[Step 1/1] call c:\windows\system32\xcopy 3\*.* "\2013-09-25 #80341.38212\3" DEMO_BUILD: ""
[Step 1/1] DEMO_BUILD: ""
[Step 1/1] call c:\windows\system32\xcopy 1\*.* "2013-09-25 #80341.38212\1" DEMO_BUILD: "true"
[Step 1/1] call c:\windows\system32\xcopy 2\*.* "2013-09-25 #80341.38212\2" DEMO_BUILD: "true"
[Step 1/1] call c:\windows\system32\xcopy 3\*.* "2013-09-25 #80341.38212\3" DEMO_BUILD: "true"
[Step 1/1] DEMO_BUILD: "true"
[Step 1/1] Process exited with code 0


As you can see, the configuration parameter DEMO_BUILD starts off true, then inside and after the first loop it is undefined, the inside and after the second loop it is defined again. I realize we are playing with SETLOCAL here, but this behavior is still very wrong.

0
Comment actions Permalink

I've installed TeamCity Pro 8.0.3 and found that all but one of the bugs above has been fixed. Although the one that remains is a bit different now.

This works fine.

set currdate=%%date:~10,4%%-%%date:~4,2%%-%%date:~7,2%%
set version=%%currdate%% #%system.build.vcs.number.NextGen_Metamorphosis_Perforce%.%autoinc.BuildRevAutoinc%
set xcopy=c:\windows\system32\xcopy

if not "%DEMO_BUILD%" == "true" (
     echo call %%xcopy%% /E /Y /i Bin64\*.* "destination\%%version%%\Bin64"
)


But adding the comments results in: "\ <value is required> undeletable" and "version <value is required> undeletable".

set currdate=%%date:~10,4%%-%%date:~4,2%%-%%date:~7,2%%
set version=%%currdate%% #%system.build.vcs.number.NextGen_Metamorphosis_Perforce%.%autoinc.BuildRevAutoinc%
set xcopy=c:\windows\system32\xcopy

if not "%DEMO_BUILD%" == "true" (
     REM for /L %%%A in (1,1,3) do (
     REM     call %%xcopy%% /E /Y /i source\%%%A\*.* "destination\%%version%%\%%%A"
     REM )
     echo call %%xcopy%% /E /Y /i Bin64\*.* "destination\%%version%%\Bin64"
)

0

Please sign in to leave a comment.