0

I am writing a CMD script to generate documentation markdown pages for my GitHub repository. I have decided to give the script a default directory for the project and its documentation folder, and if the end user wants to use a different one, they must specify it, before the next step.

My code is something like:

echo.
setlocal enabledelayedexpansion
set projectDirectory=GroupManagementAppServer
set documentationFolder=documentation
rem ask user for confirmation of projectDirectory,documentationFolder to use
choice /m "By default, project directory is %projectDirectory% and documentation is stored in %documentationFolder%. Should I use these?"
rem if no
if %errorlevel% == 2 (
rem get projectDirectory,documentationFolder from user
set /p relativeDocumentationPathname=Please enter relative pathname to the documentation folder: 
rem parse input
call :getAbsolutePath %relativeDocumentationPathname%
set documentationFolder=%_absolutePath%
set projectDirectory="%documentationFolder%\.."
)
echo %_absolutePath%
echo %documentationFolder%
echo %projectDirectory%

:getAbsolutePath
SETLOCAL
for %%i in ("%1%") do (
set filedrive=%%~di
set filepath=%%~pi
set filename=%%~ni
set fileextension=%%~xi
)
ENDLOCAL & SET _absolutePath=%filedrive%%filepath%%filename%%fileextension%

thus far, and when the echos complete, it's as if documentationFolder was never redefined! What the heck is going on, and how do I fix this, so that I can implement the rest of this and move on to actually getting some documentation on?

Ken White
  • 123,280
  • 14
  • 225
  • 444
Mike Warren
  • 3,796
  • 5
  • 47
  • 99
  • 1
    Before the label `:getAbsolutePath`, place a `goto :EOF`! in the sub-routine, `%1%` should read `%~1`; in the `call` command line, place `""` around the path argument; note that the variables are no longer available after termination of your script, because you have a `setlocal` at the beginning, and ending a script executes an implicit `endlocal`... – aschipfl Jan 04 '17 at 23:15
  • To the person who voted to close this question: why? I spent the better part of the whole day looking up syntax and how to do this stuff, tackling this on my own, and simplifying it so that it can be looked at here. You owe me an explanation. – Mike Warren Jan 04 '17 at 23:22
  • @aschipfl It changed nothing. – Mike Warren Jan 04 '17 at 23:26
  • I missed mentioning the missing delayed-expansion feature, which is the main issue here; I voted to close the question, because there are tons of similar questions, even some with almost the same title, which let me conclude your lack of searching... – aschipfl Jan 04 '17 at 23:33
  • Possible duplicate of: [Why variables are not set](http://stackoverflow.com/questions/33532280/why-variables-are-not-set) – aschipfl Jan 04 '17 at 23:33
  • The answer there didn't work. I tried it. – Mike Warren Jan 04 '17 at 23:40
  • 2
    You have [delayed expansion](http://ss64.com/nt/delayedexpansion.html) enabled, but you are not using it; read variables like `!VAR!` rather than `%VAR%` in case they are set *and* read in the same parenthesised block of code... – aschipfl Jan 04 '17 at 23:56
  • 3
    Possible duplicate of [Windows Batch Variables Won't Set](http://stackoverflow.com/questions/9681863/windows-batch-variables-wont-set) – SomethingDark Jan 05 '17 at 02:53

2 Answers2

1

Here is the fixed code with delayed expansion properly applied, the sub-routine reduced and some minor improvements, mainly related to quotation:

echo/
setlocal EnableDelayedExpansion
set "projectDirectory=GroupManagementAppServer"
set "documentationFolder=documentation"
rem // Ask user for confirmation of `projectDirectory`, `documentationFolder` to use:
choice /M "By default, project directory is '%projectDirectory%' and documentation is stored in '%documentationFolder%'. Should I use these?"
rem // If no:
if %errorlevel% == 2 (
    rem // Get `projectDirectory`, `documentationFolder` from user:
    set /P relativeDocumentationPathname="Please enter relative pathname to the documentation folder: "
    rem // Parse input:
    call :getAbsolutePath "%relativeDocumentationPathname%"
    set "documentationFolder=!_absolutePath!"
    set "projectDirectory=!documentationFolder!\.."
)
echo %_absolutePath%
echo %documentationFolder%
echo %projectDirectory%
goto :EOF

:getAbsolutePath
setlocal
for /D %%I in ("%~1") do (
    set "filespec=%%~fI"
)
endlocal & set "_absolutePath=%filespec%"
aschipfl
  • 33,626
  • 12
  • 54
  • 99
0

I'd suggest you use the SO search facility in the top black bar and try to find delayedexpansion. There are hundreds of items on this matter.

Fundamentally, when a block (parenthesised series of statements) is encountered, the entire block is evaluated, substituting the then-current values of the variables and once that is done, the code is executed.

In your case, call echo %%var%% would show the modified values, or using the modified values within a subroutine (like call :arouthethatechosthevalues) would implement the new values.

Magoo
  • 77,302
  • 8
  • 62
  • 84