@@ -6,7 +6,30 @@ import liqp.Template
66import dotty .dokka .model .api ._
77import dotty .tools .dotc .core .Contexts .Context
88
9- case class SourceLink (val path : Option [Path ], val urlTemplate : Template )
9+ trait SourceLink :
10+ val path : Option [Path ] = None
11+ def render (path : String , operation : String , line : Option [Int ]): String
12+
13+ case class PrefixedSourceLink (val myPath : Path , nested : SourceLink ) extends SourceLink :
14+ export nested .render
15+ override val path = Some (myPath)
16+
17+ case class TemplateSourceLink (val urlTemplate : Template ) extends SourceLink :
18+ override val path : Option [Path ] = None
19+ override def render (path : String , operation : String , line : Option [Int ]): String =
20+ val config = java.util.HashMap [String , Object ]()
21+ config.put(" path" , path)
22+ line.foreach(l => config.put(" line" , l.toString))
23+ config.put(" operation" , operation)
24+
25+ urlTemplate.render(config)
26+
27+ case class WebBasedSourceLink (prefix : String , revision : String ) extends SourceLink :
28+ override val path : Option [Path ] = None
29+ override def render (path : String , operation : String , line : Option [Int ]): String =
30+ val action = if operation == " view" then " blob" else operation
31+ val linePart = line.fold(" " )(l => s " #L $l" )
32+ s " $prefix/ $action/ $revision/ $path$linePart"
1033
1134object SourceLink :
1235 val SubPath = " ([^=]+)=(.+)" .r
@@ -18,41 +41,39 @@ object SourceLink:
1841 " €{FILE_LINE}" -> " {{ line }}"
1942 )
2043
21- def githubTemplate (organization : String , repo : String )(revision : String ) =
22- s """ https://github.com/ $organization/ $repo/{{ operation | replace: "view", "blob" }}/ $revision/{{ path }}#L{{ line }} """ .stripMargin
44+ def githubPrefix (org : String , repo : String ) = s " https://github.com/ $org/ $repo"
2345
24- def gitlabTemplate (organization : String , repo : String )(revision : String ) =
25- s """ https://gitlab.com/ $organization/ $repo/-/{{ operation | replace: "view", "blob" }}/ $revision/{{ path }}#L{{ line }} """
46+ def gitlabPrefix (org : String , repo : String ) = s " https://gitlab.com/ $org/ $repo/- "
2647
2748
2849 private def parseLinkDefinition (s : String ): Option [SourceLink ] = ???
2950
3051 def parse (string : String , revision : Option [String ]): Either [String , SourceLink ] =
3152 def asTemplate (template : String ) =
32- try Right (SourceLink ( None , Template .parse(template))) catch
53+ try Right (TemplateSourceLink ( Template .parse(template))) catch
3354 case e : RuntimeException =>
3455 Left (s " Failed to parse template: ${e.getMessage}" )
3556
3657 string match
3758 case KnownProvider (name, organization, repo) =>
38- def withRevision (template : String => String ) =
39- revision.fold(Left (s " No revision provided " ))(rev => Right (SourceLink ( None , Template .parse( template(rev)) )))
59+ def withRevision (template : String => SourceLink ) =
60+ revision.fold(Left (s " No revision provided " ))(r => Right (template(r )))
4061
4162 name match
4263 case " github" =>
43- withRevision(githubTemplate( organization, repo))
64+ withRevision(rev => WebBasedSourceLink (githubPrefix( organization, repo), rev ))
4465 case " gitlab" =>
45- withRevision(gitlabTemplate( organization, repo))
66+ withRevision(rev => WebBasedSourceLink (gitlabPrefix( organization, repo), rev ))
4667 case other =>
4768 Left (s " ' $other' is not a known provider, please provide full source path template. " )
4869
4970 case SubPath (prefix, config) =>
5071 parse(config, revision) match
5172 case l : Left [String , _] => l
52- case Right (SourceLink ( Some (prefix), _) ) =>
73+ case Right (_: PrefixedSourceLink ) =>
5374 Left (s " Source path $string has duplicated subpath setting (scm template can not contains '=') " )
54- case Right (SourceLink ( None , template) ) =>
55- Right (SourceLink ( Some ( Paths .get(prefix)), template ))
75+ case Right (nested ) =>
76+ Right (PrefixedSourceLink ( Paths .get(prefix), nested ))
5677 case BrokenKnownProvider (" gitlab" | " github" ) =>
5778 Left (s " Does not match known provider syntax: `<name>://organization/repository` " )
5879 case scaladocSetting if ScalaDocPatten .findFirstIn(scaladocSetting).nonEmpty =>
@@ -70,15 +91,9 @@ type Operation = "view" | "edit"
7091case class SourceLinks (links : Seq [SourceLink ], projectRoot : Path ):
7192 def pathTo (rawPath : Path , line : Option [Int ] = None , operation : Operation = " view" ): Option [String ] =
7293 def resolveRelativePath (path : Path ) =
73- links.find(_.path.forall(p => path.startsWith(p))).map { link =>
74- val config = java.util.HashMap [String , Object ]()
75- val pathString = path.toString.replace('\\ ' , '/' )
76- config.put(" path" , pathString)
77- line.foreach(l => config.put(" line" , l.toString))
78- config.put(" operation" , operation)
79-
80- link.urlTemplate.render(config)
81- }
94+ links
95+ .find(_.path.forall(p => path.startsWith(p)))
96+ .map(_.render(path.toString.replace('\\ ' , '/' ), operation, line))
8297
8398 if rawPath.isAbsolute then
8499 if rawPath.startsWith(projectRoot) then resolveRelativePath(projectRoot.relativize(rawPath))
0 commit comments