-
Notifications
You must be signed in to change notification settings - Fork 2
/
installdumux.py
196 lines (157 loc) · 6.58 KB
/
installdumux.py
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/usr/bin/env python3
# SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
# SPDX-License-Identifier: GPL-3.0-or-later
"""
One click install script for dumux
"""
import os
import sys
import argparse
import itertools
import logging
import subprocess
import time
from shutil import which
logger = logging.getLogger("installdumux")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler(stream=sys.stdout)
streamHandler.setLevel(logging.INFO)
streamHandler.setFormatter(logging.Formatter("-- %(levelname)s: %(message)s"))
logger.addHandler(streamHandler)
fileHandler = logging.FileHandler("installdumux.log", encoding="utf-8")
fileHandler.setLevel(logging.DEBUG)
logger.addHandler(fileHandler)
_SPINNER = itertools.cycle(range(4))
class _Version:
def __init__(self, version: str) -> None:
self._version = [int(v) for v in version.strip(" ").strip("\n").split(".")]
def __lt__(self, other) -> bool:
for versionSelf, versionOther in zip(self._version, other._version):
if versionSelf < versionOther:
return True
if versionSelf > versionOther:
return False
return False
parser = argparse.ArgumentParser(
prog="installdumux",
usage="./installdumux.py [OPTIONS]",
description="This script downloads and compiles the latest release of Dumux.",
)
# Optional arguments
parser.add_argument("--dune-version", default="2.9", help="Dune version to be checked out.")
parser.add_argument("--dumux-version", default="3.8", help="Dumux version to be checked out.")
args = vars(parser.parse_args())
duneBranch = (
args["dune_version"] if args["dune_version"] == "master" else "releases/" + args["dune_version"]
)
dumuxBranch = (
args["dumux_version"]
if args["dumux_version"] == "master"
else "releases/" + args["dumux_version"]
)
def showMessage(message):
"""Pretty print message"""
logger.info("*" * 120)
logger.info(message)
logger.info("*" * 120)
def spin(condition, *arguments, **keyWordArguments):
"""Display a progress symbol while condition is true"""
while condition(*arguments, **keyWordArguments):
sys.stdout.write("༄ " * next(_SPINNER))
sys.stdout.flush()
time.sleep(0.2)
sys.stdout.write("\r\033[K")
def checkCppVersion():
"""Check compiler version"""
requiredversion = "9.3"
result = subprocess.check_output(["g++", "-dumpversion"]).decode().strip()
if _Version(result) < _Version(requiredversion):
logger.error("An error occurred while checking for prerequisites.")
logger.error(f"g++ greater than or equal to {requiredversion} is required.")
sys.exit(1)
def runCommand(command, workdir="."):
"""Run command with error checking"""
logger.debug(f"Running {' '.join(command)}")
with open("../installdumux.log", "a") as log:
with subprocess.Popen(
command,
stdout=log,
stderr=log,
universal_newlines=True,
cwd=workdir,
) as popen:
spin(lambda p: p.poll() is None, popen)
returnCode = popen.wait()
if returnCode:
logger.error(f"The command {' '.join(command)} returned with non-zero exit code.")
logger.error("You find the error message in the file 'installdumux.log'.")
logger.error("If you can't fix the problem yourself consider reporting your issue")
logger.error("on the mailing list ([email protected]) and")
logger.error("attach the file 'installdumux.log'.")
sys.exit(1)
def gitClone(url, branch=None):
"""Clone git repo"""
clone = ["git", "clone"]
if branch:
clone += ["-b", branch]
runCommand(command=[*clone, url])
def gitSetBranch(folder, branch):
"""Checkout specific git branch"""
checkout = ["git", "checkout", branch]
runCommand(command=checkout, workdir=folder)
# clear the log file
with open("installdumux.log", "w") as _:
pass
#################################################################
#################################################################
# (1/3) Check some prerequisites
#################################################################
#################################################################
programs = ["git", "gcc", "g++", "cmake", "pkg-config"]
showMessage(f"(1/3) Checking all prerequisites: {' '.join(programs)}...")
# check some prerequisites
for program in programs:
if which(program) is None:
logger.error("An error occurred while checking for prerequisites.")
logger.error(f"The required program '{program}' has not been found.")
sys.exit(1)
if which("paraview") is None:
logger.warning("ParaView could not be found. (You might have it but we can't find it.)")
logger.warning("We recommend installing ParaView to view simulation results.")
checkCppVersion()
showMessage("(1/3) Step completed. All prerequisites found.")
#################################################################
#################################################################
# (2/3) Clone modules
#################################################################
#################################################################
# make a new folder containing everything
os.makedirs("./dumux", exist_ok=True)
os.chdir("dumux")
showMessage(
"(2/3) Cloning repositories. This may take a while. "
"Make sure to be connected to the internet..."
)
# the core modules
for module in ["common", "geometry", "grid", "localfunctions", "istl"]:
if not os.path.exists(f"dune-{module}"):
gitClone(f"https://gitlab.dune-project.org/core/dune-{module}.git", duneBranch)
else:
logger.info(f"Skip cloning dune-{module} because the folder already exists.")
gitSetBranch(f"dune-{module}", duneBranch)
# dumux
if not os.path.exists("dumux"):
gitClone("https://git.iws.uni-stuttgart.de/dumux-repositories/dumux.git", dumuxBranch)
else:
logger.info("Skip cloning dumux because the folder already exists.")
gitSetBranch("dumux", dumuxBranch)
showMessage("(2/3) Step completed. All repositories have been cloned into a containing folder.")
#################################################################
#################################################################
# (3/3) Configure and build
#################################################################
#################################################################
showMessage(
"(3/3) Configure and build dune modules and dumux using dunecontrol. "
"This may take several minutes..."
)