taskcluster-taskgraph 9.2.1__tar.gz → 10.0.0__tar.gz

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.
Files changed (139) hide show
  1. {taskcluster-taskgraph-9.2.1/src/taskcluster_taskgraph.egg-info → taskcluster-taskgraph-10.0.0}/PKG-INFO +1 -1
  2. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0/src/taskcluster_taskgraph.egg-info}/PKG-INFO +1 -1
  3. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/__init__.py +1 -1
  4. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/run-task/fetch-content +44 -25
  5. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/docker_image.py +2 -2
  6. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/run/__init__.py +23 -10
  7. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_run.py +21 -0
  8. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/LICENSE +0 -0
  9. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/MANIFEST.in +0 -0
  10. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/README.rst +0 -0
  11. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/pyproject.toml +0 -0
  12. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/base.in +0 -0
  13. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/base.txt +0 -0
  14. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/dev.in +0 -0
  15. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/dev.txt +0 -0
  16. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/test.in +0 -0
  17. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/requirements/test.txt +0 -0
  18. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/setup.cfg +0 -0
  19. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/setup.py +0 -0
  20. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskcluster_taskgraph.egg-info/SOURCES.txt +0 -0
  21. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskcluster_taskgraph.egg-info/dependency_links.txt +0 -0
  22. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskcluster_taskgraph.egg-info/entry_points.txt +0 -0
  23. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskcluster_taskgraph.egg-info/requires.txt +0 -0
  24. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskcluster_taskgraph.egg-info/top_level.txt +0 -0
  25. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/__init__.py +0 -0
  26. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
  27. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/cancel.py +0 -0
  28. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/cancel_all.py +0 -0
  29. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  30. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/registry.py +0 -0
  31. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/retrigger.py +0 -0
  32. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/actions/util.py +0 -0
  33. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/config.py +0 -0
  34. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/create.py +0 -0
  35. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/decision.py +0 -0
  36. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/docker.py +0 -0
  37. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/filter_tasks.py +0 -0
  38. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/generator.py +0 -0
  39. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/graph.py +0 -0
  40. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/loader/__init__.py +0 -0
  41. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/loader/default.py +0 -0
  42. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/loader/transform.py +0 -0
  43. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/main.py +0 -0
  44. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/morph.py +0 -0
  45. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/optimize/__init__.py +0 -0
  46. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/optimize/base.py +0 -0
  47. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/optimize/strategies.py +0 -0
  48. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/parameters.py +0 -0
  49. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/run-task/hgrc +0 -0
  50. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
  51. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/run-task/run-task +0 -0
  52. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/target_tasks.py +0 -0
  53. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/task.py +0 -0
  54. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/taskgraph.py +0 -0
  55. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/__init__.py +0 -0
  56. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/base.py +0 -0
  57. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
  58. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/chunking.py +0 -0
  59. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/code_review.py +0 -0
  60. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/fetch.py +0 -0
  61. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/from_deps.py +0 -0
  62. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/notify.py +0 -0
  63. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/run/common.py +0 -0
  64. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/run/index_search.py +0 -0
  65. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/run/run_task.py +0 -0
  66. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
  67. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/task.py +0 -0
  68. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/transforms/task_context.py +0 -0
  69. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/__init__.py +0 -0
  70. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/archive.py +0 -0
  71. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/attributes.py +0 -0
  72. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/cached_tasks.py +0 -0
  73. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/copy.py +0 -0
  74. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/dependencies.py +0 -0
  75. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/docker.py +0 -0
  76. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/hash.py +0 -0
  77. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/keyed_by.py +0 -0
  78. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/parameterization.py +0 -0
  79. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/path.py +0 -0
  80. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/python_path.py +0 -0
  81. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/readonlydict.py +0 -0
  82. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/schema.py +0 -0
  83. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/set_name.py +0 -0
  84. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/shell.py +0 -0
  85. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/taskcluster.py +0 -0
  86. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/taskgraph.py +0 -0
  87. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/templates.py +0 -0
  88. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/time.py +0 -0
  89. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/treeherder.py +0 -0
  90. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/vcs.py +0 -0
  91. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/verify.py +0 -0
  92. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/workertypes.py +0 -0
  93. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/src/taskgraph/util/yaml.py +0 -0
  94. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
  95. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_actions_registry.py +0 -0
  96. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_create.py +0 -0
  97. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_decision.py +0 -0
  98. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_docker.py +0 -0
  99. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_generator.py +0 -0
  100. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_graph.py +0 -0
  101. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_main.py +0 -0
  102. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_morph.py +0 -0
  103. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_optimize.py +0 -0
  104. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_optimize_strategies.py +0 -0
  105. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_parameters.py +0 -0
  106. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_scripts_fetch_content.py +0 -0
  107. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_scripts_run_task.py +0 -0
  108. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_target_tasks.py +0 -0
  109. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_taskgraph.py +0 -0
  110. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transform_chunking.py +0 -0
  111. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transform_docker_image.py +0 -0
  112. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transform_task_context.py +0 -0
  113. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_base.py +0 -0
  114. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_cached_tasks.py +0 -0
  115. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_fetch.py +0 -0
  116. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_from_deps.py +0 -0
  117. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_notify.py +0 -0
  118. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_run_run_task.py +0 -0
  119. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_run_toolchain.py +0 -0
  120. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_transforms_task.py +0 -0
  121. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_archive.py +0 -0
  122. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_attributes.py +0 -0
  123. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_cached_tasks.py +0 -0
  124. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_copy.py +0 -0
  125. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_dependencies.py +0 -0
  126. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_docker.py +0 -0
  127. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_parameterization.py +0 -0
  128. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_path.py +0 -0
  129. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_python_path.py +0 -0
  130. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_readonlydict.py +0 -0
  131. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_schema.py +0 -0
  132. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_taskcluster.py +0 -0
  133. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_templates.py +0 -0
  134. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_time.py +0 -0
  135. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_treeherder.py +0 -0
  136. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_vcs.py +0 -0
  137. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_verify.py +0 -0
  138. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_workertypes.py +0 -0
  139. {taskcluster-taskgraph-9.2.1 → taskcluster-taskgraph-10.0.0}/test/test_util_yaml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: taskcluster-taskgraph
