jolt 0.9.342__py3-none-any.whl → 0.9.429__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 +358 -159
- jolt/cli.py +71 -104
- jolt/config.py +14 -26
- jolt/filesystem.py +2 -2
- jolt/graph.py +56 -28
- jolt/influence.py +67 -2
- jolt/loader.py +150 -186
- jolt/log.py +12 -2
- jolt/manifest.py +0 -46
- jolt/options.py +35 -12
- jolt/pkgs/abseil.py +42 -0
- jolt/pkgs/asio.py +25 -0
- jolt/pkgs/autoconf.py +41 -0
- jolt/pkgs/automake.py +41 -0
- jolt/pkgs/b2.py +31 -0
- jolt/pkgs/boost.py +111 -0
- jolt/pkgs/boringssl.py +32 -0
- jolt/pkgs/busybox.py +39 -0
- jolt/pkgs/bzip2.py +43 -0
- jolt/pkgs/cares.py +29 -0
- jolt/pkgs/catch2.py +36 -0
- jolt/pkgs/cbindgen.py +17 -0
- jolt/pkgs/cista.py +19 -0
- jolt/pkgs/clang.py +44 -0
- jolt/pkgs/cli11.py +23 -0
- jolt/pkgs/cmake.py +48 -0
- jolt/pkgs/cpython.py +196 -0
- jolt/pkgs/crun.py +29 -0
- jolt/pkgs/curl.py +38 -0
- jolt/pkgs/dbus.py +18 -0
- jolt/pkgs/double_conversion.py +24 -0
- jolt/pkgs/fastfloat.py +21 -0
- jolt/pkgs/ffmpeg.py +28 -0
- jolt/pkgs/flatbuffers.py +29 -0
- jolt/pkgs/fmt.py +27 -0
- jolt/pkgs/fstree.py +20 -0
- jolt/pkgs/gflags.py +18 -0
- jolt/pkgs/glib.py +18 -0
- jolt/pkgs/glog.py +25 -0
- jolt/pkgs/glslang.py +21 -0
- jolt/pkgs/golang.py +16 -11
- jolt/pkgs/googlebenchmark.py +18 -0
- jolt/pkgs/googletest.py +46 -0
- jolt/pkgs/gperf.py +15 -0
- jolt/pkgs/grpc.py +73 -0
- jolt/pkgs/hdf5.py +19 -0
- jolt/pkgs/help2man.py +14 -0
- jolt/pkgs/inja.py +28 -0
- jolt/pkgs/jsoncpp.py +31 -0
- jolt/pkgs/libarchive.py +43 -0
- jolt/pkgs/libcap.py +44 -0
- jolt/pkgs/libdrm.py +44 -0
- jolt/pkgs/libedit.py +42 -0
- jolt/pkgs/libevent.py +31 -0
- jolt/pkgs/libexpat.py +27 -0
- jolt/pkgs/libfastjson.py +21 -0
- jolt/pkgs/libffi.py +16 -0
- jolt/pkgs/libglvnd.py +30 -0
- jolt/pkgs/libogg.py +28 -0
- jolt/pkgs/libpciaccess.py +18 -0
- jolt/pkgs/libseccomp.py +21 -0
- jolt/pkgs/libtirpc.py +24 -0
- jolt/pkgs/libtool.py +42 -0
- jolt/pkgs/libunwind.py +35 -0
- jolt/pkgs/libva.py +18 -0
- jolt/pkgs/libvorbis.py +33 -0
- jolt/pkgs/libxml2.py +35 -0
- jolt/pkgs/libxslt.py +17 -0
- jolt/pkgs/libyajl.py +16 -0
- jolt/pkgs/llvm.py +81 -0
- jolt/pkgs/lua.py +54 -0
- jolt/pkgs/lz4.py +26 -0
- jolt/pkgs/m4.py +14 -0
- jolt/pkgs/make.py +17 -0
- jolt/pkgs/mesa.py +81 -0
- jolt/pkgs/meson.py +17 -0
- jolt/pkgs/mstch.py +28 -0
- jolt/pkgs/mysql.py +60 -0
- jolt/pkgs/nasm.py +49 -0
- jolt/pkgs/ncurses.py +30 -0
- jolt/pkgs/ng_log.py +25 -0
- jolt/pkgs/ninja.py +45 -0
- jolt/pkgs/nlohmann_json.py +25 -0
- jolt/pkgs/nodejs.py +19 -11
- jolt/pkgs/opencv.py +24 -0
- jolt/pkgs/openjdk.py +26 -0
- jolt/pkgs/openssl.py +103 -0
- jolt/pkgs/paho.py +76 -0
- jolt/pkgs/patchelf.py +16 -0
- jolt/pkgs/perl.py +42 -0
- jolt/pkgs/pkgconfig.py +64 -0
- jolt/pkgs/poco.py +39 -0
- jolt/pkgs/protobuf.py +77 -0
- jolt/pkgs/pugixml.py +27 -0
- jolt/pkgs/python.py +19 -0
- jolt/pkgs/qt.py +35 -0
- jolt/pkgs/rapidjson.py +26 -0
- jolt/pkgs/rapidyaml.py +28 -0
- jolt/pkgs/re2.py +30 -0
- jolt/pkgs/re2c.py +17 -0
- jolt/pkgs/readline.py +15 -0
- jolt/pkgs/rust.py +41 -0
- jolt/pkgs/sdl.py +28 -0
- jolt/pkgs/simdjson.py +27 -0
- jolt/pkgs/soci.py +46 -0
- jolt/pkgs/spdlog.py +29 -0
- jolt/pkgs/spirv_llvm.py +21 -0
- jolt/pkgs/spirv_tools.py +24 -0
- jolt/pkgs/sqlite.py +83 -0
- jolt/pkgs/ssl.py +12 -0
- jolt/pkgs/texinfo.py +15 -0
- jolt/pkgs/tomlplusplus.py +22 -0
- jolt/pkgs/wayland.py +26 -0
- jolt/pkgs/x11.py +58 -0
- jolt/pkgs/xerces_c.py +20 -0
- jolt/pkgs/xorg.py +360 -0
- jolt/pkgs/xz.py +29 -0
- jolt/pkgs/yamlcpp.py +30 -0
- jolt/pkgs/zeromq.py +47 -0
- jolt/pkgs/zlib.py +69 -0
- jolt/pkgs/zstd.py +33 -0
- jolt/plugins/autotools.py +66 -0
- jolt/plugins/cmake.py +74 -6
- jolt/plugins/conan.py +238 -0
- jolt/plugins/cxxinfo.py +7 -0
- jolt/plugins/docker.py +3 -3
- jolt/plugins/environ.py +11 -0
- jolt/plugins/fetch.py +141 -0
- jolt/plugins/gdb.py +10 -6
- jolt/plugins/git.py +60 -11
- jolt/plugins/libtool.py +63 -0
- jolt/plugins/linux.py +990 -0
- jolt/plugins/meson.py +61 -0
- jolt/plugins/ninja-compdb.py +11 -7
- jolt/plugins/ninja.py +245 -26
- jolt/plugins/paths.py +11 -1
- jolt/plugins/pkgconfig.py +219 -0
- jolt/plugins/podman.py +15 -41
- jolt/plugins/python.py +137 -0
- jolt/plugins/rust.py +25 -0
- jolt/plugins/scheduler.py +18 -14
- jolt/plugins/selfdeploy/setup.py +2 -1
- jolt/plugins/selfdeploy.py +21 -30
- jolt/plugins/strings.py +19 -10
- jolt/scheduler.py +428 -138
- jolt/tasks.py +159 -7
- jolt/tools.py +105 -51
- jolt/utils.py +16 -1
- jolt/version.py +1 -1
- {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/METADATA +64 -9
- jolt-0.9.429.dist-info/RECORD +207 -0
- {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/WHEEL +1 -1
- jolt/plugins/debian.py +0 -338
- jolt/plugins/repo.py +0 -253
- jolt-0.9.342.dist-info/RECORD +0 -93
- {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/entry_points.txt +0 -0
- {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
from jolt import attributes
|
|
2
|
+
from jolt import filesystem as fs
|
|
3
|
+
from jolt import log
|
|
4
|
+
from jolt import utils
|
|
5
|
+
from jolt.error import raise_error_if
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PkgConfigHelper(object):
|
|
9
|
+
|
|
10
|
+
TEMPLATE_PKGCONFIG = """
|
|
11
|
+
prefix={{ artifact.final_path }}
|
|
12
|
+
|
|
13
|
+
Name: {{ pkgname }}
|
|
14
|
+
Description: {{ pkgname }} package
|
|
15
|
+
Version: {{ artifact.identity }}
|
|
16
|
+
|
|
17
|
+
Cflags: {% for flag in cxxflags %}{{ flag }} {% endfor %}{% for inc in incpaths %}-I${prefix}/{{ inc }} {% endfor %}{% for macro in macros %}-D{{ macro }} {% endfor %}
|
|
18
|
+
|
|
19
|
+
Libs: {% for flag in ldflags %}{{ flag }} {% endfor %}{% for libpath in libpaths %}-L${prefix}/{{ libpath }} {% endfor %}{% for library in libraries %}-l{{ library }} {% endfor %}
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, artifact, tools):
|
|
24
|
+
self.artifact = artifact
|
|
25
|
+
self.tools = tools
|
|
26
|
+
|
|
27
|
+
def _mkpath(self, path):
|
|
28
|
+
if fs.path.commonpath([path, self.artifact.path]) != self.artifact.path:
|
|
29
|
+
return path
|
|
30
|
+
return fs.path.relpath(path, self.artifact.path)
|
|
31
|
+
|
|
32
|
+
def cflags(self, package):
|
|
33
|
+
package = " ".join(utils.as_list(package))
|
|
34
|
+
try:
|
|
35
|
+
with self.tools.environ(**self.environ):
|
|
36
|
+
output = self.tools.run("{} --maximum-traverse-depth=1 --cflags-only-other {}", self.pkgconfig, package, output=False)
|
|
37
|
+
return output.strip().split()
|
|
38
|
+
except Exception as e:
|
|
39
|
+
log.debug("PkgConfig.cflags: {}", str(e))
|
|
40
|
+
return []
|
|
41
|
+
|
|
42
|
+
def incpaths(self, package):
|
|
43
|
+
package = " ".join(utils.as_list(package))
|
|
44
|
+
try:
|
|
45
|
+
with self.tools.environ(**self.environ):
|
|
46
|
+
output = self.tools.run("{} --maximum-traverse-depth=1 --cflags-only-I {}", self.pkgconfig, package, output=False)
|
|
47
|
+
return [self._mkpath(inc[2:]) for inc in output.strip().split()]
|
|
48
|
+
except Exception as e:
|
|
49
|
+
log.debug("PkgConfig.incpaths: {}", str(e))
|
|
50
|
+
return []
|
|
51
|
+
|
|
52
|
+
def linkflags(self, package):
|
|
53
|
+
package = " ".join(utils.as_list(package))
|
|
54
|
+
try:
|
|
55
|
+
with self.tools.environ(**self.environ):
|
|
56
|
+
output = self.tools.run("{} --maximum-traverse-depth=1 --libs-only-other {}", self.pkgconfig, package, output=False)
|
|
57
|
+
return output.strip().split()
|
|
58
|
+
except Exception as e:
|
|
59
|
+
log.debug("PkgConfig.linkflags: {}", str(e))
|
|
60
|
+
return []
|
|
61
|
+
|
|
62
|
+
def libpaths(self, package):
|
|
63
|
+
package = " ".join(utils.as_list(package))
|
|
64
|
+
try:
|
|
65
|
+
with self.tools.environ(**self.environ):
|
|
66
|
+
output = self.tools.run("{} --maximum-traverse-depth=1 --libs-only-L {}", self.pkgconfig, package, output=False)
|
|
67
|
+
return [self._mkpath(lib[2:]) for lib in output.strip().split()]
|
|
68
|
+
except Exception as e:
|
|
69
|
+
log.debug("PkgConfig.libpaths: {}", str(e))
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
def libraries(self, package):
|
|
73
|
+
package = " ".join(utils.as_list(package))
|
|
74
|
+
try:
|
|
75
|
+
with self.tools.environ(**self.environ):
|
|
76
|
+
output = self.tools.run("{} --maximum-traverse-depth=1 --libs-only-l {}", self.pkgconfig, package, output=False)
|
|
77
|
+
return [lib[2:] for lib in output.strip().split()]
|
|
78
|
+
except Exception as e:
|
|
79
|
+
log.debug("PkgConfig.libraries: {}", str(e))
|
|
80
|
+
return []
|
|
81
|
+
|
|
82
|
+
def write_pc(self, package):
|
|
83
|
+
with self.tools.tmpdir() as tmpdir, self.tools.cwd(tmpdir):
|
|
84
|
+
content = self.tools.render(
|
|
85
|
+
self.TEMPLATE_PKGCONFIG,
|
|
86
|
+
artifact=self.artifact,
|
|
87
|
+
pkgname=package,
|
|
88
|
+
macros=list(self.artifact.cxxinfo.macros),
|
|
89
|
+
incpaths=list(self.artifact.cxxinfo.incpaths),
|
|
90
|
+
libpaths=list(self.artifact.cxxinfo.libpaths),
|
|
91
|
+
libraries=list(self.artifact.cxxinfo.libraries),
|
|
92
|
+
)
|
|
93
|
+
print(content)
|
|
94
|
+
self.tools.write_file(f"{package}.pc", content, expand=False)
|
|
95
|
+
self.artifact.collect(f"{package}.pc", "lib/pkgconfig/")
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def pkgconfig(self):
|
|
99
|
+
pkgconf = self.tools.which(self.tools.getenv("PKG_CONFIG", "pkg-config"))
|
|
100
|
+
raise_error_if(not pkgconf, "No pkg-config tool found in PATH")
|
|
101
|
+
return pkgconf
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def environ(self):
|
|
105
|
+
path = self.artifact.environ.get("PKG_CONFIG_PATH")
|
|
106
|
+
if path is None:
|
|
107
|
+
self.tools._task.verbose("No PKG_CONFIG_PATH in artifact environment")
|
|
108
|
+
|
|
109
|
+
# Path from the artifact environment
|
|
110
|
+
path = str(path).split(fs.pathsep)
|
|
111
|
+
path = fs.pathsep.join(fs.path.join(self.artifact.path, p) for p in path)
|
|
112
|
+
|
|
113
|
+
# Append existing PKG_CONFIG_PATH from the tools environment
|
|
114
|
+
if self.tools.getenv("PKG_CONFIG_PATH"):
|
|
115
|
+
path = path + fs.pathsep + self.tools.getenv("PKG_CONFIG_PATH")
|
|
116
|
+
|
|
117
|
+
return {"PKG_CONFIG_PATH": path}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def to_cxxinfo(
|
|
121
|
+
pkg: list | str,
|
|
122
|
+
cflags: bool = True,
|
|
123
|
+
cxxflags: bool = True,
|
|
124
|
+
incpaths: bool = True,
|
|
125
|
+
ldflags: bool = True,
|
|
126
|
+
libpaths: bool = True,
|
|
127
|
+
libraries: bool = True,
|
|
128
|
+
):
|
|
129
|
+
"""
|
|
130
|
+
Decorator to add pkg-config information to cxxinfo metadata of an artifact.
|
|
131
|
+
|
|
132
|
+
The decorator enables interoperability between libraries built with Jolt's
|
|
133
|
+
Ninja plugin and external packages that provide pkg-config files.
|
|
134
|
+
|
|
135
|
+
It uses the pkg-config tool to query for compiler and linker flags,
|
|
136
|
+
include paths, library paths, and libraries associated with a given package.
|
|
137
|
+
If the relevant flags are found, they are appended to the corresponding fields
|
|
138
|
+
in the artifact's cxxinfo metadata.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
pkg (str): The name of the pkg-config package to be added to cxxinfo.
|
|
142
|
+
cflags (bool): Whether to add C compiler flags from pkg-config.
|
|
143
|
+
cxxflags (bool): Whether to add C++ compiler flags from pkg-config.
|
|
144
|
+
incpaths (bool): Whether to add include paths from pkg-config.
|
|
145
|
+
ldflags (bool): Whether to add linker flags from pkg-config.
|
|
146
|
+
libpaths (bool): Whether to add library paths from pkg-config.
|
|
147
|
+
libraries (bool): Whether to add libraries from pkg-config.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def decorate(cls):
|
|
151
|
+
original_publish = cls.publish
|
|
152
|
+
|
|
153
|
+
def publish(self, artifact, tools):
|
|
154
|
+
original_publish(self, artifact, tools)
|
|
155
|
+
|
|
156
|
+
pc = PkgConfigHelper(artifact, tools)
|
|
157
|
+
if not pc.environ:
|
|
158
|
+
self.verbose("Skipping pkg-config cxxinfo addition due to missing PKG_CONFIG_PATH.")
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
if cflags:
|
|
162
|
+
artifact.cxxinfo.cflags.extend(pc.cflags(pkg))
|
|
163
|
+
if cxxflags:
|
|
164
|
+
artifact.cxxinfo.cxxflags.extend(pc.cflags(pkg))
|
|
165
|
+
if incpaths:
|
|
166
|
+
artifact.cxxinfo.incpaths.extend(pc.incpaths(pkg))
|
|
167
|
+
if ldflags:
|
|
168
|
+
artifact.cxxinfo.ldflags.extend(pc.linkflags(pkg))
|
|
169
|
+
if libpaths:
|
|
170
|
+
artifact.cxxinfo.libpaths.extend(pc.libpaths(pkg))
|
|
171
|
+
if libraries:
|
|
172
|
+
artifact.cxxinfo.libraries.extend(pc.libraries(pkg))
|
|
173
|
+
|
|
174
|
+
cls.publish = publish
|
|
175
|
+
return cls
|
|
176
|
+
|
|
177
|
+
return decorate
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def from_cxxinfo(package):
|
|
181
|
+
"""
|
|
182
|
+
Decorator to write a pkg-config file for the given package
|
|
183
|
+
based on the cxxinfo metadata of the artifact.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def decorate(cls):
|
|
187
|
+
original_publish = cls.publish
|
|
188
|
+
original_unpack = cls.unpack
|
|
189
|
+
|
|
190
|
+
def publish(self, artifact, tools):
|
|
191
|
+
original_publish(self, artifact, tools)
|
|
192
|
+
|
|
193
|
+
pc = PkgConfigHelper(artifact, tools)
|
|
194
|
+
pc.write_pc(package)
|
|
195
|
+
|
|
196
|
+
def unpack(self, artifact, tools):
|
|
197
|
+
original_unpack(self, artifact, tools)
|
|
198
|
+
|
|
199
|
+
pc = PkgConfigHelper(artifact, tools)
|
|
200
|
+
pc.write_pc(package)
|
|
201
|
+
|
|
202
|
+
cls.publish = publish
|
|
203
|
+
cls.unpack = unpack
|
|
204
|
+
return cls
|
|
205
|
+
|
|
206
|
+
return decorate
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def requires():
|
|
210
|
+
""" Decorator to add pkg-config requirements to a task. """
|
|
211
|
+
|
|
212
|
+
import jolt.pkgs.pkgconfig
|
|
213
|
+
|
|
214
|
+
def decorate(cls):
|
|
215
|
+
cls = attributes.requires("requires_pkgconf")(cls)
|
|
216
|
+
cls.requires_pkgconf = ["pkgconf"]
|
|
217
|
+
return cls
|
|
218
|
+
|
|
219
|
+
return decorate
|
jolt/plugins/podman.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from jolt import
|
|
1
|
+
from jolt import Parameter, Resource, Task
|
|
2
2
|
from jolt.error import raise_task_error_if
|
|
3
3
|
from jolt.tasks import TaskRegistry
|
|
4
4
|
from jolt import attributes
|
|
@@ -15,7 +15,6 @@ from jolt.cache import ArtifactAttributeSetProvider
|
|
|
15
15
|
import contextlib
|
|
16
16
|
import json
|
|
17
17
|
from os import path
|
|
18
|
-
from platform import system
|
|
19
18
|
import tarfile
|
|
20
19
|
|
|
21
20
|
|
|
@@ -100,35 +99,6 @@ class PodmanAttributeProvider(ArtifactAttributeSetProvider):
|
|
|
100
99
|
artifact.podman.unapply(task, artifact)
|
|
101
100
|
|
|
102
101
|
|
|
103
|
-
class PodmanClient(Download):
|
|
104
|
-
""" Task: Downloads and publishes the Podman command line client.
|
|
105
|
-
|
|
106
|
-
The task will be automatically made available after importing
|
|
107
|
-
``jolt.plugins.podman``.
|
|
108
|
-
"""
|
|
109
|
-
|
|
110
|
-
name = "podman/cli"
|
|
111
|
-
""" Name of the task """
|
|
112
|
-
|
|
113
|
-
arch = Parameter("x86_64", help="Host architecture")
|
|
114
|
-
""" Host architecture [x86_64] """
|
|
115
|
-
|
|
116
|
-
collect = ["podman/podman"]
|
|
117
|
-
|
|
118
|
-
host = Parameter(system().lower(), help="Host operating system")
|
|
119
|
-
""" Host operating system [autodetected] """
|
|
120
|
-
|
|
121
|
-
url = "https://download.podman.com/{host}/static/stable/{arch}/podman-{version}.tgz"
|
|
122
|
-
""" URL of binaries """
|
|
123
|
-
|
|
124
|
-
version = Parameter("20.10.13", help="Podman version")
|
|
125
|
-
""" Podman version [20.10.13] """
|
|
126
|
-
|
|
127
|
-
def publish(self, artifact, tools):
|
|
128
|
-
super().publish(artifact, tools)
|
|
129
|
-
artifact.environ.PATH.append("podman")
|
|
130
|
-
|
|
131
|
-
|
|
132
102
|
@attributes.requires("_image")
|
|
133
103
|
class Container(Resource):
|
|
134
104
|
"""
|
|
@@ -206,8 +176,8 @@ class Container(Resource):
|
|
|
206
176
|
"""
|
|
207
177
|
|
|
208
178
|
volumes_default = [
|
|
209
|
-
"{joltdir}
|
|
210
|
-
"{joltcachedir}
|
|
179
|
+
"{joltdir}",
|
|
180
|
+
"{joltcachedir}",
|
|
211
181
|
]
|
|
212
182
|
"""
|
|
213
183
|
A list of default volumes to mount.
|
|
@@ -247,7 +217,7 @@ class Container(Resource):
|
|
|
247
217
|
def _image(self):
|
|
248
218
|
registry = TaskRegistry.get()
|
|
249
219
|
tool = tools.Tools(self)
|
|
250
|
-
if registry.
|
|
220
|
+
if registry.has_task(tool.expand(self.image)):
|
|
251
221
|
return [self.image]
|
|
252
222
|
return []
|
|
253
223
|
|
|
@@ -284,7 +254,7 @@ class Container(Resource):
|
|
|
284
254
|
|
|
285
255
|
@property
|
|
286
256
|
def _volumes(self):
|
|
287
|
-
return " ".join([utils.option("-v ", self.tools.
|
|
257
|
+
return " ".join([utils.option("-v ", self.tools.expand_path(vol))
|
|
288
258
|
for vol in self.volumes_default + self.volumes])
|
|
289
259
|
|
|
290
260
|
def acquire(self, artifact, deps, tools, owner):
|
|
@@ -344,8 +314,6 @@ class PodmanLogin(Resource):
|
|
|
344
314
|
name = "podman/login"
|
|
345
315
|
""" Name of the resource """
|
|
346
316
|
|
|
347
|
-
requires = ["podman/cli"]
|
|
348
|
-
|
|
349
317
|
user = Parameter("", help="Podman Registry username")
|
|
350
318
|
"""
|
|
351
319
|
Podman Registry username.
|
|
@@ -385,7 +353,6 @@ class PodmanLogin(Resource):
|
|
|
385
353
|
tools.run("podman logout {server}")
|
|
386
354
|
|
|
387
355
|
|
|
388
|
-
TaskRegistry.get().add_task_class(PodmanClient)
|
|
389
356
|
TaskRegistry.get().add_task_class(PodmanLogin)
|
|
390
357
|
|
|
391
358
|
|
|
@@ -445,7 +412,6 @@ class ContainerImage(Task):
|
|
|
445
412
|
|
|
446
413
|
Optionally add requirements to:
|
|
447
414
|
|
|
448
|
-
- ``podman/cli`` to provision the Podman client, if none is available on the host.
|
|
449
415
|
- ``podman/login`` to automatically login to the Podman registry.
|
|
450
416
|
|
|
451
417
|
This class must be subclassed.
|
|
@@ -468,7 +434,6 @@ class ContainerImage(Task):
|
|
|
468
434
|
class Busybox(ContainerImage):
|
|
469
435
|
\"\"\" Publishes Busybox image as gzip-compressed tarball \"\"\"
|
|
470
436
|
compression = "gz"
|
|
471
|
-
requires = ["podman/cli"]
|
|
472
437
|
tags = ["busybox:{identity}"]
|
|
473
438
|
|
|
474
439
|
"""
|
|
@@ -518,6 +483,7 @@ class ContainerImage(Task):
|
|
|
518
483
|
- custom
|
|
519
484
|
- directory
|
|
520
485
|
- docker-archive
|
|
486
|
+
- ext4
|
|
521
487
|
- oci-archive
|
|
522
488
|
- oci-directory
|
|
523
489
|
- squashfs
|
|
@@ -551,6 +517,9 @@ class ContainerImage(Task):
|
|
|
551
517
|
The ``podman/login`` Jolt resource can be used for that purpose.
|
|
552
518
|
"""
|
|
553
519
|
|
|
520
|
+
size = None
|
|
521
|
+
""" Size of the image, e.g. "64M" (for certain output formats). """
|
|
522
|
+
|
|
554
523
|
squash = False
|
|
555
524
|
""" Squash image layers """
|
|
556
525
|
|
|
@@ -629,7 +598,7 @@ class ContainerImage(Task):
|
|
|
629
598
|
tools.run("podman image save --format={output} {} -o {}", self.tags[0], "image.tar")
|
|
630
599
|
if output == "oci-directory":
|
|
631
600
|
tools.run("podman image save --format=oci-dir {} -o {}", self.tags[0], "image.dir")
|
|
632
|
-
if output in ["archive", "cpio", "custom", "directory", "squashfs"]:
|
|
601
|
+
if output in ["archive", "cpio", "custom", "directory", "ext4", "squashfs"]:
|
|
633
602
|
ctr = tools.run("podman create {}", self.tags[0])
|
|
634
603
|
try:
|
|
635
604
|
with tools.runprefix("podman unshare "):
|
|
@@ -641,6 +610,9 @@ class ContainerImage(Task):
|
|
|
641
610
|
elif output == "cpio":
|
|
642
611
|
with tools.cwd(mount_path):
|
|
643
612
|
tools.run("find | podman unshare cpio -o -F {}/image.cpio -H newc", outdir, output_on_error=True)
|
|
613
|
+
elif output == "ext4":
|
|
614
|
+
assert self.size, "Size must be set for ext4 output"
|
|
615
|
+
tools.run("mke2fs -t ext4 -F -L rootfs -d {} image.ext4 {size}", mount_path, output_on_error=True)
|
|
644
616
|
elif output == "squashfs":
|
|
645
617
|
tools.run("mksquashfs {} image.squashfs", mount_path, output_on_error=True)
|
|
646
618
|
else:
|
|
@@ -695,6 +667,8 @@ class ContainerImage(Task):
|
|
|
695
667
|
self.publish_custom(artifact, tools)
|
|
696
668
|
if output in ["directory"]:
|
|
697
669
|
artifact.paths.rootfs = output
|
|
670
|
+
if output in ["ext4"]:
|
|
671
|
+
artifact.collect("image.ext4", output + "/{_imagefile}.ext4")
|
|
698
672
|
if output in ["squashfs"]:
|
|
699
673
|
artifact.collect("image.squashfs", output + "/{_imagefile}.squashfs")
|
|
700
674
|
|
jolt/plugins/python.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
|
|
3
|
+
from jolt import Task
|
|
4
|
+
from jolt import attributes
|
|
3
5
|
from jolt import filesystem as fs
|
|
4
6
|
from jolt.cache import ArtifactStringAttribute
|
|
5
7
|
from jolt.cache import ArtifactAttributeSet
|
|
6
8
|
from jolt.cache import ArtifactAttributeSetProvider
|
|
9
|
+
from jolt.error import raise_task_error_if
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
class PythonVariable(ArtifactStringAttribute):
|
|
@@ -98,3 +101,137 @@ class PythonProvider(ArtifactAttributeSetProvider):
|
|
|
98
101
|
|
|
99
102
|
def unapply(self, task, artifact):
|
|
100
103
|
artifact.python.unapply(task, artifact)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@attributes.system
|
|
107
|
+
@attributes.requires("requires_python")
|
|
108
|
+
class PythonEnv(Task):
|
|
109
|
+
"""
|
|
110
|
+
Base class for Python virtual environment tasks.
|
|
111
|
+
|
|
112
|
+
Builds a Python virtual environment and installs specified packages.
|
|
113
|
+
|
|
114
|
+
The venv module from the Python standard library must be available in the
|
|
115
|
+
Python installation used to run the task.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
abstract = True
|
|
119
|
+
""" This is an abstract base class that should be inherited by concrete tasks. """
|
|
120
|
+
|
|
121
|
+
executable = "python3"
|
|
122
|
+
""" Python executable to use for creating the virtual environment. """
|
|
123
|
+
|
|
124
|
+
requirements = []
|
|
125
|
+
"""
|
|
126
|
+
List of Python packages to install in the virtual environment.
|
|
127
|
+
|
|
128
|
+
Each entry should be a string suitable for pip, e.g., "package==version".
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def _verify_influence(self, deps, artifact, tools, sources=None):
|
|
132
|
+
# No influence to verify
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
def relocate_scripts(self, artifact, tools, frompath, topath):
|
|
136
|
+
bindir = "Scripts" if self.system == "windows" else "bin"
|
|
137
|
+
|
|
138
|
+
with tools.cwd(artifact.path, bindir):
|
|
139
|
+
for script in tools.glob("*"):
|
|
140
|
+
if script.startswith("python"):
|
|
141
|
+
continue
|
|
142
|
+
tools.replace_in_file(script, frompath, topath)
|
|
143
|
+
|
|
144
|
+
with tools.cwd(artifact.path):
|
|
145
|
+
if not tools.exists("local/bin"):
|
|
146
|
+
return
|
|
147
|
+
with tools.cwd("local", "bin"):
|
|
148
|
+
for script in tools.glob("*"):
|
|
149
|
+
tools.replace_in_file(script, frompath, topath)
|
|
150
|
+
|
|
151
|
+
def publish(self, artifact, tools):
|
|
152
|
+
# Create a parallel installation by copying a Python installation
|
|
153
|
+
|
|
154
|
+
# First locate the Python executable to copy
|
|
155
|
+
py_exe = tools.which(self.executable)
|
|
156
|
+
raise_task_error_if(
|
|
157
|
+
py_exe is None, self,
|
|
158
|
+
f"Python executable '{self.executable}' not found in PATH.",
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Follow symlinks to get the real executable
|
|
162
|
+
py_exe = fs.path.realpath(py_exe)
|
|
163
|
+
|
|
164
|
+
# Determine the Python home directory
|
|
165
|
+
py_home = fs.path.dirname(fs.path.dirname(py_exe))
|
|
166
|
+
|
|
167
|
+
# Determine the Python version
|
|
168
|
+
self.version_major = tools.run(
|
|
169
|
+
[py_exe, "-c", "import sys; print(\"{{}}.{{}}\".format(sys.version_info[0], sys.version_info[1]))"],
|
|
170
|
+
shell=False,
|
|
171
|
+
output_on_error=True).strip()
|
|
172
|
+
|
|
173
|
+
self.info("Python executable: {0}", py_exe)
|
|
174
|
+
self.info("Python home: {0}", py_home)
|
|
175
|
+
self.info("Python version: {0}", self.version_major)
|
|
176
|
+
|
|
177
|
+
# Copy the Python installation to the artifact path
|
|
178
|
+
with tools.cwd(py_home):
|
|
179
|
+
artifact.collect(py_exe, "bin/python3")
|
|
180
|
+
artifact.collect("lib/python3")
|
|
181
|
+
artifact.collect("lib/python{version_major}")
|
|
182
|
+
artifact.collect("lib/libpython{version_major}.*")
|
|
183
|
+
|
|
184
|
+
# Create common symlinks
|
|
185
|
+
if self.system != "windows":
|
|
186
|
+
with tools.cwd(artifact.path, "bin"):
|
|
187
|
+
tools.symlink("python3", "python")
|
|
188
|
+
tools.symlink("python3", "python{version_major}")
|
|
189
|
+
|
|
190
|
+
# Install required packages into the artifact using pip
|
|
191
|
+
with tools.environ(PYTHONHOME=artifact.path):
|
|
192
|
+
py_exe = fs.path.join(artifact.path, "bin", "python3")
|
|
193
|
+
with tools.tmpdir() as tmp, tools.cwd(tmp):
|
|
194
|
+
tools.write_file(
|
|
195
|
+
"requirements.txt",
|
|
196
|
+
"\n".join(self.requirements) + "\n"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
pip_cmd = [
|
|
200
|
+
py_exe,
|
|
201
|
+
"-m",
|
|
202
|
+
"pip",
|
|
203
|
+
"--isolated",
|
|
204
|
+
"--no-cache-dir",
|
|
205
|
+
"install",
|
|
206
|
+
"-r",
|
|
207
|
+
"requirements.txt",
|
|
208
|
+
"--break-system-packages",
|
|
209
|
+
]
|
|
210
|
+
tools.run(pip_cmd, shell=False)
|
|
211
|
+
|
|
212
|
+
artifact.environ.PATH.append("bin")
|
|
213
|
+
artifact.environ.PATH.append("local/bin")
|
|
214
|
+
artifact.strings.install_prefix = artifact.path
|
|
215
|
+
|
|
216
|
+
def unpack(self, artifact, tools):
|
|
217
|
+
# Relocate the virtual environment by adjusting script paths
|
|
218
|
+
frompath = artifact.strings.install_prefix
|
|
219
|
+
topath = artifact.final_path
|
|
220
|
+
self.relocate_scripts(artifact, tools, frompath, topath)
|
|
221
|
+
|
|
222
|
+
artifact.strings.install_prefix = artifact.final_path
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def requires(python=True):
|
|
226
|
+
""" Decorator to add Python requirements to a task. """
|
|
227
|
+
|
|
228
|
+
import jolt.pkgs.cpython
|
|
229
|
+
|
|
230
|
+
def decorate(cls):
|
|
231
|
+
if python:
|
|
232
|
+
cls = attributes.requires("requires_python")(cls)
|
|
233
|
+
cls.requires_python = ["cpython"]
|
|
234
|
+
|
|
235
|
+
return cls
|
|
236
|
+
|
|
237
|
+
return decorate
|
jolt/plugins/rust.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from jolt import attributes, Task
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@attributes.common_metadata()
|
|
5
|
+
class Rust(Task):
|
|
6
|
+
""" Base class for Rust-based build tasks. """
|
|
7
|
+
|
|
8
|
+
abstract = True
|
|
9
|
+
|
|
10
|
+
srcdir = None
|
|
11
|
+
"""
|
|
12
|
+
Source directory for the Rust project.
|
|
13
|
+
|
|
14
|
+
If None, defaults to the task work directory (joltdir).
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def run(self, deps, tools):
|
|
18
|
+
self.builddir = tools.builddir(incremental=True)
|
|
19
|
+
self.installdir = tools.builddir("install")
|
|
20
|
+
with tools.cwd(self.srcdir or self.joltdir):
|
|
21
|
+
tools.run("cargo install --path . --target-dir={builddir} --root={installdir}")
|
|
22
|
+
|
|
23
|
+
def publish(self, artifact, tools):
|
|
24
|
+
with tools.cwd(self.installdir):
|
|
25
|
+
artifact.collect("*", symlinks=True)
|
jolt/plugins/scheduler.py
CHANGED
|
@@ -13,7 +13,6 @@ from jolt import config
|
|
|
13
13
|
from jolt import hooks
|
|
14
14
|
from jolt import loader
|
|
15
15
|
from jolt import log
|
|
16
|
-
from jolt import manifest
|
|
17
16
|
from jolt import common_pb2 as common_pb
|
|
18
17
|
from jolt import scheduler
|
|
19
18
|
from jolt import utils
|
|
@@ -145,6 +144,15 @@ class RemoteExecutor(NetworkExecutor):
|
|
|
145
144
|
self.session = session
|
|
146
145
|
self.task = task
|
|
147
146
|
|
|
147
|
+
def schedule(self, env):
|
|
148
|
+
"""
|
|
149
|
+
Schedule the task for execution.
|
|
150
|
+
|
|
151
|
+
The task is marked as in progress before scheduling.
|
|
152
|
+
"""
|
|
153
|
+
self.task.set_in_progress()
|
|
154
|
+
return super().schedule(env)
|
|
155
|
+
|
|
148
156
|
def cancel(self):
|
|
149
157
|
"""
|
|
150
158
|
Cancel the build session.
|
|
@@ -436,21 +444,11 @@ class RemoteSession(object):
|
|
|
436
444
|
if self.build:
|
|
437
445
|
return
|
|
438
446
|
|
|
439
|
-
registry = ExecutorRegistry.get()
|
|
440
|
-
|
|
441
447
|
if not self.buildenv:
|
|
442
|
-
# Create a list of parameters to send to the scheduler.
|
|
443
|
-
parameters = []
|
|
444
|
-
for key, value in registry.get_network_parameters(None).items():
|
|
445
|
-
parameters.append(common_pb.Property(key=key, value=value))
|
|
446
|
-
|
|
447
|
-
# Add parameters from the config / command line (-c params.key).
|
|
448
|
-
parameters.extend(config.export_params())
|
|
449
|
-
|
|
450
448
|
# Create the build environment.
|
|
451
449
|
self.buildenv = common_pb.BuildEnvironment(
|
|
452
450
|
client=selfdeploy.get_client(),
|
|
453
|
-
parameters=
|
|
451
|
+
parameters=config.export_params(),
|
|
454
452
|
task_default_parameters=scheduler.export_task_default_params(self.tasks),
|
|
455
453
|
tasks=scheduler.export_tasks(self.tasks + self.pruned),
|
|
456
454
|
workspace=loader.export_workspace(self.tasks),
|
|
@@ -580,8 +578,14 @@ def executor(ctx, worker, build, request):
|
|
|
580
578
|
loglevel = request.environment.loglevel
|
|
581
579
|
log.set_level_pb(loglevel)
|
|
582
580
|
|
|
583
|
-
# Import
|
|
584
|
-
|
|
581
|
+
# Import workspace
|
|
582
|
+
loader.import_workspace(request.environment)
|
|
583
|
+
|
|
584
|
+
# Import configuration snippet
|
|
585
|
+
config.import_config(request.environment.config)
|
|
586
|
+
|
|
587
|
+
# Import configuration parameters (-c params.key)
|
|
588
|
+
config.import_params({param.key: param.value for param in request.environment.parameters})
|
|
585
589
|
|
|
586
590
|
options = JoltOptions(
|
|
587
591
|
network=True,
|
jolt/plugins/selfdeploy/setup.py
CHANGED
|
@@ -85,6 +85,7 @@ setup(
|
|
|
85
85
|
"protobuf",
|
|
86
86
|
"psutil",
|
|
87
87
|
"pygit2",
|
|
88
|
+
"py7zr",
|
|
88
89
|
"requests",
|
|
89
90
|
"zstandard",
|
|
90
91
|
"tqdm",
|
|
@@ -92,7 +93,7 @@ setup(
|
|
|
92
93
|
dependency_links=[],
|
|
93
94
|
extras_require={
|
|
94
95
|
"allure": ["allure-python-commons"],
|
|
95
|
-
"conan": ["conan
|
|
96
|
+
"conan": ["conan>=2.0"],
|
|
96
97
|
"dev": ["check-manifest"],
|
|
97
98
|
"doc": ["sphinx-click", "sphinx-rtd-theme"],
|
|
98
99
|
"test": ["coverage"],
|