genDenoCmdLineHelp.cmd - One-click complete command line help generator for Deno

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
sst
Posts: 93
Joined: 12 Apr 2018 23:45

genDenoCmdLineHelp.cmd - One-click complete command line help generator for Deno

#1 Post by sst » 21 Jan 2022 23:21

genDenoCmdLineHelp.cmd

A one-click utility batch file to generate complete command line help documentation including SubCommands for Deno (https://deno.land)
It should work for future versions of Deno with new and/or removed SubCommands.
The generated documentation text file will be placed in the same directory as the batch file.
For the batch file to work, the Deno executable must be present in the same directory as the batch file or one directory up or be accessible through the PATH environment variable.
It was written for my own use, so it is not very polished for the public but it gets the job done.

Code: Select all

:: genDenoCmdLineHelp.cmd v4
:: https://www.dostips.com/forum/viewtopic.php?f=3&t=10354

:: Version History
:: v4
:: - Added subcommand retrieval support for Deno >= 1.32.2
:: - Added optional replcement routine :denoHelp_coCR for consistent line endings,
::   It has to be activated manually by a small change in the script
:: - Added link to the related dostips topic
:: - Added version history
:: v3
:: - Added subcommand retrieval support for Deno >= 1.18.0
:: - Published the script on dostips
:: v2
:: - Removed hard-coded subcommands and implemented the logic to get subcommands dynamically
:: - Added spliting and #subcommand tagging in output for clarity and easier command searching
:: v1
:: - Initial version


@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_SYSDIR=%SystemRoot%\System32"
call :getConsoleCP CP
"%_SYSDIR%\chcp" >nul 65001
call :getDP0 _dp0
set "_denoAppExe="
if exist "%_dp0%\deno.exe" (
    set "_denoAppExe=%_dp0%\deno.exe"
) else if exist "%_dp0%\..\deno.exe" (
    set "_denoAppExe=%_dp0%\..\deno.exe"
) else (
    for %%A in ("deno.exe") do set "_denoAppExe=%%~$PATH:A"
)
if defined _denoAppExe (
    for %%A in ("%_denoAppExe%") do set "_denoAppExe=%%~fA"
    call :getDenoSubCommands && (
        call :denoHelp >"%_dp0%\deno_commandline.txt"
    ) || (echo INTERNAL_ERROR&pause)>&2
) else (echo DENO_NOT_FOUND&pause)>&2
"%_SYSDIR%\chcp" >nul %CP%
exit /b

:denoHelp
setlocal DisableDelayedExpansion
call :repeat divide "-" 72
set "divide=echo,&echo,%divide%&echo,&REM/ #"
set "tagCommand=echo,#%%C&echo,&::"
"%_denoAppExe%" --help
for %%C in (%subCommands%) do (
    %divide% & %tagCommand%
    "%_denoAppExe%" %%C --help
)
exit /b 0

:: denoHelp_noCR
:: [Optional replacement routine for :denoHelp]
:: Deno outputs with unix line endings(LF) and cmd with dos/win (CRLF)
:: Use :denoHelp_noCR instead of :denoHelp if consistent line endings in the output file is a concern.
:: It is very slow compared to :denoHelp. It may or may not worth the extra dominating seconds.
:denoHelp_noCR
setlocal DisableDelayedExpansion
call :repeat divide "-" 72
"%_denoAppExe%" --help
for %%C in (%subCommands%) do (
    REM Clean but slow workaround For consistent line endings - I prefered to avoid set LF=^\n\n and set /p stuff
    "%_denoAppExe%" eval "console.log('\n%divide%\n\n#%%C\n')"
    "%_denoAppExe%" %%C --help
)
exit /b 0

:getDenoSubCommands
setlocal DisableDelayedExpansion
set "subCommands=,"
set "searchHead=*"
set "singleToken=*"
set "lineFormatDetermined="
set "isCommand="
set /a count=0
call :isDeno && for /F "tokens=*" %%A in ('@"%_denoAppExe%" --help') do (
    if defined searchHead (
        if "%%A"=="Commands:" (
            REM Deno >= 1.32.2
            set "searchHead="
            set "EndMarker=Options:"
        ) else if "%%A"=="SUBCOMMANDS:" (
            set "searchHead="
            set "EndMarker=ENVIRONMENT VARIABLES:"
        )
    ) else (
        setlocal EnableDelayedExpansion
        if "%%A"=="!EndMarker!" (
            if !count! EQU 0 exit /b 1
            for /F "delims=" %%R in ("!subCommands!") do (
                endlocal & endlocal
                set "subCommands=%%R"
                exit /b 0
            )
        )
        endlocal
        if not defined lineFormatDetermined (
            for /F "tokens=1,2" %%1 in ("%%A") do (
                if "%%2" NEQ "" (
                    REM Deno < 1.18.0
                    set "singleToken="
                    set "isCommand=*" 
                )
            )
            set "lineFormatDetermined=*"
        )
        for /F "tokens=1,2" %%1 in ("%%A") do (
            if defined singleToken (
                if "%%2" EQU "" (
                    set "isCommand=*"
                ) else (
                    set "isCommand="
                )
            )
            if defined isCommand if /i "%%1" NEQ "help" (
                set /a count+=1
                setlocal EnableDelayedExpansion
                for /F "delims=" %%R in ("!subCommands!") do (
                    endlocal
                    set "subCommands=%%R,%%1"
                )
            )
        )
    )
)
exit /b 1

:isDeno
("%_denoAppExe%" --version) | ("%_SYSDIR%\findstr.exe" /RC:"^typescript[\ ][\ ]*[^\ ][^\ ]*") >nul && exit /b 0
exit /b 1

:getDP0
for %%A in ("%~dp0\#\..") do set "%~1=%%~fA" & exit /b

:getConsoleCP <resultVar>
setlocal DisableDelayedExpansion
set "chcpOut=" & set "chcpGarbage= " & set "CP="
for /F "tokens=*" %%a in ('@"%_SYSDIR%\chcp"') do (
    set "chcpOut=%%a"
    for /F "tokens=1-2 delims=0123456789" %%a in ("%%a") do set "chcpGarbage=%%a%%b"
)
for /F "delims=%chcpGarbage: =% " %%a in ("%chcpOut%") do set "CP=%%a"
endlocal & set /a "%~1=%CP%+0" & exit /b

:repeat <resultVar> <"stringLiteral" | stringVar> <repeatCount>
(
    setlocal
    set "__repeat.ParentDelayIsOff=!"
    setlocal DisableDelayedExpansion
    (set __repeat.string=%2)
    set /a "__repeat.count=%~3 + 0"
    if defined __repeat.string (
        setlocal EnableDelayedExpansion
        for /F "tokens=1 delims="eol^= %%A in ("!__repeat.string!") do (
            endlocal
            if "%%A"=="%%~A" (
                setlocal EnableDelayedExpansion
                set "__repeat.string=!%~2!"
            ) else (
                set "__repeat.string=%%~A"
                setlocal EnableDelayedExpansion
            )
        )
        if not defined __repeat.string exit /b
        set "__repeat.result="
        if !__repeat.count! LSS 1 set /a __repeat.count=1
        if !__repeat.count! GTR 4095 set /a __repeat.count=4095
        for /L %%A in (1,1,!__repeat.count!) do set "__repeat.result=!__repeat.result!!__repeat.string!"
        if not defined __repeat.ParentDelayIsOff (
            if "!__repeat.result!" NEQ "!__repeat.result:*!=!" call :DelayProtect __repeat.result
        )
        for /F "tokens=1 delims="eol^= %%R in ("!__repeat.result!") do (
            endlocal & endlocal & endlocal
            set "%~1=%%R"
        )
    )
    exit /b
)

:DelayProtect <outVar> <srcVar> | <out_and_src_Var>
setlocal
set "__DelayProtect.CallerDelayIsOff=!"
setlocal EnableDelayedExpansion
set "__DelayProtect.out=%~1"
set "__DelayProtect.src=!%~2!"
if not defined __DelayProtect.out exit /b
if "%~2"=="" set "__DelayProtect.src=!%__DelayProtect.out%!"
if not defined __DelayProtect.src exit /b
set "out=!__DelayProtect.out!" & set "__DelayProtect.out="
set "src=!__DelayProtect.src!" & set "__DelayProtect.src="
if "!src!"=="!src:*!=!" exit /b
set "src=!src:"=""!"
set "src=!src:^=^^^^!"
set "src=%src:!=^^^!%"
if not defined __DelayProtect.CallerDelayIsOff set "src=!src:^=^^^^!"
if not defined __DelayProtect.CallerDelayIsOff (
    set "src=%src:!=^^^!%"
)
for /F delims^=^ eol^= %%Z in ("!src:""="!^") do (
    endlocal & endlocal
    set "%out%=%%Z"
)
exit /b

UPDATE - 2023-04-08
Updated the script to handle the change in the main help output introduced from Deno 1.32.2+

Post Reply