Repository: comonicon/Comonicon.jl (julia)

Issue:
Empty docstring causes a bounds error
If a blank command description is given, a bounds error is thrown.

```julia
using Comonicon
"""
"""
@main
```

This is caused by
https://github.com/comonicon/Comonicon.jl/blob/ebb18333389d6cdbaae2c191315d4b8c8de5290c/src/frontend/markdown.jl#L134-L140

Where we see `[1]` before checking that there is any content at all.

###### Comonicon 0.12.17/master

Pull request description:
fix #214

Patch:
diff --git a/src/frontend/cast.jl b/src/frontend/cast.jl
index f83454b..5aad66a 100644
--- a/src/frontend/cast.jl
+++ b/src/frontend/cast.jl
@@ -521,6 +521,8 @@ end
 function codegen_multiple_main_entry(m::Module, line, cmd, configs)
     name = configs.name
 
+    isdefined(m, :CASTED_COMMANDS) ||
+        throw(ArgumentError("expect @cast in module $m for multi-command CLI"))
     @gensym doc
     return quote
         Core.@__doc__ const COMMAND_ENTRY_DOC_STUB = nothing
diff --git a/src/frontend/markdown.jl b/src/frontend/markdown.jl
index 6191306..8ad317a 100644
--- a/src/frontend/markdown.jl
+++ b/src/frontend/markdown.jl
@@ -29,7 +29,9 @@ function split_docstring(doc::Markdown.MD)
 end
 
 function has_docstring(doc::Markdown.MD)
-    paragraph = first(read_content(doc))
+    content = read_content(doc)
+    isempty(content) && return false
+    paragraph = first(content)
     flag = paragraph isa Markdown.Paragraph && paragraph.content == Any["No documentation found."]
     return !flag
 end
@@ -132,7 +134,7 @@ end
 
 read_content(x) = x
 function read_content(md::Markdown.MD)
-    if md.content[1] isa Markdown.MD
+    if !isempty(md.content) && md.content[1] isa Markdown.MD
         return read_content(md.content[1])
     else
         return md.content


Test patch:
diff --git a/test/frontend/markdown.jl b/test/frontend/markdown.jl
index e9d3f0c..6990616 100644
--- a/test/frontend/markdown.jl
+++ b/test/frontend/markdown.jl
@@ -234,6 +234,22 @@ end
     @test options["registry"].hint == "registry name"
 end
 
+module TestEmptyDocString
+using Test
+using Comonicon
+
+@cast test() = @test true
+
+"""
+"""
+@main
+
+end # TestEmptyDocString
+
+@testset "empty docstring" begin
+    TestEmptyDocString.command_main(["test"])
+end
+
 end # TestMarkdown
 
 module TestLazyLoad