-
Notifications
You must be signed in to change notification settings - Fork 302
/
Channel.scala
106 lines (83 loc) · 3.06 KB
/
Channel.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package coursier.install
import java.nio.file.{FileSystem, FileSystems, Path}
import java.util.regex.Pattern.quote
import coursier.core.Module
import coursier.parse.{JavaOrScalaModule, ModuleParser}
sealed abstract class Channel extends Product with Serializable {
def repr: String
}
object Channel {
final case class FromModule(module: Module) extends Channel {
def repr: String =
module.repr
}
final case class FromUrl(url: String) extends Channel {
def repr: String =
url
}
final case class FromDirectory(path: Path) extends Channel {
def repr: String =
path.toString
}
def module(module: Module): FromModule =
FromModule(module)
private lazy val ghUrlMatcher =
(quote("https://github.com/") + "([^/]*)/([^/]*)" + quote("/blob/") + "([^/]*)" + quote("/") + "(.*)").r.pattern
private def defaultGhFileName = "apps.json"
private def defaultGhPath = defaultGhFileName
private def defaultGhBranch = "master"
private def ghUrl(org: String, name: String, branch: String, path: String): String =
s"https://raw.githubusercontent.com/$org/$name/$branch/$path"
def url(url: String): FromUrl = {
val m = ghUrlMatcher.matcher(url)
val url0 =
if (m.matches()) {
val org = m.group(1)
val name = m.group(2)
val branch = m.group(3)
val path = m.group(4)
ghUrl(org, name, branch, path)
} else
url
// https://github.com/coursier/apps/blob/master/apps/resources/ammonite.json
// https://raw.githubusercontent.com/coursier/apps/master/apps/resources/ammonite.json
FromUrl(url0)
}
def parse(s: String): Either[String, Channel] =
parse(s, FileSystems.getDefault)
def parse(s: String, fs: FileSystem): Either[String, Channel] =
if (s.contains("://"))
Right(Channel.url(s))
else if ((s.startsWith("gh:") || s.startsWith("github:")) && s.contains("/")) {
val s0 =
if (s.startsWith("gh:")) s.stripPrefix("gh:")
else s.stripPrefix("github:")
val (orgName, path) = s0.split(":", 2) match {
case Array(orgName0, path0) =>
(orgName0, path0)
case Array(orgName0) =>
(orgName0, defaultGhPath)
}
val orgNameBranchOrError = orgName.split("/", 3) match {
case Array(org0, name0) => Right((org0, name0, defaultGhBranch))
case Array(org0, name0, branch0) => Right((org0, name0, branch0))
case _ => Left(s"Malformed github channel '$s'")
}
orgNameBranchOrError.map {
case (org, name, branch) =>
val path0 =
if (path.endsWith("/"))
path + defaultGhFileName
else
path
val url = ghUrl(org, name, branch, path0)
FromUrl(url)
}
} else if (s.contains(":"))
ModuleParser.javaOrScalaModule(s).flatMap {
case j: JavaOrScalaModule.JavaModule => Right(Channel.module(j.module))
case s: JavaOrScalaModule.ScalaModule => Left(s"Scala dependencies ($s) not accepted as channels")
}
else
Right(FromDirectory(fs.getPath(s).toAbsolutePath))
}