Last active
November 17, 2023 21:03
-
-
Save flipdazed/0e2ce987ffa179fe9944ac32db469250 to your computer and use it in GitHub Desktop.
Lists all issues that are not assigned to a project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script lists all the open issues in specified owner's repository or all repositories if no specific one is given. | |
# The mandatory parameter is -o (owner) and optional parameters are -r (repository) and -c (cache time). | |
# If no repository(-r) is mentioned, it fetches issues from all repositories of that owner. | |
# It also caches results of recently fetched project issues based on cache_time (-c). The default cache_time is 3600 seconds if not passed. | |
# After fetching all issues, it finds the difference between all_issues and issue_details to get issues not allocated to any project. | |
# Usage: ./script_name.sh -o [owner] -r [repository] -c [cache_time] | |
# Example: ./script_name.sh -o Microsoft -r vscode -c 5000 | |
# Be very careful of Case! | |
owner="" | |
# Flag to check if owner parameter is passed | |
owner_flag=false | |
# Default repository | |
repo="" | |
# Check for optional parameters | |
while getopts r:c:o: flag | |
do | |
case "${flag}" in | |
r) repo=${OPTARG};; | |
c) cache_time=${OPTARG};; | |
o) owner=${OPTARG}; owner_flag=true;; | |
esac | |
done | |
# If no owner (-o) is supplied, print error message and exit | |
if ! $owner_flag | |
then | |
echo "Error: Owner (-o) is mandatory!" | |
exit 1 | |
fi | |
# ID array to store all issue numbers | |
if [ -z "$repo" ] | |
then | |
# If no repository is specified, search all owner's repositories | |
all_issues=($(gh search issues -L 500 --state open --owner $owner --json number,repository | jq -c '.[]')) | |
else | |
# If a repository is specified, restrict the search to that repository | |
all_issues=($(gh search issues -R $repo -L 500 --state open --owner $owner --json number,repository | jq -c '.[]')) | |
fi | |
# Your existing script to get project-allocated issues starts here | |
# Array to store issues that are allocated to projects | |
# echo 'Getting all issues assigned to project...' | |
project_issue_details=() | |
cache_dir=".cache" | |
mkdir -p "$cache_dir" # Make sure the cache directory exists | |
# Set default cache time if not set | |
if [ -z "$cache_time" ] | |
then | |
cache_time=3600 | |
fi | |
project_numbers=($(gh project list --owner $owner --format json --closed | jq '.projects[].number')) | |
for project_number in "${project_numbers[@]}" | |
do | |
cache_file="$cache_dir/project_${project_number}_issues" | |
if [ -f "$cache_file" ]; then | |
# The cache file exists: check it hasn't expired | |
file_time=$(stat -f "%m" "$cache_file") | |
curr_time=$(date +%s) | |
if [ $(($curr_time - $file_time)) -le $cache_time ]; then | |
# Cache valid, use cached data | |
issue_details=($(cat "$cache_file")) | |
else | |
# echo "Cache expired. Fetching issues for Project: #${project_number}" | |
_issue_numbers=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.number')) | |
_issue_repo=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.repository')) | |
# Get the length of one of the arrays | |
length=${#_issue_numbers[@]} | |
# Initialize an empty array | |
declare -a issue_details | |
# Combine elements from both arrays | |
for ((i=0; i<$length; i++)); do | |
issue_details+=("${_issue_repo[$i]//\"}#${_issue_numbers[$i]}") | |
done | |
echo "${issue_details[@]}" > "$cache_file" | |
fi | |
else | |
# No cache exists: fetch data and store in cache | |
_issue_numbers=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.number')) | |
_issue_repo=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.repository')) | |
# Get the length of one of the arrays | |
length=${#_issue_numbers[@]} | |
# Initialize an empty array | |
declare -a issue_details | |
# Combine elements from both arrays | |
for ((i=0; i<$length; i++)); do | |
issue_details+=("${_issue_repo[$i]//\"}#${_issue_numbers[$i]}") | |
done | |
echo "${issue_details[@]}" > "$cache_file" | |
fi | |
# Extend the array | |
project_issue_details+=("${issue_details[@]}") | |
done | |
# Find the difference between all_issues and issue_details to get issues not allocated to any project | |
echo | |
echo "Issues in ${repo} not allocated to any project:" | |
for i in "${all_issues[@]}"; do | |
# Parse issue number and repository name from the JSON | |
issue_number=$(echo "$i" | jq '.number') | |
issue_repo=$(echo "$i" | jq -r '.repository.name') | |
skip= | |
for j in "${project_issue_details[@]}"; do | |
# project_issue_number=$(echo "$j" | jq '.content.number') | |
# project_issue_repo=$(echo "$j" | jq -r '.content.repository') | |
[[ $issue_repo != $repo ]] && { | |
skip=1 | |
break | |
} | |
[[ $j == "$owner/$issue_repo#$issue_number" ]] && { | |
skip=1 | |
break | |
} | |
done | |
[[ -n $skip ]] || { | |
# Get the issue title and URL using the GitHub API | |
issue_info=$(gh api repos/$owner/$issue_repo/issues/$issue_number --jq '.title, .html_url') | |
# Parse the response to get the title and URL | |
issue_title=$(echo "$issue_info" | awk 'NR==1') | |
issue_url=$(echo "$issue_info" | awk 'NR==2') | |
# Print a markdown formatted hyperlink | |
echo "* \`$owner/$issue_repo#$issue_number\`: [$issue_title]($issue_url)" | |
} | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment