taskcluster-taskgraph 7.3.1__tar.gz → 8.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 (140) hide show
  1. {taskcluster-taskgraph-7.3.1/src/taskcluster_taskgraph.egg-info → taskcluster-taskgraph-8.0.0}/PKG-INFO +1 -1
  2. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/pyproject.toml +1 -0
  3. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0/src/taskcluster_taskgraph.egg-info}/PKG-INFO +1 -1
  4. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskcluster_taskgraph.egg-info/SOURCES.txt +1 -2
  5. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/__init__.py +1 -1
  6. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/retrigger.py +1 -3
  7. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/decision.py +1 -0
  8. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/main.py +31 -11
  9. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/morph.py +1 -0
  10. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/optimize/strategies.py +11 -5
  11. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/parameters.py +3 -0
  12. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/from_deps.py +10 -9
  13. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/run/__init__.py +1 -5
  14. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/task.py +3 -3
  15. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/cached_tasks.py +1 -3
  16. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/hash.py +1 -4
  17. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/keyed_by.py +1 -3
  18. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/parameterization.py +5 -6
  19. taskcluster-taskgraph-8.0.0/src/taskgraph/util/set_name.py +34 -0
  20. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/taskcluster.py +8 -18
  21. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/verify.py +2 -9
  22. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/yaml.py +4 -1
  23. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_main.py +30 -1
  24. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_morph.py +1 -0
  25. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_optimize_strategies.py +33 -1
  26. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_parameters.py +6 -0
  27. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_from_deps.py +41 -1
  28. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_cached_tasks.py +2 -4
  29. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_parameterization.py +11 -0
  30. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_taskcluster.py +28 -0
  31. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_vcs.py +9 -11
  32. taskcluster-taskgraph-7.3.1/src/taskgraph/files_changed.py +0 -92
  33. taskcluster-taskgraph-7.3.1/test/test_files_changed.py +0 -110
  34. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/LICENSE +0 -0
  35. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/MANIFEST.in +0 -0
  36. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/README.rst +0 -0
  37. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/base.in +0 -0
  38. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/base.txt +0 -0
  39. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/dev.in +0 -0
  40. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/dev.txt +0 -0
  41. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/test.in +0 -0
  42. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/requirements/test.txt +0 -0
  43. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/setup.cfg +0 -0
  44. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/setup.py +0 -0
  45. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskcluster_taskgraph.egg-info/dependency_links.txt +0 -0
  46. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskcluster_taskgraph.egg-info/entry_points.txt +0 -0
  47. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskcluster_taskgraph.egg-info/requires.txt +0 -0
  48. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskcluster_taskgraph.egg-info/top_level.txt +0 -0
  49. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/__init__.py +0 -0
  50. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/add_new_jobs.py +0 -0
  51. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/cancel.py +0 -0
  52. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/cancel_all.py +0 -0
  53. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/rebuild_cached_tasks.py +0 -0
  54. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/registry.py +0 -0
  55. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/actions/util.py +0 -0
  56. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/config.py +0 -0
  57. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/create.py +0 -0
  58. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/docker.py +0 -0
  59. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/filter_tasks.py +0 -0
  60. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/generator.py +0 -0
  61. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/graph.py +0 -0
  62. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/loader/__init__.py +0 -0
  63. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/loader/default.py +0 -0
  64. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/loader/transform.py +0 -0
  65. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/optimize/__init__.py +0 -0
  66. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/optimize/base.py +0 -0
  67. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/run-task/fetch-content +0 -0
  68. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/run-task/hgrc +0 -0
  69. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/run-task/robustcheckout.py +0 -0
  70. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/run-task/run-task +0 -0
  71. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/target_tasks.py +0 -0
  72. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/task.py +0 -0
  73. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/taskgraph.py +0 -0
  74. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/__init__.py +0 -0
  75. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/base.py +0 -0
  76. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/cached_tasks.py +0 -0
  77. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/chunking.py +0 -0
  78. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/code_review.py +0 -0
  79. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/docker_image.py +0 -0
  80. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/fetch.py +0 -0
  81. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/notify.py +0 -0
  82. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/run/common.py +0 -0
  83. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/run/index_search.py +0 -0
  84. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/run/run_task.py +0 -0
  85. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/run/toolchain.py +0 -0
  86. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/transforms/task_context.py +0 -0
  87. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/__init__.py +0 -0
  88. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/archive.py +0 -0
  89. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/attributes.py +0 -0
  90. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/dependencies.py +0 -0
  91. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/docker.py +0 -0
  92. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/memoize.py +0 -0
  93. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/path.py +0 -0
  94. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/python_path.py +0 -0
  95. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/readonlydict.py +0 -0
  96. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/schema.py +0 -0
  97. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/shell.py +0 -0
  98. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/taskgraph.py +0 -0
  99. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/templates.py +0 -0
  100. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/time.py +0 -0
  101. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/treeherder.py +0 -0
  102. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/vcs.py +0 -0
  103. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/src/taskgraph/util/workertypes.py +0 -0
  104. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_actions_rebuild_cached_tasks.py +0 -0
  105. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_actions_registry.py +0 -0
  106. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_create.py +0 -0
  107. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_decision.py +0 -0
  108. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_generator.py +0 -0
  109. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_graph.py +0 -0
  110. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_optimize.py +0 -0
  111. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_scripts_fetch_content.py +0 -0
  112. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_scripts_run_task.py +0 -0
  113. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_target_tasks.py +0 -0
  114. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_taskgraph.py +0 -0
  115. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transform_chunking.py +0 -0
  116. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transform_docker_image.py +0 -0
  117. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transform_task_context.py +0 -0
  118. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_base.py +0 -0
  119. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_cached_tasks.py +0 -0
  120. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_fetch.py +0 -0
  121. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_notify.py +0 -0
  122. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_run.py +0 -0
  123. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_run_run_task.py +0 -0
  124. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_run_toolchain.py +0 -0
  125. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_transforms_task.py +0 -0
  126. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_archive.py +0 -0
  127. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_attributes.py +0 -0
  128. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_dependencies.py +0 -0
  129. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_docker.py +0 -0
  130. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_memoize.py +0 -0
  131. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_path.py +0 -0
  132. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_python_path.py +0 -0
  133. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_readonlydict.py +0 -0
  134. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_schema.py +0 -0
  135. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_templates.py +0 -0
  136. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_time.py +0 -0
  137. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_treeherder.py +0 -0
  138. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_verify.py +0 -0
  139. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.0.0}/test/test_util_workertypes.py +0 -0
  140. {taskcluster-taskgraph-7.3.1 → taskcluster-taskgraph-8.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: 7.3.1
3
+ Version: 8.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
@@ -58,5 +58,6 @@ exclude = [ # TODO fix errors in these files
58
58
  "src/taskgraph/util/taskcluster.py",
59
59
  "src/taskgraph/util/vcs.py",
60
60
  "src/taskgraph/util/workertypes.py",
61
+ "src/taskgraph/util/yaml.py",
61
62
  ]
62
63
  reportIncompatibleMethodOverride = false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: taskcluster-taskgraph
3
- Version: 7.3.1
3
+ Version: 8.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
@@ -20,7 +20,6 @@ src/taskgraph/config.py
20
20
  src/taskgraph/create.py
21
21
  src/taskgraph/decision.py
22
22
  src/taskgraph/docker.py
23
- src/taskgraph/files_changed.py
24
23
  src/taskgraph/filter_tasks.py
25
24
  src/taskgraph/generator.py
26
25
  src/taskgraph/graph.py
@@ -78,6 +77,7 @@ src/taskgraph/util/path.py
78
77
  src/taskgraph/util/python_path.py
79
78
  src/taskgraph/util/readonlydict.py
80
79
  src/taskgraph/util/schema.py
80
+ src/taskgraph/util/set_name.py
81
81
  src/taskgraph/util/shell.py
82
82
  src/taskgraph/util/taskcluster.py
83
83
  src/taskgraph/util/taskgraph.py
@@ -92,7 +92,6 @@ test/test_actions_rebuild_cached_tasks.py
92
92
  test/test_actions_registry.py
93
93
  test/test_create.py
94
94
  test/test_decision.py
95
- test/test_files_changed.py
96
95
  test/test_generator.py
97
96
  test/test_graph.py
98
97
  test/test_main.py
@@ -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__ = "7.3.1"
5
+ __version__ = "8.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
@@ -206,9 +206,7 @@ def rerun_action(parameters, graph_config, input, task_group_id, task_id):
206
206
  label = task["metadata"]["name"]
207
207
  if task_id not in label_to_taskid.values():
208
208
  logger.error(
209
- "Refusing to rerun {}: taskId {} not in decision task {} label_to_taskid!".format(
210
- label, task_id, decision_task_id
211
- )
209
+ f"Refusing to rerun {label}: taskId {task_id} not in decision task {decision_task_id} label_to_taskid!"
212
210
  )
213
211
 
214
212
  _rerun_task(task_id, label)
@@ -185,6 +185,7 @@ def get_decision_parameters(graph_config, options):
185
185
 
186
186
  # Define default filter list, as most configurations shouldn't need
187
187
  # custom filters.
188
+ parameters["files_changed"] = repo.get_changed_files("AM")
188
189
  parameters["filters"] = [
189
190
  "target_tasks_method",
190
191
  ]
@@ -121,7 +121,7 @@ def get_taskgraph_generator(root, parameters):
121
121
  return TaskGraphGenerator(root_dir=root, parameters=parameters)
122
122
 
123
123
 
124
- def format_taskgraph(options, parameters, logfile=None):
124
+ def format_taskgraph(options, parameters, overrides, logfile=None):
125
125
  import taskgraph
126
126
  from taskgraph.parameters import parameters_loader
127
127
 
@@ -139,7 +139,7 @@ def format_taskgraph(options, parameters, logfile=None):
139
139
  if isinstance(parameters, str):
140
140
  parameters = parameters_loader(
141
141
  parameters,
142
- overrides={"target-kinds": options.get("target_kinds")},
142
+ overrides=overrides,
143
143
  strict=False,
144
144
  )
145
145
 
@@ -173,7 +173,7 @@ def dump_output(out, path=None, params_spec=None):
173
173
  print(out + "\n", file=fh)
174
174
 
175
175
 
176
- def generate_taskgraph(options, parameters, logdir):
176
+ def generate_taskgraph(options, parameters, overrides, logdir):
177
177
  from taskgraph.parameters import Parameters
178
178
 
179
179
  def logfile(spec):
@@ -189,14 +189,16 @@ def generate_taskgraph(options, parameters, logdir):
189
189
  # tracebacks a little more readable and avoids additional process overhead.
190
190
  if len(parameters) == 1:
191
191
  spec = parameters[0]
192
- out = format_taskgraph(options, spec, logfile(spec))
192
+ out = format_taskgraph(options, spec, overrides, logfile(spec))
193
193
  dump_output(out, options["output_file"])
194
194
  return 0
195
195
 
196
196
  futures = {}
197
197
  with ProcessPoolExecutor(max_workers=options["max_workers"]) as executor:
198
198
  for spec in parameters:
199
- f = executor.submit(format_taskgraph, options, spec, logfile(spec))
199
+ f = executor.submit(
200
+ format_taskgraph, options, spec, overrides, logfile(spec)
201
+ )
200
202
  futures[f] = spec
201
203
 
202
204
  returncode = 0
@@ -293,6 +295,15 @@ def generate_taskgraph(options, parameters, logdir):
293
295
  "generations will happen from the same invocation (one per parameters "
294
296
  "specified).",
295
297
  )
