82615
|
1 |
/* Title: Pure/Tools/caddy_setup.scala
|
|
2 |
Author: Makarius
|
|
3 |
|
|
4 |
Dynamic setup of Caddy component.
|
|
5 |
*/
|
|
6 |
|
|
7 |
package isabelle
|
|
8 |
|
|
9 |
|
|
10 |
object Caddy_Setup {
|
|
11 |
/* platform information */
|
|
12 |
|
|
13 |
sealed case class Platform_Info(platform: String, xcaddy_template: String)
|
|
14 |
extends Platform.Info {
|
|
15 |
def xcaddy_download(url: String, version: String): String =
|
|
16 |
Url.append_path(url, xcaddy_template.replace("{V}", version))
|
|
17 |
}
|
|
18 |
|
|
19 |
val all_platforms: List[Platform_Info] =
|
|
20 |
List(
|
|
21 |
Platform_Info("arm64-darwin", "v{V}/xcaddy_{V}_mac_arm64.tar.gz"),
|
|
22 |
Platform_Info("arm64-linux", "v{V}/xcaddy_{V}_linux_arm64.tar.gz"),
|
|
23 |
Platform_Info("x86_64-darwin", "v{V}/xcaddy_{V}_mac_amd64.tar.gz"),
|
|
24 |
Platform_Info("x86_64-linux", "v{V}/xcaddy_{V}_linux_amd64.tar.gz"),
|
|
25 |
Platform_Info("x86_64-windows", "v{V}/xcaddy_{V}_windows_amd64.zip"))
|
|
26 |
|
|
27 |
|
|
28 |
/* download and setup */
|
|
29 |
|
|
30 |
def default_target_dir: Path = Components.default_components_base
|
|
31 |
def default_caddy_version: String = Isabelle_System.getenv_strict("ISABELLE_CADDY_SETUP_VERSION")
|
|
32 |
def default_caddy_modules: String = Isabelle_System.getenv_strict("ISABELLE_CADDY_SETUP_MODULES")
|
|
33 |
def default_xcaddy_url: String = "https://github.com/caddyserver/xcaddy/releases/download"
|
|
34 |
def default_xcaddy_version: String = "0.4.4"
|
|
35 |
|
|
36 |
def show_settings(): List[String] =
|
|
37 |
for (a <- List("ISABELLE_CADDY_SETUP_VERSION", "ISABELLE_CADDY_SETUP_MODULES"))
|
|
38 |
yield {
|
|
39 |
val b = Isabelle_System.getenv(a)
|
|
40 |
a + "=" + quote(b)
|
|
41 |
}
|
|
42 |
|
|
43 |
def caddy_setup(
|
|
44 |
caddy_version: String = default_caddy_version,
|
|
45 |
caddy_modules: String = default_caddy_modules,
|
|
46 |
xcaddy_url: String = default_xcaddy_url,
|
|
47 |
xcaddy_version: String = default_xcaddy_version,
|
|
48 |
target_dir: Path = default_target_dir,
|
|
49 |
progress: Progress = new Progress,
|
|
50 |
force: Boolean = false
|
|
51 |
): Unit = {
|
|
52 |
val platform = Isabelle_Platform.local.ISABELLE_PLATFORM(windows = true, apple = true)
|
|
53 |
|
|
54 |
|
|
55 |
/* component directory */
|
|
56 |
|
|
57 |
val component_dir =
|
|
58 |
Components.Directory(target_dir + Path.basic("caddy-" + caddy_version))
|
|
59 |
.create(permissive = true)
|
|
60 |
|
|
61 |
progress.echo("Component directory " + component_dir)
|
|
62 |
|
|
63 |
component_dir.write_settings("""
|
|
64 |
ISABELLE_CADDY_HOME="$COMPONENT"
|
|
65 |
|
|
66 |
if [ -n "$ISABELLE_WINDOWS_PLATFORM64" -a -d "$ISABELLE_CADDY_HOME/$ISABELLE_WINDOWS_PLATFORM64" ]; then
|
|
67 |
ISABELLE_CADDY="$ISABELLE_CADDY_HOME/$ISABELLE_WINDOWS_PLATFORM64/caddy.exe"
|
|
68 |
elif [ -n "$ISABELLE_APPLE_PLATFORM64" -a -d "$ISABELLE_CADDY_HOME/$ISABELLE_APPLE_PLATFORM64" ]; then
|
|
69 |
ISABELLE_CADDY="$ISABELLE_CADDY_HOME/$ISABELLE_APPLE_PLATFORM64/caddy"
|
|
70 |
elif [ -d "$ISABELLE_CADDY_HOME/$ISABELLE_PLATFORM64" ]; then
|
|
71 |
ISABELLE_CADDY="$ISABELLE_CADDY_HOME/$ISABELLE_PLATFORM64/caddy"
|
|
72 |
fi
|
|
73 |
""")
|
|
74 |
|
|
75 |
for (old <- proper_string(Isabelle_System.getenv("ISABELLE_CADDY_HOME"))) {
|
|
76 |
Components.update_components(false, Path.explode(old))
|
|
77 |
}
|
|
78 |
|
|
79 |
Components.update_components(true, component_dir.path)
|
|
80 |
|
|
81 |
|
|
82 |
/* download and setup */
|
|
83 |
|
|
84 |
Isabelle_System.with_tmp_dir("tmp") { tmp_dir =>
|
|
85 |
val platform_info: Platform_Info =
|
|
86 |
all_platforms.find(_.platform == platform)
|
|
87 |
.getOrElse(error("Bad platform " + quote(platform)))
|
|
88 |
|
|
89 |
val platform_dir = component_dir.path + platform_info.path
|
|
90 |
if (platform_dir.is_dir && !force) {
|
|
91 |
progress.echo_warning("Platform " + platform + " already installed")
|
|
92 |
}
|
|
93 |
else {
|
|
94 |
progress.echo("Platform " + platform + " ...")
|
|
95 |
progress.expose_interrupt()
|
|
96 |
|
|
97 |
Isabelle_System.make_directory(platform_dir)
|
|
98 |
|
|
99 |
val xcaddy_dir = Isabelle_System.make_directory(tmp_dir + Path.explode("xcaddy"))
|
|
100 |
val xcaddy_download = platform_info.xcaddy_download(xcaddy_url, xcaddy_version)
|
|
101 |
|
|
102 |
val xcaddy_archive_name =
|
|
103 |
Url.get_base_name(xcaddy_download) getOrElse
|
|
104 |
error("Malformed download URL " + quote(xcaddy_download))
|
|
105 |
val xcaddy_archive_path = tmp_dir + Path.basic(xcaddy_archive_name)
|
|
106 |
|
|
107 |
Isabelle_System.download_file(xcaddy_download, xcaddy_archive_path)
|
|
108 |
Isabelle_System.extract(xcaddy_archive_path, xcaddy_dir)
|
|
109 |
|
|
110 |
progress.echo("Building caddy " + caddy_version)
|
|
111 |
progress.bash(
|
|
112 |
Library.make_lines(
|
|
113 |
"set -e",
|
|
114 |
"xcaddy/xcaddy build v" + Bash.string(caddy_version) +
|
|
115 |
Word.explode(caddy_modules).map(s => " --with " + Bash.string(s)).mkString,
|
|
116 |
"./caddy list-modules"),
|
|
117 |
cwd = tmp_dir, echo = progress.verbose).check
|
|
118 |
|
|
119 |
Isabelle_System.copy_file(tmp_dir + Path.explode("caddy").platform_exe, platform_dir)
|
|
120 |
}
|
|
121 |
}
|
|
122 |
|
|
123 |
File.find_files(component_dir.path.file, pred = file => File.is_exe(file.getName)).
|
|
124 |
foreach(file => File.set_executable(File.path(file)))
|
|
125 |
|
|
126 |
|
|
127 |
/* README */
|
|
128 |
|
|
129 |
File.write(component_dir.README,
|
|
130 |
"""This installation of Caddy has been produced via "isabelle caddy_setup".
|
|
131 |
|
|
132 |
|
|
133 |
Makarius
|
|
134 |
""" + Date.Format.date(Date.now()) + "\n")
|
|
135 |
}
|
|
136 |
|
|
137 |
|
|
138 |
/* Isabelle tool wrapper */
|
|
139 |
|
|
140 |
val isabelle_tool =
|
|
141 |
Isabelle_Tool("caddy_setup", "dynamic setup of Caddy component", Scala_Project.here,
|
|
142 |
{ args =>
|
|
143 |
var target_dir = default_target_dir
|
|
144 |
var xcaddy_url = default_xcaddy_url
|
|
145 |
var xcaddy_version = default_xcaddy_version
|
|
146 |
var caddy_modules = default_caddy_modules
|
|
147 |
var caddy_version = default_caddy_version
|
|
148 |
var force = false
|
|
149 |
var verbose = false
|
|
150 |
|
|
151 |
val getopts = Getopts("""
|
|
152 |
Usage: isabelle caddy_setup [OPTIONS]
|
|
153 |
|
|
154 |
Options are:
|
|
155 |
-D DIR target directory (default ".")
|
|
156 |
-N MODULES non-standard modules for caddy
|
|
157 |
(default: ISABELLE_CADDY_SETUP_MODULES="""" + default_caddy_modules + """")
|
|
158 |
-U URL download URL for xcaddy (default: """" + default_xcaddy_url + """")
|
|
159 |
-V VERSION version for caddy
|
|
160 |
(default: ISABELLE_CADDY_SETUP_VERSION="""" + default_caddy_version + """")
|
|
161 |
-W VERSION version for xcaddy (default: """" + default_xcaddy_version + """")
|
|
162 |
-f force fresh installation of specified platforms
|
|
163 |
-v verbose
|
|
164 |
|
|
165 |
Build the Caddy webserver via xcaddy and configure it as Isabelle
|
|
166 |
component. See also https://github.com/caddyserver/xcaddy""",
|
|
167 |
"D:" -> (arg => target_dir = Path.explode(arg)),
|
|
168 |
"N:" -> (arg => caddy_modules = arg),
|
|
169 |
"U:" -> (arg => xcaddy_url = arg),
|
|
170 |
"V:" -> (arg => caddy_version = arg),
|
|
171 |
"W:" -> (arg => xcaddy_version = arg),
|
|
172 |
"f" -> (_ => force = true),
|
|
173 |
"v" -> (_ => verbose = true))
|
|
174 |
|
|
175 |
val more_args = getopts(args)
|
|
176 |
if (more_args.nonEmpty) getopts.usage()
|
|
177 |
|
|
178 |
val progress = new Console_Progress(verbose = verbose)
|
|
179 |
|
|
180 |
caddy_setup(caddy_version = caddy_version, caddy_modules = caddy_modules,
|
|
181 |
xcaddy_url = xcaddy_url, xcaddy_version = xcaddy_version, target_dir = target_dir,
|
|
182 |
progress = progress, force = force)
|
|
183 |
})
|
|
184 |
}
|
|
185 |
|
|
186 |
class Caddy_Setup extends Setup_Tool("caddy_setup", "ISABELLE_CADDY_SETUP") {
|
|
187 |
override val test_file: Path = Path.explode("lib/Tools/caddy")
|
|
188 |
}
|