6
6
import click
7
7
from tabulate import tabulate
8
8
9
- from kcidev .libs .common import kci_msg , kci_msg_green , kci_msg_red
9
+ from kcidev .libs .common import kci_msg , kci_msg_bold , kci_msg_green , kci_msg_red
10
10
from kcidev .libs .dashboard import (
11
11
dashboard_fetch_boot_issues ,
12
12
dashboard_fetch_boots ,
16
16
dashboard_fetch_commits_history ,
17
17
dashboard_fetch_issue ,
18
18
dashboard_fetch_issue_builds ,
19
+ dashboard_fetch_issue_list ,
19
20
dashboard_fetch_issue_tests ,
20
21
dashboard_fetch_issues_extra ,
21
22
dashboard_fetch_summary ,
41
42
cmd_tests ,
42
43
print_issue ,
43
44
print_issues ,
45
+ print_missing_data ,
44
46
)
45
47
46
48
@@ -473,21 +475,22 @@ def print_stats(data, headers, max_col_width, table_fmt):
473
475
)
474
476
475
477
476
- def get_new_issues (origin , tree_name , giturl , branch , commit , arch ):
478
+ def get_new_issues (origin , tree_name , giturl , branch , commit , arch , use_json = False ):
477
479
"""Get new KCIDB issue for a checkout"""
478
480
try :
481
+ kci_msg_green (f"{ tree_name } /{ branch } :{ commit } " )
479
482
data = dashboard_fetch_summary (origin , giturl , branch , commit , arch , True )
480
483
tree_summary = data ["summary" ]
481
484
items = ["builds" , "boots" , "tests" ]
482
- all_issues = []
483
485
new_issues = []
486
+ issue_id_version = []
484
487
for item in items :
485
488
for i in tree_summary [item ]["issues" ]:
486
- all_issues .append ([i ["id" ], i ["version" ]])
487
- if not all_issues :
488
- kci_msg_red ( f" { tree_name } / { branch } : { commit } No issues found" )
489
+ issue_id_version .append ([i ["id" ], i ["version" ]])
490
+ if not issue_id_version :
491
+ kci_msg ( " No issues found" )
489
492
return
490
- issue_extras = dashboard_fetch_issues_extra (all_issues , True )["issues" ]
493
+ issue_extras = dashboard_fetch_issues_extra (issue_id_version , True )["issues" ]
491
494
for issue_id , extras in issue_extras .items ():
492
495
first_incident = extras .get ("first_incident" )
493
496
if first_incident :
@@ -496,13 +499,14 @@ def get_new_issues(origin, tree_name, giturl, branch, commit, arch):
496
499
first_incident ["git_commit_hash" ] == commit ,
497
500
first_incident ["git_repository_url" ] == giturl ,
498
501
first_incident ["git_repository_branch" ] == branch ,
502
+ first_incident ["tree_name" ] == tree_name ,
499
503
]
500
504
):
501
- new_issues .append (issue_id )
505
+ new_issues .append (dashboard_fetch_issue ( issue_id , False ) )
502
506
if not new_issues :
503
- kci_msg_red ( f" { tree_name } / { branch } : { commit } No new issues found" )
507
+ kci_msg ( " No new issues found" )
504
508
else :
505
- kci_msg_green ( f" { tree_name } / { branch } : { commit } New issues: { new_issues } " )
509
+ print_issues ( new_issues )
506
510
except click .ClickException as e :
507
511
print ("Exception:" , e .message )
508
512
@@ -682,6 +686,215 @@ def detect(
682
686
print_stats (stats , headers , max_col_width , table_fmt )
683
687
684
688
689
+ def get_missing_issue_items (
690
+ ctx , origin , item_type , giturl , branch , commit , tree_name , arch
691
+ ):
692
+ """Get information of failed or inconclusive builds/boots for which KCIDB
693
+ issues don't exist"""
694
+ try :
695
+ if item_type == "builds" :
696
+ results_cmd = builds
697
+ dashboard_func = dashboard_fetch_build_issues
698
+ elif item_type == "boots" :
699
+ results_cmd = boots
700
+ dashboard_func = dashboard_fetch_boot_issues
701
+ else :
702
+ kci_msg_red ("Please specify 'builds' or 'boots' as items type" )
703
+ return []
704
+
705
+ dashboard_items = ctx .invoke (
706
+ results_cmd ,
707
+ origin = origin ,
708
+ giturl = giturl ,
709
+ branch = branch ,
710
+ commit = commit ,
711
+ status = "all" ,
712
+ count = True ,
713
+ verbose = False ,
714
+ arch = arch ,
715
+ )
716
+
717
+ missing_ids = []
718
+ for item in dashboard_items :
719
+ # Exclude passed builds/boots
720
+ if item ["status" ] == "PASS" :
721
+ continue
722
+ item_id = item ["id" ]
723
+ try :
724
+ _ = dashboard_func (item_id , False , error_verbose = False )
725
+ except click .ClickException as e :
726
+ if "No issues" in e .message :
727
+ missing_ids .append ({item_id : item ["status" ]})
728
+ if missing_ids :
729
+ return [f"{ tree_name } /{ branch } " , commit , missing_ids ]
730
+ return []
731
+ except click .Abort :
732
+ kci_msg_red (
733
+ f"{ tree_name } /{ branch } : Aborted while fetching dashboard builds/boots"
734
+ )
735
+ return []
736
+ except click .ClickException as e :
737
+ kci_msg_red (f"{ tree_name } /{ branch } : { e .message } " )
738
+ return []
739
+
740
+
741
+ @results .command (
742
+ name = "issues" ,
743
+ help = """Fetch KCIDB issues from the dashboard
744
+
745
+ \b
746
+ Examples:
747
+ # Get issues
748
+ kci-dev results issues --origin <origin> --days <number-of-days>
749
+ # Get new issues for all checkouts
750
+ kci-dev issues --new --days <number-of-days> --origin <origin>
751
+ # Get new issues for a checkout
752
+ kci-dev issues --new --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
753
+ # Get failed or inconclusive builds and boots without any issue for all checkouts
754
+ kci-dev issues --missing
755
+ # Get failed or inconclusive builds and boots without any issue for specific checkout
756
+ kci-dev issues --missing --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
757
+ # Get failed/inconclusive builds without issues
758
+ kci-dev issues --missing --builds
759
+ # Get failed/inconclusive boots without issues
760
+ kci-dev issues --missing --boots
761
+ """ ,
762
+ )
763
+ @click .option (
764
+ "--origin" ,
765
+ help = "Select KCIDB origin" ,
766
+ default = "maestro" ,
767
+ )
768
+ @click .option (
769
+ "--days" ,
770
+ help = "Provide a period of time in days to get results for" ,
771
+ type = int ,
772
+ default = "5" ,
773
+ )
774
+ @click .option (
775
+ "--new" ,
776
+ is_flag = True ,
777
+ help = "Fetch new KCIDB issues for a checkout" ,
778
+ )
779
+ @click .option (
780
+ "--giturl" ,
781
+ help = "Git URL of kernel tree" ,
782
+ )
783
+ @click .option (
784
+ "--branch" ,
785
+ help = "Branch to get results for" ,
786
+ )
787
+ @click .option (
788
+ "--commit" ,
789
+ help = "Commit or tag to get results for" ,
790
+ )
791
+ @click .option (
792
+ "--git-folder" ,
793
+ help = "Path of git repository folder" ,
794
+ type = click .Path (exists = True , file_okay = False , dir_okay = True ),
795
+ )
796
+ @click .option (
797
+ "--latest" ,
798
+ is_flag = True ,
799
+ help = "Select latest results available" ,
800
+ )
801
+ @click .option (
802
+ "--missing" ,
803
+ is_flag = True ,
804
+ help = "List all failed/incomplete builds and boots without any issue associated to them" ,
805
+ )
806
+ @click .option (
807
+ "--builds" ,
808
+ is_flag = True ,
809
+ help = "The option can be used along with '--missing' to list only builds" ,
810
+ )
811
+ @click .option (
812
+ "--boots" ,
813
+ is_flag = True ,
814
+ help = "The option can be used along with '--missing' to list only boots" ,
815
+ )
816
+ @click .option ("--arch" , help = "Filter by arch" )
817
+ @click .pass_context
818
+ @results_display_options
819
+ def issues (
820
+ ctx ,
821
+ origin ,
822
+ days ,
823
+ new ,
824
+ giturl ,
825
+ branch ,
826
+ commit ,
827
+ use_json ,
828
+ latest ,
829
+ git_folder ,
830
+ arch ,
831
+ missing ,
832
+ builds ,
833
+ boots ,
834
+ ):
835
+ """Issues command handler"""
836
+ if not new and not missing :
837
+ data = dashboard_fetch_issue_list (origin , days , use_json )
838
+ print_issues (data )
839
+ if new :
840
+ if not all ([giturl , branch , commit ]):
841
+ kci_msg ("Fetching new issues for all checkouts..." )
842
+ trees_list = ctx .invoke (trees , origin = origin , days = days , verbose = False )
843
+ for tree in trees_list :
844
+ giturl = tree ["git_repository_url" ]
845
+ branch = tree ["git_repository_branch" ]
846
+ commit = tree ["git_commit_hash" ]
847
+ tree_name = tree ["tree_name" ]
848
+ get_new_issues (
849
+ origin , tree_name , giturl , branch , commit , arch , use_json
850
+ )
851
+ return
852
+ kci_msg ("Fetching new issues for the checkout..." )
853
+ giturl , branch , commit = set_giturl_branch_commit (
854
+ origin , giturl , branch , commit , latest , git_folder
855
+ )
856
+ tree_name = get_tree_name (origin , giturl , branch )
857
+ get_new_issues (origin , tree_name , giturl , branch , commit , arch , use_json )
858
+ if missing :
859
+ if builds :
860
+ item_types = ["builds" ]
861
+ elif boots :
862
+ item_types = ["boots" ]
863
+ else :
864
+ item_types = ["builds" , "boots" ]
865
+
866
+ if all ([giturl , branch , commit ]):
867
+ tree_name = get_tree_name (origin , giturl , branch )
868
+ for item_type in item_types :
869
+ final_stats = []
870
+ kci_msg_green (f"Fetching data for { item_type } ..." )
871
+ stats = get_missing_issue_items (
872
+ ctx , origin , item_type , giturl , branch , commit , tree_name , arch
873
+ )
874
+ if stats :
875
+ final_stats .append (stats )
876
+ if final_stats :
877
+ print_missing_data (item_type , final_stats )
878
+
879
+ else :
880
+ trees_list = ctx .invoke (trees , origin = origin , days = days , verbose = False )
881
+ for item_type in item_types :
882
+ kci_msg_green (f"Fetching data for { item_type } ..." )
883
+ final_stats = []
884
+ for tree in trees_list :
885
+ giturl = tree ["git_repository_url" ]
886
+ branch = tree ["git_repository_branch" ]
887
+ commit = tree ["git_commit_hash" ]
888
+ tree_name = tree ["tree_name" ]
889
+ stats = get_missing_issue_items (
890
+ ctx , origin , item_type , giturl , branch , commit , tree_name , arch
891
+ )
892
+ if stats :
893
+ final_stats .append (stats )
894
+ if final_stats :
895
+ print_missing_data (item_type , final_stats )
896
+
897
+
685
898
@results .command (
686
899
name = "issue" ,
687
900
help = """Fetch KCIDB issue matching provided ID.
0 commit comments