nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.64k stars 1.47k forks source link

nim doc fails building runnableExamples when nim compiler path has spaces #19803

Open stoneface86 opened 2 years ago

stoneface86 commented 2 years ago

Running nim doc when the path of the nim compiler has spaces in it fails to build the runnableExamples

Example

Have nim installed in a path with spaces in it, for this example I'm using C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\bin\nim.exe

Save this as test.nim:

proc foo*() =
    ## foo
    runnableExamples:
        foo()
    discard

Then run:

nim doc --project --index:on test.nim

Current Output

Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nim.cfg' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\config.nims' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nim.cfg' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\config.nims' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nimdoc.cfg' [Conf]
.........................................................
C:\Users\Bren (Work)\Desktop\osShellCmd\test.nim(3, 6) Hint: 'foo' is declared but not used [XDeclaredButNotUsed]
Hint: 
26974 lines; 0.250s; 25.465MiB peakmem; proj: C:\Users\Bren (Work)\Desktop\osShellCmd\test.nim; out: C:\Users\Bren (Work)\Desktop\osShellCmd\htmldocs\test.html [SuccessX]
PS C:\Users\Bren (Work)\Desktop\osShellCmd> nim doc --project --index:on test.nim
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nim.cfg' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\config.nims' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nim.cfg' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\config.nims' [Conf]
Hint: used config file 'C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\config\nimdoc.cfg' [Conf]
.........................................................'C:\Users\Bren' is not recognized as an internal or external command,
operable program or batch file.
[runnableExamples] failed: generated file: 'C:\Users\Bren (Work)\nimcache\test_d\runnableExamples\test_group0_examples.nim' group: 'rdoccmd: 
docCmd:
code: # autogenerated by docgen
# source: C:\Users\Bren (Work)\Desktop\osShellCmd\test.nim
# rdoccmd:
import "C:\\Users\\Bren (Work)\\nimcache\\test_d\\runnableExamples\\test_examples_1.nim"

index: 0
' cmd: "C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\bin\nim.exe" c -r --lib:"C:\Users\Bren (Work)\.choosenim\toolchains\nim-1.6.6\lib" --warning:UnusedImport:off --path:"C:\Users\Bren (Work)\Desktop\osShellCmd" --nimcache:"C:\Users\Bren (Work)\nimcache\test_d\runnableExamples"   "C:\Users\Bren (Work)\nimcache\test_d\runnableExamples\test_group0_examples.nim"

Expected Output

Same as current but without the "[runnableExamples] failed: ..."

Possible Solution

Unsure, might be a platform-specific issue with os.execShellCmd

Additional Information

Occurs on both stable and devel, Windows 10 64-bit. Did not test other platforms.

Nim Compiler Version 1.6.6 [Windows: amd64]
Compiled at 2022-05-05
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release
Nim Compiler Version 1.7.1 [Windows: amd64]
Compiled at 2022-05-18
Copyright (c) 2006-2022 by Andreas Rumpf

active boot switches: -d:release

Forum post where I first encountered the issue - https://forum.nim-lang.org/t/9161

xigoi commented 2 years ago

Possible solution: escape spaces? Is that possible in Windows shell?

stoneface86 commented 2 years ago

https://github.com/nim-lang/Nim/blob/devel/compiler/docgen.nim#L536 Issue with execShellCmd perhaps? I don't think this is expected behavior:

import std/os
# dummy.exe was compiled from an empty nim module
echo execShellCmd("\"folder with space\\dummy.exe\" bogus bogus")
echo execShellCmd("\"folder with space\\dummy.exe\" \"bogus bogus\"")

Output:

0
'folder' is not recognized as an internal or external command,
operable program or batch file.
1

The second command runs fine when running it in command prompt.

This hack works:

echo execShellCmd("if 1==1 \"folder with space\\dummy.exe\" \"bogus bogus\"")

https://stackoverflow.com/questions/4244095/system-function-seems-to-ignore-quote-marks

stoneface86 commented 2 years ago

Possible solution: escape spaces? Is that possible in Windows shell?

Command prompt supports escaping a space by using a space preceded by a caret, ie ^ but this rarely works apparently In Powershell you can use a grave followed by a space.

Tried both of these and they didn't work. execShellCmd calls the c standard library function system which on windows uses command prompt. Command prompt likes to remove quotations if you have multiple of them for some odd reason. From what I've researched, it seems like using CreateProcess is the preferred approach.

So a possible solution would be to use CreateProcess on windows for os.execShellCmd instead of system. Or to prepend if 1==1 to the command passed to system