298
+ @argument(
299
+ "--force-local-files-changed",
300
+ default=False,
301
+ action="store_true",
302
+ help="Compute the 'files-changed' parameter from local version control, "
303
+ "even when explicitly using a parameter set that already has it defined. "
304
+ "Note that this is already the default behaviour when no parameters are "
305
+ "specified.",
306
+ )
296
307
  @argument(
297
308
  "--no-optimize",
298
309
  dest="optimize",
@@ -367,9 +378,11 @@ def show_taskgraph(options):
367
378
  diffdir = None
368
379
  output_file = options["output_file"]
369
380
 
370
- if options["diff"]:
381
+ if options["diff"] or options["force_local_files_changed"]:
371
382
  repo = get_repository(os.getcwd())
372
383
 
384
+ if options["diff"]:
385
+ assert repo is not None
373
386
  if not repo.working_directory_clean():
374
387
  print(
375
388
  "abort: can't diff taskgraph with dirty working directory",
@@ -393,15 +406,22 @@ def show_taskgraph(options):
393
406
  )
394
407
  print(f"Generating {options['graph_attr']} @ {cur_rev}", file=sys.stderr)
395
408
 
409
+ overrides = {
410
+ "target-kinds": options.get("target_kinds"),
411
+ }
396
412
  parameters: List[Any[str, Parameters]] = options.pop("parameters")
397
413
  if not parameters:
398
- overrides = {
399
- "target-kinds": options.get("target_kinds"),
400
- }
401
414
  parameters = [
402
415
  parameters_loader(None, strict=False, overrides=overrides)
403
416
  ] # will use default values
404
417
 
418
+ # This is the default behaviour anyway, so no need to re-compute.
419
+ options["force_local_files_changed"] = False
420
+
421
+ elif options["force_local_files_changed"]:
422
+ assert repo is not None
423
+ overrides["files-changed"] = sorted(repo.get_changed_files("AM"))
424
+
405
425
  for param in parameters[:]:
406
426
  if isinstance(param, str) and os.path.isdir(param):
407
427
  parameters.remove(param)
@@ -427,7 +447,7 @@ def show_taskgraph(options):
427
447
  # to setup its `mach` based logging.
428
448
  setup_logging()
429
449
 
430
- ret = generate_taskgraph(options, parameters, logdir)
450
+ ret = generate_taskgraph(options, parameters, overrides, logdir)
431
451
 
432
452
  if options["diff"]:
433
453
  assert diffdir is not None
@@ -451,7 +471,7 @@ def show_taskgraph(options):
451
471
  diffdir, f"{options['graph_attr']}_{base_rev_file}"
452
472
  )
