scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.88k stars 1.06k forks source link

Title property in sidebar.yml should be optional #12983

Closed vincenzobaz closed 3 years ago

vincenzobaz commented 3 years ago

Compiler version

3.0.0

Description

Given the problem in #12969 , I use the title frontmatter property to specify the label appearing in the sidebar. Therefore I do not need the title property in sidebar.yml anymore. However if I only use urls in sidebar.yml (which I need to specify the order of elements in the sidebar), the documentation generation error fails with

[error] java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
[error]         at xsbt.DottydocRunner.run(DottydocRunner.java:65)
[error]         at xsbt.ScaladocInterface.run(ScaladocInterface.java:11)
[error]         at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:329)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:175)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:133)
[error]         at sbt.Doc$.$anonfun$scaladoc$1(Doc.scala:52)
[error]         at sbt.Doc$.$anonfun$scaladoc$1$adapted(Doc.scala:40)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1(RawCompileLike.scala:79)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1$adapted(RawCompileLike.scala:72)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4(RawCompileLike.scala:63)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4$adapted(RawCompileLike.scala:61)
[error]         at sbt.util.Tracked$.$anonfun$inputChangedW$1(Tracked.scala:219)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1(RawCompileLike.scala:68)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1$adapted(RawCompileLike.scala:52)
[error]         at sbt.Defaults$.$anonfun$docTaskSettings$4(Defaults.scala:2158)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error]         at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error]         at sbt.Execute.work(Execute.scala:291)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]         at java.base/java.lang.Thread.run(Thread.java:829)
[error] Caused by: java.lang.reflect.InvocationTargetException
[error]         at jdk.internal.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at xsbt.DottydocRunner.run(DottydocRunner.java:61)
[error]         at xsbt.ScaladocInterface.run(ScaladocInterface.java:11)
[error]         at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:329)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:175)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:133)
[error]         at sbt.Doc$.$anonfun$scaladoc$1(Doc.scala:52)
[error]         at sbt.Doc$.$anonfun$scaladoc$1$adapted(Doc.scala:40)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1(RawCompileLike.scala:79)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1$adapted(RawCompileLike.scala:72)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4(RawCompileLike.scala:63)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4$adapted(RawCompileLike.scala:61)
[error]         at sbt.util.Tracked$.$anonfun$inputChangedW$1(Tracked.scala:219)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1(RawCompileLike.scala:68)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1$adapted(RawCompileLike.scala:52)
[error]         at sbt.Defaults$.$anonfun$docTaskSettings$4(Defaults.scala:2158)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error]         at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error]         at sbt.Execute.work(Execute.scala:291)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]         at java.base/java.lang.Thread.run(Thread.java:829)
[error] Caused by: scala.MatchError: RawInput(,docs/getting-started.html,[]) (of class dotty.tools.scaladoc.site.Sidebar$RawInput)
[error]         at dotty.tools.scaladoc.site.Sidebar$.toSidebar(SidebarParser.scala:30)
[error]         at dotty.tools.scaladoc.site.Sidebar$.load$$anonfun$1(SidebarParser.scala:36)
[error]         at scala.collection.immutable.List.map(List.scala:246)
[error]         at dotty.tools.scaladoc.site.Sidebar$.load(SidebarParser.scala:36)
[error]         at dotty.tools.scaladoc.site.StaticSiteContext.sideBarConfig(StaticSiteContext.scala:37)
[error]         at dotty.tools.scaladoc.site.StaticSiteContext.templates(StaticSiteContext.scala:40)
[error]         at dotty.tools.scaladoc.renderers.HtmlRenderer.<init>(HtmlRenderer.scala:42
[error]         at dotty.tools.scaladoc.Scaladoc$.run(Scaladoc.scala:182)
[error]         at dotty.tools.scaladoc.Scaladoc$.run$$anonfun$1(Scaladoc.scala:67)
[error]         at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error]         at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error]         at scala.Option.map(Option.scala:242)
[error]         at dotty.tools.scaladoc.Scaladoc$.run(Scaladoc.scala:69)
[error]         at dotty.tools.dottydoc.Main$.process(Main.scala:25)
[error]         at dotty.tools.dottydoc.Main.process(Main.scala)
[error]         at jdk.internal.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at xsbt.DottydocRunner.run(DottydocRunner.java:61)
[error]         at xsbt.ScaladocInterface.run(ScaladocInterface.java:11)
[error]         at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error]         at sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:329)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:175)
[error]         at sbt.internal.inc.AnalyzingCompiler.doc(AnalyzingCompiler.scala:133)
[error]         at sbt.Doc$.$anonfun$scaladoc$1(Doc.scala:52)
[error]         at sbt.Doc$.$anonfun$scaladoc$1$adapted(Doc.scala:40)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1(RawCompileLike.scala:79)
[error]         at sbt.RawCompileLike$.$anonfun$prepare$1$adapted(RawCompileLike.scala:72)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4(RawCompileLike.scala:63)
[error]         at sbt.RawCompileLike$.$anonfun$cached$4$adapted(RawCompileLike.scala:61)
[error]         at sbt.util.Tracked$.$anonfun$inputChangedW$1(Tracked.scala:219)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1(RawCompileLike.scala:68)
[error]         at sbt.RawCompileLike$.$anonfun$cached$1$adapted(RawCompileLike.scala:52)
[error]         at sbt.Defaults$.$anonfun$docTaskSettings$4(Defaults.scala:2158)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error]         at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error]         at sbt.Execute.work(Execute.scala:291)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]         at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]         at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]         at java.base/java.lang.Thread.run(Thread.java:829)
[error] (Compile / doc) java.lang.reflect.InvocationTargetException

Expectation

If no title is specified in sidebar.yml, scaladoc should

  1. Check if title is present in the frontmatter of the markdown file specified in url and use that
  2. If title is not present in the frontmatter of the markdown specified in url, generate a title from the filename
BarkingBad commented 3 years ago

According to spec title is mandatory:

The sidebar key is mandatory, as well as title for each element.

I know there is a bug that actually ignored the title property and if there was not header inside markdown file itself, it took its name as title.

I can either:

The second option seems doable, but I'm not sure if we have all the data at the right moment, will confirm that.

@vincenzobaz @pikinier20 @romanowski what do you think about that?

romanowski commented 3 years ago

I do not like sidebar.yaml in first place:) I lean towards 1st option.

vincenzobaz commented 3 years ago

As the title can be specified in the frontmatter or derived by the filename, I think that the title property in sidebar.yml should not be mandatory. Thus, the first 2 proposals seem viable.

I prefer the second option because I believe that the title the closest to content (in the frontmatter) should have priority over the one defined in sidebar.yml. This file should contain information about the position of the page and the order of the pages in the sidebar, but using it to rename pages does not feel very natural to me. In other words sidebar.yml is about structure, not content.

There is a third option which does not rely on scaladoc to make a decision and which consists in throwing an error if the title is specified in both locations, which I could endorse as well.

Similarly to @romanowski, I am not particularly fond of sidebar.yml first of all because it is yaml and then because of how url are specified in it: in the spec it looks like we are giving urls to the generated html, while I would prefer giving paths to the source markdowns. However I think that a configuration file is necessary and useful and could contain more information used to generate the site like the JSON versions location, markdown-accessible variables, scaladoc version as well as structure of the sidebar