3
- Version: 9.2.1
3
+ Version: 10.0.0
4
4
  Summary: Build taskcluster taskgraphs
5
5
  Home-page: https://github.com/taskcluster/taskgraph
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: taskcluster-taskgraph
3
- Version: 9.2.1
3
+ Version: 10.0.0
4
4
  Summary: Build taskcluster taskgraphs
5
5
  Home-page: https://github.com/taskcluster/taskgraph
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -2,7 +2,7 @@
2
2
  # License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
4
 
5
- __version__ = "9.2.1"
5
+ __version__ = "10.0.0"
6
6
 
7
7
  # Maximum number of dependencies a single task can have
8
8
  # https://docs.taskcluster.net/reference/platform/taskcluster-queue/references/api#createTask
@@ -10,6 +10,7 @@ import contextlib
10
10
  import datetime
11
11
  import gzip
12
12
  import hashlib
13
+ import io
13
14
  import json
14
15
  import lzma
15
16
  import multiprocessing
@@ -332,21 +333,41 @@ def gpg_verify_path(path: pathlib.Path, public_key_data: bytes, signature_data:
332
333
  subprocess.run(["gpgconf", "--kill", "gpg-agent"], env=env)
333
334
 
334
335
 
335
- def open_tar_stream(path: pathlib.Path):
336
- """"""
337
- if path.suffix == ".bz2":
338
- return bz2.open(str(path), "rb")
339
- elif path.suffix in (".gz", ".tgz") :
340
- return gzip.open(str(path), "rb")
341
- elif path.suffix == ".xz":
342
- return lzma.open(str(path), "rb")
343
- elif path.suffix == ".zst":
344
- dctx = ZstdDecompressor()
345
- return dctx.stream_reader(path.open("rb"))
346
- elif path.suffix == ".tar":
347
- return path.open("rb")
348
- else:
349
- raise ValueError("unknown archive format for tar file: %s" % path)
336
+ class ArchiveTypeNotSupported(Exception):
337
+ def __init__(self, path: pathlib.Path):
338
+ super(Exception, self).__init__("Archive type not supported for %s" % path)
339
+
340
+
341
+ def open_stream(path: pathlib.Path):
342
+ """Attempt to identify a path as an extractable archive by looking at its
343
+ content."""
344
+ fh = path.open(mode="rb")
345
+ magic = fh.read(6)
346
+ fh.seek(0)
347
+ if magic[:2] == b"PK":
348
+ return "zip", fh
349
+ if magic[:2] == b"\x1f\x8b":
350
+ fh = gzip.GzipFile(fileobj=fh)
351
+ elif magic[:3] == b"BZh":
352
+ fh = bz2.BZ2File(fh)
353
+ elif magic == b"\xfd7zXZ\x00":
354
+ fh = lzma.LZMAFile(fh)
355
+ elif magic[:4] == b"\x28\xb5\x2f\xfd":
356
+ fh = ZstdDecompressor().stream_reader(fh)
357
+ fh = io.BufferedReader(fh)
358
+ try:
359
+ # A full tar info header is 512 bytes.
360
+ headers = fh.peek(512)
361
+ # 257 is the offset of the ustar magic.
362
+ magic = headers[257 : 257 + 8]
363
+ # For older unix tar, rely on TarInfo.frombuf's checksum check
364
+ if magic in (b"ustar\x0000", b"ustar \x00") or tarfile.TarInfo.frombuf(
365
+ headers[:512], tarfile.ENCODING, "surrogateescape"
366
+ ):
367
+ return "tar", fh
368
+ except Exception as e:
369
+ pass
370
+ raise ArchiveTypeNotSupported(path)
350
371
 
351
372
 
352
373
  def archive_type(path: pathlib.Path):
@@ -359,7 +380,7 @@ def archive_type(path: pathlib.Path):
359
380
  return None
360
381
 
361
382
 
362
- def extract_archive(path, dest_dir, typ):
383
+ def extract_archive(path, dest_dir):
363
384
  """Extract an archive to a destination directory."""
364
385
 
365
386
  # Resolve paths to absolute variants.
@@ -371,8 +392,8 @@ def extract_archive(path, dest_dir, typ):
371
392
 
372
393
  # We pipe input to the decompressor program so that we can apply
373
394
  # custom decompressors that the program may not know about.
395
+ typ, ifh = open_stream(path)
374
396
  if typ == "tar":
375
- ifh = open_tar_stream(path)
376
397
  # On Windows, the tar program doesn't support things like symbolic
377
398
  # links, while Windows actually support them. The tarfile module in
378
399
  # python does. So use that. But since it's significantly slower than
@@ -419,10 +440,8 @@ def repack_archive(
419
440
  ):
420
441
  assert orig != dest
421
442
  log("Repacking as %s" % dest)
422
- orig_typ = archive_type(orig)
443
+ orig_typ, ifh = open_stream(orig)
423
444
  typ = archive_type(dest)
424
- if not orig_typ:
425
- raise Exception("Archive type not supported for %s" % orig.name)
426
445
  if not typ:
427
446
  raise Exception("Archive type not supported for %s" % dest.name)
428
447
 
@@ -448,7 +467,7 @@ def repack_archive(
448
467
  ctx = ZstdCompressor()
449
468
  if orig_typ == "zip":
450
469
  assert typ == "tar"
451
- zip = zipfile.ZipFile(orig)
470
+ zip = zipfile.ZipFile(ifh)
452
471
  # Convert the zip stream to a tar on the fly.
453
472
  with ctx.stream_writer(fh) as compressor, tarfile.open(
454
473
  fileobj=compressor, mode="w:"
@@ -490,7 +509,6 @@ def repack_archive(
490
509
  raise Exception("Repacking a tar to zip is not supported")
491
510
  assert typ == "tar"
492
511
 
493
- ifh = open_tar_stream(orig)
494
512
  if filter:
495
513
  # To apply the filter, we need to open the tar stream and
496
514
  # tweak it.
@@ -533,11 +551,12 @@ def fetch_and_extract(url, dest_dir, extract=True, sha256=None, size=None):
533
551
  if not extract:
534
552
  return
535
553
 
536
- typ = archive_type(dest_path)
537
- if typ:
538
- extract_archive(dest_path, dest_dir, typ)
554
+ try:
555
+ extract_archive(dest_path, dest_dir)
539
556
  log("Removing %s" % dest_path)
540
557
  dest_path.unlink()
558
+ except ArchiveTypeNotSupported:
559
+ pass
541
560
 
542
561
 
543
562
  def fetch_urls(downloads):
@@ -24,9 +24,9 @@ CONTEXTS_DIR = "docker-contexts"
24
24
  DIGEST_RE = re.compile("^[0-9a-f]{64}$")
25
25
 
26
26
  IMAGE_BUILDER_IMAGE = (
27
- "mozillareleases/image_builder:5.0.0"
27
+ "mozillareleases/image_builder:5.1.0"
28
28
  "@sha256:"
29
- "e510a9a9b80385f71c112d61b2f2053da625aff2b6d430411ac42e424c58953f"
29
+ "7fe70dcedefffffa03237ba5d456d42e0d7461de066db3f7a7c280a104869cd5"
30
30
  )
31
31
 
32
32
  transforms = TransformSequence()
@@ -14,7 +14,7 @@ import copy
14
14
  import json
15
15
  import logging
16
16
 
17
- from voluptuous import Any, Exclusive, Extra, Optional, Required
17
+ from voluptuous import Exclusive, Extra, Optional, Required
18
18
 
19
19
  from taskgraph.transforms.base import TransformSequence
20
20
  from taskgraph.transforms.cached_tasks import order_tasks
@@ -85,7 +85,6 @@ run_description_schema = Schema(
85
85
  },
86
86
  # A list of artifacts to install from 'fetch' tasks.
87
87
  Optional("fetches"): {
88
- Any("toolchain", "fetch"): [str],
89
88
  str: [
90
89
  str,
91
90
  fetches_schema,
@@ -252,7 +251,15 @@ def use_fetches(config, tasks):
252
251
  for kind in sorted(fetches):
253
252
  artifacts = fetches[kind]
254
253
  if kind in ("fetch", "toolchain"):
255
- for fetch_name in sorted(artifacts):
254
+ for artifact in sorted(artifacts):
255
+ # Convert name only fetch entries to full fledged ones for
256
+ # easier processing.
257
+ if isinstance(artifact, str):
258
+ artifact = {
259
+ "artifact": artifact,
260
+ }
261
+
262
+ fetch_name = artifact["artifact"]
256
263
  label = f"{kind}-{fetch_name}"
257
264
  label = aliases.get(label, label)
258
265
  if label not in artifact_names:
@@ -263,15 +270,21 @@ def use_fetches(config, tasks):
263
270
  env.update(extra_env[label])
264
271
 
265
272
  path = artifact_names[label]
273
+ dest = artifact.get("dest", None)
274
+ extract = artifact.get("extract", True)
275
+ verify_hash = artifact.get("verify-hash", False)
266
276
 
267
277
  dependencies[label] = label
268
- task_fetches.append(
269
- {
270
- "artifact": path,
271
- "task": f"<{label}>",
272
- "extract": True,
273
- }
274
- )
278
+ fetch = {
279
+ "artifact": path,
280
+ "task": f"<{label}>",
281
+ "extract": extract,
282
+ }
283
+ if dest is not None:
284
+ fetch["dest"] = dest
285
+ if verify_hash:
286
+ fetch["verify-hash"] = verify_hash
287
+ task_fetches.append(fetch)
275
288
  else:
276
289
  if kind not in dependencies:
277
290
  raise Exception(
@@ -6,6 +6,7 @@
6
6
  Tests for the 'run' transform subsystem.
7
7
  """
8
8
 
9
+ import json
9
10
  import os
10
11
  from copy import deepcopy
11
12
  from pprint import pprint
@@ -89,6 +90,12 @@ def assert_use_fetches_toolchain_env(task):
89
90
  assert task["worker"]["env"]["FOO"] == "1"
90
91
 
91
92
 
93
+ def assert_use_fetches_toolchain_extract_false(task):
94
+ fetches = json.loads(task["worker"]["env"]["MOZ_FETCHES"]["task-reference"])
95
+ assert len(fetches) == 1
96
+ assert fetches[0]["extract"] is False
97
+
98
+
92
99
  @pytest.mark.parametrize(
93
100
  "task,kind_dependencies_tasks",
94
101
  (
@@ -107,6 +114,20 @@ def assert_use_fetches_toolchain_env(task):
107
114
  ],
108
115
  id="toolchain_env",
109
116
  ),
117
+ pytest.param(
118
+ {"fetches": {"toolchain": [{"artifact": "foo", "extract": False}]}},
119
+ [
120
+ Task(
121
+ kind="toolchain",
122
+ label="toolchain-foo",
123
+ attributes={
124
+ "toolchain-artifact": "target.whl",
125
+ },
126
+ task={},
127
+ )
128
+ ],
129
+ id="toolchain_extract_false",
130
+ ),
110
131
  ),
111
132
  )
112
133
  def test_use_fetches(