8
8
import os
9
9
import time
10
10
import datetime
11
+ import json
11
12
from github import Github , GithubException
12
13
from github .GithubException import UnknownObjectException
13
14
from collections import defaultdict
14
15
from west .manifest import Manifest
15
16
from west .manifest import ManifestProject
17
+ from git import Repo
18
+ from pathlib import Path
16
19
17
20
TOP_DIR = os .path .join (os .path .dirname (__file__ ))
18
21
sys .path .insert (0 , os .path .join (TOP_DIR , "scripts" ))
19
22
from get_maintainer import Maintainers
20
23
24
+ zephyr_base = os .getenv ('ZEPHYR_BASE' , os .path .join (TOP_DIR , '..' ))
25
+
21
26
def log (s ):
22
27
if args .verbose > 0 :
23
28
print (s , file = sys .stdout )
@@ -50,11 +55,73 @@ def parse_args():
50
55
parser .add_argument ("-r" , "--repo" , default = "zephyr" ,
51
56
help = "Github repository" )
52
57
58
+ parser .add_argument ("-c" , "--commits" , default = None ,
59
+ help = "Commit range in the form: a..b" )
60
+
61
+ parser .add_argument ("--manifest" , action = "store_true" , default = False ,
62
+ help = "Dump manifest changes" )
63
+
64
+ parser .add_argument ("--areas" , default = None ,
65
+ help = "Load list of areas from file generated by --manifest" )
66
+
53
67
parser .add_argument ("-v" , "--verbose" , action = "count" , default = 0 ,
54
68
help = "Verbose Output" )
55
69
56
70
args = parser .parse_args ()
57
71
72
+
73
+ def process_manifest ():
74
+ log ("Processing manifest changes" )
75
+ repo = Repo (zephyr_base )
76
+ old_manifest_content = repo .git .show (f"{ args .commits [:- 2 ]} :west.yml" )
77
+ with open ("west_old.yml" , "w" ) as manifest :
78
+ manifest .write (old_manifest_content )
79
+ old_manifest = Manifest .from_file ("west_old.yml" )
80
+ new_manifest = Manifest .from_file ("west.yml" )
81
+ old_projs = set ((p .name , p .revision ) for p in old_manifest .projects )
82
+ new_projs = set ((p .name , p .revision ) for p in new_manifest .projects )
83
+ # Removed projects
84
+ rprojs = set (filter (lambda p : p [0 ] not in list (p [0 ] for p in new_projs ),
85
+ old_projs - new_projs ))
86
+ # Updated projects
87
+ uprojs = set (filter (lambda p : p [0 ] in list (p [0 ] for p in old_projs ),
88
+ new_projs - old_projs ))
89
+ # Added projects
90
+ aprojs = new_projs - old_projs - uprojs
91
+
92
+ # All projs
93
+ projs = rprojs | uprojs | aprojs
94
+ projs_names = [name for name , rev in projs ]
95
+
96
+ log (f"found modified projects: { projs_names } " )
97
+ areas = []
98
+ for p in projs_names :
99
+ areas .append (f'West project: { p } ' )
100
+
101
+ log (f'manifest areas: { areas } ' )
102
+ return areas
103
+
104
+
105
+ def dump_manifest_changes (gh , maintainer_file , number ):
106
+ gh_repo = gh .get_repo (f"{ args .org } /{ args .repo } " )
107
+ pr = gh_repo .get_pull (number )
108
+ fn = list (pr .get_files ())
109
+ areas = []
110
+ for changed_file in fn :
111
+ log (f"file: { changed_file .filename } " )
112
+
113
+ if changed_file .filename in ['west.yml' ,'submanifests/optional.yaml' ]:
114
+ changed_areas = process_manifest ()
115
+ for _area in changed_areas :
116
+ area_match = maintainer_file .name2areas (_area )
117
+ if area_match :
118
+ areas .extend (area_match )
119
+
120
+ log (f"Areas: { areas } " )
121
+ # now dump the list of areas into a json file
122
+ with open ("manifest_areas.json" , "w" ) as f :
123
+ json .dump ([area .name for area in areas ], f , indent = 4 )
124
+
58
125
def process_pr (gh , maintainer_file , number ):
59
126
60
127
gh_repo = gh .get_repo (f"{ args .org } /{ args .repo } " )
@@ -67,13 +134,8 @@ def process_pr(gh, maintainer_file, number):
67
134
found_maintainers = defaultdict (int )
68
135
69
136
num_files = 0
70
- all_areas = set ()
71
137
fn = list (pr .get_files ())
72
138
73
- for changed_file in fn :
74
- if changed_file .filename in ['west.yml' ,'submanifests/optional.yaml' ]:
75
- break
76
-
77
139
if pr .commits == 1 and (pr .additions <= 1 and pr .deletions <= 1 ):
78
140
labels = {'size: XS' }
79
141
@@ -82,14 +144,28 @@ def process_pr(gh, maintainer_file, number):
82
144
return
83
145
84
146
for changed_file in fn :
147
+
85
148
num_files += 1
86
149
log (f"file: { changed_file .filename } " )
87
- areas = maintainer_file .path2areas (changed_file .filename )
150
+
151
+ areas = []
152
+ if changed_file .filename in ['west.yml' ,'submanifests/optional.yaml' ]:
153
+ if args .areas and Path (args .areas ).is_file ():
154
+ with open (args .areas , "r" ) as f :
155
+ parsed_areas = json .load (f )
156
+ for _area in parsed_areas :
157
+ area_match = maintainer_file .name2areas (_area )
158
+ if area_match :
159
+ areas .extend (area_match )
160
+ else :
161
+ log (f"Manifest changes detected but no --areas file specified, skipping..." )
162
+ continue
163
+ else :
164
+ areas = maintainer_file .path2areas (changed_file .filename )
88
165
89
166
if not areas :
90
167
continue
91
168
92
- all_areas .update (areas )
93
169
is_instance = False
94
170
sorted_areas = sorted (areas , key = lambda x : 'Platform' in x .name , reverse = True )
95
171
for area in sorted_areas :
@@ -358,7 +434,9 @@ def main():
358
434
gh = Github (token )
359
435
maintainer_file = Maintainers (args .maintainer_file )
360
436
361
- if args .pull_request :
437
+ if args .pull_request and args .manifest :
438
+ dump_manifest_changes (gh , maintainer_file , args .pull_request )
439
+ elif args .pull_request :
362
440
process_pr (gh , maintainer_file , args .pull_request )
363
441
elif args .issue :
364
442
process_issue (gh , maintainer_file , args .issue )
0 commit comments