453
473
  print(f"Generating {options['graph_attr']} @ {base_rev}", file=sys.stderr)
454
- ret |= generate_taskgraph(options, parameters, logdir)
474
+ ret |= generate_taskgraph(options, parameters, overrides, logdir)
455
475
  finally:
456
476
  repo.update(cur_rev)
457
477
 
@@ -38,6 +38,7 @@ registered_morphs = []
38
38
 
39
39
  def register_morph(func):
40
40
  registered_morphs.append(func)
41
+ return func
41
42
 
42
43
 
43
44
  def amend_taskgraph(taskgraph, label_to_taskid, to_add):
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
  from datetime import datetime
3
3
 
4
- from taskgraph import files_changed
5
4
  from taskgraph.optimize.base import OptimizationStrategy, register_strategy
5
+ from taskgraph.util.path import match as match_path
6
6
  from taskgraph.util.taskcluster import find_task_id, status_task
7
7
 
8
8
  logger = logging.getLogger(__name__)
@@ -48,17 +48,23 @@ class IndexSearch(OptimizationStrategy):
48
48
 
49
49
  @register_strategy("skip-unless-changed")
50
50
  class SkipUnlessChanged(OptimizationStrategy):
51
+
52
+ def check(self, files_changed, patterns):
53
+ for pattern in patterns:
54
+ for path in files_changed:
55
+ if match_path(path, pattern):
56
+ return True
57
+ return False
58
+
51
59
  def should_remove_task(self, task, params, file_patterns):
