Package explicitly inventoried entries without following symlinks.
128 workers: int = 1) -> str:
129 """!
130 @brief Package explicitly inventoried entries without following symlinks.
131 @param[in] root Value supplied through the `root` argument.
132 @param[in] spec Value supplied through the `spec` argument.
133 @param[in] destination Value supplied through the `destination` argument.
134 @param[in] compression Value supplied through the `compression` argument.
135 @param[in] workers Maximum compressor worker count.
136 @return Compressor implementation used for the archive chunk.
137 """
138 tar_executable = shutil.which("tar")
139 compressor = None
140 compressor_args = []
141 if compression in _PARALLEL_GZIP_VALUES and shutil.which("pigz"):
142 compressor = shutil.which("pigz")
143 compressor_args = [compressor, "-c", "-p", str(workers), "-1" if compression == "fast" else "-6"]
144 elif compression == "maximum" and shutil.which("xz"):
145 compressor = shutil.which("xz")
146 compressor_args = [compressor, "-c", "-T", str(workers), "-9e"]
147 if compressor and tar_executable:
148 list_file = tempfile.NamedTemporaryFile(prefix="picurv-tar-list-", delete=False)
149 try:
150 list_file.write(b"\0".join(path.encode("utf-8") for path in spec["entries"]) + b"\0")
151 list_file.close()
152 tar_command = [
153 tar_executable, "-C", root, "--null", "--verbatim-files-from", "--no-recursion",
154 "-T", list_file.name, "-cf", "-",
155 ]
156 with tempfile.TemporaryFile() as tar_stderr, open(destination, "wb") as output:
157 producer = subprocess.Popen(tar_command, stdout=subprocess.PIPE, stderr=tar_stderr)
158 consumer = subprocess.Popen(
159 compressor_args, stdin=producer.stdout, stdout=output, stderr=subprocess.PIPE
160 )
161 producer.stdout.close()
162 _, compressor_stderr = consumer.communicate()
163 producer_code = producer.wait()
164 if producer_code != 0 or consumer.returncode != 0:
165 tar_stderr.seek(0)
166 detail = (
167 tar_stderr.read().decode("utf-8", "replace")
168 or compressor_stderr.decode("utf-8", "replace")
169 or "parallel archive command failed"
170 ).strip()
171 raise StorageError(detail)
172 return f"{os.path.basename(compressor)}:{workers}"
173 finally:
174 try:
175 os.remove(list_file.name)
176 except FileNotFoundError:
177 pass
178
179 kwargs = {}
180 if compression == "none":
181 mode = "w"
182 elif compression == "fast":
183 mode = "w:gz"
184 kwargs["compresslevel"] = 1
185 elif compression == "balanced":
186 mode = "w:gz"
187 kwargs["compresslevel"] = 6
188 else:
189 mode = "w:xz"
190 kwargs["preset"] = 9
191 with tarfile.open(destination, mode, dereference=False, **kwargs) as archive:
192 for relative in spec["entries"]:
193 source = os.path.join(root, *relative.split("/"))
194 if not os.path.lexists(source):
195 raise StorageError(f"Artifact changed during packaging; entry disappeared: {source}")
196 archive.add(source, arcname=relative, recursive=False)
197 return "python-tarfile"
198
199