jolt 0.9.355__py3-none-any.whl → 0.9.371__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.
- jolt/__init__.py +47 -0
- jolt/cache.py +339 -159
- jolt/cli.py +29 -98
- jolt/config.py +14 -26
- jolt/graph.py +27 -15
- jolt/loader.py +141 -180
- jolt/manifest.py +0 -46
- jolt/options.py +35 -12
- jolt/plugins/conan.py +238 -0
- jolt/plugins/docker.py +1 -1
- jolt/plugins/environ.py +11 -0
- jolt/plugins/gdb.py +6 -5
- jolt/plugins/linux.py +943 -0
- jolt/plugins/ninja-compdb.py +7 -6
- jolt/plugins/podman.py +4 -4
- jolt/plugins/scheduler.py +18 -14
- jolt/plugins/selfdeploy/setup.py +1 -1
- jolt/plugins/selfdeploy.py +1 -22
- jolt/plugins/strings.py +16 -6
- jolt/scheduler.py +428 -138
- jolt/tasks.py +27 -0
- jolt/tools.py +15 -8
- jolt/version.py +1 -1
- {jolt-0.9.355.dist-info → jolt-0.9.371.dist-info}/METADATA +2 -2
- {jolt-0.9.355.dist-info → jolt-0.9.371.dist-info}/RECORD +28 -29
- jolt/plugins/debian.py +0 -338
- jolt/plugins/repo.py +0 -253
- {jolt-0.9.355.dist-info → jolt-0.9.371.dist-info}/WHEEL +0 -0
- {jolt-0.9.355.dist-info → jolt-0.9.371.dist-info}/entry_points.txt +0 -0
- {jolt-0.9.355.dist-info → jolt-0.9.371.dist-info}/top_level.txt +0 -0
jolt/loader.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from collections import OrderedDict
|
|
2
1
|
from contextlib import contextmanager
|
|
3
2
|
import fasteners
|
|
4
3
|
import json
|
|
@@ -11,20 +10,34 @@ import sys
|
|
|
11
10
|
from types import ModuleType
|
|
12
11
|
|
|
13
12
|
from jolt import inspection
|
|
14
|
-
from jolt.tasks import
|
|
15
|
-
from jolt.
|
|
16
|
-
from jolt.error import raise_error_if, raise_task_error_if
|
|
13
|
+
from jolt.tasks import Task, TaskGenerator
|
|
14
|
+
from jolt.error import raise_error_if
|
|
17
15
|
from jolt import common_pb2 as common_pb
|
|
18
16
|
from jolt import config
|
|
19
17
|
from jolt import filesystem as fs
|
|
20
18
|
from jolt import log
|
|
21
19
|
from jolt import utils
|
|
22
|
-
from jolt.manifest import ManifestExtension
|
|
23
|
-
from jolt.manifest import ManifestExtensionRegistry
|
|
24
20
|
from jolt.tools import Tools
|
|
25
21
|
|
|
26
22
|
|
|
27
23
|
class Recipe(object):
|
|
24
|
+
"""
|
|
25
|
+
Abstract representation a single recipe file.
|
|
26
|
+
|
|
27
|
+
Implementations of this class are responsible for reading the recipe source
|
|
28
|
+
from the filesystem. The recipe source is then parsed and the tasks are
|
|
29
|
+
extracted and made available for execution.
|
|
30
|
+
|
|
31
|
+
The format of the recipe source is implementation defined.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
tasks = []
|
|
35
|
+
"""
|
|
36
|
+
List of task classes defined in the recipe.
|
|
37
|
+
|
|
38
|
+
Available after the recipe has been loaded.
|
|
39
|
+
"""
|
|
40
|
+
|
|
28
41
|
def __init__(self, path, joltdir=None, project=None, source=None):
|
|
29
42
|
self.path = path
|
|
30
43
|
self.basepath = os.path.basename(path)
|
|
@@ -33,13 +46,15 @@ class Recipe(object):
|
|
|
33
46
|
self.source = source
|
|
34
47
|
self.tasks = []
|
|
35
48
|
|
|
36
|
-
def load(self
|
|
49
|
+
def load(self):
|
|
50
|
+
""" Load the recipe source from the file system. """
|
|
37
51
|
raise_error_if(self.source is not None, "recipe already loaded: {}", self.path)
|
|
38
52
|
|
|
39
53
|
with open(self.path) as f:
|
|
40
54
|
self.source = f.read()
|
|
41
55
|
|
|
42
56
|
def save(self):
|
|
57
|
+
""" Save the recipe source to the file system. """
|
|
43
58
|
raise_error_if(self.source is None, "recipe source unknown: {}", self.path)
|
|
44
59
|
|
|
45
60
|
with open(self.path, "w") as f:
|
|
@@ -47,6 +62,8 @@ class Recipe(object):
|
|
|
47
62
|
|
|
48
63
|
|
|
49
64
|
class NativeRecipe(Recipe):
|
|
65
|
+
""" Represents a Python recipe file (.jolt, .py). """
|
|
66
|
+
|
|
50
67
|
@staticmethod
|
|
51
68
|
def _is_abstract(cls):
|
|
52
69
|
return cls.__dict__.get("abstract", False) or cls.__name__.startswith("_")
|
|
@@ -58,6 +75,13 @@ class NativeRecipe(Recipe):
|
|
|
58
75
|
not NativeRecipe._is_abstract(cls)
|
|
59
76
|
|
|
60
77
|
def load(self, joltdir=None):
|
|
78
|
+
"""
|
|
79
|
+
Load the recipe source from the file system.
|
|
80
|
+
|
|
81
|
+
Python classes defined in the recipe source are extracted and made available
|
|
82
|
+
as tasks for execution. Task classes must be subclasses of Task or TaskGenerator.
|
|
83
|
+
|
|
84
|
+
"""
|
|
61
85
|
super(NativeRecipe, self).load()
|
|
62
86
|
|
|
63
87
|
name = utils.canonical(self.path)
|
|
@@ -88,17 +112,42 @@ class NativeRecipe(Recipe):
|
|
|
88
112
|
|
|
89
113
|
|
|
90
114
|
class Loader(object):
|
|
91
|
-
|
|
115
|
+
"""
|
|
116
|
+
Base class for recipe loaders.
|
|
117
|
+
|
|
118
|
+
A Loader is responsible for finding recipes in the file system providing a list
|
|
119
|
+
of Recipe:s from which tasks can be loaded.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
def recipes(self) -> list:
|
|
123
|
+
""" Return a list of Recipe:s from which tasks can be loaded. """
|
|
92
124
|
pass
|
|
93
125
|
|
|
94
126
|
|
|
95
127
|
class LoaderFactory(object):
|
|
128
|
+
"""
|
|
129
|
+
A factory for creating Loader instances.
|
|
130
|
+
|
|
131
|
+
Factories are registered with the JoltLoader where it is used to create Loader instances.
|
|
132
|
+
"""
|
|
96
133
|
def create(self):
|
|
97
134
|
raise NotImplementedError()
|
|
98
135
|
|
|
99
136
|
|
|
100
137
|
class NativeLoader(Loader):
|
|
138
|
+
""" A loader for Python recipe files (.jolt, .py). """
|
|
139
|
+
|
|
101
140
|
def __init__(self, searchpath):
|
|
141
|
+
"""
|
|
142
|
+
Create a new NativeLoader instance.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
searchpath (str): The path to search for recipe files. If the path is a file,
|
|
146
|
+
only that file will be loaded. If the path is a directory, all files with
|
|
147
|
+
the .jolt or .py extension will be loaded.
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
|
|
102
151
|
self._files = self._find_files(searchpath)
|
|
103
152
|
self._recipes = self._load_files(self._files) if self._files else []
|
|
104
153
|
|
|
@@ -109,7 +158,7 @@ class NativeLoader(Loader):
|
|
|
109
158
|
|
|
110
159
|
_, ext = fs.path.splitext(searchpath)
|
|
111
160
|
raise_error_if(not fs.path.exists(searchpath), "File does not exist: {}", searchpath)
|
|
112
|
-
raise_error_if(ext not in [".jolt", ".py"], "Invalid file extension: {}", ext)
|
|
161
|
+
raise_error_if(ext not in [".build", ".jolt", ".py"], "Invalid file extension: {}", ext)
|
|
113
162
|
|
|
114
163
|
return [searchpath]
|
|
115
164
|
|
|
@@ -129,6 +178,7 @@ _loaders = []
|
|
|
129
178
|
|
|
130
179
|
|
|
131
180
|
def register(factory):
|
|
181
|
+
""" Register a LoaderFactory with the JoltLoader. """
|
|
132
182
|
raise_error_if(not issubclass(factory, LoaderFactory),
|
|
133
183
|
"{} is not a LoaderFactory", factory.__name__)
|
|
134
184
|
_loaders.append(factory)
|
|
@@ -136,12 +186,22 @@ def register(factory):
|
|
|
136
186
|
|
|
137
187
|
@register
|
|
138
188
|
class NativeLoaderFactory(LoaderFactory):
|
|
189
|
+
""" A factory for creating NativeLoader instances. """
|
|
139
190
|
def create(self, searchpath):
|
|
140
191
|
return NativeLoader(searchpath)
|
|
141
192
|
|
|
142
193
|
|
|
143
194
|
@utils.Singleton
|
|
144
195
|
class JoltLoader(object):
|
|
196
|
+
"""
|
|
197
|
+
The JoltLoader is responsible for loading recipes from the file system.
|
|
198
|
+
|
|
199
|
+
The JoltLoader is a singleton and is used to load recipes from the file system.
|
|
200
|
+
The recipes are loaded from the workspace directory and any project directories
|
|
201
|
+
defined in the workspace. The recipes are then made available for execution.
|
|
202
|
+
|
|
203
|
+
"""
|
|
204
|
+
|
|
145
205
|
filename = "*.jolt"
|
|
146
206
|
|
|
147
207
|
def __init__(self):
|
|
@@ -149,61 +209,14 @@ class JoltLoader(object):
|
|
|
149
209
|
self._recipes = []
|
|
150
210
|
self._tasks = []
|
|
151
211
|
self._path = None
|
|
152
|
-
self._project_modules = OrderedDict()
|
|
153
|
-
self._project_recipes = OrderedDict()
|
|
154
|
-
self._project_resources = OrderedDict()
|
|
155
212
|
self._build_path = None
|
|
156
213
|
self._workspace_name = None
|
|
157
214
|
|
|
158
|
-
def _add_project_module(self, project, src):
|
|
159
|
-
modules = self._project_modules.get(project, [])
|
|
160
|
-
modules.append(src)
|
|
161
|
-
self._project_modules[project] = modules
|
|
162
|
-
|
|
163
|
-
def _get_project_modules(self, project):
|
|
164
|
-
return self._project_modules.get(project, [])
|
|
165
|
-
|
|
166
|
-
def _add_project_recipe(self, project, joltdir, src):
|
|
167
|
-
recipes = self._project_recipes.get(project, [])
|
|
168
|
-
recipes.append((joltdir, src))
|
|
169
|
-
self._project_recipes[project] = recipes
|
|
170
|
-
|
|
171
|
-
def _get_project_recipes(self, project):
|
|
172
|
-
return self._project_recipes.get(project, [])
|
|
173
|
-
|
|
174
215
|
def _get_first_recipe_path(self):
|
|
175
216
|
for recipe in self.recipes:
|
|
176
217
|
return recipe.path
|
|
177
|
-
for project, recipes in self._project_recipes.items():
|
|
178
|
-
for joltdir, src in recipes:
|
|
179
|
-
return fs.path.join(self._path, src)
|
|
180
218
|
return None
|
|
181
219
|
|
|
182
|
-
def _add_project_resource(self, project, resource_name, resource_task):
|
|
183
|
-
class ProjectResource(Alias):
|
|
184
|
-
name = project + "/" + resource_name
|
|
185
|
-
requires = [resource_task]
|
|
186
|
-
|
|
187
|
-
self._tasks.append(ProjectResource)
|
|
188
|
-
resources = self._project_resources.get(project, [])
|
|
189
|
-
resources.append((resource_name, resource_task))
|
|
190
|
-
self._project_resources[project] = resources
|
|
191
|
-
|
|
192
|
-
def _get_project_resources(self, project):
|
|
193
|
-
return self._project_resources.get(project, [])
|
|
194
|
-
|
|
195
|
-
def _load_project_recipes(self):
|
|
196
|
-
for project, recipes in self._project_recipes.items():
|
|
197
|
-
resources = [resource for _, resource in self._get_project_resources(project)]
|
|
198
|
-
for joltdir, src in recipes:
|
|
199
|
-
joltdir = fs.path.join(self.joltdir, joltdir) if joltdir else self.joltdir
|
|
200
|
-
recipe = NativeRecipe(fs.path.join(self._path, src), joltdir, project)
|
|
201
|
-
recipe.load()
|
|
202
|
-
for task in recipe.tasks:
|
|
203
|
-
task._resources = resources
|
|
204
|
-
attributes.requires("_resources")(task)
|
|
205
|
-
self._tasks += recipe.tasks
|
|
206
|
-
|
|
207
220
|
def _find_workspace_path(self, searchdir):
|
|
208
221
|
for factory in _loaders:
|
|
209
222
|
loader = factory().create(searchdir)
|
|
@@ -219,7 +232,16 @@ class JoltLoader(object):
|
|
|
219
232
|
def _get_searchpaths(self):
|
|
220
233
|
return [self.workspace_path]
|
|
221
234
|
|
|
222
|
-
def load(self,
|
|
235
|
+
def load(self, registry=None):
|
|
236
|
+
"""
|
|
237
|
+
Load all recipes from the workspace directory.
|
|
238
|
+
|
|
239
|
+
Optionally populate the task registry with the tasks found in the recipes.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
List of Task classes found in the recipes.
|
|
243
|
+
"""
|
|
244
|
+
|
|
223
245
|
if not self.workspace_path:
|
|
224
246
|
self.set_workspace_path(self._find_workspace_path(os.getcwd()))
|
|
225
247
|
|
|
@@ -234,17 +256,22 @@ class JoltLoader(object):
|
|
|
234
256
|
self._recipes.append(recipe)
|
|
235
257
|
self._tasks += recipe.tasks
|
|
236
258
|
|
|
237
|
-
self._load_project_recipes()
|
|
238
|
-
|
|
239
259
|
# Create workspace lock on the first loaded recipe
|
|
240
260
|
if not self._lock:
|
|
241
261
|
path = self._get_first_recipe_path()
|
|
242
262
|
if path:
|
|
243
263
|
self._lock = fasteners.InterProcessLock(path)
|
|
244
264
|
|
|
265
|
+
# Add tasks to the registry if provided
|
|
266
|
+
if registry is not None:
|
|
267
|
+
for task in self._tasks:
|
|
268
|
+
registry.add_task_class(task)
|
|
269
|
+
|
|
245
270
|
return self._tasks
|
|
246
271
|
|
|
247
272
|
def load_file(self, path, joltdir=None):
|
|
273
|
+
""" Load a single recipe file. """
|
|
274
|
+
|
|
248
275
|
for factory in _loaders:
|
|
249
276
|
loader = factory().create(path)
|
|
250
277
|
for recipe in loader.recipes:
|
|
@@ -254,6 +281,8 @@ class JoltLoader(object):
|
|
|
254
281
|
self._tasks += recipe.tasks
|
|
255
282
|
|
|
256
283
|
def load_plugin(self, filepath):
|
|
284
|
+
""" Load a single plugin file. """
|
|
285
|
+
|
|
257
286
|
plugin, ext = os.path.splitext(fs.path.basename(filepath))
|
|
258
287
|
loader = SourceFileLoader("jolt.plugins." + plugin, filepath)
|
|
259
288
|
module = ModuleType(loader.name)
|
|
@@ -262,6 +291,15 @@ class JoltLoader(object):
|
|
|
262
291
|
sys.modules[loader.name] = module
|
|
263
292
|
|
|
264
293
|
def load_plugins(self):
|
|
294
|
+
"""
|
|
295
|
+
Load all configured plugins.
|
|
296
|
+
|
|
297
|
+
Plugins are loaded from the plugin path configured in the Jolt configuration file
|
|
298
|
+
or from the default plugin path in the Jolt package.
|
|
299
|
+
|
|
300
|
+
If a plugin is already loaded, it will not be loaded again. If a plugin is not found
|
|
301
|
+
in the plugin path, it will not be loaded.
|
|
302
|
+
"""
|
|
265
303
|
searchpath = config.get("jolt", "pluginpath")
|
|
266
304
|
searchpath = searchpath.split(":") if searchpath else []
|
|
267
305
|
searchpath.append(fs.path.join(fs.path.dirname(__file__), "plugins"))
|
|
@@ -288,14 +326,17 @@ class JoltLoader(object):
|
|
|
288
326
|
|
|
289
327
|
@property
|
|
290
328
|
def tasks(self):
|
|
329
|
+
""" Returns a list of all loaded tasks. """
|
|
291
330
|
return self._tasks
|
|
292
331
|
|
|
293
332
|
@property
|
|
294
333
|
def joltdir(self):
|
|
334
|
+
""" Returns the path to the workspace. """
|
|
295
335
|
return self._path
|
|
296
336
|
|
|
297
337
|
@property
|
|
298
338
|
def workspace_name(self):
|
|
339
|
+
""" Returns the name of the workspace. """
|
|
299
340
|
return self._workspace_name or os.path.basename(self.workspace_path)
|
|
300
341
|
|
|
301
342
|
def set_workspace_name(self, name):
|
|
@@ -303,6 +344,7 @@ class JoltLoader(object):
|
|
|
303
344
|
|
|
304
345
|
@property
|
|
305
346
|
def workspace_path(self):
|
|
347
|
+
""" Returns the path to the workspace. """
|
|
306
348
|
return self._path
|
|
307
349
|
|
|
308
350
|
@contextmanager
|
|
@@ -319,10 +361,12 @@ class JoltLoader(object):
|
|
|
319
361
|
|
|
320
362
|
@property
|
|
321
363
|
def build_path(self):
|
|
364
|
+
""" Returns the path to the build directory. """
|
|
322
365
|
return self._build_path or os.path.join(self.workspace_path, "build")
|
|
323
366
|
|
|
324
367
|
@property
|
|
325
368
|
def build_path_rel(self):
|
|
369
|
+
"""" Returns the path to the build directory relative to the workspace. """
|
|
326
370
|
return os.path.relpath(self.build_path, self.workspace_path)
|
|
327
371
|
|
|
328
372
|
def set_build_path(self, path):
|
|
@@ -330,98 +374,6 @@ class JoltLoader(object):
|
|
|
330
374
|
log.debug("Jolt build path: {}", self._build_path)
|
|
331
375
|
|
|
332
376
|
|
|
333
|
-
class RecipeExtension(ManifestExtension):
|
|
334
|
-
def export_manifest(self, manifest, tasks):
|
|
335
|
-
loader = JoltLoader.get()
|
|
336
|
-
|
|
337
|
-
for recipe in loader.recipes:
|
|
338
|
-
manifest_recipe = manifest.create_recipe()
|
|
339
|
-
manifest_recipe.path = recipe.basepath
|
|
340
|
-
manifest_recipe.source = recipe.source
|
|
341
|
-
|
|
342
|
-
projects = set([task.task.joltproject for task in tasks])
|
|
343
|
-
for project in filter(lambda x: x is not None, projects):
|
|
344
|
-
manifest_project = manifest.create_project()
|
|
345
|
-
manifest_project.name = project
|
|
346
|
-
|
|
347
|
-
for name, resource_task in loader._get_project_resources(project):
|
|
348
|
-
resource = manifest_project.create_resource()
|
|
349
|
-
resource.name = name
|
|
350
|
-
resource.text = resource_task
|
|
351
|
-
|
|
352
|
-
for joltdir, src in loader._get_project_recipes(project):
|
|
353
|
-
recipe = manifest_project.create_recipe()
|
|
354
|
-
recipe.src = src
|
|
355
|
-
if joltdir:
|
|
356
|
-
recipe.joltdir = joltdir
|
|
357
|
-
|
|
358
|
-
for path in loader._get_project_modules(project):
|
|
359
|
-
module = manifest_project.create_module()
|
|
360
|
-
module.path = path
|
|
361
|
-
|
|
362
|
-
def import_manifest(self, manifest):
|
|
363
|
-
loader = JoltLoader.get()
|
|
364
|
-
loader.set_workspace_path(manifest.get_workspace_path() or os.getcwd())
|
|
365
|
-
loader.set_workspace_name(manifest.get_workspace_name())
|
|
366
|
-
if manifest.build:
|
|
367
|
-
loader.set_build_path(manifest.build)
|
|
368
|
-
|
|
369
|
-
for recipe in manifest.recipes:
|
|
370
|
-
recipe = Recipe(recipe.path, source=recipe.source)
|
|
371
|
-
recipe.save()
|
|
372
|
-
|
|
373
|
-
for project in manifest.projects:
|
|
374
|
-
for recipe in project.recipes:
|
|
375
|
-
loader._add_project_recipe(project.name, recipe.joltdir, recipe.src)
|
|
376
|
-
|
|
377
|
-
for resource in project.resources:
|
|
378
|
-
loader._add_project_resource(project.name, resource.name, resource.text)
|
|
379
|
-
|
|
380
|
-
# Acquire resource immediately
|
|
381
|
-
task = TaskRegistry.get().get_task(resource.text, manifest=manifest)
|
|
382
|
-
raise_task_error_if(not isinstance(task, WorkspaceResource), task,
|
|
383
|
-
"only workspace resources are allowed in manifest")
|
|
384
|
-
task.acquire_ws()
|
|
385
|
-
|
|
386
|
-
for module in project.modules:
|
|
387
|
-
loader._add_project_module(project.name, module.src)
|
|
388
|
-
sys.path.append(fs.path.join(manifest.get_workspace_path(), module.src))
|
|
389
|
-
|
|
390
|
-
def import_protobuf(self, buildenv):
|
|
391
|
-
loader = JoltLoader.get()
|
|
392
|
-
loader.set_workspace_path(os.getcwd())
|
|
393
|
-
loader.set_workspace_name(buildenv.workspace.name)
|
|
394
|
-
if buildenv.workspace.builddir:
|
|
395
|
-
loader.set_build_path(buildenv.workspace.builddir)
|
|
396
|
-
|
|
397
|
-
# Write .jolt files into workspace
|
|
398
|
-
for file in buildenv.workspace.files:
|
|
399
|
-
if file.content:
|
|
400
|
-
with open(file.path, "w") as f:
|
|
401
|
-
f.write(file.content)
|
|
402
|
-
|
|
403
|
-
for project in buildenv.workspace.projects:
|
|
404
|
-
for recipe in project.recipes:
|
|
405
|
-
loader._add_project_recipe(project.name, recipe.workdir, recipe.path)
|
|
406
|
-
|
|
407
|
-
for resource in project.resources:
|
|
408
|
-
loader._add_project_resource(project.name, resource.alias, resource.name)
|
|
409
|
-
|
|
410
|
-
# Acquire resource immediately
|
|
411
|
-
task = TaskRegistry.get().get_task(resource.name, buildenv=buildenv)
|
|
412
|
-
raise_task_error_if(
|
|
413
|
-
not isinstance(task, WorkspaceResource), task,
|
|
414
|
-
"only workspace resources are allowed in manifest")
|
|
415
|
-
task.acquire_ws()
|
|
416
|
-
|
|
417
|
-
for path in project.paths:
|
|
418
|
-
loader._add_project_module(project.name, path.path)
|
|
419
|
-
sys.path.append(fs.path.join(loader.workspace_path, path.path))
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
ManifestExtensionRegistry.add(RecipeExtension())
|
|
423
|
-
|
|
424
|
-
|
|
425
377
|
def get_workspacedir():
|
|
426
378
|
workspacedir = JoltLoader.get().workspace_path
|
|
427
379
|
assert workspacedir is not None, "No workspace present"
|
|
@@ -441,8 +393,45 @@ def workspace_locked(func):
|
|
|
441
393
|
return wrapper
|
|
442
394
|
|
|
443
395
|
|
|
396
|
+
def import_workspace(buildenv: common_pb.BuildEnvironment):
|
|
397
|
+
"""
|
|
398
|
+
Import workspace from a BuildEnvironment protobuf message.
|
|
399
|
+
|
|
400
|
+
This function will create files, recipes, resources and modules in the workspace
|
|
401
|
+
based on the information in the BuildEnvironment message.
|
|
402
|
+
|
|
403
|
+
The workspace tree is not pulled and checked out here. This is done by the
|
|
404
|
+
worker before it starts the executor.
|
|
405
|
+
|
|
406
|
+
"""
|
|
407
|
+
loader = JoltLoader.get()
|
|
408
|
+
loader.set_workspace_path(os.getcwd())
|
|
409
|
+
loader.set_workspace_name(buildenv.workspace.name)
|
|
410
|
+
if buildenv.workspace.builddir:
|
|
411
|
+
loader.set_build_path(buildenv.workspace.builddir)
|
|
412
|
+
|
|
413
|
+
# Write .jolt files into workspace
|
|
414
|
+
for file in buildenv.workspace.files:
|
|
415
|
+
if file.content:
|
|
416
|
+
with open(file.path, "w") as f:
|
|
417
|
+
f.write(file.content)
|
|
418
|
+
|
|
419
|
+
|
|
444
420
|
@workspace_locked
|
|
445
|
-
def export_workspace(tasks=None):
|
|
421
|
+
def export_workspace(tasks=None) -> common_pb.Workspace:
|
|
422
|
+
"""
|
|
423
|
+
Export workspace to a Workspace protobuf message.
|
|
424
|
+
|
|
425
|
+
This function will create a Workspace protobuf message containing all the
|
|
426
|
+
recipes, resources and modules in the workspace. If tasks is provided, only
|
|
427
|
+
the projects associated with the tasks will be exported. Otherwise, all
|
|
428
|
+
projects will be exported.
|
|
429
|
+
|
|
430
|
+
If the workspace is configured to use a remote cache, the workspace will be
|
|
431
|
+
pushed to the remote cache using the fstree tool. The tree hash of the
|
|
432
|
+
workspace will be included in the returned Workspace message.
|
|
433
|
+
|
|
434
|
+
"""
|
|
446
435
|
loader = JoltLoader.get()
|
|
447
436
|
tools = Tools()
|
|
448
437
|
tree = None
|
|
@@ -561,32 +550,4 @@ def export_workspace(tasks=None):
|
|
|
561
550
|
)
|
|
562
551
|
)
|
|
563
552
|
|
|
564
|
-
if tasks is None:
|
|
565
|
-
projects = loader._project_recipes.keys()
|
|
566
|
-
else:
|
|
567
|
-
projects = set([task.task.joltproject for task in tasks])
|
|
568
|
-
|
|
569
|
-
for project in filter(lambda x: x is not None, projects):
|
|
570
|
-
pb_project = common_pb.Project()
|
|
571
|
-
pb_project.name = project
|
|
572
|
-
|
|
573
|
-
for name, resource_task in loader._get_project_resources(project):
|
|
574
|
-
resource = common_pb.Project.Resource()
|
|
575
|
-
resource.alias = name
|
|
576
|
-
resource.name = resource_task
|
|
577
|
-
pb_project.resources.append(resource)
|
|
578
|
-
|
|
579
|
-
for joltdir, src in loader._get_project_recipes(project):
|
|
580
|
-
recipe = common_pb.Project.Recipe()
|
|
581
|
-
recipe.path = src
|
|
582
|
-
if joltdir:
|
|
583
|
-
recipe.workdir = joltdir
|
|
584
|
-
pb_project.recipes.append(recipe)
|
|
585
|
-
|
|
586
|
-
for path in loader._get_project_modules(project):
|
|
587
|
-
syspath = common_pb.Project.SystemPath(path=path)
|
|
588
|
-
pb_project.paths.append(syspath)
|
|
589
|
-
|
|
590
|
-
workspace.projects.append(pb_project)
|
|
591
|
-
|
|
592
553
|
return workspace
|
jolt/manifest.py
CHANGED
|
@@ -241,49 +241,3 @@ class JoltManifest(ElementTree):
|
|
|
241
241
|
for manifest_task in self.tasks:
|
|
242
242
|
self._identities[manifest_task.name] = manifest_task.identity
|
|
243
243
|
return self._identities
|
|
244
|
-
|
|
245
|
-
@staticmethod
|
|
246
|
-
def export(task):
|
|
247
|
-
manifest = JoltManifest()
|
|
248
|
-
ManifestExtensionRegistry.export_manifest(manifest, task)
|
|
249
|
-
return manifest
|
|
250
|
-
|
|
251
|
-
def process_import(self):
|
|
252
|
-
ManifestExtensionRegistry.import_manifest(self)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
class ManifestExtensionRegistry(object):
|
|
256
|
-
extensions = []
|
|
257
|
-
|
|
258
|
-
@staticmethod
|
|
259
|
-
def add(extension, priority=0):
|
|
260
|
-
ManifestExtensionRegistry.extensions.append((extension, priority))
|
|
261
|
-
ManifestExtensionRegistry.extensions.sort(key=lambda x: x[1])
|
|
262
|
-
|
|
263
|
-
@staticmethod
|
|
264
|
-
def export_manifest(manifest, task):
|
|
265
|
-
for extension, _ in ManifestExtensionRegistry.extensions:
|
|
266
|
-
extension.export_manifest(manifest, task)
|
|
267
|
-
|
|
268
|
-
@staticmethod
|
|
269
|
-
def import_manifest(manifest):
|
|
270
|
-
if not manifest.is_valid():
|
|
271
|
-
return
|
|
272
|
-
for extension, _ in ManifestExtensionRegistry.extensions:
|
|
273
|
-
extension.import_manifest(manifest)
|
|
274
|
-
|
|
275
|
-
@staticmethod
|
|
276
|
-
def import_protobuf(pb):
|
|
277
|
-
for extension, _ in ManifestExtensionRegistry.extensions:
|
|
278
|
-
extension.import_protobuf(pb)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
class ManifestExtension(object):
|
|
282
|
-
def export_manifest(self, manifest, task):
|
|
283
|
-
pass
|
|
284
|
-
|
|
285
|
-
def import_manifest(self, manifest):
|
|
286
|
-
pass
|
|
287
|
-
|
|
288
|
-
def import_protobuf(self, pb):
|
|
289
|
-
pass
|
jolt/options.py
CHANGED
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
|
|
2
2
|
class JoltOptions(object):
|
|
3
|
+
""" Jolt options that control the behavior of builds. """
|
|
4
|
+
|
|
5
|
+
debug = False
|
|
6
|
+
""" Enable debug mode. Break into debugger on exceptions. """
|
|
7
|
+
|
|
8
|
+
download = True
|
|
9
|
+
""" Enable downloading of remote artifacts, both session and persistent. """
|
|
10
|
+
|
|
11
|
+
download_session = True
|
|
12
|
+
""" Enable downloading of remote session artifacts. """
|
|
13
|
+
|
|
14
|
+
keep_going = False
|
|
15
|
+
""" Keep going with the build after a task fails. """
|
|
16
|
+
|
|
17
|
+
local = False
|
|
18
|
+
""" Disable network access. """
|
|
19
|
+
|
|
20
|
+
network = False
|
|
21
|
+
""" Distribute tasks to workers. """
|
|
22
|
+
|
|
23
|
+
upload = True
|
|
24
|
+
""" Enable uploading of artifacts. """
|
|
25
|
+
|
|
26
|
+
worker = False
|
|
27
|
+
""" Running as a worker. """
|
|
28
|
+
|
|
29
|
+
salt = None
|
|
30
|
+
""" Salt for hashing (--salt). """
|
|
31
|
+
|
|
32
|
+
jobs = 1
|
|
33
|
+
""" Number of concurrent local tasks to run (1). """
|
|
34
|
+
|
|
35
|
+
mute = False
|
|
36
|
+
""" Mute task output, until a task fails. """
|
|
37
|
+
|
|
3
38
|
def __init__(self, **kwargs):
|
|
4
|
-
self.debug = False
|
|
5
|
-
self.default = []
|
|
6
|
-
self.download = True
|
|
7
|
-
self.download_session = True
|
|
8
|
-
self.keep_going = False
|
|
9
|
-
self.local = False
|
|
10
|
-
self.network = False
|
|
11
|
-
self.upload = True
|
|
12
|
-
self.worker = False
|
|
13
|
-
self.salt = None
|
|
14
|
-
self.jobs = 1
|
|
15
|
-
self.mute = False
|
|
16
39
|
self.__dict__.update(kwargs)
|