52
60
  # pushlog_id == -1 - this is the case when run from a cron.yml job or on a git repository
53
61
  if params.get("repository_type") == "hg" and params.get("pushlog_id") == -1:
54
62
  return False
55
63
 
56
- changed = files_changed.check(params, file_patterns)
64
+ changed = self.check(params["files_changed"], file_patterns)
57
65
  if not changed:
58
66
  logger.debug(
59
- 'no files found matching a pattern in `skip-unless-changed` for "{}"'.format(
60
- task.label
61
- )
67
+ f'no files found matching a pattern in `skip-unless-changed` for "{task.label}"'
62
68
  )
63
69
  return True
64
70
  return False
@@ -40,6 +40,7 @@ base_schema = Schema(
40
40
  Required("do_not_optimize"): [str],
41
41
  Required("enable_always_target"): Any(bool, [str]),
42
42
  Required("existing_tasks"): {str: str},
43
+ Required("files_changed"): [str],
43
44
  Required("filters"): [str],
44
45
  Required("head_ref"): str,
45
46
  Required("head_repository"): str,
@@ -86,6 +87,7 @@ def _get_defaults(repo_root=None):
86
87
  # Use fake values if no repo is detected.
87
88
  repo = Mock(branch="", head_rev="", tool="git")
88
89
  repo.get_url.return_value = ""
90
+ repo.get_changed_files.return_value = []
89
91
 
90
92
  try:
91
93
  repo_url = repo.get_url()
@@ -108,6 +110,7 @@ def _get_defaults(repo_root=None):
108
110
  "do_not_optimize": [],
109
111
  "enable_always_target": True,
110
112
  "existing_tasks": {},
113
+ "files_changed": repo.get_changed_files("AM"),
111
114
  "filters": ["target_tasks_method"],
112
115
  "head_ref": repo.branch or repo.head_rev,
113
116
  "head_repository": repo_url,
@@ -20,6 +20,7 @@ from taskgraph.transforms.run import fetches_schema
20
20
  from taskgraph.util.attributes import attrmatch
21
21
  from taskgraph.util.dependencies import GROUP_BY_MAP, get_dependencies
22
22
  from taskgraph.util.schema import Schema, validate_schema
23
+ from taskgraph.util.set_name import SET_NAME_MAP
23
24
 
24
25
  FROM_DEPS_SCHEMA = Schema(
25
26
  {
@@ -41,12 +42,14 @@ FROM_DEPS_SCHEMA = Schema(
41
42
  "set-name",
42
43
  description=dedent(
43
44
  """
44
- When True, `from_deps` will derive a name for the generated
45
- tasks from the name of the primary dependency. Defaults to
46
- True.
45
+ UPDATE ME AND DOCS
47
46
  """.lstrip()
48
47
  ),
49
- ): bool,
48
+ ): Any(
49
+ None,
50
+ *SET_NAME_MAP,
51
+ {Any(*SET_NAME_MAP): object},
52
+ ),
50
53
  Optional(
51
54
  "with-attributes",
52
55
  description=dedent(
@@ -170,7 +173,7 @@ def from_deps(config, tasks):
170
173
  groups = func(config, deps)
171
174
 
172
175
  # Split the task, one per group.
173
- set_name = from_deps.get("set-name", True)
176
+ set_name = from_deps.get("set-name", "strip-kind")
174
177
  copy_attributes = from_deps.get("copy-attributes", False)
175
178
  unique_kinds = from_deps.get("unique-kinds", True)
176
179
  fetches = from_deps.get("fetches", [])
@@ -203,10 +206,8 @@ def from_deps(config, tasks):
203
206
  primary_dep = [dep for dep in group if dep.kind == primary_kind][0]
204
207
 
205
208
  if set_name:
206
- if primary_dep.label.startswith(primary_kind):
207
- new_task["name"] = primary_dep.label[len(primary_kind) + 1 :]
208
- else:
209
- new_task["name"] = primary_dep.label
209
+ func = SET_NAME_MAP[set_name]
210
+ new_task["name"] = func(config, deps, primary_dep, primary_kind)
210
211
 
211
212
  if copy_attributes:
212
213
  attrs = new_task.setdefault("attributes", {})
@@ -403,11 +403,7 @@ def run_task_using(worker_implementation, run_using, schema=None, defaults={}):
403
403
  for_run_using = registry.setdefault(run_using, {})
404
404
  if worker_implementation in for_run_using:
405
405
  raise Exception(
406
- "run_task_using({!r}, {!r}) already exists: {!r}".format(
407
- run_using,
408
- worker_implementation,
409
- for_run_using[worker_implementation],
410
- )
406
+ f"run_task_using({run_using!r}, {worker_implementation!r}) already exists: {for_run_using[worker_implementation]!r}"
411
407
  )
412
408
  for_run_using[worker_implementation] = (func, schema, defaults)
413
409
  return func
@@ -1153,9 +1153,9 @@ def build_task(config, tasks):
1153
1153
  config.params["project"] + th_project_suffix, branch_rev
1154
1154
  )
1155
1155
  )
1156
- task_def["metadata"]["description"] += " ([Treeherder push]({}))".format(
1157
- th_push_link
1158
- )
1156
+ task_def["metadata"][
1157
+ "description"
1158
+ ] += f" ([Treeherder push]({th_push_link}))"
1159
1159
 
1160
1160
  # add the payload and adjust anything else as required (e.g., scopes)
1161
1161
  payload_builders[task["worker"]["implementation"]].builder(
@@ -7,9 +7,7 @@ import hashlib
7
7
  import time
8
8
 
9
9
  TARGET_CACHE_INDEX = "{cache_prefix}.cache.level-{level}.{type}.{name}.hash.{digest}"
10
- TARGET_PR_CACHE_INDEX = (
11
- "{cache_prefix}.cache.head.{head_ref}.{type}.{name}.hash.{digest}"
12
- )
10
+ TARGET_PR_CACHE_INDEX = "{cache_prefix}.cache.pr.{type}.{name}.hash.{digest}"
13
11
  EXTRA_CACHE_INDEXES = [
14
12
  "{cache_prefix}.cache.level-{level}.{type}.{name}.latest",
15
13
  "{cache_prefix}.cache.level-{level}.{type}.{name}.pushdate.{build_date_long}",
@@ -39,10 +39,7 @@ def hash_paths(base_path, patterns):
39
39
  raise Exception("%s did not match anything" % pattern)
40
40
  for path in sorted(found):
41
41
  h.update(
42
- "{} {}\n".format(
43
- hash_path(mozpath.abspath(mozpath.join(base_path, path))),
44
- mozpath.normsep(path),
45
- ).encode("utf-8")
42
+ f"{hash_path(mozpath.abspath(mozpath.join(base_path, path)))} {mozpath.normsep(path)}\n".encode()
46
43
  )
47
44
  return h.hexdigest()
48
45
 
@@ -91,7 +91,5 @@ def evaluate_keyed_by(
91
91
  continue
92
92
 
93
93
  raise Exception(
94
- "No {} matching {!r} nor 'default' found while determining item {}".format(
95
- keyed_by, key, item_name
96
- )
94
+ f"No {keyed_by} matching {key!r} nor 'default' found while determining item {item_name}"
97
95
  )
@@ -83,12 +83,11 @@ def resolve_task_references(label, task_def, task_id, decision_task_id, dependen
83
83
  f"task '{label}' has no dependency named '{dependency}'"
84
84
  )
85
85
 
86
- assert artifact_name.startswith(
87
- "public/"
88
- ), "artifact-reference only supports public artifacts, not `{}`".format(
89
- artifact_name
90
- )
91
- return get_artifact_url(task_id, artifact_name)
86
+ use_proxy = False
87
+ if not artifact_name.startswith("public/"):
88
+ use_proxy = True
89
+
90
+ return get_artifact_url(task_id, artifact_name, use_proxy=use_proxy)
92
91
 
93
92
  return ARTIFACT_REFERENCE_PATTERN.sub(repl, val)
94
93
 
@@ -0,0 +1,34 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
+
5
+ # Define a collection of set_name functions
6
+ # Note: this is stored here instead of where it is used in the `from_deps`
7
+ # transform to give consumers a chance to register their own `set_name`
8
+ # handlers before the `from_deps` schema is created.
9
+ SET_NAME_MAP = {}
10
+
11
+
12
+ def set_name(name, schema=None):
13
+ def wrapper(func):
14
+ assert (
15
+ name not in SET_NAME_MAP
16
+ ), f"duplicate set_name function name {name} ({func} and {SET_NAME_MAP[name]})"
17
+ SET_NAME_MAP[name] = func
18
+ func.schema = schema
19
+ return func
20
+
21
+ return wrapper
22
+
23
+
24
+ @set_name("strip-kind")
25
+ def set_name_strip_kind(config, tasks, primary_dep, primary_kind):
26
+ if primary_dep.label.startswith(primary_kind):
27
+ return primary_dep.label[len(primary_kind) + 1 :]
28
+ else:
29
+ return primary_dep.label
30
+
31
+
32
+ @set_name("retain-kind")
33
+ def set_name_retain_kind(config, tasks, primary_dep, primary_kind):
34
+ return primary_dep.label
@@ -3,6 +3,7 @@
3
3
  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
4
 
5
5
 
6
+ import copy
6
7
  import datetime
7
8
  import functools
8
9
  import logging
@@ -139,22 +140,9 @@ def _handle_artifact(path, response):
139
140
 
140
141
  def get_artifact_url(task_id, path, use_proxy=False):
141
142
  artifact_tmpl = liburls.api(
142
- get_root_url(False), "queue", "v1", "task/{}/artifacts/{}"
143
+ get_root_url(use_proxy), "queue", "v1", "task/{}/artifacts/{}"
143
144
  )
144
- data = artifact_tmpl.format(task_id, path)
145
- if use_proxy:
146
- # Until Bug 1405889 is deployed, we can't download directly
147
- # from the taskcluster-proxy. Work around by using the /bewit
148
- # endpoint instead.
149
- # The bewit URL is the body of a 303 redirect, which we don't
150
- # want to follow (which fetches a potentially large resource).
151
- response = _do_request(
152
- os.environ["TASKCLUSTER_PROXY_URL"] + "/bewit",
153
- data=data,
154
- allow_redirects=False,
155
- )
156
- return response.text
157
- return data
145
+ return artifact_tmpl.format(task_id, path)
158
146
 
159
147
 
160
148
  def get_artifact(task_id, path, use_proxy=False):
@@ -247,6 +235,7 @@ def get_task_url(task_id, use_proxy=False):
247
235
  return task_tmpl.format(task_id)
248
236
 
249
237
 
238
+ @memoize
250
239
  def get_task_definition(task_id, use_proxy=False):
251
240
  response = _do_request(get_task_url(task_id, use_proxy))
252
241
  return response.json()
@@ -372,13 +361,14 @@ def list_task_group_incomplete_tasks(task_group_id):
372
361
  break
373
362
 
374
363
 
364
+ @memoize
375
365
  def _get_deps(task_ids, use_proxy):
376
366
  upstream_tasks = {}
377
367
  for task_id in task_ids:
378
368
  task_def = get_task_definition(task_id, use_proxy)
379
369
  upstream_tasks[task_def["metadata"]["name"]] = task_id
380
370
 
381
- upstream_tasks.update(_get_deps(task_def["dependencies"], use_proxy))
371
+ upstream_tasks.update(_get_deps(tuple(task_def["dependencies"]), use_proxy))
382
372
 
383
373
  return upstream_tasks
384
374
 
@@ -403,6 +393,6 @@ def get_ancestors(
403
393
  for task_id in task_ids:
404
394
  task_def = get_task_definition(task_id, use_proxy)
405
395
 
406
- upstream_tasks.update(_get_deps(task_def["dependencies"], use_proxy))
396
+ upstream_tasks.update(_get_deps(tuple(task_def["dependencies"]), use_proxy))
407
397
 
408
- return upstream_tasks
398
+ return copy.deepcopy(upstream_tasks)
@@ -173,9 +173,7 @@ def verify_trust_domain_v2_routes(
173
173
  if route.startswith(route_prefix):
174
174
  if route in scratch_pad:
175
175
  raise Exception(
176
- "conflict between {}:{} for route: {}".format(
177
- task.label, scratch_pad[route], route
178
- )
176
+ f"conflict between {task.label}:{scratch_pad[route]} for route: {route}"
179
177
  )
180
178
  else:
181
179
  scratch_pad[route] = task.label
@@ -231,12 +229,7 @@ def verify_dependency_tiers(task, taskgraph, scratch_pad, graph_config, paramete
231
229
  continue
232
230
  if tier < tiers[d]:
233
231
  raise Exception(
234
- "{} (tier {}) cannot depend on {} (tier {})".format(
235
- task.label,
236
- printable_tier(tier),
237
- d,
238
- printable_tier(tiers[d]),
239
- )
232
+ f"{task.label} (tier {printable_tier(tier)}) cannot depend on {d} (tier {printable_tier(tiers[d])})"
240
233
  )
241
234
 
242
235
 
@@ -5,7 +5,10 @@
5
5
 
6
6
  import os
7
7
 
8
- from yaml.loader import SafeLoader
8
+ try:
9
+ from yaml import CSafeLoader as SafeLoader
10
+ except ImportError:
11
+ from yaml import SafeLoader
9
12
 
10
13
 
11
14
  class UnicodeLoader(SafeLoader):
@@ -2,6 +2,7 @@
2
2
  # http://creativecommons.org/publicdomain/zero/1.0/
3
3
 
4
4
  import os
5
+ import sys
5
6
  from pathlib import Path
6
7
  from textwrap import dedent
7
8
 
@@ -48,7 +49,7 @@ def run_taskgraph(maketgg, monkeypatch):
48
49
  ("morphed", ["_fake-t-0", "_fake-t-1"]),
49
50
  ),
50
51
  )
51
- def test_show_taskgraph(run_taskgraph, capsys, attr, expected):
52
+ def test_show_taskgraph_attr(run_taskgraph, capsys, attr, expected):
52
53
  res = run_taskgraph([attr])
53
54
  assert res == 0
54
55
 
@@ -72,6 +73,34 @@ def test_show_taskgraph_parallel(run_taskgraph):
72
73
  assert res == 1
73
74
 
74
75
 
76
+ def test_show_taskgraph_force_local_files_changed(mocker, run_taskgraph):
77
+ repo = mocker.MagicMock()
78
+ repo.get_changed_files.return_value = ["foo.txt"]
79
+
80
+ m = mocker.MagicMock()
81
+ m.get_repository.return_value = repo
82
+ mocker.patch.dict(sys.modules, {"taskgraph.util.vcs": m})
83
+
84
+ res = run_taskgraph(["full"])
85
+ assert res == 0
86
+ assert not repo.get_changed_files.called
87
+
88
+ res = run_taskgraph(["full", "--force-local-files-changed"])
89
+ assert res == 0
90
+ assert not repo.get_changed_files.called
91
+
92
+ res = run_taskgraph(
93
+ [
94
+ "full",
95
+ "--force-local-files-changed",
96
+ "-p",
97
+ "taskcluster/test/params/mc-onpush.yml",
98
+ ]
99
+ )
100
+ assert res == 0
101
+ assert repo.get_changed_files.call_count == 1
102
+
103
+
75
104
  def test_tasks_regex(run_taskgraph, capsys):
76
105
  run_taskgraph(["full", "--tasks=_.*-t-1"])
77
106
  out, _ = capsys.readouterr()
@@ -82,6 +82,7 @@ def test_register_morph(monkeypatch, make_taskgraph):
82
82
  label_to_taskid["count"] += 1
83
83
  return taskgraph, label_to_taskid
84
84
 
85
+ assert callable(fake_morph)
85
86
  assert label_to_taskid == {}
86
87
  morph.morph(taskgraph, label_to_taskid, None, None)
87
88
  assert label_to_taskid == {"count": 1}
@@ -3,11 +3,12 @@
3
3
 
4
4
  import os
5
5
  from datetime import datetime
6
+ from test.fixtures.gen import make_task
6
7
  from time import mktime
7
8
 
8
9
  import pytest
9
10
 
10
- from taskgraph.optimize.strategies import IndexSearch
11
+ from taskgraph.optimize.strategies import IndexSearch, SkipUnlessChanged
11
12
 
12
13
 
13
14
  @pytest.fixture
@@ -68,3 +69,34 @@ def test_index_search(responses, params, state, expires, expected):
68
69
  opt = IndexSearch()
69
70
  deadline = "2021-06-07T19:03:20.482Z"
70
71
  assert opt.should_replace_task({}, params, deadline, (index_path,)) == expected
72
+
73
+
74
+ @pytest.mark.parametrize(
75
+ "params,file_patterns,should_optimize",
76
+ (
77
+ pytest.param({"files_changed": []}, ["foo.txt"], True, id="no files changed"),
78
+ pytest.param(
79
+ {"files_changed": ["foo.txt"]}, ["foo.txt"], False, id="files match"
80
+ ),
81
+ pytest.param(
82
+ {"files_changed": ["foo.txt"]},
83
+ ["bar.tx", "foo.txt"],
84
+ False,
85
+ id="files match multiple",
86
+ ),
87
+ pytest.param(
88
+ {"files_changed": ["bar.txt"]}, ["foo.txt"], True, id="files don't match"
89
+ ),
90
+ pytest.param(
91
+ {"repository_type": "hg", "pushlog_id": -1, "files_changed": ["bar.txt"]},
92
+ ["foo.txt"],
93
+ False,
94
+ id="cron task",
95
+ ),
96
+ ),
97
+ )
98
+ def test_skip_unless_changed(params, file_patterns, should_optimize):
99
+ task = make_task("task")
100
+
101
+ opt = SkipUnlessChanged()
102
+ assert opt.should_remove_task(task, params, file_patterns) == should_optimize