omdev 0.0.0.dev223__py3-none-any.whl → 0.0.0.dev225__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,6 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  import contextlib
4
- import heapq
5
4
  import os.path
6
5
  import tarfile
7
6
  import typing as ta
@@ -10,10 +9,6 @@ from omlish.lite.cached import cached_nullary
10
9
  from omlish.lite.check import check
11
10
  from omlish.lite.contextmanagers import ExitStacked
12
11
 
13
- from .compression import OciCompression
14
- from .tars import OciDataTarWriter
15
- from .tars import WrittenOciDataTarFileInfo
16
-
17
12
 
18
13
  ##
19
14
 
@@ -207,175 +202,3 @@ class OciLayerUnpacker(ExitStacked):
207
202
  def write(self) -> None:
208
203
  for input_file in self._input_files:
209
204
  self._unpack_file(input_file)
210
-
211
-
212
- #
213
-
214
-
215
- class OciLayerPacker(ExitStacked):
216
- def __init__(
217
- self,
218
- input_file_path: str,
219
- output_file_paths: ta.Sequence[str],
220
- *,
221
- compression: ta.Optional[OciCompression] = None,
222
- ) -> None:
223
- super().__init__()
224
-
225
- self._input_file_path = input_file_path
226
- self._output_file_paths = list(output_file_paths)
227
- self._compression = compression
228
-
229
- self._output_file_indexes_by_name: ta.Dict[str, int] = {}
230
-
231
- #
232
-
233
- @cached_nullary
234
- def _input_tar_file(self) -> tarfile.TarFile:
235
- # FIXME: check uncompressed
236
- return self._enter_context(tarfile.open(self._input_file_path))
237
-
238
- #
239
-
240
- @cached_nullary
241
- def _entries_by_name(self) -> ta.Mapping[str, tarfile.TarInfo]:
242
- return {
243
- info.name: info
244
- for info in self._input_tar_file().getmembers()
245
- }
246
-
247
- #
248
-
249
- class _CategorizedEntries(ta.NamedTuple):
250
- files_by_name: ta.Mapping[str, tarfile.TarInfo]
251
- non_files_by_name: ta.Mapping[str, tarfile.TarInfo]
252
- links_by_name: ta.Mapping[str, tarfile.TarInfo]
253
-
254
- @cached_nullary
255
- def _categorized_entries(self) -> _CategorizedEntries:
256
- files_by_name: ta.Dict[str, tarfile.TarInfo] = {}
257
- non_files_by_name: ta.Dict[str, tarfile.TarInfo] = {}
258
- links_by_name: ta.Dict[str, tarfile.TarInfo] = {}
259
-
260
- for name, info in self._entries_by_name().items():
261
- if info.type in tarfile.REGULAR_TYPES:
262
- files_by_name[name] = info
263
- elif info.type in (tarfile.LNKTYPE, tarfile.GNUTYPE_LONGLINK):
264
- links_by_name[name] = info
265
- else:
266
- non_files_by_name[name] = info
267
-
268
- return self._CategorizedEntries(
269
- files_by_name=files_by_name,
270
- non_files_by_name=non_files_by_name,
271
- links_by_name=links_by_name,
272
- )
273
-
274
- #
275
-
276
- @cached_nullary
277
- def _non_files_sorted_by_name(self) -> ta.Sequence[tarfile.TarInfo]:
278
- return sorted(
279
- self._categorized_entries().non_files_by_name.values(),
280
- key=lambda info: info.name,
281
- )
282
-
283
- @cached_nullary
284
- def _files_descending_by_size(self) -> ta.Sequence[tarfile.TarInfo]:
285
- return sorted(
286
- self._categorized_entries().files_by_name.values(),
287
- key=lambda info: -check.isinstance(info.size, int),
288
- )
289
-
290
- #
291
-
292
- @cached_nullary
293
- def _output_files(self) -> ta.Sequence[ta.BinaryIO]:
294
- return [
295
- self._enter_context(open(output_file_path, 'wb'))
296
- for output_file_path in self._output_file_paths
297
- ]
298
-
299
- @cached_nullary
300
- def _output_tar_writers(self) -> ta.Sequence[OciDataTarWriter]:
301
- return [
302
- self._enter_context(
303
- OciDataTarWriter(
304
- output_file,
305
- compression=self._compression,
306
- ),
307
- )
308
- for output_file in self._output_files()
309
- ]
310
-
311
- #
312
-
313
- def _write_entry(
314
- self,
315
- info: tarfile.TarInfo,
316
- output_file_idx: int,
317
- ) -> None:
318
- check.not_in(info.name, self._output_file_indexes_by_name)
319
-
320
- writer = self._output_tar_writers()[output_file_idx]
321
-
322
- if info.type in tarfile.REGULAR_TYPES:
323
- with check.not_none(self._input_tar_file().extractfile(info)) as f:
324
- writer.add_file(info, f) # type: ignore
325
-
326
- else:
327
- writer.add_file(info)
328
-
329
- self._output_file_indexes_by_name[info.name] = output_file_idx
330
-
331
- @cached_nullary
332
- def _write_non_files(self) -> None:
333
- for non_file in self._non_files_sorted_by_name():
334
- self._write_entry(non_file, 0)
335
-
336
- @cached_nullary
337
- def _write_files(self) -> None:
338
- writers = self._output_tar_writers()
339
-
340
- bins = [
341
- (writer.info().compressed_sz, i)
342
- for i, writer in enumerate(writers)
343
- ]
344
-
345
- heapq.heapify(bins)
346
-
347
- for file in self._files_descending_by_size():
348
- _, bin_index = heapq.heappop(bins)
349
-
350
- writer = writers[bin_index]
351
-
352
- self._write_entry(file, bin_index)
353
-
354
- bin_size = writer.info().compressed_sz
355
-
356
- heapq.heappush(bins, (bin_size, bin_index))
357
-
358
- @cached_nullary
359
- def _write_links(self) -> None:
360
- for link in self._categorized_entries().links_by_name.values():
361
- link_name = check.non_empty_str(link.linkname)
362
-
363
- output_file_idx = self._output_file_indexes_by_name[link_name]
364
-
365
- self._write_entry(link, output_file_idx)
366
-
367
- @cached_nullary
368
- def write(self) -> ta.Mapping[str, WrittenOciDataTarFileInfo]:
369
- writers = self._output_tar_writers()
370
-
371
- self._write_non_files()
372
- self._write_files()
373
- self._write_links()
374
-
375
- for output_tar_writer in writers:
376
- output_tar_writer.tar_file().close()
377
-
378
- return {
379
- output_file_path: output_tar_writer.info()
380
- for output_file_path, output_tar_writer in zip(self._output_file_paths, writers)
381
- }
omdev/oci/repositories.py CHANGED
@@ -72,6 +72,9 @@ class DirectoryOciRepository(FileOciRepository):
72
72
 
