vortex-nwp 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vortex/__init__.py +159 -0
- vortex/algo/__init__.py +13 -0
- vortex/algo/components.py +2462 -0
- vortex/algo/mpitools.py +1953 -0
- vortex/algo/mpitools_templates/__init__.py +1 -0
- vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
- vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
- vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
- vortex/algo/serversynctools.py +171 -0
- vortex/config.py +112 -0
- vortex/data/__init__.py +19 -0
- vortex/data/abstractstores.py +1510 -0
- vortex/data/containers.py +835 -0
- vortex/data/contents.py +622 -0
- vortex/data/executables.py +275 -0
- vortex/data/flow.py +119 -0
- vortex/data/geometries.ini +2689 -0
- vortex/data/geometries.py +799 -0
- vortex/data/handlers.py +1230 -0
- vortex/data/outflow.py +67 -0
- vortex/data/providers.py +487 -0
- vortex/data/resources.py +207 -0
- vortex/data/stores.py +1390 -0
- vortex/data/sync_templates/__init__.py +0 -0
- vortex/gloves.py +309 -0
- vortex/layout/__init__.py +20 -0
- vortex/layout/contexts.py +577 -0
- vortex/layout/dataflow.py +1220 -0
- vortex/layout/monitor.py +969 -0
- vortex/nwp/__init__.py +14 -0
- vortex/nwp/algo/__init__.py +21 -0
- vortex/nwp/algo/assim.py +537 -0
- vortex/nwp/algo/clim.py +1086 -0
- vortex/nwp/algo/coupling.py +831 -0
- vortex/nwp/algo/eda.py +840 -0
- vortex/nwp/algo/eps.py +785 -0
- vortex/nwp/algo/forecasts.py +886 -0
- vortex/nwp/algo/fpserver.py +1303 -0
- vortex/nwp/algo/ifsnaming.py +463 -0
- vortex/nwp/algo/ifsroot.py +404 -0
- vortex/nwp/algo/monitoring.py +263 -0
- vortex/nwp/algo/mpitools.py +694 -0
- vortex/nwp/algo/odbtools.py +1258 -0
- vortex/nwp/algo/oopsroot.py +916 -0
- vortex/nwp/algo/oopstests.py +220 -0
- vortex/nwp/algo/request.py +660 -0
- vortex/nwp/algo/stdpost.py +1641 -0
- vortex/nwp/data/__init__.py +30 -0
- vortex/nwp/data/assim.py +380 -0
- vortex/nwp/data/boundaries.py +314 -0
- vortex/nwp/data/climfiles.py +521 -0
- vortex/nwp/data/configfiles.py +153 -0
- vortex/nwp/data/consts.py +954 -0
- vortex/nwp/data/ctpini.py +149 -0
- vortex/nwp/data/diagnostics.py +209 -0
- vortex/nwp/data/eda.py +147 -0
- vortex/nwp/data/eps.py +432 -0
- vortex/nwp/data/executables.py +1045 -0
- vortex/nwp/data/fields.py +111 -0
- vortex/nwp/data/gridfiles.py +380 -0
- vortex/nwp/data/logs.py +584 -0
- vortex/nwp/data/modelstates.py +363 -0
- vortex/nwp/data/monitoring.py +193 -0
- vortex/nwp/data/namelists.py +696 -0
- vortex/nwp/data/obs.py +840 -0
- vortex/nwp/data/oopsexec.py +74 -0
- vortex/nwp/data/providers.py +207 -0
- vortex/nwp/data/query.py +206 -0
- vortex/nwp/data/stores.py +160 -0
- vortex/nwp/data/surfex.py +337 -0
- vortex/nwp/syntax/__init__.py +9 -0
- vortex/nwp/syntax/stdattrs.py +437 -0
- vortex/nwp/tools/__init__.py +10 -0
- vortex/nwp/tools/addons.py +40 -0
- vortex/nwp/tools/agt.py +67 -0
- vortex/nwp/tools/bdap.py +59 -0
- vortex/nwp/tools/bdcp.py +41 -0
- vortex/nwp/tools/bdm.py +24 -0
- vortex/nwp/tools/bdmp.py +54 -0
- vortex/nwp/tools/conftools.py +1661 -0
- vortex/nwp/tools/drhook.py +66 -0
- vortex/nwp/tools/grib.py +294 -0
- vortex/nwp/tools/gribdiff.py +104 -0
- vortex/nwp/tools/ifstools.py +203 -0
- vortex/nwp/tools/igastuff.py +273 -0
- vortex/nwp/tools/mars.py +68 -0
- vortex/nwp/tools/odb.py +657 -0
- vortex/nwp/tools/partitioning.py +258 -0
- vortex/nwp/tools/satrad.py +71 -0
- vortex/nwp/util/__init__.py +6 -0
- vortex/nwp/util/async.py +212 -0
- vortex/nwp/util/beacon.py +40 -0
- vortex/nwp/util/diffpygram.py +447 -0
- vortex/nwp/util/ens.py +279 -0
- vortex/nwp/util/hooks.py +139 -0
- vortex/nwp/util/taskdeco.py +85 -0
- vortex/nwp/util/usepygram.py +697 -0
- vortex/nwp/util/usetnt.py +101 -0
- vortex/proxy.py +6 -0
- vortex/sessions.py +374 -0
- vortex/syntax/__init__.py +9 -0
- vortex/syntax/stdattrs.py +867 -0
- vortex/syntax/stddeco.py +185 -0
- vortex/toolbox.py +1117 -0
- vortex/tools/__init__.py +20 -0
- vortex/tools/actions.py +523 -0
- vortex/tools/addons.py +316 -0
- vortex/tools/arm.py +96 -0
- vortex/tools/compression.py +325 -0
- vortex/tools/date.py +27 -0
- vortex/tools/ddhpack.py +10 -0
- vortex/tools/delayedactions.py +782 -0
- vortex/tools/env.py +541 -0
- vortex/tools/folder.py +834 -0
- vortex/tools/grib.py +738 -0
- vortex/tools/lfi.py +953 -0
- vortex/tools/listings.py +423 -0
- vortex/tools/names.py +637 -0
- vortex/tools/net.py +2124 -0
- vortex/tools/odb.py +10 -0
- vortex/tools/parallelism.py +368 -0
- vortex/tools/prestaging.py +210 -0
- vortex/tools/rawfiles.py +10 -0
- vortex/tools/schedulers.py +480 -0
- vortex/tools/services.py +940 -0
- vortex/tools/storage.py +996 -0
- vortex/tools/surfex.py +61 -0
- vortex/tools/systems.py +3976 -0
- vortex/tools/targets.py +440 -0
- vortex/util/__init__.py +9 -0
- vortex/util/config.py +1122 -0
- vortex/util/empty.py +24 -0
- vortex/util/helpers.py +216 -0
- vortex/util/introspection.py +69 -0
- vortex/util/iosponge.py +80 -0
- vortex/util/roles.py +49 -0
- vortex/util/storefunctions.py +129 -0
- vortex/util/structs.py +26 -0
- vortex/util/worker.py +162 -0
- vortex_nwp-2.0.0.dist-info/METADATA +67 -0
- vortex_nwp-2.0.0.dist-info/RECORD +144 -0
- vortex_nwp-2.0.0.dist-info/WHEEL +5 -0
- vortex_nwp-2.0.0.dist-info/licenses/LICENSE +517 -0
- vortex_nwp-2.0.0.dist-info/top_level.txt +1 -0
vortex/tools/addons.py
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Abstract classes for System addons.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
|
|
7
|
+
from bronx.fancies import loggers
|
|
8
|
+
from bronx.syntax.decorators import nicedeco
|
|
9
|
+
import footprints
|
|
10
|
+
|
|
11
|
+
from vortex.config import get_from_config_w_default
|
|
12
|
+
from vortex.layout import contexts
|
|
13
|
+
from vortex.tools.env import Environment
|
|
14
|
+
from vortex.tools.systems import OSExtended
|
|
15
|
+
|
|
16
|
+
logger = loggers.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
#: No automatic export
|
|
19
|
+
__all__ = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Addon(footprints.FootprintBase):
|
|
23
|
+
"""Root class for any :class:`Addon` system subclasses."""
|
|
24
|
+
|
|
25
|
+
_abstract = True
|
|
26
|
+
_collector = ("addon",)
|
|
27
|
+
_footprint = dict(
|
|
28
|
+
info="Default add-on",
|
|
29
|
+
attr=dict(
|
|
30
|
+
kind=dict(),
|
|
31
|
+
sh=dict(
|
|
32
|
+
type=OSExtended,
|
|
33
|
+
alias=("shell",),
|
|
34
|
+
access="rwx-weak",
|
|
35
|
+
),
|
|
36
|
+
env=dict(
|
|
37
|
+
type=Environment,
|
|
38
|
+
optional=True,
|
|
39
|
+
default=None,
|
|
40
|
+
access="rwx",
|
|
41
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
42
|
+
),
|
|
43
|
+
cfginfo=dict(
|
|
44
|
+
optional=True,
|
|
45
|
+
default="[kind]",
|
|
46
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
47
|
+
),
|
|
48
|
+
cmd=dict(
|
|
49
|
+
optional=True,
|
|
50
|
+
default=None,
|
|
51
|
+
access="rwx",
|
|
52
|
+
),
|
|
53
|
+
path=dict(
|
|
54
|
+
optional=True,
|
|
55
|
+
default=None,
|
|
56
|
+
access="rwx",
|
|
57
|
+
),
|
|
58
|
+
cycle=dict(
|
|
59
|
+
optional=True,
|
|
60
|
+
default=None,
|
|
61
|
+
access="rwx",
|
|
62
|
+
),
|
|
63
|
+
toolkind=dict(optional=True, default=None),
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def __init__(self, *args, **kw):
|
|
68
|
+
"""Abstract Addon initialisation."""
|
|
69
|
+
logger.debug("Abstract Addon init %s", self.__class__)
|
|
70
|
+
super().__init__(*args, **kw)
|
|
71
|
+
self.sh.extend(self)
|
|
72
|
+
self._context_cache = defaultdict(dict)
|
|
73
|
+
self._cmd_xperms_cache = set()
|
|
74
|
+
if self.env is None:
|
|
75
|
+
self.env = Environment(active=False, clear=True)
|
|
76
|
+
clsenv = self.__class__.__dict__
|
|
77
|
+
for k in [x for x in clsenv.keys() if x.isupper()]:
|
|
78
|
+
self.env[k] = clsenv[k]
|
|
79
|
+
if self.path is None:
|
|
80
|
+
self.path = get_from_config_w_default(
|
|
81
|
+
section="nwp-tools",
|
|
82
|
+
key=self.kind,
|
|
83
|
+
default=None,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def in_shell(cls, shell):
|
|
88
|
+
"""Grep any active instance of that class in the specified shell."""
|
|
89
|
+
lx = [x for x in shell.search if isinstance(x, cls)]
|
|
90
|
+
return lx[0] if lx else None
|
|
91
|
+
|
|
92
|
+
def _query_context(self):
|
|
93
|
+
"""Return the path and cmd for the current context.
|
|
94
|
+
|
|
95
|
+
Results are cached so that the context's localtracker is explored only once.
|
|
96
|
+
|
|
97
|
+
.. note:: We use the localtracker instead of the sequence because, in
|
|
98
|
+
multistep jobs, the localtracker is preserved between steps. It's
|
|
99
|
+
less elegant but it plays nice with MTOOL.
|
|
100
|
+
"""
|
|
101
|
+
ctxtag = contexts.Context.tag_focus()
|
|
102
|
+
if ctxtag not in self._context_cache and self.toolkind is not None:
|
|
103
|
+
ltrack = contexts.current().localtracker
|
|
104
|
+
# NB: 'str' is important because local might be in unicode...
|
|
105
|
+
candidates = [
|
|
106
|
+
str(self.sh.path.realpath(local))
|
|
107
|
+
for local, entry in ltrack.items()
|
|
108
|
+
if (
|
|
109
|
+
entry.latest_rhdict("get")
|
|
110
|
+
.get("resource", dict())
|
|
111
|
+
.get("kind", "")
|
|
112
|
+
== self.toolkind
|
|
113
|
+
)
|
|
114
|
+
]
|
|
115
|
+
if candidates:
|
|
116
|
+
realpath = candidates.pop()
|
|
117
|
+
self._context_cache[ctxtag] = dict(
|
|
118
|
+
path=self.sh.path.dirname(realpath),
|
|
119
|
+
cmd=self.sh.path.basename(realpath),
|
|
120
|
+
)
|
|
121
|
+
return self._context_cache[ctxtag]
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def actual_path(self):
|
|
125
|
+
"""The path that should be used in the current context."""
|
|
126
|
+
infos = self._query_context()
|
|
127
|
+
ctxpath = infos.get("path", None)
|
|
128
|
+
return self.path if ctxpath is None else ctxpath
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def actual_cmd(self):
|
|
132
|
+
"""The cmd that should be used in the current context."""
|
|
133
|
+
infos = self._query_context()
|
|
134
|
+
ctxcmd = infos.get("cmd", None)
|
|
135
|
+
return self.cmd if ctxcmd is None else ctxcmd
|
|
136
|
+
|
|
137
|
+
def _spawn_commons(self, cmd, **kw):
|
|
138
|
+
"""Internal method setting local environment and calling standard shell spawn."""
|
|
139
|
+
|
|
140
|
+
# Is there a need for an interpreter ?
|
|
141
|
+
if "interpreter" in kw:
|
|
142
|
+
cmd.insert(0, kw.pop("interpreter"))
|
|
143
|
+
else:
|
|
144
|
+
# The first element of the command line needs to be executable
|
|
145
|
+
if cmd[0] not in self._cmd_xperms_cache:
|
|
146
|
+
self._cmd_xperms_cache.add(cmd[0])
|
|
147
|
+
self.sh.xperm(cmd[0], force=True)
|
|
148
|
+
|
|
149
|
+
# Overwrite global module env values with specific ones
|
|
150
|
+
with self.sh.env.clone() as localenv:
|
|
151
|
+
localenv.verbose(True, self.sh)
|
|
152
|
+
localenv.update(self.env)
|
|
153
|
+
|
|
154
|
+
# Check if a pipe is requested
|
|
155
|
+
inpipe = kw.pop("inpipe", False)
|
|
156
|
+
|
|
157
|
+
# Ask the attached shell to run the addon command
|
|
158
|
+
if inpipe:
|
|
159
|
+
kw.setdefault("stdout", True)
|
|
160
|
+
rc = self.sh.popen(cmd, **kw)
|
|
161
|
+
else:
|
|
162
|
+
rc = self.sh.spawn(cmd, **kw)
|
|
163
|
+
|
|
164
|
+
return rc
|
|
165
|
+
|
|
166
|
+
def _spawn(self, cmd, **kw):
|
|
167
|
+
"""Internal method setting local environment and calling standard shell spawn."""
|
|
168
|
+
|
|
169
|
+
# Insert the actual tool command as first argument
|
|
170
|
+
cmd.insert(0, self.actual_cmd)
|
|
171
|
+
if self.actual_path is not None:
|
|
172
|
+
cmd[0] = self.actual_path + "/" + cmd[0]
|
|
173
|
+
|
|
174
|
+
return self._spawn_commons(cmd, **kw)
|
|
175
|
+
|
|
176
|
+
def _spawn_wrap(self, cmd, **kw):
|
|
177
|
+
"""Internal method setting local environment and calling standard shell spawn."""
|
|
178
|
+
|
|
179
|
+
# Insert the tool path before the first argument
|
|
180
|
+
if self.actual_path is not None:
|
|
181
|
+
cmd[0] = self.actual_path + "/" + cmd[0]
|
|
182
|
+
|
|
183
|
+
return self._spawn_commons(cmd, **kw)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class FtrawEnableAddon(Addon):
|
|
187
|
+
"""Root class for any :class:`Addon` system subclasses that needs to override rawftput."""
|
|
188
|
+
|
|
189
|
+
_abstract = True
|
|
190
|
+
_footprint = dict(
|
|
191
|
+
info="Default add-on with rawftput support.",
|
|
192
|
+
attr=dict(
|
|
193
|
+
rawftshell=dict(
|
|
194
|
+
info="Path to ftserv's concatenation shell",
|
|
195
|
+
optional=True,
|
|
196
|
+
default=None,
|
|
197
|
+
access="rwx",
|
|
198
|
+
doc_visibility=footprints.doc.visibility.GURU,
|
|
199
|
+
),
|
|
200
|
+
),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def __init__(self, *args, **kw):
|
|
204
|
+
"""Abstract Addon initialisation."""
|
|
205
|
+
logger.debug("Abstract Addon init %s", self.__class__)
|
|
206
|
+
super().__init__(*args, **kw)
|
|
207
|
+
# If needed, look in the config file for the rawftshell
|
|
208
|
+
if self.rawftshell is None:
|
|
209
|
+
self.rawftshell = get_from_config_w_default(
|
|
210
|
+
section="rawftshell",
|
|
211
|
+
key=self.kind,
|
|
212
|
+
default=None,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class AddonGroup(footprints.FootprintBase):
|
|
217
|
+
"""Root class for any :class:`AddonGroup` system subclasses.
|
|
218
|
+
|
|
219
|
+
An AddonGroup is not really an Addon... it just loads a bunch of other
|
|
220
|
+
Addons or AddonGroups into the current shell.
|
|
221
|
+
"""
|
|
222
|
+
|
|
223
|
+
_abstract = True
|
|
224
|
+
_collector = ("addon",)
|
|
225
|
+
_footprint = dict(
|
|
226
|
+
info="Default add-on group",
|
|
227
|
+
attr=dict(
|
|
228
|
+
kind=dict(),
|
|
229
|
+
sh=dict(
|
|
230
|
+
type=OSExtended,
|
|
231
|
+
alias=("shell",),
|
|
232
|
+
),
|
|
233
|
+
env=dict(
|
|
234
|
+
type=Environment,
|
|
235
|
+
optional=True,
|
|
236
|
+
default=None,
|
|
237
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
238
|
+
),
|
|
239
|
+
cycle=dict(
|
|
240
|
+
optional=True,
|
|
241
|
+
default=None,
|
|
242
|
+
),
|
|
243
|
+
verboseload=dict(
|
|
244
|
+
optional=True,
|
|
245
|
+
default=True,
|
|
246
|
+
type=bool,
|
|
247
|
+
),
|
|
248
|
+
),
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
_addonslist = None
|
|
252
|
+
|
|
253
|
+
def __init__(self, *args, **kw):
|
|
254
|
+
"""Abstract Addon initialisation."""
|
|
255
|
+
logger.debug("Abstract Addon init %s", self.__class__)
|
|
256
|
+
super().__init__(*args, **kw)
|
|
257
|
+
self._addons_load()
|
|
258
|
+
|
|
259
|
+
def _addons_load(self):
|
|
260
|
+
if self._addonslist is None:
|
|
261
|
+
raise RuntimeError(
|
|
262
|
+
"the _addonslist classe variable must be overriden."
|
|
263
|
+
)
|
|
264
|
+
self._load_addons_from_list(self._addonslist)
|
|
265
|
+
|
|
266
|
+
def _load_addons_from_list(self, addons):
|
|
267
|
+
if self.verboseload:
|
|
268
|
+
logger.info("Loading the %s Addons group.", self.kind)
|
|
269
|
+
for addon in addons:
|
|
270
|
+
_shadd = footprints.proxy.addon(
|
|
271
|
+
kind=addon,
|
|
272
|
+
sh=self.sh,
|
|
273
|
+
env=self.env,
|
|
274
|
+
cycle=self.cycle,
|
|
275
|
+
verboseload=self.verboseload,
|
|
276
|
+
)
|
|
277
|
+
if self.verboseload:
|
|
278
|
+
logger.info("%s Addon is: %s", addon, repr(_shadd))
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def require_external_addon(*addons):
|
|
282
|
+
"""
|
|
283
|
+
A method decorator usable in addons, that will check if addons listed in
|
|
284
|
+
**addons** are properly loaded in the parent System object.
|
|
285
|
+
|
|
286
|
+
If not, a :class:`RuntimeError` exception will be raised.
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
@nicedeco
|
|
290
|
+
def r_addon_decorator(method):
|
|
291
|
+
def decorated(self, *kargs, **kwargs):
|
|
292
|
+
# Create a cache in self... ugly but efficient !
|
|
293
|
+
if not hasattr(self, "_require_external_addon_check_cache"):
|
|
294
|
+
setattr(self, "_require_external_addon_check_cache", set())
|
|
295
|
+
ko_addons = set()
|
|
296
|
+
loaded_addons = None
|
|
297
|
+
for addon in addons:
|
|
298
|
+
if addon in self._require_external_addon_check_cache:
|
|
299
|
+
continue
|
|
300
|
+
if loaded_addons is None:
|
|
301
|
+
loaded_addons = self.sh.loaded_addons()
|
|
302
|
+
if addon in loaded_addons:
|
|
303
|
+
self._require_external_addon_check_cache.add(addon)
|
|
304
|
+
else:
|
|
305
|
+
ko_addons.add(addon)
|
|
306
|
+
if ko_addons:
|
|
307
|
+
raise RuntimeError(
|
|
308
|
+
"The following addons are needed to use the {:s} method: {:s}".format(
|
|
309
|
+
method.__name__, ", ".join(ko_addons)
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
return method(self, *kargs, **kwargs)
|
|
313
|
+
|
|
314
|
+
return decorated
|
|
315
|
+
|
|
316
|
+
return r_addon_decorator
|
vortex/tools/arm.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module needed to work with ARM tools such as Forge.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from bronx.fancies import loggers
|
|
6
|
+
|
|
7
|
+
from vortex.util.config import load_template
|
|
8
|
+
|
|
9
|
+
#: No automatic export
|
|
10
|
+
__all__ = ["ArmForgeTool"]
|
|
11
|
+
|
|
12
|
+
logger = loggers.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ArmForgeTool:
|
|
16
|
+
"""Work with the ARM tools such as DDT & MAP."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, ticket):
|
|
19
|
+
"""
|
|
20
|
+
:param ticket: The current Vortex' session ticket.
|
|
21
|
+
"""
|
|
22
|
+
self._t = ticket
|
|
23
|
+
self._sh = self._t.sh
|
|
24
|
+
self._config = self._sh.default_target.items("armtools")
|
|
25
|
+
self._ddtpath = self._sh.env.get("VORTEX_ARM_DDT_PATH", None)
|
|
26
|
+
self._mappath = self._sh.env.get("VORTEX_ARM_MAP_PATH", None)
|
|
27
|
+
self._forgedir = self._sh.env.get(
|
|
28
|
+
"VORTEX_ARM_FORGE_DIR", self.config.get("forgedir", None)
|
|
29
|
+
)
|
|
30
|
+
self._forgeversion = self._sh.env.get(
|
|
31
|
+
"VORTEX_ARM_FORGE_VERSION", self.config.get("forgeversion", 999999)
|
|
32
|
+
)
|
|
33
|
+
self._forgeversion = int(self._forgeversion)
|
|
34
|
+
if self._forgedir and self._ddtpath is None:
|
|
35
|
+
self._ddtpath = self._sh.path.join(self._forgedir, "bin", "ddt")
|
|
36
|
+
if self._forgedir and self._mappath is None:
|
|
37
|
+
self._mappath = self._sh.path.join(self._forgedir, "bin", "map")
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def config(self):
|
|
41
|
+
"""The configuration dictionary."""
|
|
42
|
+
return self._config
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def ddtpath(self):
|
|
46
|
+
"""The path to the DDT debuger executable."""
|
|
47
|
+
if self._ddtpath is None:
|
|
48
|
+
raise RuntimeError(
|
|
49
|
+
"DDT requested but the DDT path is not configured."
|
|
50
|
+
)
|
|
51
|
+
return self._ddtpath
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def mappath(self):
|
|
55
|
+
"""The path to the MAP profiler executable."""
|
|
56
|
+
if self._mappath is None:
|
|
57
|
+
raise RuntimeError(
|
|
58
|
+
"MAP requested but the MAP path is not configured."
|
|
59
|
+
)
|
|
60
|
+
return self._mappath
|
|
61
|
+
|
|
62
|
+
def _dump_forge_session(self, sources=(), workdir=None):
|
|
63
|
+
"""Create the ARM Forge's session file to list source directories."""
|
|
64
|
+
targetfile = "armforge-vortex-session-file.ddt"
|
|
65
|
+
if workdir:
|
|
66
|
+
targetfile = self._sh.path.join(workdir, targetfile)
|
|
67
|
+
tpl = load_template(
|
|
68
|
+
self._t,
|
|
69
|
+
"@armforge-session-conf.tpl",
|
|
70
|
+
encoding="utf-8",
|
|
71
|
+
version=self._forgeversion,
|
|
72
|
+
)
|
|
73
|
+
sconf = tpl.substitute(
|
|
74
|
+
sourcedirs="\n".join(
|
|
75
|
+
[
|
|
76
|
+
" <directory>{:s}</directory>".format(d)
|
|
77
|
+
for d in sources
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
with open(targetfile, "w") as fhs:
|
|
82
|
+
fhs.write(sconf)
|
|
83
|
+
return targetfile
|
|
84
|
+
|
|
85
|
+
def ddt_prefix_cmd(self, sources=(), workdir=None):
|
|
86
|
+
"""Generate the prefix command required to start DDT."""
|
|
87
|
+
if sources:
|
|
88
|
+
return [
|
|
89
|
+
self.ddtpath,
|
|
90
|
+
"--session={:s}".format(
|
|
91
|
+
self._dump_forge_session(sources, workdir=workdir)
|
|
92
|
+
),
|
|
93
|
+
"--connect",
|
|
94
|
+
]
|
|
95
|
+
else:
|
|
96
|
+
return [self.ddtpath, "--connect"]
|