summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Enedino Hernandez Samaniego <alejandro.enedino.hernandez-samaniego@xilinx.com>2018-09-04 23:45:44 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-09-06 10:36:31 +0100
commitf65c898ba69afb3c0091d566a0ede1717536f9b6 (patch)
treed69bf30cc13a827665cad47c98957fa6f7780e95
parentd3148222f06895be867dae8eb6ba33777f03a6a5 (diff)
downloadpoky-f65c898ba69afb3c0091d566a0ede1717536f9b6.tar.gz
python3: Clean up create manifest script
This patch intends to clean up the whole create_manifest script/task for python3. This is an effort to make the code more human friendly and facilitate adoption, it not only cleans up the code but it also improves comments, it should also be easier to upgrade the manifest after each python3 upgrade now, with these fixes the transition to python 3.7 should be seamless. It fixes a rather harmless bug where module dependencies were being added twice to the core package and adds tests and sqlite3-tests as special packages since we want specific dependencies on those. It also fixes a bug that happened on a few packages that contained a directory with the same name as the module itself e.g. asyncio, where the script avoided checking that module for dependencies. Lastly, it improves the output, it errors out if a module is found on more than one package, which is what usually happens when python upstream introduces a new file, hence why the current manifest is unaware of, it is better to exit with an error because otherwise the user wouldnt know if anything went wrong unless the output of the script was checked manually. (From OE-Core rev: 658042073cb58c58ac4db4ff13689d1ffd89b72e) Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandr@xilinx.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/python/python3/create_manifest3.py432
1 files changed, 242 insertions, 190 deletions
diff --git a/meta/recipes-devtools/python/python3/create_manifest3.py b/meta/recipes-devtools/python/python3/create_manifest3.py
index 41a6bb071a..1849152ea3 100644
--- a/meta/recipes-devtools/python/python3/create_manifest3.py
+++ b/meta/recipes-devtools/python/python3/create_manifest3.py
@@ -48,21 +48,21 @@ import os
48pyversion = str(sys.argv[1]) 48pyversion = str(sys.argv[1])
49 49
50# Hack to get native python search path (for folders), not fond of it but it works for now 50# Hack to get native python search path (for folders), not fond of it but it works for now
51pivot='recipe-sysroot-native' 51pivot = 'recipe-sysroot-native'
52for p in sys.path: 52for p in sys.path:
53 if pivot in p: 53 if pivot in p:
54 nativelibfolder=p[:p.find(pivot)+len(pivot)] 54 nativelibfolder = p[:p.find(pivot)+len(pivot)]
55 55
56# Empty dict to hold the whole manifest 56# Empty dict to hold the whole manifest
57new_manifest = {} 57new_manifest = {}
58 58
59# Check for repeated files, folders and wildcards 59# Check for repeated files, folders and wildcards
60allfiles=[] 60allfiles = []
61repeated=[] 61repeated = []
62wildcards=[] 62wildcards = []
63 63
64hasfolders=[] 64hasfolders = []
65allfolders=[] 65allfolders = []
66 66
67def isFolder(value): 67def isFolder(value):
68 value = value.replace('${PYTHON_MAJMIN}',pyversion) 68 value = value.replace('${PYTHON_MAJMIN}',pyversion)
@@ -79,166 +79,204 @@ def isCached(item):
79 79
80# Read existing JSON manifest 80# Read existing JSON manifest
81with open('python3-manifest.json') as manifest: 81with open('python3-manifest.json') as manifest:
82 old_manifest=json.load(manifest) 82 old_manifest = json.load(manifest)
83
84 83
84#
85# First pass to get core-package functionality, because we base everything on the fact that core is actually working 85# First pass to get core-package functionality, because we base everything on the fact that core is actually working
86# Not exactly the same so it should not be a function 86# Not exactly the same so it should not be a function
87#
88
87print ('Getting dependencies for package: core') 89print ('Getting dependencies for package: core')
88 90
89# Special call to check for core package 91
92# This special call gets the core dependencies and
93# appends to the old manifest so it doesnt hurt what it
94# currently holds.
95# This way when other packages check for dependencies
96# on the new core package, they will still find them
97# even when checking the old_manifest
98
90output = subprocess.check_output([sys.executable, 'get_module_deps3.py', 'python-core-package']).decode('utf8') 99output = subprocess.check_output([sys.executable, 'get_module_deps3.py', 'python-core-package']).decode('utf8')
91for item in output.split(): 100for coredep in output.split():
92 item = item.replace(pyversion,'${PYTHON_MAJMIN}') 101 coredep = coredep.replace(pyversion,'${PYTHON_MAJMIN}')
93 # We append it so it doesnt hurt what we currently have: 102 if isCached(coredep):
94 if isCached(item): 103 if coredep not in old_manifest['core']['cached']:
95 if item not in old_manifest['core']['cached']: 104 old_manifest['core']['cached'].append(coredep)
96 # We use the same data structure since its the one which will be used to check
97 # dependencies for other packages
98 old_manifest['core']['cached'].append(item)
99 else: 105 else:
100 if item not in old_manifest['core']['files']: 106 if coredep not in old_manifest['core']['files']:
101 # We use the same data structure since its the one which will be used to check 107 old_manifest['core']['files'].append(coredep)
102 # dependencies for other packages 108
103 old_manifest['core']['files'].append(item) 109
104 110# The second step is to loop through the existing files contained in the core package
105for value in old_manifest['core']['files']: 111# according to the old manifest, identify if they are modules, or some other type
106 value = value.replace(pyversion,'${PYTHON_MAJMIN}') 112# of file that we cant import (directories, binaries, configs) in which case we
107 # Ignore folders, since we don't import those, difficult to handle multilib 113# can only assume they were added correctly (manually) so we ignore those and
108 if isFolder(value): 114# pass them to the manifest directly.
109 # Pass it directly 115
110 if isCached(value): 116for filedep in old_manifest['core']['files']:
111 if value not in old_manifest['core']['cached']: 117 if isFolder(filedep):
112 old_manifest['core']['cached'].append(value) 118 if isCached(filedep):
119 if filedep not in old_manifest['core']['cached']:
120 old_manifest['core']['cached'].append(filedep)
113 else: 121 else:
114 if value not in old_manifest['core']['files']: 122 if filedep not in old_manifest['core']['files']:
115 old_manifest['core']['files'].append(value) 123 old_manifest['core']['files'].append(filedep)
116 continue 124 continue
117 # Ignore binaries, since we don't import those, assume it was added correctly (manually) 125 if '${bindir}' in filedep:
118 if '${bindir}' in value: 126 if filedep not in old_manifest['core']['files']:
119 # Pass it directly 127 old_manifest['core']['files'].append(filedep)
120 if value not in old_manifest['core']['files']:
121 old_manifest['core']['files'].append(value)
122 continue 128 continue
123 # Ignore empty values 129 if filedep == '':
124 if value == '':
125 continue 130 continue
126 if '${includedir}' in value: 131 if '${includedir}' in filedep:
127 if value not in old_manifest['core']['files']: 132 if filedep not in old_manifest['core']['files']:
128 old_manifest['core']['files'].append(value) 133 old_manifest['core']['files'].append(filedep)
129 continue 134 continue
130 # Get module name , shouldnt be affected by libdir/bindir 135
131 value = os.path.splitext(os.path.basename(os.path.normpath(value)))[0] 136 # Get actual module name , shouldnt be affected by libdir/bindir, etc.
132 137 pymodule = os.path.splitext(os.path.basename(os.path.normpath(filedep)))[0]
133 # Launch separate task for each module for deterministic behavior 138
134 # Each module will only import what is necessary for it to work in specific 139
135 print ('Getting dependencies for module: %s' % value) 140 # We now know that were dealing with a python module, so we can import it
136 output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % value]).decode('utf8') 141 # and check what its dependencies are.
137 print ('The following dependencies were found for module %s:\n' % value) 142 # We launch a separate task for each module for deterministic behavior.
143 # Each module will only import what is necessary for it to work in specific.
144 # The output of each task will contain each module's dependencies
145
146 print ('Getting dependencies for module: %s' % pymodule)
147 output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % pymodule]).decode('utf8')
148 print ('The following dependencies were found for module %s:\n' % pymodule)
138 print (output) 149 print (output)
139 for item in output.split(): 150
140 item = item.replace(pyversion,'${PYTHON_MAJMIN}') 151
141 152 for pymodule_dep in output.split():
142 # We append it so it doesnt hurt what we currently have: 153 pymodule_dep = pymodule_dep.replace(pyversion,'${PYTHON_MAJMIN}')
143 if isCached(item): 154
144 if item not in old_manifest['core']['cached']: 155 if isCached(pymodule_dep):
145 # We use the same data structure since its the one which will be used to check 156 if pymodule_dep not in old_manifest['core']['cached']:
146 # dependencies for other packages 157 old_manifest['core']['cached'].append(pymodule_dep)
147 old_manifest['core']['cached'].append(item)
148 else: 158 else:
149 if item not in old_manifest['core']['files']: 159 if pymodule_dep not in old_manifest['core']['files']:
150 # We use the same data structure since its the one which will be used to check 160 old_manifest['core']['files'].append(pymodule_dep)
151 # dependencies for other packages 161
152 old_manifest['core']['files'].append(item) 162
153 163# At this point we are done with the core package.
154 164# The old_manifest dictionary is updated only for the core package because
155# We check which packages include folders 165# all others will use this a base.
156for key in old_manifest: 166
157 for value in old_manifest[key]['files']: 167
158 # Ignore folders, since we don't import those, difficult to handle multilib 168# To improve the script speed, we check which packages contain directories
159 if isFolder(value): 169# since we will be looping through (only) those later.
160 print ('%s is a folder' % value) 170for pypkg in old_manifest:
161 if key not in hasfolders: 171 for filedep in old_manifest[pypkg]['files']:
162 hasfolders.append(key) 172 if isFolder(filedep):
163 if value not in allfolders: 173 print ('%s is a folder' % filedep)
164 allfolders.append(value) 174 if pypkg not in hasfolders:
165 175 hasfolders.append(pypkg)
166for key in old_manifest: 176 if filedep not in allfolders:
177 allfolders.append(filedep)
178
179
180
181# This is the main loop that will handle each package.
182# It works in a similar fashion than the step before, but
183# we will now be updating a new dictionary that will eventually
184# become the new manifest.
185#
186# The following loops though all packages in the manifest,
187# through all files on each of them, and checks whether or not
188# they are modules and can be imported.
189# If they can be imported, then it checks for dependencies for
190# each of them by launching a separate task.
191# The output of that task is then parsed and the manifest is updated
192# accordingly, wether it should add the module on FILES for the current package
193# or if that module already belongs to another package then the current one
194# will RDEPEND on it
195
196for pypkg in old_manifest:
167 # Use an empty dict as data structure to hold data for each package and fill it up 197 # Use an empty dict as data structure to hold data for each package and fill it up
168 new_manifest[key]={} 198 new_manifest[pypkg] = {}
169 new_manifest[key]['files']=[] 199 new_manifest[pypkg]['files'] = []
170 200 new_manifest[pypkg]['rdepends'] = []
171 new_manifest[key]['rdepends']=[] 201
172 # All packages should depend on core 202 # All packages should depend on core
173 if key != 'core': 203 if pypkg != 'core':
174 new_manifest[key]['rdepends'].append('core') 204 new_manifest[pypkg]['rdepends'].append('core')
175 new_manifest[key]['cached']=[] 205 new_manifest[pypkg]['cached'] = []
176 else: 206 else:
177 new_manifest[key]['cached']=old_manifest[key]['cached'] 207 new_manifest[pypkg]['cached'] = old_manifest[pypkg]['cached']
178 new_manifest[key]['summary']=old_manifest[key]['summary'] 208 new_manifest[pypkg]['summary'] = old_manifest[pypkg]['summary']
209
179 210
180 # Handle special cases, we assume that when they were manually added
181 # to the manifest we knew what we were doing.
182 print('\n') 211 print('\n')
183 print('--------------------------') 212 print('--------------------------')
184 print ('Handling package %s' % key) 213 print ('Handling package %s' % pypkg)
185 print('--------------------------') 214 print('--------------------------')
186 special_packages=['misc', 'modules', 'dev'] 215
187 if key in special_packages or 'staticdev' in key: 216 # Handle special cases, we assume that when they were manually added
188 print('Passing %s package directly' % key) 217 # to the manifest we knew what we were doing.
189 new_manifest[key]=old_manifest[key] 218 special_packages = ['misc', 'modules', 'dev', 'tests', 'sqlite3-tests']
219 if pypkg in special_packages or 'staticdev' in pypkg:
220 print('Passing %s package directly' % pypkg)
221 new_manifest[pypkg] = old_manifest[pypkg]
190 continue 222 continue
191 223
192 for value in old_manifest[key]['files']: 224 for filedep in old_manifest[pypkg]['files']:
193 # We already handled core on the first pass 225 # We already handled core on the first pass, we can ignore it now
194 if key == 'core': 226 if pypkg == 'core':
195 new_manifest[key]['files'].append(value) 227 if filedep not in new_manifest[pypkg]['files']:
228 new_manifest[pypkg]['files'].append(filedep)
196 continue 229 continue
197 # Ignore folders, since we don't import those, difficult to handle multilib 230
198 if isFolder(value): 231 # Handle/ignore what we cant import
199 # Pass folders directly 232 if isFolder(filedep):
200 new_manifest[key]['files'].append(value) 233 new_manifest[pypkg]['files'].append(filedep)
201 # Ignore binaries, since we don't import those 234 # Asyncio (and others) are both the package and the folder name, we should not skip those...
202 if '${bindir}' in value: 235 path,mod = os.path.split(filedep)
203 # Pass it directly to the new manifest data structure 236 if mod != pypkg:
204 if value not in new_manifest[key]['files']: 237 continue
205 new_manifest[key]['files'].append(value) 238 if '${bindir}' in filedep:
239 if filedep not in new_manifest[pypkg]['files']:
240 new_manifest[pypkg]['files'].append(filedep)
206 continue 241 continue
207 # Ignore empty values 242 if filedep == '':
208 if value == '':
209 continue 243 continue
210 if '${includedir}' in value: 244 if '${includedir}' in filedep:
211 if value not in new_manifest[key]['files']: 245 if filedep not in new_manifest[pypkg]['files']:
212 new_manifest[key]['files'].append(value) 246 new_manifest[pypkg]['files'].append(filedep)
213 continue 247 continue
214 248
215 # Get module name , shouldnt be affected by libdir/bindir 249 # Get actual module name , shouldnt be affected by libdir/bindir, etc.
216 # We need to check if the imported module comes from another (e.g. sqlite3.dump) 250 # We need to check if the imported module comes from another (e.g. sqlite3.dump)
217 path,value = os.path.split(value) 251 path,pymodule = os.path.split(filedep)
218 path = os.path.basename(path) 252 path = os.path.basename(path)
219 value = os.path.splitext(os.path.basename(value))[0] 253 pymodule = os.path.splitext(os.path.basename(pymodule))[0]
220 254
221 # If this condition is met, it means we need to import it from another module 255 # If this condition is met, it means we need to import it from another module
222 # or its the folder itself (e.g. unittest) 256 # or its the folder itself (e.g. unittest)
223 if path == key: 257 if path == pypkg:
224 if value: 258 if pymodule:
225 value = path + '.' + value 259 pymodule = path + '.' + pymodule
226 else: 260 else:
227 value = path 261 pymodule = path
228 262
229 # Launch separate task for each module for deterministic behavior 263
230 # Each module will only import what is necessary for it to work in specific 264
231 print ('\nGetting dependencies for module: %s' % value) 265 # We now know that were dealing with a python module, so we can import it
232 output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % value]).decode('utf8') 266 # and check what its dependencies are.
233 # We can print dependencies for debugging purposes 267 # We launch a separate task for each module for deterministic behavior.
234 print ('The following dependencies were found for module %s:\n' % value) 268 # Each module will only import what is necessary for it to work in specific.
269 # The output of each task will contain each module's dependencies
270
271 print ('\nGetting dependencies for module: %s' % pymodule)
272 output = subprocess.check_output([sys.executable, 'get_module_deps3.py', '%s' % pymodule]).decode('utf8')
273 print ('The following dependencies were found for module %s:\n' % pymodule)
235 print (output) 274 print (output)
236 # Output will have all dependencies
237 275
238 reportFILES = [] 276 reportFILES = []
239 reportRDEPS = [] 277 reportRDEPS = []
240 278
241 for item in output.split(): 279 for pymodule_dep in output.split():
242 280
243 # Warning: This first part is ugly 281 # Warning: This first part is ugly
244 # One of the dependencies that was found, could be inside of one of the folders included by another package 282 # One of the dependencies that was found, could be inside of one of the folders included by another package
@@ -258,22 +296,22 @@ for key in old_manifest:
258 # is folder_string inside path/folder1/folder2/filename?, 296 # is folder_string inside path/folder1/folder2/filename?,
259 # Yes, it works, but we waste a couple of milliseconds. 297 # Yes, it works, but we waste a couple of milliseconds.
260 298
261 item = item.replace(pyversion,'${PYTHON_MAJMIN}') 299 pymodule_dep = pymodule_dep.replace(pyversion,'${PYTHON_MAJMIN}')
262 inFolders=False 300 inFolders = False
263 for folder in allfolders: 301 for folder in allfolders:
264 if folder in item: 302 if folder in pymodule_dep:
265 inFolders = True # Did we find a folder? 303 inFolders = True # Did we find a folder?
266 folderFound = False # Second flag to break inner for 304 folderFound = False # Second flag to break inner for
267 # Loop only through packages which contain folders 305 # Loop only through packages which contain folders
268 for keyfolder in hasfolders: 306 for pypkg_with_folder in hasfolders:
269 if (folderFound == False): 307 if (folderFound == False):
270 #print('Checking folder %s on package %s' % (item,keyfolder)) 308 # print('Checking folder %s on package %s' % (pymodule_dep,pypkg_with_folder))
271 for file_folder in old_manifest[keyfolder]['files'] or file_folder in old_manifest[keyfolder]['cached']: 309 for folder_dep in old_manifest[pypkg_with_folder]['files'] or folder_dep in old_manifest[pypkg_with_folder]['cached']:
272 if file_folder==folder: 310 if folder_dep == folder:
273 print ('%s folder found in %s' % (folder, keyfolder)) 311 print ('%s folder found in %s' % (folder, pypkg_with_folder))
274 folderFound = True 312 folderFound = True
275 if keyfolder not in new_manifest[key]['rdepends'] and keyfolder != key: 313 if pypkg_with_folder not in new_manifest[pypkg]['rdepends'] and pypkg_with_folder != pypkg:
276 new_manifest[key]['rdepends'].append(keyfolder) 314 new_manifest[pypkg]['rdepends'].append(pypkg_with_folder)
277 else: 315 else:
278 break 316 break
279 317
@@ -282,81 +320,95 @@ for key in old_manifest:
282 continue 320 continue
283 321
284 322
285 # We might already have it on the dictionary since it could depend on a (previously checked) module 323
286 if item not in new_manifest[key]['files'] and item not in new_manifest[key]['cached']: 324 # No directories beyond this point
325 # We might already have this module on the dictionary since it could depend on a (previously checked) module
326 if pymodule_dep not in new_manifest[pypkg]['files'] and pymodule_dep not in new_manifest[pypkg]['cached']:
287 # Handle core as a special package, we already did it so we pass it to NEW data structure directly 327 # Handle core as a special package, we already did it so we pass it to NEW data structure directly
288 if key=='core': 328 if pypkg == 'core':
289 print('Adding %s to %s FILES' % (item, key)) 329 print('Adding %s to %s FILES' % (pymodule_dep, pypkg))
290 if item.endswith('*'): 330 if pymodule_dep.endswith('*'):
291 wildcards.append(item) 331 wildcards.append(pymodule_dep)
292 if isCached(item): 332 if isCached(pymodule_dep):
293 new_manifest[key]['cached'].append(item) 333 new_manifest[pypkg]['cached'].append(pymodule_dep)
294 else: 334 else:
295 new_manifest[key]['files'].append(item) 335 new_manifest[pypkg]['files'].append(pymodule_dep)
296
297 # Check for repeated files
298 if item not in allfiles:
299 allfiles.append(item)
300 else:
301 repeated.append(item)
302 336
337 # Check for repeated files
338 if pymodule_dep not in allfiles:
339 allfiles.append(pymodule_dep)
340 else:
341 if pymodule_dep not in repeated:
342 repeated.append(pymodule_dep)
303 else: 343 else:
304 344
305 345
306 # Check if this dependency is already contained on another package, so we add it 346 # Last step: Figure out if we this belongs to FILES or RDEPENDS
347 # We check if this module is already contained on another package, so we add that one
307 # as an RDEPENDS, or if its not, it means it should be contained on the current 348 # as an RDEPENDS, or if its not, it means it should be contained on the current
308 # package, so we should add it to FILES 349 # package, and we should add it to FILES
309 for newkey in old_manifest: 350 for possible_rdep in old_manifest:
310 # Debug 351 # Debug
311 #print('Checking %s ' % item + ' in %s' % newkey) 352 # print('Checking %s ' % pymodule_dep + ' in %s' % possible_rdep)
312 if item in old_manifest[newkey]['files'] or item in old_manifest[newkey]['cached']: 353 if pymodule_dep in old_manifest[possible_rdep]['files'] or pymodule_dep in old_manifest[possible_rdep]['cached']:
313 # Since were nesting, we need to check its not the same key 354 # Since were nesting, we need to check its not the same pypkg
314 if(newkey!=key): 355 if(possible_rdep != pypkg):
315 if newkey not in new_manifest[key]['rdepends']: 356 if possible_rdep not in new_manifest[pypkg]['rdepends']:
316 # Add it to the new manifest data struct 357 # Add it to the new manifest data struct as RDEPENDS since it contains something this module needs
317 reportRDEPS.append('Adding %s to %s RDEPENDS, because it contains %s\n' % (newkey, key, item)) 358 reportRDEPS.append('Adding %s to %s RDEPENDS, because it contains %s\n' % (possible_rdep, pypkg, pymodule_dep))
318 new_manifest[key]['rdepends'].append(newkey) 359 new_manifest[pypkg]['rdepends'].append(possible_rdep)
319 break 360 break
320 else: 361 else:
362
363 # Since this module wasnt found on another package, it is not an RDEP,
364 # so we add it to FILES for this package.
321 # A module shouldn't contain itself (${libdir}/python3/sqlite3 shouldnt be on sqlite3 files) 365 # A module shouldn't contain itself (${libdir}/python3/sqlite3 shouldnt be on sqlite3 files)
322 if os.path.basename(item) != key: 366 if os.path.basename(pymodule_dep) != pypkg:
323 reportFILES.append(('Adding %s to %s FILES\n' % (item, key))) 367 reportFILES.append(('Adding %s to %s FILES\n' % (pymodule_dep, pypkg)))
324 # Since it wasnt found on another package, its not an RDEP, so add it to FILES for this package 368 if isCached(pymodule_dep):
325 if isCached(item): 369 new_manifest[pypkg]['cached'].append(pymodule_dep)
326 new_manifest[key]['cached'].append(item)
327 else: 370 else:
328 new_manifest[key]['files'].append(item) 371 new_manifest[pypkg]['files'].append(pymodule_dep)
329 372 if pymodule_dep.endswith('*'):
330 if item.endswith('*'): 373 wildcards.append(pymodule_dep)
331 wildcards.append(item) 374 if pymodule_dep not in allfiles:
332 if item not in allfiles: 375 allfiles.append(pymodule_dep)
333 allfiles.append(item)
334 else: 376 else:
335 repeated.append(item) 377 if pymodule_dep not in repeated:
378 repeated.append(pymodule_dep)
336 379
337 print('\n') 380 print('\n')
338 print('#################################') 381 print('#################################')
339 print('Summary for module %s' % value) 382 print('Summary for module %s' % pymodule)
340 print('FILES found for module %s:' % value) 383 print('FILES found for module %s:' % pymodule)
341 print(''.join(reportFILES)) 384 print(''.join(reportFILES))
342 print('RDEPENDS found for module %s:' % value) 385 print('RDEPENDS found for module %s:' % pymodule)
343 print(''.join(reportRDEPS)) 386 print(''.join(reportRDEPS))
344 print('#################################') 387 print('#################################')
345 388
346print ('The following files are repeated (contained in more than one package), please check which package should get it:') 389print('The following FILES contain wildcards, please check if they are necessary')
347print (repeated)
348print('The following files contain wildcards, please check they are necessary')
349print(wildcards) 390print(wildcards)
350print('The following files contain folders, please check they are necessary') 391print('The following FILES contain folders, please check if they are necessary')
351print(hasfolders) 392print(hasfolders)
352 393
394
353# Sort it just so it looks nicer 395# Sort it just so it looks nicer
354for key in new_manifest: 396for pypkg in new_manifest:
355 new_manifest[key]['files'].sort() 397 new_manifest[pypkg]['files'].sort()
356 new_manifest[key]['cached'].sort() 398 new_manifest[pypkg]['cached'].sort()
357 new_manifest[key]['rdepends'].sort() 399 new_manifest[pypkg]['rdepends'].sort()
358 400
359# Create the manifest from the data structure that was built 401# Create the manifest from the data structure that was built
360with open('python3-manifest.json.new','w') as outfile: 402with open('python3-manifest.json.new','w') as outfile:
361 json.dump(new_manifest,outfile,sort_keys=True, indent=4) 403 json.dump(new_manifest,outfile,sort_keys=True, indent=4)
362 outfile.write('\n') 404 outfile.write('\n')
405
406if (repeated):
407 error_msg = '\n\nERROR:\n'
408 error_msg += 'The following files are repeated (contained in more than one package),\n'
409 error_msg += 'this is likely to happen when new files are introduced after an upgrade,\n'
410 error_msg += 'please check which package should get it,\n modify the manifest accordingly and re-run the create_manifest task:\n'
411 error_msg += '\n'.join(repeated)
412 error_msg += '\n'
413 sys.exit(error_msg)
414