73
73
  self._data_dir = check.non_empty_str(data_dir)
74
74
 
75
+ def __repr__(self) -> str:
76
+ return f'{self.__class__.__name__}({self._data_dir!r})'
77
+
75
78
  def read_file(self, path: str) -> bytes:
76
79
  full_path = os.path.join(self._data_dir, path)
77
80
  check.arg(is_path_in_dir(self._data_dir, full_path))
@@ -109,6 +112,9 @@ class TarFileOciRepository(FileOciRepository):
109
112
 
110
113
  self._tar_file = tar_file
111
114
 
115
+ def __repr__(self) -> str:
116
+ return f'{self.__class__.__name__}({self._tar_file!r})'
117
+
112
118
  def read_file(self, path: str) -> bytes:
113
119
  if (ti := self._tar_file.getmember(path)) is None:
114
120
  raise FileNotFoundError(path)
omdev/precheck/lite.py CHANGED
@@ -9,7 +9,7 @@ import textwrap
9
9
  import typing as ta
10
10
 
11
11
  from omlish import cached
12
- from omlish.subprocesses import subprocess_maybe_shell_wrap_exec
12
+ from omlish.subprocesses.wrap import subprocess_maybe_shell_wrap_exec
13
13
 
14
14
  from .. import magic
15
15
  from .base import Precheck
omdev/pyproject/pkg.py CHANGED
@@ -38,7 +38,7 @@ import typing as ta
38
38
  from omlish.formats.toml.writer import TomlWriter
39
39
  from omlish.lite.cached import cached_nullary
40
40
  from omlish.lite.logs import log
41
- from omlish.subprocesses import subprocesses
41
+ from omlish.subprocesses.sync import subprocesses
42
42
 
43
43
  from ..cexts.magic import CextMagic
44
44
  from ..magic.find import find_magic_files