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_green , kci_msg_json , kci_msg_red
10
10
from kcidev .libs .dashboard import (
11
11
dashboard_fetch_boot_issues ,
12
- dashboard_fetch_boots ,
12
+ dashboard_fetch_boots ,
13
13
dashboard_fetch_build ,
14
14
dashboard_fetch_build_issues ,
15
15
dashboard_fetch_builds ,
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
@@ -500,21 +502,22 @@ def print_stats(data, headers, max_col_width, table_fmt):
500
502
)
501
503
502
504
503
- def get_new_issues (origin , tree_name , giturl , branch , commit , arch ):
505
+ def get_new_issues (origin , tree_name , giturl , branch , commit , arch , use_json = False ):
504
506
"""Get new KCIDB issue for a checkout"""
505
507
try :
508
+ kci_msg_green (f"{ tree_name } /{ branch } :{ commit } " )
506
509
data = dashboard_fetch_summary (origin , giturl , branch , commit , arch , True )
507
510
tree_summary = data ["summary" ]
508
511
items = ["builds" , "boots" , "tests" ]
509
- all_issues = []
510
512
new_issues = []
513
+ issue_id_version = []
511
514
for item in items :
512
515
for i in tree_summary [item ]["issues" ]:
513
- all_issues .append ([i ["id" ], i ["version" ]])
514
- if not all_issues :
515
- kci_msg_red ( f" { tree_name } / { branch } : { commit } No issues found" )
516
+ issue_id_version .append ([i ["id" ], i ["version" ]])
517
+ if not issue_id_version :
518
+ kci_msg ( " No issues found" )
516
519
return
517
- issue_extras = dashboard_fetch_issues_extra (all_issues , True )["issues" ]
520
+ issue_extras = dashboard_fetch_issues_extra (issue_id_version , True )["issues" ]
518
521
for issue_id , extras in issue_extras .items ():
519
522
first_incident = extras .get ("first_incident" )
520
523
if first_incident :
@@ -523,13 +526,18 @@ def get_new_issues(origin, tree_name, giturl, branch, commit, arch):
523
526
first_incident ["git_commit_hash" ] == commit ,
524
527
first_incident ["git_repository_url" ] == giturl ,
525
528
first_incident ["git_repository_branch" ] == branch ,
529
+ first_incident ["tree_name" ] == tree_name ,
526
530
]
527
531
):
528
- new_issues .append (issue_id )
532
+ new_issues .append (dashboard_fetch_issue ( issue_id , False ) )
529
533
if not new_issues :
530
- kci_msg_red ( f" { tree_name } / { branch } : { commit } No new issues found" )
534
+ kci_msg ( " No new issues found" )
531
535
else :
532
- kci_msg_green (f"{ tree_name } /{ branch } :{ commit } New issues: { new_issues } " )
536
+ if use_json :
537
+ kci_msg_json (new_issues )
538
+ else :
539
+ for i in new_issues :
540
+ print_issue (i )
533
541
except click .ClickException as e :
534
542
print ("Exception:" , e .message )
535
543
@@ -709,6 +717,279 @@ def detect(
709
717
print_stats (stats , headers , max_col_width , table_fmt )
710
718
711
719
720
+ def get_missing_issue_items (
721
+ ctx , origin , item_type , giturl , branch , commit , tree_name , arch
722
+ ):
723
+ """Get information of failed or inconclusive builds/boots for which KCIDB
724
+ issues don't exist"""
725
+ try :
726
+ if item_type == "builds" :
727
+ results_cmd = builds
728
+ dashboard_func = dashboard_fetch_build_issues
729
+ elif item_type == "boots" :
730
+ results_cmd = boots
731
+ dashboard_func = dashboard_fetch_boot_issues
732
+ else :
733
+ kci_msg_red ("Please specify 'builds' or 'boots' as items type" )
734
+ return []
735
+
736
+ dashboard_items = ctx .invoke (
737
+ results_cmd ,
738
+ origin = origin ,
739
+ giturl = giturl ,
740
+ branch = branch ,
741
+ commit = commit ,
742
+ status = "all" ,
743
+ count = True ,
744
+ verbose = False ,
745
+ arch = arch ,
746
+ error_verbose = False ,
747
+ )
748
+
749
+ missing_ids = []
750
+ for item in dashboard_items :
751
+ # Exclude passed builds/boots
752
+ if item ["status" ] == "PASS" :
753
+ continue
754
+ item_id = item ["id" ]
755
+ try :
756
+ _ = dashboard_func (item_id , False , error_verbose = False )
757
+ except click .ClickException as e :
758
+ if "No issues" in e .message :
759
+ missing_ids .append ({item_id : item ["status" ]})
760
+ if missing_ids :
761
+ return [f"{ tree_name } /{ branch } " , commit , missing_ids ]
762
+ return []
763
+ except click .Abort :
764
+ kci_msg_red (
765
+ f"{ tree_name } /{ branch } : Aborted while fetching dashboard builds/boots"
766
+ )
767
+ return []
768
+ except click .ClickException as e :
769
+ kci_msg_red (f"{ tree_name } /{ branch } : { e .message } " )
770
+ return []
771
+
772
+
773
+ def get_filtered_issues (origin , tree_name , giturl , branch , commit , arch ):
774
+ """Get KCIDB issues for a checkout"""
775
+ try :
776
+ kci_msg_green (f"{ tree_name } /{ branch } :{ commit } " )
777
+ data = dashboard_fetch_summary (origin , giturl , branch , commit , arch , True )
778
+ tree_summary = data ["summary" ]
779
+ items = ["builds" , "boots" , "tests" ]
780
+ all_issues = []
781
+ new_issues = []
782
+ issue_id_version = []
783
+ for item in items :
784
+ for i in tree_summary [item ]["issues" ]:
785
+ issue_item = dashboard_fetch_issue (i ["id" ], False )
786
+ all_issues .append (issue_item )
787
+ issue_id_version .append ([i ["id" ], i ["version" ]])
788
+ if not all_issues :
789
+ kci_msg ("No issues found" )
790
+ return
791
+ issue_extras = dashboard_fetch_issues_extra (issue_id_version , True )["issues" ]
792
+ for issue_id , extras in issue_extras .items ():
793
+ first_incident = extras .get ("first_incident" )
794
+ if first_incident :
795
+ if all (
796
+ [
797
+ first_incident ["git_commit_hash" ] == commit ,
798
+ first_incident ["git_repository_url" ] == giturl ,
799
+ first_incident ["git_repository_branch" ] == branch ,
800
+ first_incident ["tree_name" ] == tree_name ,
801
+ ]
802
+ ):
803
+ new_issues .append (issue_id )
804
+
805
+ for i in all_issues :
806
+ if i ["id" ] in new_issues :
807
+ print_issue (i , True )
808
+ else :
809
+ print_issue (i )
810
+
811
+ except click .ClickException as e :
812
+ print ("Exception:" , e .message )
813
+
814
+
815
+ @results .command (
816
+ name = "issues" ,
817
+ help = """Fetch KCIDB issues from the dashboard
818
+
819
+ \b
820
+ Examples:
821
+ # Get issues
822
+ kci-dev results issues --origin <origin> --days <number-of-days>
823
+ # Get new issues for all checkouts
824
+ kci-dev issues --new --days <number-of-days> --origin <origin>
825
+ # Get new issues for a checkout
826
+ kci-dev issues --new --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
827
+ # Get failed or inconclusive builds and boots without any issue for all checkouts
828
+ kci-dev issues --missing
829
+ # Get failed or inconclusive builds and boots without any issue for specific checkout
830
+ kci-dev issues --missing --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
831
+ # Get failed/inconclusive builds without issues
832
+ kci-dev issues --missing --builds
833
+ # Get failed/inconclusive boots without issues
834
+ kci-dev issues --missing --boots
835
+ """ ,
836
+ )
837
+ @click .option (
838
+ "--origin" ,
839
+ help = "Select KCIDB origin" ,
840
+ default = "maestro" ,
841
+ )
842
+ @click .option (
843
+ "--days" ,
844
+ help = "Provide a period of time in days to get results for" ,
845
+ type = int ,
846
+ default = "5" ,
847
+ )
848
+ @click .option (
849
+ "--new" ,
850
+ is_flag = True ,
851
+ help = "Fetch new KCIDB issues for a checkout" ,
852
+ )
853
+ @click .option (
854
+ "--giturl" ,
855
+ help = "Git URL of kernel tree" ,
856
+ )
857
+ @click .option (
858
+ "--branch" ,
859
+ help = "Branch to get results for" ,
860
+ )
861
+ @click .option (
862
+ "--commit" ,
863
+ help = "Commit or tag to get results for" ,
864
+ )
865
+ @click .option (
866
+ "--git-folder" ,
867
+ help = "Path of git repository folder" ,
868
+ type = click .Path (exists = True , file_okay = False , dir_okay = True ),
869
+ )
870
+ @click .option (
871
+ "--latest" ,
872
+ is_flag = True ,
873
+ help = "Select latest results available" ,
874
+ )
875
+ @click .option (
876
+ "--missing" ,
877
+ is_flag = True ,
878
+ help = "List all failed/incomplete builds and boots without any issue associated to them" ,
879
+ )
880
+ @click .option (
881
+ "--builds" ,
882
+ is_flag = True ,
883
+ help = "The option can be used along with '--missing' to list only builds" ,
884
+ )
885
+ @click .option (
886
+ "--boots" ,
887
+ is_flag = True ,
888
+ help = "The option can be used along with '--missing' to list only boots" ,
889
+ )
890
+ @click .option ("--arch" , help = "Filter by arch" )
891
+ @click .option ("--tree" , help = "Filter by tree name" )
892
+ @click .pass_context
893
+ @results_display_options
894
+ def issues (
895
+ ctx ,
896
+ origin ,
897
+ days ,
898
+ new ,
899
+ giturl ,
900
+ branch ,
901
+ commit ,
902
+ use_json ,
903
+ latest ,
904
+ git_folder ,
905
+ arch ,
906
+ tree ,
907
+ missing ,
908
+ builds ,
909
+ boots ,
910
+ ):
911
+ """Issues command handler"""
912
+ if not new and not missing :
913
+ if not any ([giturl , branch , commit ]):
914
+ data = dashboard_fetch_issue_list (origin , days , use_json )
915
+ print_issues (data )
916
+ return
917
+ if not all ([giturl , branch , commit ]):
918
+ raise click .UsageError (
919
+ "Please provide --giturl, --branch and --commit to get issues for"
920
+ )
921
+ if not tree :
922
+ tree = get_tree_name (origin , giturl , branch )
923
+ get_filtered_issues (origin , tree , giturl , branch , commit , arch )
924
+ if new :
925
+ if not any ([giturl , branch , commit ]):
926
+ kci_msg ("Fetching new issues for all checkouts..." )
927
+ trees_list = ctx .invoke (trees , origin = origin , days = days , verbose = False )
928
+ for t in trees_list :
929
+ giturl = t ["git_repository_url" ]
930
+ branch = t ["git_repository_branch" ]
931
+ commit = t ["git_commit_hash" ]
932
+ tree_name = t ["tree_name" ]
933
+ get_new_issues (
934
+ origin , tree_name , giturl , branch , commit , arch , use_json
935
+ )
936
+ return
937
+ if not all ([giturl , branch , commit ]):
938
+ raise click .UsageError (
939
+ "Please provide --giturl, --branch, and --commit to fetch new issues for "
940
+ "a checkout or else omit all these options to fetch new issues for all the "
941
+ "checkouts"
942
+ )
943
+ kci_msg ("Fetching new issues for the checkout..." )
944
+ giturl , branch , commit = set_giturl_branch_commit (
945
+ origin , giturl , branch , commit , latest , git_folder
946
+ )
947
+ if not tree :
948
+ tree = get_tree_name (origin , giturl , branch )
949
+ get_new_issues (origin , tree , giturl , branch , commit , arch , use_json )
950
+ if missing :
951
+ if builds :
952
+ item_types = ["builds" ]
953
+ elif boots :
954
+ item_types = ["boots" ]
955
+ else :
956
+ item_types = ["builds" , "boots" ]
957
+
958
+ if all ([giturl , branch , commit ]):
959
+ if not tree :
960
+ tree = get_tree_name (origin , giturl , branch )
961
+ for item_type in item_types :
962
+ final_stats = []
963
+ kci_msg ("" )
964
+ kci_msg_green (f"Fetching data for { item_type } ..." )
965
+ stats = get_missing_issue_items (
966
+ ctx , origin , item_type , giturl , branch , commit , tree , arch
967
+ )
968
+ if stats :
969
+ final_stats .append (stats )
970
+ if final_stats :
971
+ print_missing_data (item_type , final_stats )
972
+
973
+ else :
974
+ trees_list = ctx .invoke (trees , origin = origin , days = days , verbose = False )
975
+ for item_type in item_types :
976
+ kci_msg ("" )
977
+ kci_msg_green (f"Fetching data for { item_type } ..." )
978
+ final_stats = []
979
+ for tree in trees_list :
980
+ giturl = tree ["git_repository_url" ]
981
+ branch = tree ["git_repository_branch" ]
982
+ commit = tree ["git_commit_hash" ]
983
+ tree_name = tree ["tree_name" ]
984
+ stats = get_missing_issue_items (
985
+ ctx , origin , item_type , giturl , branch , commit , tree_name , arch
986
+ )
987
+ if stats :
988
+ final_stats .append (stats )
989
+ if final_stats :
990
+ print_missing_data (item_type , final_stats )
991
+
992
+
712
993
@results .command (
713
994
name = "issue" ,
714
995
help = """Fetch KCIDB issue matching provided ID.
0 commit comments