Skip to content

Commit

Permalink
add sort-with-dependency-tree.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Jul 11, 2024
1 parent 06b1db0 commit ef1fcd1
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
76 changes: 76 additions & 0 deletions ci/sort-with-dependency-tree.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Source this file.
#
# Sorts a provided list of manifest paths according to their position in the
# workspace dependency tree.

sort_with_dependency_tree() {
# Input list of manifest paths
local manifest_paths=("$@")

# Generate the dependency graph using cargo metadata
local metadata
metadata=$(cargo metadata --no-deps --format-version 1)
local sorted_manifests=()

# Function to get dependencies for a given package
get_dependencies() {
local package_name=$1
echo "$metadata" | jq -r --arg package_name "$package_name" '.packages[] | select(.name == $package_name) | .dependencies[].name'
}

# Topological sort function
topological_sort() {
local visited=()
local temp_visited=()
local stack=()

visit() {
local pkg=$1
if [[ " ${temp_visited[*]} " =~ " ${pkg} " ]]; then
echo "Cyclic dependency detected!" >&2
exit 1
fi

if [[ ! " ${visited[*]} " =~ " ${pkg} " ]]; then
temp_visited+=("$pkg")
local deps
deps=$(get_dependencies "$pkg")
for dep in $deps; do
visit "$dep"
done
visited+=("$pkg")
temp_visited=(${temp_visited[@]/$pkg})
stack+=("$pkg")
fi
}

for file in "${manifest_paths[@]}"; do
local package_name
package_name=$(grep -E '^name\s*=' "$file" | sed -E 's/name\s*=\s*"(.*)"/\1/')
visit "$package_name"
done

sorted_manifests=("${stack[@]}")
}

# Perform topological sort
topological_sort

# Map sorted package names back to their manifest paths
local final_sorted_manifests=()
for pkg in "${sorted_manifests[@]}"; do
for file in "${manifest_paths[@]}"; do
local package_name
package_name=$(grep -E '^name\s*=' "$file" | sed -E 's/name\s*=\s*"(.*)"/\1/')
if [ "$pkg" == "$package_name" ]; then
final_sorted_manifests+=("$file")
fi
done
done

# Return the sorted list of manifest paths
echo "${final_sorted_manifests[@]}"
}

# Export the function so it can be used in other scripts
export -f sort_with_dependency_tree
20 changes: 20 additions & 0 deletions ci/test-sort.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

# Source the sort-with-dependency-tree.sh script
source ci/sort-with-dependency-tree.sh

# List of manifest paths
manifest_paths=(
"token/program-2022/Cargo.toml"
"libraries/pod/Cargo.toml"
"token/transfer-hook/interface/Cargo.toml"
)

# Invoke the sourced function with the manifest paths
sorted=$(sort_with_dependency_tree "${manifest_paths[@]}")

# Print the sorted manifest paths
echo "Sorted manifest paths:"
for manifest_path in $sorted; do
echo "$manifest_path"
done

0 comments on commit ef1fcd1

Please sign in to comment.