Repository: comonicon/Comonicon.jl
Pull request #241 (2023-05-08 09:01:38)

generate batch script entryfile for windows
This doesn't fix every issue I've met when using Comonicon on Windows, but I believe it's a good first step.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
Patch coverage has no change and project coverage change: **`-81.84`** :warning:
> Comparison is base [(`63c46c0`)](https://app.codecov.io/gh/comonicon/Comonicon.jl/commit/63c46c021a1774d563927bcc74b9c1999fa72ee8?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) 82.84% compared to head [(`8c9fcca`)](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) 1.01%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #241       +/-   ##
==========================================
- Coverage   82.84%   1.01%   -81.84%     
==========================================
  Files          21      20        -1     
  Lines        1586    1569       -17     
==========================================
- Hits         1314      16     -1298     
- Misses        272    1553     +1281     
```


| [Impacted Files](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [src/builder/install.jl](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2J1aWxkZXIvaW5zdGFsbC5qbA==) | `0.00% <0.00%> (-74.67%)` | :arrow_down: |

... and [19 files with indirect coverage changes](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/comonicon/Comonicon.jl/pull/241?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

Roger-luo: I'm good to merge this PR since it's not breaking any CIs, I'm wondering what you think would be the next step? e.g how should people add this to their path on windows?

Patch:
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 72e6be2..b96837d 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -22,6 +22,19 @@ jobs:
           - 'Comonicon'
           - 'lib'
           - 'example'
+        include:
+          - os: windows-latest
+            version: '1'
+            arch: x64
+            package: 'Comonicon'
+          - os: windows-latest
+            version: '1'
+            arch: x64
+            package: 'lib'
+          # - os: windows-latest
+          #   version: '1'
+          #   arch: x64
+          #   package: 'example'
     steps:
       - uses: actions/checkout@v2
       - uses: julia-actions/setup-julia@v1
diff --git a/src/ast/printing.jl b/src/ast/printing.jl
index 5d58abe..e1422f1 100644
--- a/src/ast/printing.jl
+++ b/src/ast/printing.jl
@@ -167,7 +167,7 @@ function print_head(io::IO, cmd::LeafCommand, t::Terminal)
         printstyled(io, tab(1), "<args>"; color = t.color.args)
     end
 
-    isempty(cmd.args) || printstyled(io, tab(1), "[options]"; color = t.color.dash)
+    isempty(cmd.options) || printstyled(io, tab(1), "[options]"; color = t.color.dash)
     isempty(cmd.flags) || printstyled(io, tab(1), "[flags]"; color = t.color.dash)
     return
 end
diff --git a/src/builder/cli.jl b/src/builder/cli.jl
index d9999b2..5be321d 100644
--- a/src/builder/cli.jl
+++ b/src/builder/cli.jl
@@ -1,4 +1,4 @@
-function print_builder_help(io::IO = stdout)
+function print_builder_help(options::Configs.Comonicon, io::IO = stdout)
     println(io, "Comonicon - Builder CLI.")
     println(io)
     print(io, "Builder CLI for Comonicon Applications. If not sepcified, run the command")
@@ -12,12 +12,19 @@ function print_builder_help(io::IO = stdout)
 
     printstyled(io, " "^4, "install"; color = :light_blue, bold = true)
     println(io, " "^21, "install the CLI locally.\n")
-
-    printstyled(io, " "^4, "app"; color = :light_blue, bold = true)
+    if isnothing(options.application)
+        printstyled(io, " "^4, "app (disabled, add [application] section in Comonicon.toml to enable) "; color = :light_yellow, bold = true)  
+    else
+        printstyled(io, " "^4, "app"; color = :light_blue, bold = true)
+    end
     printstyled(io, " [tarball]"; color = :blue)
     println(io, " "^15, "build the application, optionally make a tarball.\n")
-
-    printstyled(io, " "^4, "sysimg"; color = :light_blue, bold = true)
+    
+    if isnothing(options.sysimg)
+        printstyled(io, " "^4, "sysimg (disabled, add [sysimg] section in Comonicon.toml to enable) "; color = :light_yellow, bold = true)
+    else
+        printstyled(io, " "^4, "sysimg"; color = :light_blue, bold = true)
+    end
     printstyled(io, " [tarball]"; color = :blue)
     println(io, " "^12, "build the system image, optionally make a tarball.\n")
 
@@ -51,7 +58,7 @@ end
 
 function command_main(m::Module, options::Configs.Comonicon)
     if "-h" in ARGS || "--help" in ARGS || "help" in ARGS
-        print_builder_help()
+        print_builder_help(options)
         return 0
     elseif isempty(ARGS) || (first(ARGS) == "install" && length(ARGS) == 1)
         if options.install.quiet
@@ -91,6 +98,6 @@ function command_main(m::Module, options::Configs.Comonicon)
     printstyled(join(ARGS, " "); color = :red)
     println()
     println()
-    print_builder_help()
+    print_builder_help(options)
     return 1
 end
diff --git a/src/builder/install.jl b/src/builder/install.jl
index a4437e2..f5a9dc4 100644
--- a/src/builder/install.jl
+++ b/src/builder/install.jl
@@ -32,6 +32,9 @@ function install_entryfile(m::Module, options::Configs.Comonicon)
     bin = install_path(options, "bin")
     # generate entry file at .juila/bin
     entryfile = joinpath(bin, options.name)
+    if Sys.iswindows()
+        entryfile = entryfile * ".cmd"
+    end
     open(entryfile, "w+") do io
         print(io, entryfile_script(m, options))
     end
@@ -94,6 +97,14 @@ function completion_script(m::Module, options::Configs.Comonicon, shell::String)
 end
 
 function entryfile_script(m::Module, options::Configs.Comonicon)
+    if Sys.iswindows()
+        return _entryfile_script_bat(m, options)
+    else
+        return _entryfile_script_bash(m, options)
+    end
+end
+
+function _entryfile_script_bash(m::Module, options::Configs.Comonicon)
     cmds = String[]
 
     julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
@@ -126,6 +137,36 @@ function entryfile_script(m::Module, options::Configs.Comonicon)
     """
 end
 
+function _entryfile_script_bat(m::Module, options::Configs.Comonicon)
+    cmds = String[]
+
+    julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
+    push!(cmds, julia_exe)
+    if !isnothing(options.sysimg)
+        dylib = sysimg_dylib(m, options)
+        push!(cmds, "--sysimage=" * dylib)
+    end
+
+    if options.install.nthreads > 1 || options.install.nthreads == "auto"
+        push!(cmds, string("--threads=", options.install.nthreads))
+    end
+
+    push!(cmds, "--startup-file=no")
+    push!(cmds, "--color=yes")
+    push!(cmds, string("--compile=", options.install.compile))
+    push!(cmds, string("--optimize=", options.install.optimize))
+    push!(cmds, "-e \"using $m; exit($(nameof(m)).command_main())\" %*")
+
+    return """
+    @echo off
+    :: generated by Comonicon for the CLI Application $(options.name)
+    setlocal
+    set JULIA_PROJECT=$(get_scratch!(m, "env"))
+    $(join(cmds, " ^\n    "))
+    endlocal
+    """
+end
+
 function ensure_path(path::String)
     if !ispath(path)
         @info "creating $path"


Test patch:
diff --git a/test/builder/install.jl b/test/builder/install.jl
index b9cbf21..bf59f79 100644
--- a/test/builder/install.jl
+++ b/test/builder/install.jl
@@ -26,20 +26,34 @@ end
 @testset "entryfile_script" begin
     options = Configs.Comonicon(name = "test")
     script = entryfile_script(TestInstall, options)
-
-    @test occursin("#!/usr/bin/env bash", script)
-    @test occursin("JULIA_PROJECT=$(get_scratch!(TestInstall, "env"))", script)
-    julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
-    @test occursin("exec $julia_exe \\\n", script)
-    @test occursin("--startup-file=no \\\n", script)
-    @test occursin("--color=yes \\\n", script)
-    @test occursin("--compile=yes \\\n", script)
-    @test occursin("--optimize=2 \\\n", script)
-    @test occursin("-- \"\${BASH_SOURCE[0]}\"", script)
-    @test occursin(
-        "using Main.TestBuilderInstall.TestInstall\nexit(TestInstall.command_main())",
-        script,
-    )
+    if Sys.iswindows()
+        @test occursin("@echo off", script)
+        @test occursin("set JULIA_PROJECT=$(get_scratch!(TestInstall, "env"))", script)
+        julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
+        @test occursin("$julia_exe ^\n", script)
+        @test occursin("--startup-file=no ^\n", script)
+        @test occursin("--color=yes ^\n", script)
+        @test occursin("--compile=yes ^\n", script)
+        @test occursin("--optimize=2 ^\n", script)
+        @test occursin(
+            "using Main.TestBuilderInstall.TestInstall; exit(TestInstall.command_main())",
+            script,
+        )
+    else
+        @test occursin("#!/usr/bin/env bash", script)
+        @test occursin("JULIA_PROJECT=$(get_scratch!(TestInstall, "env"))", script)
+        julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
+        @test occursin("exec $julia_exe \\\n", script)
+        @test occursin("--startup-file=no \\\n", script)
+        @test occursin("--color=yes \\\n", script)
+        @test occursin("--compile=yes \\\n", script)
+        @test occursin("--optimize=2 \\\n", script)
+        @test occursin("-- \"\${BASH_SOURCE[0]}\"", script)
+        @test occursin(
+            "using Main.TestBuilderInstall.TestInstall\nexit(TestInstall.command_main())",
+            script,
+        )
+    end
 end
 
 @testset "test completion script" begin
diff --git a/test/codegen/julia/plugin.jl b/test/codegen/julia/plugin.jl
index d17b9f2..c380dc5 100644
--- a/test/codegen/julia/plugin.jl
+++ b/test/codegen/julia/plugin.jl
@@ -26,7 +26,11 @@ end
 
 using Test
 using Comonicon
-withenv("PATH" => "$(pkgdir(Comonicon, "test", "codegen", "julia")):$(ENV["PATH"])") do
-    Sys.which("node-cmd3")
-    @test TestPlugin.command_main(["cmd3"]) == 0
+if Sys.iswindows()
+    @test_broken false
+else
+    withenv("PATH" => "$(pkgdir(Comonicon, "test", "codegen", "julia")):$(ENV["PATH"])") do
+        Sys.which("node-cmd3")
+        @test TestPlugin.command_main(["cmd3"]) == 0
+    end
 end