|
@@ -11,13 +11,31 @@
|
|
#include <BuildTarget/Common/TestImpactBuildTargetException.h>
|
|
#include <BuildTarget/Common/TestImpactBuildTargetException.h>
|
|
#include <BuildTarget/Common/TestImpactBuildTargetList.h>
|
|
#include <BuildTarget/Common/TestImpactBuildTargetList.h>
|
|
|
|
|
|
|
|
+#include <AzCore/std/containers/queue.h>
|
|
|
|
+#include <AzCore/std/containers/stack.h>
|
|
#include <AzCore/std/containers/unordered_map.h>
|
|
#include <AzCore/std/containers/unordered_map.h>
|
|
#include <AzCore/std/containers/unordered_set.h>
|
|
#include <AzCore/std/containers/unordered_set.h>
|
|
|
|
+#include <AzCore/std/functional.h>
|
|
|
|
|
|
namespace TestImpact
|
|
namespace TestImpact
|
|
{
|
|
{
|
|
|
|
+ //! Result to return when visiting vertices in the build graph.
|
|
|
|
+ enum class BuildGraphVertexVisitResult : AZ::u8
|
|
|
|
+ {
|
|
|
|
+ Continue, //!< Continue traversing the build graph.
|
|
|
|
+ AbortBranchTraversal, //!< Abort traversal of this particular branch in the build graph.
|
|
|
|
+ AbortGraphTraversal //!< Abort traversal of the build graph.
|
|
|
|
+ };
|
|
|
|
+
|
|
template<typename ProductionTarget, typename TestTarget>
|
|
template<typename ProductionTarget, typename TestTarget>
|
|
struct BuildGraphVertex;
|
|
struct BuildGraphVertex;
|
|
|
|
+
|
|
|
|
+ //! Visitor callback for when traversing the build graphs.
|
|
|
|
+ //! @param vertex The current vertex to visit in the build graph.
|
|
|
|
+ //! @param distance The distance of this vertex to the root build target in the build graph.
|
|
|
|
+ //! @returns The traversal result for the build graph to act upon.
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ using BuildGraphVertexVisitor = AZStd::function<BuildGraphVertexVisitResult(const BuildGraphVertex<ProductionTarget, TestTarget>& vertex, size_t distance)>;
|
|
|
|
|
|
//! Build graph target set for dependencies or dependers.
|
|
//! Build graph target set for dependencies or dependers.
|
|
template<typename ProductionTarget, typename TestTarget>
|
|
template<typename ProductionTarget, typename TestTarget>
|
|
@@ -59,8 +77,35 @@ namespace TestImpact
|
|
//! Returns the vertex for the specified build target, else throws `BuildTargetException`.
|
|
//! Returns the vertex for the specified build target, else throws `BuildTargetException`.
|
|
const BuildGraphVertex<ProductionTarget, TestTarget>& GetVertexOrThrow(
|
|
const BuildGraphVertex<ProductionTarget, TestTarget>& GetVertexOrThrow(
|
|
const BuildTarget<ProductionTarget, TestTarget>& buildTarget) const;
|
|
const BuildTarget<ProductionTarget, TestTarget>& buildTarget) const;
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ //! Walks the specified target's build dependencies.
|
|
|
|
+ void WalkBuildDependencies(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const;
|
|
|
|
+
|
|
|
|
+ //! Walks the specified target's build dependers.
|
|
|
|
+ void WalkBuildDependers(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const;
|
|
|
|
+
|
|
|
|
+ //! Walks the specified target's runtime dependencies.
|
|
|
|
+ void WalkRuntimeDependencies(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const;
|
|
|
|
+
|
|
|
|
+ //! Walks the specified target's runtime dependers.
|
|
|
|
+ void WalkRuntimeDependers(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const;
|
|
|
|
+
|
|
private:
|
|
private:
|
|
|
|
+ //! Generic function for walking the specified target's build grpah.
|
|
|
|
+ void WalkTargetBuildGraphSet(
|
|
|
|
+ TargetBuildGraph<ProductionTarget, TestTarget> BuildGraphVertex<ProductionTarget, TestTarget>::*graph,
|
|
|
|
+ TargetBuildGraphSet<ProductionTarget, TestTarget> TargetBuildGraph<ProductionTarget, TestTarget>::*set,
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const;
|
|
|
|
+
|
|
//! Map of all graph vertices, identified by build target.
|
|
//! Map of all graph vertices, identified by build target.
|
|
AZStd::unordered_map<BuildTarget<ProductionTarget, TestTarget>, BuildGraphVertex<ProductionTarget, TestTarget>>
|
|
AZStd::unordered_map<BuildTarget<ProductionTarget, TestTarget>, BuildGraphVertex<ProductionTarget, TestTarget>>
|
|
m_buildGraphVertices;
|
|
m_buildGraphVertices;
|
|
@@ -160,6 +205,101 @@ namespace TestImpact
|
|
|
|
|
|
return *vertex;
|
|
return *vertex;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ void BuildGraph<ProductionTarget, TestTarget>::WalkTargetBuildGraphSet(
|
|
|
|
+ TargetBuildGraph<ProductionTarget, TestTarget> BuildGraphVertex<ProductionTarget, TestTarget>::*graph,
|
|
|
|
+ TargetBuildGraphSet<ProductionTarget, TestTarget> TargetBuildGraph<ProductionTarget, TestTarget>::*set,
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const
|
|
|
|
+ {
|
|
|
|
+ AZStd::queue<const BuildGraphVertex<ProductionTarget, TestTarget>*> vertexQueue;
|
|
|
|
+ AZStd::unordered_set<const BuildGraphVertex<ProductionTarget, TestTarget>*> visitedVertices;
|
|
|
|
+ AZStd::unordered_map<const BuildGraphVertex<ProductionTarget, TestTarget>*, size_t> vertexDistances;
|
|
|
|
+
|
|
|
|
+ // Skip visiting the root vertex and start visiting its children instead
|
|
|
|
+ const auto& parentVertex = GetVertexOrThrow(buildTarget);
|
|
|
|
+ visitedVertices.insert(&parentVertex);
|
|
|
|
+ for (const auto* child : parentVertex.*graph.*set)
|
|
|
|
+ {
|
|
|
|
+ vertexQueue.push(child);
|
|
|
|
+ vertexDistances[child] = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ while (!vertexQueue.empty())
|
|
|
|
+ {
|
|
|
|
+ const auto* vertex = vertexQueue.front();
|
|
|
|
+ vertexQueue.pop();
|
|
|
|
+
|
|
|
|
+ if (const auto result = visitor(*vertex, vertexDistances[vertex]);
|
|
|
|
+ result == BuildGraphVertexVisitResult::AbortGraphTraversal)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ else if (result == BuildGraphVertexVisitResult::AbortBranchTraversal)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (const auto* child : vertex->*graph.*set)
|
|
|
|
+ {
|
|
|
|
+ if (!visitedVertices.contains(child))
|
|
|
|
+ {
|
|
|
|
+ visitedVertices.insert(child);
|
|
|
|
+ vertexQueue.push(child);
|
|
|
|
+ vertexDistances[child] = vertexDistances[vertex] + 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ void BuildGraph<ProductionTarget, TestTarget>::WalkBuildDependencies(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const
|
|
|
|
+ {
|
|
|
|
+ WalkTargetBuildGraphSet(
|
|
|
|
+ &BuildGraphVertex<ProductionTarget, TestTarget>::m_dependencies,
|
|
|
|
+ &TargetBuildGraph<ProductionTarget, TestTarget>::m_build,
|
|
|
|
+ buildTarget,
|
|
|
|
+ visitor);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ void BuildGraph<ProductionTarget, TestTarget>::WalkBuildDependers(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const
|
|
|
|
+ {
|
|
|
|
+ WalkTargetBuildGraphSet(
|
|
|
|
+ &BuildGraphVertex<ProductionTarget, TestTarget>::m_dependers,
|
|
|
|
+ &TargetBuildGraph<ProductionTarget, TestTarget>::m_build,
|
|
|
|
+ buildTarget,
|
|
|
|
+ visitor);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ void BuildGraph<ProductionTarget, TestTarget>::WalkRuntimeDependencies(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const
|
|
|
|
+ {
|
|
|
|
+ WalkTargetBuildGraphSet(
|
|
|
|
+ &BuildGraphVertex<ProductionTarget, TestTarget>::m_dependencies,
|
|
|
|
+ &TargetBuildGraph<ProductionTarget, TestTarget>::m_runtime,
|
|
|
|
+ buildTarget,
|
|
|
|
+ visitor);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<typename ProductionTarget, typename TestTarget>
|
|
|
|
+ void BuildGraph<ProductionTarget, TestTarget>::WalkRuntimeDependers(
|
|
|
|
+ const BuildTarget<ProductionTarget, TestTarget>& buildTarget,
|
|
|
|
+ const BuildGraphVertexVisitor<ProductionTarget, TestTarget>& visitor) const
|
|
|
|
+ {
|
|
|
|
+ WalkTargetBuildGraphSet(
|
|
|
|
+ &BuildGraphVertex<ProductionTarget, TestTarget>::m_dependers,
|
|
|
|
+ &TargetBuildGraph<ProductionTarget, TestTarget>::m_runtime,
|
|
|
|
+ buildTarget,
|
|
|
|
+ visitor);
|
|
|
|
+ }
|
|
} // namespace TestImpact
|
|
} // namespace TestImpact
|
|
|
|
|
|
namespace AZStd
|
|
namespace AZStd
|