Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix windows batch argument probrem. #393

Merged
merged 6 commits into from
Nov 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
@setlocal enabledelayedexpansion

@echo off

if "%@@APP_ENV_NAME@@_HOME%"=="" set "@@APP_ENV_NAME@@_HOME=%~dp0\\.."
set ERROR_CODE=0

set "APP_LIB_DIR=%@@APP_ENV_NAME@@_HOME%\lib\"

rem Detect if we were double clicked, although theoretically A user could
rem manually run cmd /c
for %%x in (%cmdcmdline%) do if %%~x==/c set DOUBLECLICKED=1
for %%x in (!cmdcmdline!) do if %%~x==/c set DOUBLECLICKED=1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between % and !?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

! is delayed-expansion literal. I understood %ENV% expanded before parse time. !ENV! after parse time, before run time.

>type test.bat
SET A=%1
if NOT "!A!" == "" echo "OK"

>test a"a

SET A=a"a
The syntax of the command is incorrect.
if NOT "a"a" == "" echo "OK"
SET A=%1
if NOT "!A!" == "" echo "OK"

>test a"a
SET A=a"a
if NOT "!A!" == "" echo "OK"
"OK"


rem FIRST we load the config file of extra options.
set "CFG_FILE=%@@APP_ENV_NAME@@_HOME%\@@APP_ENV_NAME@@_config.txt"
Expand Down Expand Up @@ -72,86 +73,60 @@ if "%JAVAOK%"=="false" (

rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config.
set _JAVA_OPTS=%JAVA_OPTS%
if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS%
if "!_JAVA_OPTS!"=="" set _JAVA_OPTS=!CFG_OPTS!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DOH, good catch.


rem We keep in _JAVA_PARAMS all -J-prefixed and -D-prefixed arguments
rem "-J" is stripped, "-D" is left as is, and everything is appended to JAVA_OPTS
set _JAVA_PARAMS=

:param_beforeloop
if [%1]==[] goto param_afterloop
set _TEST_PARAM=%~1

rem ignore arguments that do not start with '-'
if not "%_TEST_PARAM:~0,1%"=="-" (
shift
goto param_beforeloop
)

set _TEST_PARAM=%~1
if "%_TEST_PARAM:~0,2%"=="-J" (
rem strip -J prefix
set _TEST_PARAM=%_TEST_PARAM:~2%
)

if "%_TEST_PARAM:~0,2%"=="-D" (
rem test if this was double-quoted property "-Dprop=42"
for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO (
if not "%%G" == "%_TEST_PARAM%" (
rem double quoted: "-Dprop=42" -> -Dprop="42"
set _JAVA_PARAMS=%%G="%%H"
) else if [%2] neq [] (
rem it was a normal property: -Dprop=42 or -Drop="42"
set _JAVA_PARAMS=%_TEST_PARAM%=%2
shift
)
)
) else (
rem a JVM property, we just append it
set _JAVA_PARAMS=%_TEST_PARAM%
)
set _APP_ARGS=

:param_loop
shift
call set _PARAM1=%%1
set "_TEST_PARAM=%~1"

if ["!_PARAM1!"]==[""] goto param_afterloop

if [%1]==[] goto param_afterloop
set _TEST_PARAM=%~1

rem ignore arguments that do not start with '-'
if not "%_TEST_PARAM:~0,1%"=="-" goto param_loop
if "%_TEST_PARAM:~0,1%"=="-" goto param_java_check
set _APP_ARGS=!_APP_ARGS! !_PARAM1!
shift
goto param_loop

set _TEST_PARAM=%~1
if "%_TEST_PARAM:~0,2%"=="-J" (
:param_java_check
if "!_TEST_PARAM:~0,2!"=="-J" (
rem strip -J prefix
set _TEST_PARAM=%_TEST_PARAM:~2%
set _JAVA_PARAMS=!_JAVA_PARAMS! !_TEST_PARAM:~2!
shift
goto param_loop
)

if "%_TEST_PARAM:~0,2%"=="-D" (
if "!_TEST_PARAM:~0,2!"=="-D" (
rem test if this was double-quoted property "-Dprop=42"
for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO (
if not "%%G" == "%_TEST_PARAM%" (
rem double quoted: "-Dprop=42" -> -Dprop="42"
set _JAVA_PARAMS=%_JAVA_PARAMS% %%G="%%H"
for /F "delims== tokens=1,*" %%G in ("!_TEST_PARAM!") DO (
if not ["%%H"] == [""] (
set _JAVA_PARAMS=!_JAVA_PARAMS! !_PARAM1!
) else if [%2] neq [] (
rem it was a normal property: -Dprop=42 or -Drop="42"
set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM%=%2
call set _PARAM1=%%1=%%2
set _JAVA_PARAMS=!_JAVA_PARAMS! !_PARAM1!
shift
)
)
) else (
rem a JVM property, we just append it
set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM%
set _APP_ARGS=!_APP_ARGS! !_PARAM1!
)
shift
goto param_loop
:param_afterloop

set _JAVA_OPTS=%_JAVA_OPTS% %_JAVA_PARAMS%
set _JAVA_OPTS=!_JAVA_OPTS! !_JAVA_PARAMS!
:run

@@APP_DEFINES@@

rem Call the application and pass all arguments unchanged.
"%_JAVACMD%" %_JAVA_OPTS% %@@APP_ENV_NAME@@_OPTS% -cp "%APP_CLASSPATH%" %APP_MAIN_CLASS% %*
"%_JAVACMD%" !_JAVA_OPTS! !@@APP_ENV_NAME@@_OPTS! -cp "%APP_CLASSPATH%" %APP_MAIN_CLASS% !_APP_ARGS!
if ERRORLEVEL 1 goto error
goto end

Expand Down
2 changes: 0 additions & 2 deletions src/sbt-test/windows/java-app-archetype/build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import NativePackagerKeys._

enablePlugins(JavaAppPackaging)

name := "windows-test"
Expand Down
98 changes: 98 additions & 0 deletions src/sbt-test/windows/test-bat-template/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
enablePlugins(JavaAppPackaging)

name := "windows-test"

version := "0.1.0"

maintainer := "Josh Suereth <[email protected]>"

packageSummary := "test-windows"

packageDescription := """Test Windows Batch."""

// debug out
val debugOutFile = file(".") / "debug_out.txt"

batScriptExtraDefines += "call :print_args %%* > "+ debugOutFile.getAbsolutePath

batScriptExtraDefines += "goto print_args_end"

batScriptExtraDefines += ":print_args"

batScriptExtraDefines += "echo cmdcmdline=!cmdcmdline!"

batScriptExtraDefines += "echo *=%*"

batScriptExtraDefines += 1.to(9).map(i => "echo %%"+i+"=%"+i).mkString("\n")

batScriptExtraDefines += "echo _JAVA_OPTS=!_JAVA_OPTS!"

batScriptExtraDefines += "echo _APP_ARGS=!_APP_ARGS!"

batScriptExtraDefines += "exit /B"

batScriptExtraDefines += ":print_args_end"


TaskKey[Unit]("check-script") <<= (stagingDirectory in Universal, name, streams) map { (dir, name, streams) =>
import scala.sys.process._
val fails = new StringBuilder()
val script = dir / "bin" / (name+".bat")
val detailScript:File = {
val d = dir / "bin" / "detail.bat"
val out = new java.io.PrintWriter( d , "UTF-8")
out.print( scala.io.Source.fromFile(script).mkString.replaceAll("@echo off","@echo on & prompt \\$g ") )
out.close
d
}
def crlf2cr(txt:String) = txt.trim.replaceAll("\\\r\\\n", "\n")
def checkOutputEnv(env:Map[String,String], expected:String, args:String*) = {
val pr = new StringBuilder()
val logger = ProcessLogger((o: String) => pr.append(o+"\n"),(e: String) => pr.append("error < " + e+"\n"))
val cmd = Seq("cmd", "/c", script.getAbsolutePath) ++ args
val result = Process(cmd, None, env.toSeq:_*) ! logger
if ( result != 0 ) {
pr.append("error code: " + result+"\n")
}
val output = crlf2cr(pr.toString)
if(output != expected.trim){
fails.append("\n---------------------------------\n")
fails.append("Failed to correctly run the main script!.\n")
fails.append("\""+cmd.mkString("\" \"")+"\"\n")
if(debugOutFile.exists){
fails.append(crlf2cr(scala.io.Source.fromFile(debugOutFile).mkString))
}
fails.append("\n--expected----------------------------\n")
fails.append(expected.trim+"\n")
fails.append("\n--found-------------------------------\n")
fails.append(crlf2cr(pr.toString)+"\n")
fails.append("\n--detail-------------------------------\n")
pr.clear
Process(Seq("cmd", "/c", detailScript.getAbsolutePath) ++ args, None, env.toSeq:_*) ! logger
fails.append(crlf2cr(pr.toString)+"\n")
}
if(debugOutFile.exists){
debugOutFile.delete()
}
}
def checkOutput(expected:String, args:String*) = checkOutputEnv(Map.empty, expected, args:_*)
checkOutput("arg #0 is [OK]\nSUCCESS!", "OK")
checkOutput("arg #0 is [OK]\nproperty(test.hoge) is [huga]\nSUCCESS!", "-Dtest.hoge=\"huga\"", "OK")
checkOutputEnv(Map("show-vmargs"->"true"), "arg #0 is [OK]\nvmarg #0 is [-Xms6m]\nSUCCESS!","-J-Xms6m", "OK")
checkOutputEnv(Map("show-vmargs"->"true"), "arg #0 is [first]\narg #1 is [-XX]\narg #2 is [last]\nproperty(test.hoge) is [huga]\nvmarg #0 is [-Dtest.hoge=huga]\nvmarg #1 is [-Xms6m]\nSUCCESS!",
"first", "-Dtest.hoge=\"huga\"", "-J-Xms6m", "-XX", "last")
// include space
checkOutput("arg #0 is [C:\\Program Files\\Java]\nproperty(test.hoge) is [C:\\Program Files\\Java]\nSUCCESS!",
"-Dtest.hoge=C:\\Program Files\\Java", "C:\\Program Files\\Java")
// split "include symbols"
checkOutput("property(test.hoge) is [\\[]!< >%]\nSUCCESS!", "\"-Dtest.hoge=\\[]!< >%\"")
checkOutput("arg #0 is [\\[]!< >%]\nSUCCESS!", "\\[]!< >%")
checkOutput("property(test.huga) is [\\[]!<>%]\nSUCCESS!", "-Dtest.huga=\"\\[]!<>%\"")
// include symbols
checkOutput("arg #0 is [\\[]!< >%]\nproperty(test.hoge) is [\\[]!< >%]\nproperty(test.huga) is [\\[]!<>%]\nSUCCESS!",
"\"-Dtest.hoge=\\[]!< >%\"", "\\[]!< >%", "-Dtest.huga=\"\\[]!<>%\"")
// include space and double-quote is failed...
// can't success include double-quote. arguments pass from Process(Seq("-Da=xx\"yy", "aa\"bb")) is parsed (%1="-Da", %2="xx\"yy aa\"bb") by cmd.exe ...
//checkOutput("arg #0 is [xx\"yy]\nproperty(test.hoge) is [aa\"bb]\nvmarg #0 is [-Dtest.hoge=aa\"bb]\nSUCCESS!", "-Dtest.hoge=aa\"bb", "xx\"yy")
assert(fails.toString == "", fails.toString)
}
1 change: 1 addition & 0 deletions src/sbt-test/windows/test-bat-template/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package test

import scala.collection.JavaConversions._

object Test extends App {
override def main(args: Array[String]): Unit = {
for((x,i) <- args.zipWithIndex) println("arg #" + i + " is [" + x + "]")
for((k,v) <- System.getProperties if k.startsWith("test.")) println("property(" + k + ") is [" + v + "]")
if(System.getenv("show-vmargs") == "true"){
for((x,i) <- java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().zipWithIndex){
println("vmarg #" + i + " is [" + x + "]")
}
}
println("SUCCESS!")
}
}
4 changes: 4 additions & 0 deletions src/sbt-test/windows/test-bat-template/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Run the windows batch.
> stage
$ exists target/universal/stage/bin/windows-test.bat
> check-script