70967
|
1 |
/* Title: Pure/Tools/phabricator.scala
|
|
2 |
Author: Makarius
|
|
3 |
|
|
4 |
Support for Phabricator server. See also:
|
|
5 |
- https://www.phacility.com/phabricator
|
|
6 |
- https://secure.phabricator.com/book/phabricator
|
|
7 |
*/
|
|
8 |
|
|
9 |
package isabelle
|
|
10 |
|
|
11 |
|
|
12 |
object Phabricator
|
|
13 |
{
|
|
14 |
/** defaults **/
|
|
15 |
|
|
16 |
val default_name = "vcs"
|
|
17 |
|
|
18 |
def default_prefix(name: String): String = "phabricator_" + name
|
|
19 |
|
|
20 |
def default_root(options: Options, name: String): Path =
|
|
21 |
Path.explode(options.string("phabricator_www_root")) + Path.basic(default_prefix(name))
|
|
22 |
|
|
23 |
def default_repo(options: Options, name: String): Path =
|
|
24 |
default_root(options, name) + Path.basic("repo")
|
|
25 |
|
|
26 |
val packages: List[String] =
|
|
27 |
Build_Docker.packages :::
|
|
28 |
// https://secure.phabricator.com/source/phabricator/browse/master/scripts/install/install_ubuntu.sh 15e6e2adea61
|
|
29 |
List("git", "mysql-server", "apache2", "libapache2-mod-php", "php", "php-mysql",
|
|
30 |
"php-gd", "php-curl", "php-apcu", "php-cli", "php-json", "php-mbstring")
|
|
31 |
|
|
32 |
|
|
33 |
|
|
34 |
/** global configuration **/
|
|
35 |
|
|
36 |
val global_config = Path.explode("/etc/isabelle-phabricator.conf")
|
|
37 |
|
|
38 |
sealed case class Config(name: String, root: Path)
|
|
39 |
|
|
40 |
def read_config(): List[Config] =
|
|
41 |
{
|
|
42 |
if (global_config.is_file) {
|
|
43 |
for (entry <- Library.trim_split_lines(File.read(global_config)) if entry.nonEmpty)
|
|
44 |
yield {
|
|
45 |
space_explode(':', entry) match {
|
|
46 |
case List(name, root) => Config(name, Path.explode(root))
|
|
47 |
case _ => error("Malformed config file " + global_config + "\nentry " + quote(entry))
|
|
48 |
}
|
|
49 |
}
|
|
50 |
}
|
|
51 |
else Nil
|
|
52 |
}
|
|
53 |
|
|
54 |
def write_config(configs: List[Config])
|
|
55 |
{
|
|
56 |
File.write(global_config,
|
|
57 |
configs.map(config => config.name + ":" + config.root.implode).mkString("", "\n", "\n"))
|
|
58 |
}
|
|
59 |
|
|
60 |
def get_config(name: String): Config =
|
|
61 |
read_config().find(config => config.name == name) getOrElse
|
|
62 |
error("Bad Isabelle/Phabricator installation " + quote(name))
|
|
63 |
|
|
64 |
|
|
65 |
|
|
66 |
/** setup **/
|
|
67 |
|
|
68 |
def phabricator_setup(
|
|
69 |
options: Options,
|
|
70 |
name: String = default_name,
|
|
71 |
prefix: String = "",
|
|
72 |
root: String = "",
|
|
73 |
repo: String = "",
|
|
74 |
progress: Progress = No_Progress)
|
|
75 |
{
|
|
76 |
/* system environment */
|
|
77 |
|
|
78 |
Linux.check_system_root()
|
|
79 |
|
|
80 |
Linux.package_update(progress = progress)
|
|
81 |
Linux.check_reboot_required()
|
|
82 |
|
|
83 |
Linux.package_install(packages, progress = progress)
|
|
84 |
Linux.check_reboot_required()
|
|
85 |
|
|
86 |
|
|
87 |
/* basic installation */
|
|
88 |
|
|
89 |
val prefix_name = proper_string(prefix) getOrElse default_prefix(name)
|
|
90 |
val root_path = if (root.nonEmpty) Path.explode(root) else default_root(options, name)
|
|
91 |
val repo_path = if (repo.nonEmpty) Path.explode(repo) else default_repo(options, name)
|
|
92 |
|
|
93 |
val configs = read_config()
|
|
94 |
|
|
95 |
for (config <- configs if config.name == name) {
|
|
96 |
error("Duplicate Phabricator installation " + quote(name) + " in " + config.root)
|
|
97 |
}
|
|
98 |
|
|
99 |
if (!Isabelle_System.bash("mkdir -p " + File.bash_path(root_path)).ok) {
|
|
100 |
error("Failed to create root directory " + root_path)
|
|
101 |
}
|
|
102 |
|
|
103 |
progress.bash(cwd = root_path.file, echo = true,
|
|
104 |
script = """
|
|
105 |
set -e
|
|
106 |
chown """ + Bash.string(options.string("phabricator_www_user")) + """ .
|
|
107 |
chmod 755 .
|
|
108 |
|
|
109 |
git clone https://github.com/phacility/libphutil.git
|
|
110 |
git clone https://github.com/phacility/arcanist.git
|
|
111 |
git clone https://github.com/phacility/phabricator.git
|
|
112 |
""").check
|
|
113 |
|
|
114 |
val config = Config(name, root_path)
|
|
115 |
write_config(configs ::: List(config))
|
|
116 |
}
|
|
117 |
|
|
118 |
|
|
119 |
/* Isabelle tool wrapper */
|
|
120 |
|
|
121 |
val isabelle_tool1 =
|
|
122 |
Isabelle_Tool("phabricator_setup", "setup Phabricator server on Ubuntu Linux", args =>
|
|
123 |
{
|
|
124 |
var options = Options.init()
|
|
125 |
var prefix = ""
|
|
126 |
var root = ""
|
|
127 |
var repo = ""
|
|
128 |
|
|
129 |
val getopts =
|
|
130 |
Getopts("""
|
|
131 |
Usage: isabelle phabricator_setup [OPTIONS] [NAME]
|
|
132 |
|
|
133 |
Options are:
|
|
134 |
-R DIR repository directory (default: """ + default_repo(options, "NAME") + """)
|
|
135 |
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
|
|
136 |
-p PREFIX prefix for derived names (default: """ + default_prefix("NAME") + """)
|
|
137 |
-r DIR installation root directory (default: """ + default_root(options, "NAME") + """)
|
|
138 |
|
|
139 |
Install Phabricator as Ubuntu LAMP application (Linux, Apache, MySQL, PHP).
|
|
140 |
|
|
141 |
Slogan: "Discuss. Plan. Code. Review. Test.
|
|
142 |
Every application your project needs, all in one tool."
|
|
143 |
|
|
144 |
The installation NAME (default: """ + quote(default_name) + """) is mapped to
|
|
145 |
a regular Unix user and used for public SSH access.
|
|
146 |
""",
|
|
147 |
"R:" -> (arg => repo = arg),
|
|
148 |
"o:" -> (arg => options = options + arg),
|
|
149 |
"p:" -> (arg => prefix = arg),
|
|
150 |
"r:" -> (arg => root = arg))
|
|
151 |
|
|
152 |
val more_args = getopts(args)
|
|
153 |
|
|
154 |
val name =
|
|
155 |
more_args match {
|
|
156 |
case Nil => default_name
|
|
157 |
case List(name) => name
|
|
158 |
case _ => getopts.usage()
|
|
159 |
}
|
|
160 |
|
|
161 |
val progress = new Console_Progress
|
|
162 |
|
|
163 |
phabricator_setup(options, name, prefix = prefix, root = root, repo = repo,
|
|
164 |
progress = progress)
|
|
165 |
})
|
|
166 |
|
|
167 |
|
|
168 |
|
|
169 |
/** update **/
|
|
170 |
|
|
171 |
def phabricator_update(name: String, progress: Progress = No_Progress)
|
|
172 |
{
|
|
173 |
Linux.check_system_root()
|
|
174 |
|
|
175 |
???
|
|
176 |
}
|
|
177 |
|
|
178 |
|
|
179 |
/* Isabelle tool wrapper */
|
|
180 |
|
|
181 |
val isabelle_tool2 =
|
|
182 |
Isabelle_Tool("phabricator_update", "update Phabricator server installation", args =>
|
|
183 |
{
|
|
184 |
val getopts =
|
|
185 |
Getopts("""
|
|
186 |
Usage: isabelle phabricator_update [NAME]
|
|
187 |
|
|
188 |
Update Phabricator installation, with lookup of NAME (default + """ + quote(default_name) + """)
|
|
189 |
in """ + global_config + "\n")
|
|
190 |
|
|
191 |
val more_args = getopts(args)
|
|
192 |
val name =
|
|
193 |
more_args match {
|
|
194 |
case Nil => default_name
|
|
195 |
case List(name) => name
|
|
196 |
case _ => getopts.usage()
|
|
197 |
}
|
|
198 |
|
|
199 |
val progress = new Console_Progress
|
|
200 |
|
|
201 |
phabricator_update(name, progress = progress)
|
|
202 |
})
|
|
203 |
}
|