From 7789d6d070f3491a9ae18913e57d787caf796731 Mon Sep 17 00:00:00 2001 From: Djuuu Date: Sun, 25 Feb 2024 17:55:48 +0100 Subject: [PATCH 1/3] mr menu status - add link to issue --- git-mr | 31 +++++++++++++++++++++++-------- test/git-mr.bats | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/git-mr b/git-mr index 7114fd5..796c9c8 100755 --- a/git-mr +++ b/git-mr @@ -1603,16 +1603,23 @@ mr_menu_contents() { mr_menu_print_title() { local issue_code=$1 - local menu_items=$2 - local current_index=$3 + local issue_title=$2 + local issue_url=$3 + local menu_items=$4 + local current_index=$5 local search_url; search_url="https://${GITLAB_DOMAIN}/dashboard/merge_requests?scope=all&state=all&search=$(urlencode "$issue_code")&in=title&sort=created_asc" local mr_count; mr_count=$(echo "$menu_items" | wc -l | tr -d ' ') echo "================================================================================" - [[ -z $current_index ]] && - echo " $(terminal_link "$search_url" "$issue_code") (${mr_count} merge request$([[ $mr_count -gt 1 ]] && echo 's'))" || - echo " $(terminal_link "$search_url" "$issue_code") (merge request ${current_index}/${mr_count})" + if [[ -n $issue_title ]] && [[ -n $issue_url ]]; then + echo " $(terminal_link "$search_url" "$issue_code") $(terminal_link "$issue_url" "$issue_title") (${mr_count} merge request$([[ $mr_count -gt 1 ]] && echo 's'))" + has_links || echolor " ⇒ $issue_url" "midgray" + else + [[ -z $current_index ]] && + echo " $(terminal_link "$search_url" "$issue_code") (${mr_count} merge request$([[ $mr_count -gt 1 ]] && echo 's'))" || + echo " $(terminal_link "$search_url" "$issue_code") (merge request ${current_index}/${mr_count})" + fi echo "================================================================================" } @@ -1620,8 +1627,16 @@ mr_menu_status() { local issue_code=$1 local menu_items=$2 + local issue_content issue_key issue_title issue_url + issue_content=$(jira_ticket_data "$issue_code") + eval "$(echo "$issue_content" | jq -r ' + "issue_key=" + (.key // empty | @sh) + ";\n" + + "issue_title=" + (.fields.summary // empty | @sh) + ";\n" + ')" + [[ -n $issue_title ]] && issue_url="https://${JIRA_INSTANCE}/browse/${issue_key}" + echo - mr_menu_print_title "$issue_code" "$menu_items" + mr_menu_print_title "$issue_code" "$issue_title" "$issue_url" "$menu_items" echo while IFS= read -r menu_item; do @@ -1668,7 +1683,7 @@ mr_menu_show() { local menu_items=$2 echo - mr_menu_print_title "$issue_code" "$menu_items" + mr_menu_print_title "$issue_code" "" "" "$menu_items" echo mr_menu_contents "$menu_items" @@ -1766,7 +1781,7 @@ mr_menu_update_all() { updated_description="$(mr_menu_replace_description "$mr_description" "$mr_menu_content")" clear_screen - mr_menu_print_title "$issue_code" "$menu_items" "$i" + mr_menu_print_title "$issue_code" "" "" "$menu_items" "$i" mr_menu_print_description "$updated_description" "$mr_url" "$mr_title" "$project_name" mr_update_data='{}' diff --git a/test/git-mr.bats b/test/git-mr.bats index 98d6723..6797e16 100644 --- a/test/git-mr.bats +++ b/test/git-mr.bats @@ -1658,8 +1658,13 @@ End" @test "Searches MRs across projects to build menu" { load "test_helper/gitlab-mock-menu.bash" - run mr_menu + run mr_menu XY-789 + assert_output "$(cat <<- EOF + No merge requests found for 'XY-789'. + EOF + )" + run mr_menu assert_output "$(cat <<- EOF ================================================================================ @@ -1677,6 +1682,33 @@ End" )" } +@test "Prints menu title" { + run mr_menu_print_title "AB-123" "" "" "$(echo -e "a\nb\nc")" + assert_output "$(cat <<- EOF + ================================================================================ + AB-123 (3 merge requests) + ================================================================================ + EOF + )" + + run mr_menu_print_title "AB-123" "" "" "$(echo -e "a\nb\nc")" 1 + assert_output "$(cat <<- EOF + ================================================================================ + AB-123 (merge request 1/3) + ================================================================================ + EOF + )" + + run mr_menu_print_title "AB-123" "My Issue" "https://example.com/AB-123" "$(echo -e "a\nb\nc")" + assert_output "$(cat <<- EOF + ================================================================================ + AB-123 My Issue (3 merge requests) + ⇒ https://example.com/AB-123 + ================================================================================ + EOF + )" +} + @test "Replaces menu in MR descriptions" { mr_description="# [AB-123 Test feature](https://example.net/AB-123) From a6672e0caa0e128dc0da697f926933c8972d1f21 Mon Sep 17 00:00:00 2001 From: Djuuu Date: Sun, 25 Feb 2024 22:17:30 +0100 Subject: [PATCH 2/3] mr menu status - add test --- test/git-mr.bats | 44 +++++++++++++- test/test_helper/gitlab-mock-menu.bash | 80 ++++++++++++++++++++++++-- 2 files changed, 116 insertions(+), 8 deletions(-) diff --git a/test/git-mr.bats b/test/git-mr.bats index 6797e16..fb86e2a 100644 --- a/test/git-mr.bats +++ b/test/git-mr.bats @@ -1673,9 +1673,9 @@ End" ## Menu - * Project C: [MR 31 title](https://example.net/31) - * Project A: [MR 11 title](https://example.net/11) - * Project B: [MR 21 title](https://example.net/21) + * Project C: [MR 31 title](https://gitlab.example.net/proj-C/-/merge_requests/31) + * Project A: [MR 11 title](https://gitlab.example.net/proj-A/-/merge_requests/11) + * Project B: [MR 21 title](https://gitlab.example.net/proj-B/-/merge_requests/21) -------------------------------------------------------------------------------- EOF @@ -1709,6 +1709,44 @@ End" )" } +@test "Prints menu status" { + load "test_helper/gitlab-mock-menu.bash" + load "test_helper/jira-mock.bash" + + run mr_menu_status "AB-123" "$(mr_menu_merge_requests "AB-123")" + assert_output "$(cat <<-EOF + + ================================================================================ + AB-123 This is an issue (3 merge requests) + ⇒ https://mycompany.example.net/browse/AB-123 + ================================================================================ + + * Project C: MR 31 title + ⇒ https://gitlab.example.net/proj-C/-/merge_requests/31 + + 🏷 [Accepted] (↣ main) + + 👍 3 👎 0 CI: ⏰ Can be merged: ✔ + + + * Project A: MR 11 title + ⇒ https://gitlab.example.net/proj-A/-/merge_requests/11 + + 🏷 [QA] (↣ main) + + 👍 2 👎 0 CI: ⏱ Can be merged: ✔ + + + * Project B: MR 21 title + ⇒ https://gitlab.example.net/proj-B/-/merge_requests/21 + + 🏷 [Review] (↣ main) + + 👍 0 👎 1 CI: ❌ Can be merged: ❌ + EOF + )" +} + @test "Replaces menu in MR descriptions" { mr_description="# [AB-123 Test feature](https://example.net/AB-123) diff --git a/test/test_helper/gitlab-mock-menu.bash b/test/test_helper/gitlab-mock-menu.bash index aad7052..777fcf9 100644 --- a/test/test_helper/gitlab-mock-menu.bash +++ b/test/test_helper/gitlab-mock-menu.bash @@ -1,16 +1,32 @@ gitlab_request() { + local f="gitlab_request " case "$1" in "merge_requests?scope=all&state=all&view=simple&search=AB-123"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log echo '[ - {"iid": 31,"title":"MR 31 title","web_url":"https://example.net/31","state":"opened","project_id": 3}, - {"iid": 11,"title":"MR 11 title","web_url":"https://example.net/11","state":"opened","project_id": 1}, - {"iid": 21,"title":"MR 21 title","web_url":"https://example.net/21","state":"opened","project_id": 2}, - {"iid": 41,"title":"MR 41 title","web_url":"https://example.net/21","state":"closed","project_id": 4} + {"iid": 31,"title":"MR 31 title","web_url":"https://'${GITLAB_DOMAIN}'/proj-C/-/merge_requests/31","state":"opened", "project_id": 3}, + {"iid": 11,"title":"MR 11 title","web_url":"https://'${GITLAB_DOMAIN}'/proj-A/-/merge_requests/11","state":"opened", "project_id": 1}, + {"iid": 21,"title":"MR 21 title","web_url":"https://'${GITLAB_DOMAIN}'/proj-B/-/merge_requests/21","state":"opened", "project_id": 2}, + {"iid": 41,"title":"MR 41 title","web_url":"https://'${GITLAB_DOMAIN}'/proj-D/-/merge_requests/41","state":"closed", "project_id": 4} ]' ;; + "projects/proj-A/merge_requests/11/discussions"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log; + echo '[]'; ;; + "projects/proj-B/merge_requests/21/discussions"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log; + echo '[]'; ;; + "projects/proj-C/merge_requests/31/discussions"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log; + echo '[]'; ;; + "projects/proj-D/merge_requests/41/discussions"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log; + echo '[]'; ;; + "projects?"*) + # echo "$f✔️ $1" >> gitlab-mock-menu.log echo '[ {"id":1,"name":"Project A"}, {"id":2,"name":"Project B"}, @@ -20,8 +36,62 @@ gitlab_request() { ;; *) - echo "$1" > mr-menu-gitlab_request.log + echo "$f❌ $1" >> gitlab-mock-menu.log return 1 ;; esac } + +gitlab_merge_request() { + local f="gitlab_merge_request " + case $1 in + 11) + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log + echo '{"iid": 11, "title": "MR 11 title", "project_id": 1, + "web_url": "https://'${GITLAB_DOMAIN}'/proj-A/-/merge_requests/11", + "head_pipeline": {"status": "running", "web_url": "https://'${GITLAB_DOMAIN}'/proj-A/-/pipelines/11"}, + "state": "opened", "labels": ["QA"], "upvotes": 2, "downvotes": 0, "target_branch": "main", "merge_status": "can_be_merged"}';; + 21) + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log + echo '{"iid": 21, "title": "MR 21 title", "project_id": 2, + "web_url": "https://'${GITLAB_DOMAIN}'/proj-B/-/merge_requests/21", + "head_pipeline": {"status": "failed", "web_url": "https://'${GITLAB_DOMAIN}'/proj-B/-/pipelines/21"}, + "state": "opened", "labels": ["Review"], "upvotes": 0, "downvotes": 1, "target_branch": "main"}';; + 31) + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log + echo '{"iid": 31, "title": "MR 31 title", "project_id": 3, + "web_url": "https://'${GITLAB_DOMAIN}'/proj-C/-/merge_requests/31", + "head_pipeline": {"status": "scheduled", "web_url": "https://'${GITLAB_DOMAIN}'/proj-C/-/pipelines/31"}, + "state": "opened", "labels": ["Accepted"], "upvotes": 3, "downvotes": 0, "target_branch": "main", "merge_status": "can_be_merged"}';; + 41) + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log + echo '{"iid": 41, "title": "MR 41 title", "project_id": 4, + "web_url": "https://'${GITLAB_DOMAIN}'/proj-D/-/merge_requests/41", + "head_pipeline": {"status": "failed", "web_url": "https://'${GITLAB_DOMAIN}'/proj-D/-/pipelines/41"}, + "state": "closed", "labels": ["Review"], "upvotes": 0, "downvotes": 1, "merge_status": }';; + *) + echo "$f❌ $1 $2" >> gitlab-mock-menu.log + return 1 ;; + esac +} + +gitlab_merge_request_threads() { + local f="gitlab_merge_request_threads " + case $1 in + 'https://gitlab.example.net/proj-A/-/merge_requests/11') + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log; + echo '[]'; ;; + 'https://gitlab.example.net/proj-B/-/merge_requests/21') + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log; + echo '[]'; ;; + 'https://gitlab.example.net/proj-C/-/merge_requests/31') + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log; + echo '[]'; ;; + 'https://gitlab.example.net/proj-D/-/merge_requests/41') + # echo "$f✔️ $1 $2" >> gitlab-mock-menu.log; + echo '[]'; ;; + *) + echo "$f❌ $1 $2" >> gitlab-mock-menu.log; + return 1; ;; + esac +} From 2935aff5cb90c6ab98b0b5b8fabcbeafa6360e73 Mon Sep 17 00:00:00 2001 From: Djuuu Date: Sun, 25 Feb 2024 23:11:00 +0100 Subject: [PATCH 3/3] mr menu update - handle description edge-cases --- git-mr | 16 +++++++++-- test/git-mr.bats | 72 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/git-mr b/git-mr index 796c9c8..e7409ee 100755 --- a/git-mr +++ b/git-mr @@ -1832,8 +1832,10 @@ mr_menu_replace_description() { [[ $menu_start -gt 0 && $menu_end -gt "$menu_start" ]] && has_menu=1 + local menu_was_output=0 + # Iterate over description lines and insert/replace menu - local i=1 mr_description_line + local i=1 mr_description_line prev_description_line while IFS=$'\n' read -r mr_description_line; do if [[ $has_menu -eq 1 ]]; then if [[ $i -lt "$menu_start" || $i -gt "$menu_end" ]]; then @@ -1844,20 +1846,30 @@ mr_menu_replace_description() { if [[ $i -eq "$menu_end" ]]; then echo_debug "Replacing menu" echo "$menu_content" + menu_was_output=1 fi fi else # output non-menu line echo "$mr_description_line" # insert menu once - if [[ $i -eq "2" ]]; then + if [[ $menu_was_output -eq 0 && -z "$mr_description_line" && $i -gt 1 ]]; then echo_debug "Inserting menu" echo "$menu_content" echo + menu_was_output=1 fi fi + + prev_description_line="$mr_description_line" ((i += 1)) done < <(echo "$mr_description") + + if [[ $menu_was_output -eq 0 ]]; then + echo_debug "Inserting menu (failsafe)" + [[ -n "$prev_description_line" ]] && echo + echo "$menu_content" + fi } mr_menu_colorize() { diff --git a/test/git-mr.bats b/test/git-mr.bats index fb86e2a..6a0b503 100644 --- a/test/git-mr.bats +++ b/test/git-mr.bats @@ -1749,6 +1749,12 @@ End" @test "Replaces menu in MR descriptions" { + local menu_content="## Menu +* New Menu item 1 +* New Menu item 2 +--------------------------------------------------------------------------------" + + # *** Replace menu in description *** mr_description="# [AB-123 Test feature](https://example.net/AB-123) This is an example. @@ -1766,13 +1772,6 @@ This is an example. * Lorem * Ipsum ---------------------------------------------------------------------------------" - - menu_content="## Menu - -* New Menu item 1 -* New Menu item 2 - --------------------------------------------------------------------------------" run mr_menu_replace_description "$mr_description" "$menu_content" @@ -1783,10 +1782,8 @@ This is an example. -------------------------------------------------------------------------------- ## Menu - * New Menu item 1 * New Menu item 2 - -------------------------------------------------------------------------------- ## Commits @@ -1796,7 +1793,7 @@ This is an example. --------------------------------------------------------------------------------" - + # *** Insert menu in description *** mr_description="# [AB-123 Test feature](https://example.net/AB-123) This is an example without menu. @@ -1806,29 +1803,68 @@ This is an example without menu. * Lorem * Ipsum" - menu_content="## Menu + run mr_menu_replace_description "$mr_description" "$menu_content" + assert_output "# [AB-123 Test feature](https://example.net/AB-123) +## Menu * New Menu item 1 * New Menu item 2 +-------------------------------------------------------------------------------- + +This is an example without menu. + +## Commits + +* Lorem +* Ipsum" + + # *** Insert menu in empty description *** + mr_description="" + run mr_menu_replace_description "$mr_description" "$menu_content" + assert_output " +## Menu +* New Menu item 1 +* New Menu item 2 --------------------------------------------------------------------------------" + # *** Insert menu in minimal description *** + + mr_description="This is a merge request." run mr_menu_replace_description "$mr_description" "$menu_content" - assert_output "# [AB-123 Test feature](https://example.net/AB-123) + assert_output "This is a merge request. ## Menu - * New Menu item 1 * New Menu item 2 +--------------------------------------------------------------------------------" --------------------------------------------------------------------------------- + mr_description="This is a merge request +paragraph." + run mr_menu_replace_description "$mr_description" "$menu_content" + assert_output "This is a merge request +paragraph. -This is an example without menu. +## Menu +* New Menu item 1 +* New Menu item 2 +--------------------------------------------------------------------------------" -## Commits + mr_description="This is +a merge request +longer +paragraph." + run mr_menu_replace_description "$mr_description" "$menu_content" + assert_output "This is +a merge request +longer +paragraph. + +## Menu +* New Menu item 1 +* New Menu item 2 +--------------------------------------------------------------------------------" -* Lorem -* Ipsum" } ################################################################################