Remove unused functions
[scm/bb/tizen.git] / tools / spec2yocto.py
1 #!/usr/bin/python
2 #
3 # Copyright 2013, Intel Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Library General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 # native
18
19 '''
20 Created on  05 fevr. 2013
21
22 @author: ronan@fridu.net
23 '''
24
25 import os
26 import shutil
27 import errno
28
29 RECIPES_SOURCE_DIR = os.path.dirname( os.path.realpath( __file__ ) )
30 RECIPES_DIR_DEST = os.path.join( RECIPES_SOURCE_DIR, "../meta-tizen-ivi" )
31 GIT_COMMAND = "git://%s/%s;tag=%s;nobranch=1"
32
33 import sys
34 import platform
35
36 from urllib import urlopen
37 from xml.etree import ElementTree
38
39 try:
40     import cmdln
41 except:
42     print >> sys.stderr, 'Error spec2yocto require "python-cmdln" please install it.'
43     sys.exit( 1 )
44
45 import fcntl
46
47 import subprocess
48 import shlex
49
50 import re
51 import select
52
53 import tempfile
54
55 import ConfigParser
56
57 # Very useful to debug spec2yocto, print the subprocess EXEC_COMMAND line.
58 DEBUG_RUN = False
59
60 CONFIGURATION_FILE_PATH = os.path.expanduser( os.path.join( "~", ".spec2yoctorc" ) )
61
62 class Spec2yoctoConfig( object ):
63     '''
64     Parse the file "spec2yocto_configure",
65
66     '''
67     def __init__( self ):
68         self.__config_parser = ConfigParser.ConfigParser()
69         self.__config_parser.optionxform = str
70
71         if not os.path.isfile( CONFIGURATION_FILE_PATH ):
72             print >> sys.stderr, "Warning CONFIGURATION_FILE_PATH \"%s\" do not exist." % (CONFIGURATION_FILE_PATH)
73             print >> sys.stderr,"         a sample is available in directory \"proto-meta-Tizen_generic/.spec2yoctorc\""
74             sys.exit(1)
75
76         self.__config_file = open( CONFIGURATION_FILE_PATH , 'rw' )
77
78         self.__config_parser.readfp( self.__config_file )
79
80     def get_current_project( self ):
81         '''
82         return the list of the manifest_meta, manifest_meta can be a file or URL.
83         '''
84
85         return self.__get_value( "project", "current" , None )
86
87     def get_manifest_meta_list( self, projet ):
88         '''
89         return the list of the manifest_meta, manifest_meta can be a file or URL.
90         '''
91         meta_manifests_res = []
92         list_of_meta_manifest = self.__get_list( projet, "manifest", [] )
93         for meta_manifest in list_of_meta_manifest:
94             meta_manifests_res.append( meta_manifest.replace( " ", "" ) )
95
96         return meta_manifests_res
97
98     def get_manifest_uri( self, meta_manifest ):
99         '''
100         return the uri of the manifest.
101         '''
102         res = self.__get_value( meta_manifest, "uri" , None )
103         res = os.path.expanduser( res )
104         res = os.path.expandvars( res )
105         return res
106
107     def get_manifest_priority( self, meta_manifest ):
108         '''
109         return the priority of the manifest.
110         '''
111         return self.__get_value( meta_manifest, "priority" , 0 )
112
113     def get_manifest_default_git_src( self, meta_manifest ):
114         '''
115         return the default_git_src of the manifest.
116         '''
117         return self.__get_value( meta_manifest, "default_git_src" , None )
118
119     def is_valide_project( self, projet ):
120         '''
121         check if project is configurate in the conf file.
122         '''
123         return ( projet in self.__config_parser.sections() )
124
125     def get_project_arch( self, projet ):
126         '''
127         return the default arch of the project.
128         '''
129         return self.__get_value( projet, "arch", None )
130
131     def get_working_dir( self, projet ):
132         '''
133         return the working dir of the project.
134         '''
135         res = self.__get_value( projet, "working_dir", "/tmp" )
136
137         res = os.path.expanduser( res )
138         res = os.path.expandvars( res )
139         return res
140
141     def get_list(self, project, list_name):
142         """
143         Returns the corresponding list.
144         """
145         res_list = self.__get_list( project, list_name, [] )
146         res = []
147         for element in res_list:
148             res.extend(self.__get_list(element, "list", []))
149         return res
150
151     def get_substitute( self , project = None ):
152
153         res = {}
154         for package in self.__config_parser.options( "substitute" ):
155             package_replace = self.__get_value( "substitute", package, None )
156             if package_replace is not None:
157                 res[package] = package_replace
158         return res
159
160     def __get_list( self, section, option, default_value ):
161         '''
162         generic fonction to get list value.
163         '''
164         if ( section in self.__config_parser.sections() ) and \
165            ( option in self.__config_parser.options( section ) ):
166             tmp_res = str( self.__config_parser.get( section, option ) )
167             return tmp_res.replace( " ", "" ).split( "," )
168         else:
169             return default_value
170
171     def __get_value( self, section, option, default_value ):
172         '''
173         generic fonction to get value.
174         '''
175         if ( section in self.__config_parser.sections() ) and \
176            ( option in self.__config_parser.options( section ) ):
177             tmp_res = self.__config_parser.get( section, option )
178             return tmp_res
179         else:
180             return default_value
181
182     def get_recipes_sources_directory( self, project ):
183         '''
184         return a list of the recipes directory needed to build the image.
185         '''
186         res = self.__get_value( project, 'recipes_dir_sources', None )
187         res = os.path.expanduser( res )
188         res = os.path.expandvars( res )
189         return res
190
191     def get_recipes_group_directory( self, project ):
192         res = self.__get_value( project, 'recipes_dir_group', None )
193         res = os.path.expanduser( res )
194         res = os.path.expandvars( res )
195         return res
196
197
198     def get_group( self , project = None ):
199         if project is None:
200             project = self.get_current_project()
201         return self.__get_list( project, 'group', [] )
202
203
204     def get_target_cpu( self , project = None ):
205         '''
206         return target cpu.
207         '''
208         if project is None:
209             project = self.get_current_project()
210         return self.__get_value( project, 'arch' , None )
211
212     def get_bb_autoreconf_blacklist( self , project = None ):
213         '''
214         return a list of package with no autoreconf.
215         '''
216         if project is None:
217             project = self.get_current_project()
218
219         blacklist_list = self.__get_list( project, "blacklist_autoreconf", [] )
220         res = []
221         for blacklist in blacklist_list:
222             res.extend( self.__get_list( blacklist, "blacklist", [] ) )
223
224         return res
225
226     def get_provided_extra( self , project = None ):
227
228         if project is None:
229             project = self.get_current_project()
230
231         provided_extra_list = self.__get_list( project, "provided-extra", [] )
232         provided_extra_dico={}
233         for provided_extra in provided_extra_list:
234             for package in self.__config_parser.options( provided_extra ):
235                 provided_list = self.__get_list( provided_extra, package, [] )
236                 provided_extra_dico[package] = provided_list
237         return provided_extra_dico
238
239
240     def get_ignore_depend( self ):
241         '''
242         return the ignore package to ignore for depends (build require).
243         '''
244         return self.__get_list( 'depends', 'ignore', [] )
245
246     def get_ignore_rdepend( self ):
247         '''
248         return the ignore package to ignore for rdepends (require).
249         '''
250         return self.__get_list( 'rdepends', 'ignore', [] )
251
252     def get_native_depend( self ):
253         '''
254         some buildRequire mean depends on native package not runtime.
255         '''
256         return self.__get_list( 'depends', 'native', [] )
257
258     def get_cross_depend( self ):
259         '''
260         some buildRequire mean depends on native package not runtime.
261         '''
262         return self.__get_list( 'depends', 'cross', [] )
263
264     def get_libtool_cross( self ):
265         '''
266         some buildRequire mean depends on libtool-cross package not runtime.
267         '''
268         return self.__get_list( 'depends', 'libtool_cross', [] )
269
270     def get_inherit_gettext( self ):
271         '''
272         some buildRequire mean inherit_gettext package not depends runtime.
273         '''
274         return self.__get_list( 'depends', 'inherit_gettext', [] )
275
276     def get_inherit(self, package):
277         '''
278         some buildRequire mean inherit_cmake package not depends runtime.
279         '''
280         return [package]
281
282     def get_group_uri( self, project ):
283
284         return self.__get_value( project, 'group_uri', None )
285
286
287 SPEC2YOCTO_CONFIG = Spec2yoctoConfig()
288
289 # Implementation taken from http://hetland.org
290 def levenshtein( a, b ):
291     """Calculates the Levenshtein distance between a and b."""
292     n, m = len( a ), len( b )
293     if n > m:
294         # Make sure n <= m, to use O(min(n,m)) space
295         a, b = b, a
296         n, m = m, n
297
298     current = range( n + 1 )
299     for i in range( 1, m + 1 ):
300         previous, current = current, [i] + [0] * n
301         for j in range( 1, n + 1 ):
302             add, delete = previous[j] + 1, current[j - 1] + 1
303             change = previous[j - 1]
304             if a[j - 1] != b[i - 1]:
305                 change = change + 1
306             current[j] = min( add, delete, change )
307
308     return current[n]
309
310 def get_packaging_files( package_path ):
311     res = []
312     for tmp_res in os.listdir( package_path ):
313         if tmp_res.endswith( ".spec" ) and os.path.isfile( package_path + "/" + tmp_res ):
314             res.append( tmp_res )
315     return res
316
317 def findBestSpecFile( package_path, package_name ):
318     """
319     Find the name of the spec file which matches best with `package_name`
320     """
321
322     package_spec_dir = package_path
323     package_spec_dir = os.path.expanduser( package_spec_dir )
324     package_spec_dir = os.path.expandvars( package_spec_dir )
325
326     specFileList = get_packaging_files( package_path )
327
328     specFile = None
329     if len( specFileList ) < 1:
330         # No spec file in list
331         specFile = None
332     elif len( specFileList ) == 1:
333         # Only one spec file
334         specFile = specFileList[0]
335     else:
336         sameStart = []
337         for spec in specFileList:
338             if str( spec[:-5] ) == str( package_name ):
339                 # This spec file has the same name as the package
340                 specFile = spec
341                 break
342             elif spec.startswith( package_name ):
343                 # This spec file has a name which looks like the package
344                 sameStart.append( spec )
345
346         if specFile is None:
347             if len( sameStart ) > 0:
348                 # Sort the list of 'same start' by the Levenshtein distance
349                 sameStart.sort( key = lambda x: levenshtein( x, package_name ) )
350                 specFile = sameStart[0]
351             else:
352                 # No spec file starts with the name of the package,
353                 # sort the whole spec file list by the Levenshtein distance
354                 specFileList.sort( key = lambda x: levenshtein( x, package_name ) )
355                 specFile = specFileList[0]
356
357     if specFile is None:
358         msg = "Found no spec file matching package name '%s'" % package_name
359         print msg
360         return -1
361
362     spec_full_path = os.path.join( package_spec_dir, specFile )
363     return  spec_full_path
364
365 def findSpecPatchFiles( patch_dir_path, package_name_list ):
366     """
367     Find the name of the patch for the spec file which matches best with `package_name`
368     """
369     patch_list = []
370
371     patch_dir_path = os.path.expanduser( patch_dir_path )
372     patch_dir_path = os.path.expandvars( patch_dir_path )
373     if package_name_list is not None:
374         for patch_name in set( package_name_list ):
375             for patch_extend in ["", "-yocto"]:
376                 patch_file = patch_name + patch_extend + ".spec.patch"
377                 patch_path = os.path.join( patch_dir_path, patch_file )
378                 if os.path.isfile( patch_path ):
379                     patch_list.append( patch_path )
380
381     return patch_list
382
383
384
385 class SubprocessCrt( object ):
386     '''
387     usefull class to control subprocess
388     '''
389     def __init__( self ):
390         '''
391         Initialize subprocess.
392         '''
393         self.output_res = ""
394         self.__idle_time = 0
395
396     def get_last_res( self ):
397         '''
398         return the last subprocess output.
399         '''
400         return self.output_res
401
402     def __read_subprocess_output( self, outputs, f_stdout, f_stderr ):
403         '''
404         read the stdout, stderr of the subprocess
405         '''
406         timed_out = True
407         select_timeout = 60
408         for file_d in select.select( [f_stdout, f_stderr], [], [], select_timeout )[0]:
409             timed_out = False
410             output = file_d.read()
411             if f_stdout == file_d:
412                 self.output_res += output
413             else:
414                 if DEBUG_RUN and ( len( output ) > 0 ):
415                     print "ERROR ****", output, len( output )
416
417             for line in output.split( "\n" ):
418                 if not line == b"" or not output.endswith( "\n" ):
419                     outputs[file_d]["EOF"] = False
420
421                 if line == b"" and not output.endswith( "\n" ):
422                     outputs[file_d]["EOF"] = True
423                 elif line != "" :
424                     res_clean = line.decode( "utf8", "replace" ).rstrip()
425                     if DEBUG_RUN:
426                         print res_clean
427
428         if timed_out:
429             self.__idle_time += select_timeout
430         else:
431             self.__idle_time = 0
432
433
434
435     def exec_subprocess( self, command ):
436         '''
437         Execute the "command" in a sub process,
438         the "command" must be a valid bash command.
439         _args and _kwargs are for compatibility.
440         '''
441
442         self.output_res = ""
443
444         # need Python 2.7.3 to do shlex.split(command)
445         splitted_command = shlex.split( str( command ) )
446         a_process = subprocess.Popen( splitted_command,
447                              stdout = subprocess.PIPE,
448                              stderr = subprocess.PIPE )
449         f_stdout = a_process.stdout
450         f_stderr = a_process.stderr
451
452         flags = fcntl.fcntl( f_stdout, fcntl.F_GETFL )
453         if not f_stdout.closed:
454             fcntl.fcntl( f_stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK )
455
456         flags = fcntl.fcntl( f_stderr, fcntl.F_GETFL )
457         if not f_stderr.closed:
458             fcntl.fcntl( f_stderr, fcntl.F_SETFL, flags | os.O_NONBLOCK )
459
460         outputs = {f_stdout: {"EOF": False},
461                    f_stderr: {"EOF": False}}
462
463
464         while ( ( not outputs[f_stdout]["EOF"] and
465                not outputs[f_stderr]["EOF"] ) or
466                ( a_process.poll() == None ) ):
467             try:
468                 self.__read_subprocess_output( outputs, f_stdout, f_stderr )
469             except select.error as error:
470                 # see http://bugs.python.org/issue9867
471                 if error.args[0] == errno.EINTR:
472                     print "Got select.error: %s" % unicode( error )
473                     continue
474                 else:
475                     raise Exception()
476
477         # maybe a_process.wait() is better ?
478         poll_res = a_process.poll()
479         if poll_res != 0:
480             return poll_res
481         return self.output_res
482
483 class RePattern:
484     '''
485     def of usefull re pattern to parse spec file.
486     '''
487     pattern_patch = r'([pP]atch[\d]*)[\s]*:[\s]*.*'
488     patternUrlSourceFile = r'Source[\d]*[\s]*:[\s]*([http,ftp].*/)(.*)'
489     patternUrlPatchFile = r'Patch[\d]*[\s]*:[\s]*([http,ftp].*/)(.*)'
490
491     patternPatch = r'[pP]atch([\d]*)[\s]*:[\s]*(.*)'
492     patternSource = r'Source([\d]*)[\s]*:[\s]*(.*)'
493
494     patternPatchCommand = r'#(patch)([\d]*)(.*)'
495
496     patternDescription = r'^Summary:\s*(.*)'
497     patternUrl = r'^Url:\s*(.*)'
498     patternGroup = r'^Group:\s*(.*)'
499     patternLicense = r'^License:\s*(.*)'
500
501     patternFiles = r'^%files\s*(.*)'
502
503     patternName = r'^Name:\s*(.*)'
504
505     patternPackage = r'^%package\s*(.*)'
506     provides_package = r'^Provides:\s*(.*)'
507
508     buildPkgconfig = r'pkgconfig\((.*)\).*'
509
510     pkgRe = r'([^ \t\n\r\f\v,]+)(?:\s+(<|>|<=|>=|=|==)\s+([^ \t\n\r\f\v,]+))?'
511
512     buildRequiresPackage = r'^BuildRequires:\s*(.*)'
513     requiresPackage = r'^Requires(?:\(\w+\))?:\s*(.*)'
514
515     paternDevel = "(.*)-devel"
516
517     pkgconfig_name = "/usr/lib/pkgconfig/([^*]*).pc"
518
519     def __init__( self ):
520         '''
521         init RePattern
522         '''
523
524 def get_macro_directory_path( current_cpu ):
525     '''
526     return all the valid macro directory.
527     '''
528     macro_paths = ""
529     for macro_dir in ["lib/*",
530                 "lib/fileattrs/*",
531                 "lib/platform/%s-linux/macros" % current_cpu,
532                 "lib/tizen/*",
533                 "etc/*",
534                 "user/.rpmmacros",
535                 "yocto/*"]:
536         macro_paths += os.path.join( "/usr/share/spec2yocto/macro", macro_dir ) + " "
537     return macro_paths
538
539 class SpecParser:
540     '''
541     spec file parser
542     '''
543     mPkgConfigDico = {}
544     msubprocess = SubprocessCrt()
545     def __init__( self, package_spec_path, package_pn = None ):
546         '''
547         init the SpecParser
548         '''
549         self.__introduction_section = "introduction_section"
550         self.__package = "%package"
551         self.__description = "%description"
552         self.__prep_flag = "%prep"
553         self.__build_flag = "%build"
554         self.__install_flag = "%install"
555         self.__clean_flag = "%clean"
556         self.__files_flag = "%files"
557         self.__check_flag = "%check"
558         #pkg_preinst, pkg_postinst, pkg_prerm, and pkg_postrm
559         self.__post_flag = "%post"
560         self.__preun_flag = "%preun"
561         self.__postun_flag = "%postun"
562         self.__pre_flag = "%pre"
563
564         self.__verifyscript_flag = "%verifyscript"
565         self.__changelog_flag = "%changelog"
566         self.__list_section = [self.__package,
567                              self.__description,
568                              self.__prep_flag,
569                              self.__build_flag,
570                              self.__install_flag,
571                              self.__clean_flag,
572                              self.__files_flag,
573                              self.__check_flag,
574                              self.__post_flag,
575                              self.__preun_flag,
576                              self.__postun_flag,
577                              self.__pre_flag,
578                              self.__verifyscript_flag,
579                              self.__changelog_flag]
580
581         self.__package_spec_path = package_spec_path
582         self.__package_pn = package_pn
583
584         self.__parsed_spec_file = None
585         self.__order_list = []
586         self.__spect_dico = {}
587         self.__patchs = []
588
589         self.__order_raw_list = []
590         self.__raw_spect_dico = {}
591
592         self.__cpu = SPEC2YOCTO_CONFIG.get_target_cpu()
593         self.__cpu_native = platform.machine()
594
595         self.__convert_spec_file()
596         self.__parse_parsed_spec_file()
597         self.__base_name = self.get_name()
598
599         self.__pkg_config = []
600
601     def __find_patch( self ):
602         '''
603         find the patchs of the spec file.
604         '''
605         self.__patchs = []
606         with open( self.__package_spec_path ) as file_d:
607             spec_file = file_d.read()
608             res_tmp = re.findall( RePattern.pattern_patch, spec_file )
609             for a_res in res_tmp:
610                 self.__patchs.append( a_res.replace( "Patch", "patch" ) )
611
612     def __is_native_build( self ):
613         '''
614         return True if the package is native.
615         '''
616         res_1 = ( self.__package_pn is not None )
617         if not res_1:
618             return res_1
619
620         res_2 = self.__package_pn.endswith( "-native" )
621
622         return  res_2
623
624     def init_rpmspec_command( self ):
625         '''
626         init rpmspec_command to parse spec file.
627         '''
628         rpmspec_command = "rpmspec "
629
630         if self.__is_native_build():
631             current_cpu = self.__cpu_native
632         else:
633             current_cpu = self.__cpu
634
635         rpmspec_command += " --macros=\"%s\" " % get_macro_directory_path( current_cpu )
636
637         rpmspec_command += " --define='buildroot ${D}' "
638         if self.__is_native_build():
639             # Not the better way to do this
640             rpmspec_command += " --define='basearch i386' "
641             # I guess other tool must be set for native build.
642             rpmspec_command += " --define='__cc gcc' "
643             # the default value of the macro is %{nil}
644             base_prefix = os.getenv( "base_prefix" )
645             if ( base_prefix != "" ) and ( base_prefix is not None ):
646                 rpmspec_command += " --define='_buildPrefix %s' " % base_prefix
647
648             rpmspec_command += " --define='%find_lang echo no find_lang for package native'"
649
650         rpmspec_command += " --define='setup #setup' "
651         rpmspec_command += " --define='setup0 #setup0' "
652
653         package_dir = os.path.dirname( self.__package_spec_path )
654
655         rpmspec_command += " --define='SOURCES ${S}/packaging/' "
656         rpmspec_command += " --define='_sourcedir ${S}/packaging/' "
657
658         rpmspec_command += " --define='BUILD_BASENAME %{basename}' "
659         rpmspec_command += " --define='find_lang  #find_lang' "
660         rpmspec_command += " --define='with_wayland  1' "
661
662         rpmspec_command += " --target='%s' " % current_cpu
663         # need to be change.
664         package_name = os.path.basename( self.__package_spec_path )[:-5]
665
666         if package_name in SPEC2YOCTO_CONFIG.get_bb_autoreconf_blacklist() :
667             oe_runconf2 = '''oe_runconf2'''
668             rpmspec_command += " --define='%%_configure %s'" % oe_runconf2
669
670         return rpmspec_command
671
672
673     def __convert_spec_file( self ):
674         '''
675         init convert spec to expand spec file.
676         '''
677         tmp_package_spec_path = self.__package_spec_path
678
679         # we can't use python rpm API to parse the spec file so we need to exec rpmspec\
680         # in a subprocess and parse the result.
681         rpmspec_command = self.init_rpmspec_command()
682
683         # it's import to remove all "Source" url because if rpm dan't find the source,\
684         # it try to downloads the file from the url.
685         with open( tmp_package_spec_path, 'r' ) as current_spec_file:
686             current_spec_string = current_spec_file.read()
687             res_url_source_files = re.findall( RePattern.patternUrlSourceFile, current_spec_string )
688
689         if len( res_url_source_files ) > 0:
690             for res_url in res_url_source_files:
691                 long_url = res_url[0] + res_url[1]
692                 short_url = res_url[1]
693                 current_spec_string = current_spec_string.replace( long_url, short_url )
694
695             with tempfile.NamedTemporaryFile( mode = 'w',
696                             suffix = '.tmp',
697                             prefix = os.path.basename( tmp_package_spec_path ) + ".",
698                             dir = os.path.dirname( tmp_package_spec_path ),
699                             delete = False ) as  tmp_spec_file:
700                 tmp_spec_file.write( current_spec_string )
701                 tmp_package_spec_path = tmp_spec_file.name
702
703         # same case as "Source"
704         with open( tmp_package_spec_path, 'r' ) as current_spec_file:
705             current_spec_string = current_spec_file.read()
706             res_url_patch_file = re.findall( RePattern.patternUrlPatchFile, current_spec_string )
707
708         if len( res_url_patch_file ) > 0:
709             for res_url in res_url_patch_file:
710                 long_url = res_url[0] + res_url[1]
711                 short_url = res_url[1]
712                 current_spec_string = current_spec_string.replace( long_url, short_url )
713             if ( tmp_package_spec_path != self.__package_spec_path ) \
714                and os.path.isfile( tmp_package_spec_path ) \
715                and not DEBUG_RUN:
716                 os.remove( tmp_package_spec_path )
717             with tempfile.NamedTemporaryFile( mode = 'w',
718                             suffix = '.tmp',
719                             prefix = os.path.basename( tmp_package_spec_path ) + ".",
720                             dir = os.path.dirname( tmp_package_spec_path ),
721                             delete = False ) as  tmp_spec_file:
722                 tmp_spec_file.write( current_spec_string )
723                 tmp_package_spec_path = tmp_spec_file.name
724
725         self.__find_patch()
726         for a_patch in self.__patchs:
727             if a_patch == "patch0":
728                 rpmspec_command += " --define='%patch #patch' "
729
730             rpmspec_command += " --define='%s #%s' " % ( a_patch, a_patch )
731
732         rpmspec_command += " --define='debug_package %{nil}'"
733
734         rpmspec_command += " --parse %s " % tmp_package_spec_path
735         if DEBUG_RUN:
736             print "rpmspec_command :", rpmspec_command
737
738
739         self.__parsed_spec_file = SpecParser.msubprocess.exec_subprocess( rpmspec_command )
740         if ( tmp_package_spec_path != self.__package_spec_path ) \
741                and os.path.isfile( tmp_package_spec_path ) \
742                and not DEBUG_RUN:
743             os.remove( tmp_package_spec_path )
744
745         if self.__parsed_spec_file == 1:
746             print >> sys.stderr, ""
747             print >> sys.stderr, "ERROR CMD: %s" % rpmspec_command
748             print >> sys.stderr, "parse error for spec file %s" % ( tmp_package_spec_path )
749             self.__parsed_spec_file = None
750             return 1
751
752         if DEBUG_RUN:
753             if not os.path.isdir( "/tmp/parsed_spec" ):
754                 os.makedirs( "/tmp/parsed_spec" )
755
756             if self.__package_pn is None:
757                 tmp_path = os.path.basename( self.__package_spec_path )
758                 package_parsed_spec_path = os.path.join( "/tmp/parsed_spec", tmp_path )
759             else:
760                 tmp_path = "%s.spec" % self.__package_pn
761                 package_parsed_spec_path = os.path.join( "/tmp/parsed_spec", tmp_path )
762
763             with open( package_parsed_spec_path, "w" ) as file_d:
764                 file_d.write( self.__parsed_spec_file )
765
766
767     def __test_section( self, line ):
768         '''
769         test if the line is the start of a new section.
770         '''
771         for sect in self.__list_section:
772             if line.startswith( sect ):
773                 return True
774         return False
775
776     def __parse_parsed_spec_file( self ):
777         '''
778         parse a spec file by section after rpmspec.
779         '''
780         # ordered dico is not provide yet...
781         self.__order_list = []
782         self.__spect_dico = {}
783
784         current_section = self.__introduction_section
785         self.__spect_dico[current_section] = []
786         self.__order_list.append( current_section )
787
788         if self.__parsed_spec_file is None:
789             return 1
790
791         for line in self.__parsed_spec_file.split( "\n" ):
792
793             if self.__test_section( line ) :
794                 if line in self.__spect_dico.keys():
795                     print "line %s" % line
796                     print "--------------------------------------"
797                     print "parsedSpecFile: %s" % self.__package_spec_path
798                     print "--------------------------------------"
799                     error_msg = "ERROR for the spec file \"%s\" this section \"%s\" is not unique."
800                     print  error_msg % ( self.__parsed_spec_file, line )
801                     # raise Exception()
802
803                 current_section = line
804                 self.__spect_dico[current_section] = []
805                 self.__order_list.append( current_section )
806
807             self.__spect_dico[current_section].append( line )
808
809     def parse_raw_spec_file( self ):
810         '''
811         parse a spec file by section before rpmspec.
812         '''
813         # need to be rewrite
814         # ordered dico is not provide yet...
815
816         self.__order_raw_list = []
817         self.__raw_spect_dico = {}
818
819         current_section = self.__introduction_section
820         self.__raw_spect_dico[current_section] = []
821         self.__order_raw_list.append( current_section )
822
823         with open( self.__package_spec_path, "r" ) as file_d:
824             parsed_raw_spec_file = file_d.read()
825
826         for line in parsed_raw_spec_file.split( "\n" ):
827             if self.__test_section( line ) :
828                 if line in self.__raw_spect_dico.keys():
829                     print "line %s" % line
830                     print "--------------------------------------"
831                     print "parsedSpecFile: %s" % self.__package_spec_path
832                     print "--------------------------------------"
833                     error_msg = "ERROR for the spec file \"%s\" this section \"%s\" is not unique."
834                     print  error_msg % ( self.__parsed_spec_file, line )
835                     raise Exception()
836
837                 current_section = line
838                 self.__raw_spect_dico[current_section] = []
839                 self.__order_raw_list.append( current_section )
840
841             self.__raw_spect_dico[current_section].append( line )
842
843
844     def get_prep_section( self ):
845         '''
846         return the prep section of the spec file.
847         '''
848         res_prep_section = "cd ${S}\n"
849
850         pattern_patch_dico = {}
851         pattern_source_dico = {}
852
853         for line in self.__spect_dico[self.__introduction_section][1:]:
854             for patch_id, files_name in re.findall( RePattern.patternPatch, line ):
855                 if patch_id == "":
856                     patch_id = "0"
857                 pattern_patch_dico[patch_id] = files_name
858
859             for source_id, files_name in re.findall( RePattern.patternSource, line ):
860                 if source_id == "":
861                     source_id = "0"
862                 pattern_source_dico[source_id] = files_name
863
864         for line in self.__spect_dico[self.__prep_flag][1:]:
865             if line.startswith( "#setup" ):
866                 splited_line = line.split()
867                 for i in range( len( splited_line ) ):
868                     if splited_line[i].startswith( "-a" ):
869                         if len( splited_line[i] ) > len( "-a" ):
870                             setup_id = splited_line[i].replace( "-a", "" )
871                         else:
872                             setup_id = splited_line[i + 1]
873                         res_prep_section += "#extracte source %s \n" % setup_id
874                         res_prep_section += "pushd ${S}\n"
875                         source = os.path.basename( pattern_source_dico[setup_id] )
876                         # not a good way to do this
877                         if source.endswith( "rpmlintrc" ):
878                             res_prep_section += "cp ${S}/packaging/%s .\n" % source
879                         else:
880                             file_name = os.path.basename( pattern_source_dico[setup_id] )
881                             res_prep_section += "unp ${S}/packaging/%s \n" % file_name
882                         res_prep_section += "popd \n"
883
884                     elif splited_line[i].startswith( "-b" ):
885                         if len( splited_line[i] ) > len( "-b" ):
886                             setup_id = splited_line[i].replace( "-b", "" )
887                         else:
888                             setup_id = splited_line[i + 1]
889
890                         res_prep_section += "#extracte source %s \n" % ( setup_id )
891                         res_prep_section += "pushd ${S}/../\n"
892                         source = os.path.basename( pattern_source_dico[setup_id] )
893                         if source.endswith( "rpmlintrc" ):
894                             res_prep_section += "cp ${S}/packaging/%s .\n" % source
895                         else:
896                             res_prep_section += "unp ${S}/packaging/%s \n" % source
897                         res_prep_section += "popd \n"
898
899                 res_prep_section += "chmod -Rf a+rX,u+w,g-w,o-w ${S}\n"
900
901
902             elif line.startswith( "#patch" ):
903                 res_findall = re.findall( RePattern.patternPatchCommand, line )
904                 # should be rewrite
905                 for patch_name, patch_id, EXEC_COMMAND in res_findall:
906                     if patch_id == '':
907                         patch_id = "0"
908
909                     files_name = pattern_patch_dico[patch_id]
910
911                     if "-p" not in EXEC_COMMAND:
912                         EXEC_COMMAND += " -p0"
913
914                     if files_name.endswith( ".bz2" ):
915                         bzcat_cmd = "bzcat ${S}/packaging/%s | patch -s %s --fuzz=2\n"
916                         bzcat_val = ( files_name, EXEC_COMMAND.replace( " -b", " -b --suffix" ) )
917                         res_prep_section += bzcat_cmd % bzcat_val
918                     else:
919                         cat_cmd = "cat ${S}/packaging/%s | patch -s %s --fuzz=2\n"
920                         cat_val = ( files_name, EXEC_COMMAND.replace( " -b", " -b --suffix" ) )
921                         res_prep_section += cat_cmd % cat_val
922
923             res_prep_section += line + "\n"
924         return res_prep_section
925
926     def get_build_section( self ):
927         '''
928         return the build section of the spec file.
929         '''
930         res_build_section = "cd ${S}\n"
931         if self.__build_flag not in self.__spect_dico.keys():
932             return 1
933
934         for line in self.__spect_dico[self.__build_flag][1:]:
935             res_build_section += line + "\n"
936
937         return res_build_section
938
939     def get_raw_build_section( self ):
940         '''
941         return the raw build section of the spec file.
942         '''
943         res_raw_build_section = ""
944         if self.__build_flag not in self.__spect_dico.keys():
945             return ""
946         for line in self.__raw_spect_dico[self.__build_flag][1:]:
947             res_raw_build_section += line + "\n"
948         return res_raw_build_section
949
950     def get_clean_raw( self ):
951         '''
952         clean the raw spec file to generate spec file for yocto packaging.
953         '''
954         res_clean_raw = ""
955         for sect in self.__order_raw_list:
956             if sect == self.__introduction_section:
957                 for line in self.__raw_spect_dico[sect]:
958                     if line.startswith("Version:"):
959                         res_clean_raw += "Version:        git\n"
960
961                     else:
962                         have_findall_source = len( re.findall( RePattern.patternSource , line ) ) > 0
963                         have_findall_patch = len( re.findall( RePattern.patternPatch, line ) ) > 0
964                         if not( have_findall_source or have_findall_patch ):
965                             res_clean_raw += line + "\n"
966
967
968             elif sect == self.__prep_flag:
969                 res_clean_raw += line + "%prep\n"
970                 res_clean_raw += line + "#FAKE\n"
971             elif sect == self.__build_flag:
972                 res_clean_raw += line + "%build\n"
973                 res_clean_raw += line + "#FAKE\n"
974             elif sect == self.__install_flag:
975                 res_clean_raw += line + "%install\n"
976                 res_clean_raw += line + "#FAKE\n"
977             elif sect == self.__check_flag:
978                 pass
979             elif sect == self.__clean_flag:
980                 pass
981             elif sect == self.__changelog_flag:
982                 pass
983             elif sect.startswith( "%files" ):
984                 for line in self.__raw_spect_dico[sect]:
985                     if line.startswith( '%manifest ' ):
986                         res_clean_raw += line[len('%manifest '):] + "\n"
987                     elif line.startswith( '%doc ' ):
988                         pass
989                     elif line.startswith( '%ghost ' ):
990                         pass
991                     elif line.startswith( '%exclude ' ):
992                         pass
993                     elif line.startswith( '%license' ):
994                         pass
995
996                     else:
997                         res_clean_raw += line + "\n"
998
999             else:
1000                 for line in self.__raw_spect_dico[sect]:
1001                     res_clean_raw += line + "\n"
1002
1003         clean_raw_command = self.init_rpmspec_command()
1004
1005         tmp_package_spec_path = self.__package_spec_path
1006         with tempfile.NamedTemporaryFile( mode = 'w',
1007                 suffix = '.tmp',
1008                 prefix = os.path.basename( tmp_package_spec_path ) + ".",
1009                 dir = os.path.dirname( tmp_package_spec_path ),
1010                 delete = False ) as  tmp_spec_file:
1011             tmp_spec_file.write( res_clean_raw )
1012             tmp_package_spec_path = tmp_spec_file.name
1013
1014         clean_raw_command += " --define='debug_package %{nil}'"
1015         clean_raw_command += " --define='docs_package %{nil}'"
1016
1017         clean_raw_command += " --parse %s " % tmp_package_spec_path
1018         if DEBUG_RUN:
1019             print "clean_raw_command :", clean_raw_command
1020
1021         parsed_spec_file = SpecParser.msubprocess.exec_subprocess( clean_raw_command )
1022
1023         if os.path.isfile( tmp_package_spec_path ) and not DEBUG_RUN:
1024             os.remove( tmp_package_spec_path )
1025
1026         if parsed_spec_file == 1:
1027             print >> sys.stderr, "parse error for spec file %s" % ( tmp_package_spec_path )
1028             parsed_spec_file = None
1029             return 1
1030
1031         fake_dbg = '''
1032 %%package -n %s-dbg
1033 Summary: #FAKE - Debugging files
1034 Group: devel
1035
1036 %%description -n %s-dbg
1037 #FAKE
1038
1039
1040 %%files -n %s-dbg
1041 %%defattr(-,-,-,-)
1042 ''' % ( self.__base_name, self.__base_name, self.__base_name )
1043         work_dir = os.getenv( "WORKDIR" )
1044
1045         if work_dir is None:
1046             return parsed_spec_file
1047
1048         base_root = os.path.join( work_dir, "package" )
1049         for root, dirs, files in os.walk( base_root ):
1050             if root.endswith( ".debug" ):
1051                 if DEBUG_RUN:
1052                     print "find directory %s " % dirs
1053                 for a_file in files:
1054                     fake_dbg += os.path.join( root, a_file ).replace( base_root, "" ) + "\n"
1055         #Test don't add dbg files
1056         #return parsed_spec_file + fake_dbg
1057
1058         return parsed_spec_file
1059
1060     def get_install_section( self ):
1061         '''
1062         return the install section.
1063         '''
1064         res_install_section = "cd ${S}\n"
1065
1066         for line in self.__spect_dico[self.__install_flag][1:]:
1067             res_install_section += line + "\n"
1068         return res_install_section
1069
1070     def get_description( self ):
1071         '''
1072         return the description of the spec file.
1073         '''
1074         for line in self.__spect_dico[self.__introduction_section] :
1075             description = re.findall( RePattern.patternDescription, line )
1076             if len( description ) > 0:
1077                 return description[0]
1078         return ""
1079
1080     def get_homepage( self ):
1081         '''
1082         return the homepage of the spec file project.
1083         '''
1084         for line in self.__spect_dico[self.__introduction_section] :
1085             description = re.findall( RePattern.patternUrl, line )
1086             if len( description ) > 0:
1087                 return description[0]
1088         return ""
1089
1090     def get_section( self ):
1091         '''
1092         return the section of the spec file project.
1093         '''
1094         for line in self.__spect_dico[self.__introduction_section] :
1095             description = re.findall( RePattern.patternGroup, line )
1096             if len( description ) > 0:
1097                 return description[0]
1098         return "System/Base"
1099
1100     def get_license( self ):
1101         '''
1102         return the licence of the package.
1103         '''
1104         for line in self.__spect_dico[self.__introduction_section] :
1105             description = re.findall( RePattern.patternLicense, line )
1106             if len( description ) > 0:
1107                 res_license = description[0]
1108                 if ";" in res_license:
1109                     res_license = res_license.replace( ";", "" )
1110
1111                 return res_license
1112         return ""
1113
1114     def get_section_key(self, __flag):
1115         '''
1116         Return the list of "__flag" sections of the spec file.
1117         '''
1118         res_section = []
1119         for section_key in self.__spect_dico.keys():
1120             if section_key.startswith(__flag):
1121                 res_section.append(section_key)
1122
1123         return res_section
1124
1125     def get_script_section_key_pre(self):
1126         '''
1127         Return the list of pre script section of the spec file.
1128         get_section_key() can't be used in this case since it will also
1129         return the %preun and %prep results.
1130         '''
1131         res_script_section = []
1132         for section_key in self.__spect_dico.keys():
1133             if section_key.startswith("%pre") and \
1134                     not section_key.startswith("%preun") and \
1135                     not section_key.startswith("%prep"):
1136                 res_script_section.append(section_key)
1137
1138         return res_script_section
1139
1140     def get_script_section_key_post(self):
1141         '''
1142         Return the list of post script section of the spec file.
1143         get_section_key() can't be used in this case since it will also
1144         return the %postun results.
1145         '''
1146         res_script_section = []
1147         for section_key in self.__spect_dico.keys():
1148             if section_key.startswith("%post") and not section_key.startswith("%postun"):
1149                 res_script_section.append(section_key)
1150
1151         return res_script_section
1152
1153     def get_files_list_from_section( self, package_section_name ):
1154         '''
1155         return a list of file
1156         '''
1157         res_list = []
1158         for line in self.__spect_dico[package_section_name][1:]:
1159             if not line.startswith( "%" ) and not line == "":
1160                 line = line.replace( "//", "/" )
1161                 res_list.append( line )
1162             elif line.startswith( "%attr(" ):
1163                 line = line.replace( "//", "/" )
1164                 pkg_f_clean=line.split(")")
1165                 pkg_f=pkg_f_clean[-1].strip()
1166                 res_list.append( pkg_f )
1167             elif line.startswith( "%doc " ):
1168                 line = line.replace( "//", "/" )
1169                 res_list.append( line.replace( "%doc ", "" ) )
1170             elif line.startswith( "%dir " ):
1171                 line = line.replace( "//", "/" )
1172                 res_list.append( line.replace( "%dir ", "" ) )
1173             elif line.startswith( "%config " ):
1174                 line = line.replace( "//", "/" )
1175                 res_list.append( line.replace( "%config ", "" ) )
1176             elif line.startswith( "%manifest " ):
1177                 line = line.replace( "//", "/" )
1178                 res_list.append( line.replace( "%manifest ", "" ) )
1179             elif line.startswith( "%config(noreplace) " ):
1180                 line = line.replace( "//", "/" )
1181                 res_list.append( line.replace( "%config(noreplace) ", "" ) )
1182             elif line.startswith( "%config(" ):
1183                 line = line.replace( "//", "/" )
1184                 pkg_f_clean=line.split(")")
1185                 pkg_f=pkg_f_clean[-1].strip()
1186                 res_list.append( pkg_f )
1187             else:
1188                 pass
1189
1190         return res_list
1191
1192     def get_script_from_section(self, __flag):
1193         '''
1194         Return the pre/post script section of the spec file.
1195         '''
1196         res_script_section = ""
1197         if __flag in self.__spect_dico.keys():
1198             for line in self.__spect_dico[__flag][1:]:
1199                 res_script_section += line + "\n"
1200
1201         return res_script_section
1202
1203     def get_files_packages( self ):
1204         '''
1205         return a dictinaire with package for key and list of files fo value.
1206         '''
1207         res_dico = {}
1208
1209         for package_section_name in self.get_section_key("%file"):
1210             tmp_package_name = package_section_name
1211             # Need to get info of the first line.
1212             if "-f " in tmp_package_name:
1213                 tmp_split = tmp_package_name.split( "-f " )
1214                 tmp_package_name = tmp_split[0]
1215
1216             package = re.findall( RePattern.patternFiles, tmp_package_name )
1217             if len( package ) > 0:
1218                 if "-n " in package[0]:
1219                     package_name = package[0].replace( "-n ", "" )
1220                 else:
1221                     package_name = self.__base_name
1222                     pkg_ext = package[0].replace( " ", "" )
1223                     if len( pkg_ext ) > 0:
1224                         package_name += "-" + pkg_ext
1225             else:
1226                 package_name = self.__base_name
1227
1228             package_name = package_name.replace( " ", "" )
1229             res_files_list = self.get_files_list_from_section( package_section_name )
1230             res_dico[ package_name ] = res_files_list
1231
1232         #db_src=self.__base_name+"-debugsource"
1233         #if db_src not in res_dico:
1234         #    res_dico[db_src] = []
1235
1236         #dbinfo=self.__base_name+"-debug"
1237         #if dbinfo not in res_dico:
1238         #    res_dico[dbinfo] = []
1239
1240         return res_dico
1241
1242     def get_name( self ):
1243         '''
1244         return the name of the package
1245         '''
1246         for line in self.__spect_dico[self.__introduction_section]:
1247             description = re.findall( RePattern.patternName, line )
1248             if len( description ) > 0:
1249                 return description[0]
1250         return ""
1251
1252     def get_provides( self ):
1253         '''
1254         return all provide service by each package of the spec file.
1255         '''
1256         provide_res = {}
1257         provide_res[self.__base_name] = []
1258         provide_res[self.__base_name].append( [self.__base_name] )
1259
1260         for k in self.__spect_dico.keys():
1261             package = re.findall( RePattern.patternPackage, k )
1262             if len( package ) > 0:
1263                 package_name = self.__clean_package_name( package[0] )
1264                 provide_res[ package_name ] = []
1265                 provide_res[ package_name ].append( [package_name] )
1266
1267             if len( package ) > 0 or ( k == self.__introduction_section ):
1268                 for line in self.__spect_dico[k]:
1269                     provides = re.findall( RePattern.provides_package, line )
1270                     for provides_line in provides:
1271                         for tmp_clean in self.__clean_package_line( provides_line ):
1272                             if k == self.__introduction_section:
1273                                 provide_res[self.__base_name].append( tmp_clean )
1274                             else:
1275                                 provide_res[package_name].append( tmp_clean )
1276         return provide_res
1277
1278     def __clean_package_name( self, package_name ):
1279         '''
1280         return the package name from spec declaration.
1281         '''
1282         # re should be better.
1283         if "-n " in package_name:
1284             package_name = package_name.replace( "-n ", "" ).replace( " ", "" )
1285         else:
1286             package_name = self.__base_name + "-" + package_name
1287
1288         return package_name
1289
1290     def get_rdepends( self ):
1291         '''
1292         return all require service by each package of the spec file.
1293         '''
1294         rdepends_res = {}
1295
1296         for k in  self.__spect_dico.keys():
1297             package = re.findall( RePattern.patternPackage, k )
1298
1299             if len( package ) > 0:
1300                 package_name = self.__clean_package_name( package[0] )
1301             else:
1302                 package_name = self.__base_name
1303
1304             if len( package ) > 0 or ( k == self.__introduction_section ):
1305                 requires_list = self.get_requires( self.__spect_dico[k] )
1306                 rdepends_res[package_name] = requires_list
1307         return rdepends_res
1308
1309
1310     def get_depends( self ):
1311         '''
1312         return all build require service by each package of the spec file.
1313         '''
1314         depends_res = {}
1315
1316         for k in self.__spect_dico.keys():
1317             package = re.findall( RePattern.patternPackage, k )
1318             if len( package ) > 0:
1319                 package_name = self.__clean_package_name( package[0] )
1320
1321             if len( package ) > 0 or ( k == self.__introduction_section ):
1322                 build_requires_list = self.get_build_requires( self.__spect_dico[k] )
1323                 if ( k == self.__introduction_section ):
1324                     depends_res[self.__base_name] = build_requires_list
1325                 else:
1326                     depends_res[package_name] = build_requires_list
1327
1328
1329         return depends_res
1330
1331     def __clean_package_line( self, package_line ):
1332         '''
1333         return package list from package declaration in spec file.
1334         '''
1335         res_first = re.findall( RePattern.pkgRe, package_line )
1336         if len( res_first ) == 0:
1337             print "__clean_package_line faild for %s" % self.__package_spec_path
1338             raise Exception()
1339         # should be rewrite cleaner.
1340         res_final = []
1341         for init_res in res_first:
1342             init_res = list( init_res )
1343             init_res[0] = init_res[0].replace( ",", "" )
1344             res_final.append( init_res )
1345         return res_final
1346
1347     def get_build_requires( self, lines ):
1348         '''
1349         return the line of every build requires.
1350         '''
1351         package_replacement = SPEC2YOCTO_CONFIG.get_substitute()
1352         build_requires_res = []
1353         for line in lines:
1354             build_requires = re.findall( RePattern.buildRequiresPackage, line )
1355             for tmp_res in build_requires:
1356                 for tmp_clean in self.__clean_package_line( tmp_res ):
1357                     if len( tmp_clean ) >= 1:
1358                         if tmp_clean[0] in package_replacement.keys():
1359                             tmp_clean[0] = package_replacement[tmp_clean[0]]
1360                         build_requires_res.append( tmp_clean )
1361         return build_requires_res
1362
1363     def get_requires( self, lines ):
1364         '''
1365         return the line of every requires.
1366         '''
1367         package_replacement = SPEC2YOCTO_CONFIG.get_substitute()
1368
1369         requires_res = []
1370         for line in lines:
1371             build_requires = re.findall( RePattern.requiresPackage, line )
1372             for tmp_res in build_requires:
1373                 for tmp_clean in self.__clean_package_line( tmp_res ):
1374                     if len( tmp_clean ) >= 1:
1375                         if tmp_clean[0] in package_replacement.keys():
1376                             tmp_clean[0] = package_replacement[tmp_clean[0]]
1377                         requires_res.append( tmp_clean )
1378         return requires_res
1379
1380 class MetaSpec:
1381     '''
1382     meta spec file for generate yocto bb.
1383     '''
1384     mProvidesDico = {}
1385     mExtraRProvidesDico = {}
1386
1387     mCrossPackageBlacklist = []
1388     mInitialPackageBlacklist = []
1389     mNativePackageBlacklist = []
1390     mOePackageBlacklist = []
1391
1392     def __init__( self,
1393                 package_recipes_dir,
1394                 package_name,
1395                 package_spec_path,
1396                 package_git_srv_src,
1397                 package_git_srv_path,
1398                 package_git_tag ):
1399         '''
1400         init the MetaSpec class
1401         '''
1402         self.__package_recipes_dir = package_recipes_dir
1403         self.__package_name = package_name
1404
1405
1406         self.__package_git_srv_src = package_git_srv_src
1407         self.__package_git_srv_path = package_git_srv_path
1408
1409         self.__package_spec_path = package_spec_path
1410         self.__git_tag = package_git_tag
1411
1412         self.__spec_parser = SpecParser( self.__package_spec_path )
1413         self.__package_spec_name = self.__spec_parser.get_name()
1414
1415         self.__packages_dico = self.__spec_parser.get_files_packages()
1416         self.__provides_dico = self.__spec_parser.get_provides()
1417
1418         self.setm_provided_dico()
1419         self.__rdepends_dico = self.__spec_parser.get_rdepends()
1420
1421         self.__base_file = self.__package_name + ".inc"
1422         #self.__base_depends_file = self.__package_name + "-depends.inc"
1423         #self.__base_rdepends_file = self.__package_name + "-rdepends.inc"
1424         #self.__base_provides_file = self.__package_name + "-rprovides.inc"
1425
1426         self.__extra_conf_file = self.__package_name + "-extraconf.inc"
1427         #self.__extra_native_conf_file = self.__package_name + "-native-extraconf.inc"
1428         #self.__extra_oe_conf_file = self.__package_name + "-oe-extraconf.inc"
1429
1430         self.__git_native_file = self.__package_name + "-native_git.bb"
1431         self.__git_oe_file = self.__package_name + "_git.bb"
1432
1433         self.__createRecipes()
1434
1435     def setm_provided_dico( self ):
1436         '''
1437         add provides_list for package_name to mProvidesDico
1438         '''
1439         provides_list = []
1440         for k_provide in self.__provides_dico.keys():
1441             for p_provide in self.__provides_dico[k_provide]:
1442                 provides_list.append( p_provide[0] )
1443         for p_provide in self.__packages_dico.keys():
1444             provides_list.extend( self.__packages_dico[p_provide] )
1445
1446         for package in self.__packages_dico.keys():
1447             for pkg_file in self.__packages_dico[package]:
1448                 pkgconfig_name_res = re.findall( RePattern.pkgconfig_name, pkg_file )
1449                 for tmp_res in pkgconfig_name_res:
1450                     provides_list.append( "pkgconfig(%s)" % tmp_res )
1451
1452         MetaSpec.mProvidesDico[self.__package_name] = provides_list
1453
1454     def set_mextra_provided_dico( self ):
1455         '''
1456         add provides_list for package_name to mExtraRProvidesDico
1457         '''
1458         provides_list = []
1459         for k_provide in self.__provides_dico.keys():
1460             for p_provide in self.__provides_dico[k_provide]:
1461                 provides_list.append( p_provide[0] )
1462         for p_provide in self.__packages_dico.keys():
1463             provides_list.extend( self.__packages_dico[p_provide] )
1464
1465         MetaSpec.mExtraRProvidesDico[self.__package_name] = provides_list
1466
1467     def __create_base_file( self ):
1468         '''
1469         create the base file of the bb file.
1470         '''
1471         bb_path = os.path.join( self.__package_recipes_dir, self.__base_file )
1472         with open( bb_path, "w" ) as file_d:
1473
1474             _description = self.__spec_parser.get_description()
1475             _homepage = self.__spec_parser.get_homepage()
1476             _section = self.__spec_parser.get_section()
1477             _priority = "10"
1478             _license = self.__spec_parser.get_license()
1479
1480             file_d.write( "DESCRIPTION = \"%s\"\n" % _description )
1481             if len( _homepage ) < 2:
1482                 _homepage = "http://nohomepage.org"
1483             file_d.write( "HOMEPAGE = \"%s\"\n" % _homepage )
1484             file_d.write( "SECTION = \"%s\"\n" % _section )
1485
1486             file_d.write( "LICENSE = \"%s\"\n" % _license )
1487             file_d.write( "\n" )
1488             file_d.write( "SRC_URI = \"\"\n" )
1489             file_d.write( "\n" )
1490             file_d.write( "S = \"${WORKDIR}/git\"\n" )
1491             file_d.write( "\n" )
1492
1493             file_d.write( "inherit autotools-brokensep\n" )
1494             file_d.write( "\n" )
1495             file_d.write( "BBCLASSEXTEND = \"\"\n"  )
1496
1497             self.__create_provides_file( file_d)
1498             self.__create_rdepends( file_d)
1499             self.__create_depends( file_d)
1500
1501             self.__create_patch( file_d)
1502             self.__create_configure( file_d)
1503             self. __create_compile( file_d)
1504             self.__create_install( file_d)
1505
1506             self.__create_script_file( file_d)
1507
1508             self.__create_files_packaging( file_d )
1509
1510             file_d.write( "require %s\n\n" % self.__extra_conf_file )
1511
1512     def __create_files_packaging(self,file_d):
1513             file_d.write( "PACKAGES = \"${PN}-dbg ${PN}-doc ${PN}-locale\"\n" )
1514             for package in self.__packages_dico.keys():
1515                 pkg_yocto_name=package
1516                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1517                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1518
1519                 if  pkg_yocto_name not in [self.__package_name+"-dbg",
1520                                            self.__package_name+"-doc",
1521                                            self.__package_name+"-locale",
1522                                           ]:
1523                     file_d.write( "PACKAGES += \" %s \"\n" % pkg_yocto_name )
1524
1525             file_d.write( "\n" )
1526
1527             _license = self.__spec_parser.get_license()
1528
1529             for package in self.__packages_dico.keys():
1530                 pkg_yocto_name=package
1531                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1532                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1533
1534                 file_d.write( "%s_files = \"\"\n" % pkg_yocto_name )
1535
1536                 for pkg_f in self.__packages_dico[package]:
1537                     pkg_f=pkg_f.strip()
1538
1539                     if  pkg_f.startswith( _license ):
1540                         pass
1541                     else:
1542                         pkg_yocto_name = package.replace("-devel","-dev")
1543                         file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, pkg_f ) )
1544
1545                 file_d.write( "\n" )
1546
1547             for package in self.__packages_dico.keys():
1548                 p_parse = package.replace( self.__package_name, "${PN}" )
1549                 p_parse = p_parse.replace("-devel","-dev")
1550                 pkg_yocto_name = package.replace("-devel","-dev")
1551                 file_d.write( "FILES_%s = \"${%s_files}\"\n" % ( p_parse, pkg_yocto_name ) )
1552             file_d.write( "\n" )
1553
1554             for package in self.__packages_dico.keys():
1555                 pkg_yocto_name = package.replace("-devel","-dev")
1556                 file_d.write( "PKG_%s= \"%s\"\n" % (pkg_yocto_name,pkg_yocto_name) )
1557             file_d.write( "\n" )
1558
1559     def __create_patch( self ,file_d):
1560         code=self.__spec_parser.get_prep_section()
1561         code=code.replace("\n","\n ")
1562         file_d.write( "do_prep() {\n" )
1563         file_d.write( " %s\n" % code )
1564         file_d.write( "}\n" )
1565         file_d.write( "do_patch_append() {\n" )
1566         file_d.write( "    bb.build.exec_func('do_prep', d)\n" )
1567         file_d.write( "}\n" )
1568         file_d.write( "\n" )
1569
1570     def __create_configure( self ,file_d):
1571         file_d.write( "do_configure() {\n" )
1572         file_d.write( "}\n" )
1573         file_d.write( "\n" )
1574
1575     def __create_compile( self ,file_d):
1576         code=self.__spec_parser.get_build_section()
1577         code=code.replace("\n","\n ")
1578         
1579         file_d.write( "do_compile() {\n" )
1580         file_d.write( " %s\n" % code )
1581         file_d.write( "}\n" )
1582         file_d.write( "\n" )
1583
1584     def __create_install( self ,file_d):
1585         code=self.__spec_parser.get_install_section()
1586         code=code.replace("\n","\n ")
1587         code=code.replace("\n EOF","\nEOF")
1588         file_d.write( "do_install() {\n" )
1589         file_d.write( " echo export RPM_BUILD_ROOT=${D}\n" )
1590         file_d.write( " %s\n" % code )
1591         file_d.write( "}\n" )
1592         file_d.write( "\n" )
1593
1594     def __create_script_file_section_code( self, spec_section):
1595         '''
1596         Returns the command executed in one of the %pre, %post, %preun
1597         or %postun section of a spec file.
1598         '''
1599         code = self.__spec_parser.get_script_from_section(spec_section)
1600         command_list = code.split("\n")
1601         formated_code = ""
1602         for line in command_list:
1603
1604             if line != "":
1605                 formated_code += "    " + line + "\n"
1606
1607         return formated_code
1608
1609     def __create_script_file_write( self, file_d, code, recipe_section, package_name):
1610         '''
1611         Writes the pre/post (un)install sections of the recipe.
1612         '''
1613         code=code.replace("/sbin/ldconfig","[ \"x\$D\" == \"x\" ] && ldconfig")
1614         code=code.replace("${prefix}","$D${prefix}")
1615
1616
1617         file_d.write("%s%s() {\n" % (recipe_section, package_name))
1618         file_d.write("    #!/bin/sh -e\n\n")
1619         file_d.write("%s\n" % code)
1620         file_d.write("}\n")
1621         file_d.write("\n")
1622
1623     def __create_script_file_session(self, file_d, flag, script_name, script_sections):
1624         '''
1625         Add script for the given flag.
1626         '''
1627         for section in script_sections:
1628             code = ""
1629             # If %section is a one line script such as: "%post -p /sbin/ldconfig"
1630             if " -p " in section:
1631                 # Remove the package name if present to only keep the command
1632                 section_split = section.split(" -p ")[1].split(" -n ")
1633                 code = "    " + section_split[0].strip()
1634             else:
1635                 code = self.__create_script_file_section_code(section)
1636             if code != "":
1637                 # Set the package name
1638                 package_name = "${PN}"
1639                 # If the package name is not the project name
1640                 if " -n " in section:
1641                     # Remove the command if any to only keep the package name
1642                     section_split = section.split(" -n ")[1].split(" -p ")
1643                     package_name = section_split[0].strip()
1644                 self.__create_script_file_write(file_d, code, script_name, package_name)
1645
1646     def __create_script_file(self, file_d):
1647         '''
1648         Add the pre/post install/uninstall sections of a spec file to
1649         the recipe.
1650         '''
1651         script_sections = self.__spec_parser.get_script_section_key_pre()
1652         self.__create_script_file_session(file_d, "%pre", "pkg_preinst_", script_sections)
1653
1654         script_sections = self.__spec_parser.get_script_section_key_post()
1655         self.__create_script_file_session(file_d, "%post", "pkg_postinst_", script_sections)
1656
1657         script_sections = self.__spec_parser.get_section_key("%preun")
1658         self.__create_script_file_session(file_d, "%preun", "pkg_prerm_", script_sections)
1659
1660         script_sections = self.__spec_parser.get_section_key("%postun")
1661         self.__create_script_file_session(file_d, "%postun", "pkg_postrm_", script_sections)
1662
1663     def __create_provides_file( self ,file_d):
1664         '''
1665         generate provide file.
1666         '''
1667         file_d.write( "PROVIDES = \"\"\n" )
1668         file_d.write( "\n" )
1669
1670         for k_provide in self.__provides_dico.keys():
1671             pkg_yocto_name=k_provide
1672             for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1673                 pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1674
1675             if len( self.__provides_dico[k_provide] ) > 0:
1676                 file_d.write( "#PROVIDES by %s\n" % pkg_yocto_name.replace(" ","") )
1677
1678             for p_provide in self.__provides_dico[k_provide]:
1679                 pkg = p_provide[0]
1680                 pkg_yocto=pkg
1681                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto ):
1682                      pkg_yocto=pkg_yocto.replace("-devel","-dev")
1683
1684                 if not len( p_provide ) == 1:
1685                     provide_text = "# the PROVIDES rules is ignore \"%s %s %s\"\n"
1686                     file_d.write( provide_text % ( pkg_yocto, p_provide[1], p_provide[2] ) )
1687
1688                 if ( pkg == "mktemp" and self.__package_name == "tizen-coreutils" ):
1689                     continue
1690
1691
1692                 if pkg_yocto_name != pkg_yocto:
1693                    file_d.write( "PROVIDES += \"%s\"\n" % ( pkg_yocto ) )
1694                    file_d.write( "RPROVIDES_%s += \"%s\"\n" % ( pkg_yocto_name, pkg_yocto ) )
1695
1696                 #for res_pkg_devel in re.findall( RePattern.paternDevel, pkg ):
1697                 #    rprovide_text = "RPROVIDES_%s += \"%s\"\n"
1698                 #    file_d.write( rprovide_text % ( k_provide, res_pkg_devel + "-dev" ) )
1699
1700             if len( self.__provides_dico[k_provide] ) > 0:
1701                 file_d.write( "\n\n" )
1702
1703     def __create_git_native_file( self ):
1704         '''
1705         create bb native file.
1706         '''
1707         bb_native_path = os.path.join( self.__package_recipes_dir, self.__git_native_file )
1708         with open( bb_native_path, "w" ) as file_d:
1709             file_d.write( "require %s\n" % self.__base_file )
1710             file_d.write( "\n" )
1711             file_d.write( "PRIORITY = \"9\"\n" )
1712             file_d.write( "\n" )
1713             file_d.write( "inherit native\n" )
1714             file_d.write( "\n" )
1715             file_d.write( "S = \"${WORKDIR}/git\"\n" )
1716             file_d.write( "\n" )
1717
1718             md5_value = "801f80980d171dd6425610833a22dbe6"
1719             file_value = "${COMMON_LICENSE_DIR}/GPL-2.0"
1720             file_chksum_text = "LIC_FILES_CHKSUM ??= \"file://%s;md5=%s\"\n"
1721             # should be generat
1722             file_d.write( file_chksum_text % ( file_value, md5_value ) )
1723             file_d.write( "\n" )
1724             command_source = "SRC_URI += \"%s\"\n" % GIT_COMMAND
1725             file_d.write( command_source % ( self.__package_git_srv_src ,
1726                                              self.__package_git_srv_path ,
1727                                              self.__git_tag ) )
1728             #file_d.write( "require %s\n" % self.__extra_native_conf_file )
1729             file_d.write( "\n" )
1730
1731     def __create_git_oe_file( self ):
1732         '''
1733         generate  bb file.
1734         '''
1735         bb_path = os.path.join( self.__package_recipes_dir, self.__git_oe_file )
1736         with open( bb_path, "w" ) as file_d:
1737             file_d.write( "require %s\n" % self.__base_file )
1738             file_d.write( "\n" )
1739             file_d.write( "PRIORITY = \"10\"\n" )
1740             file_d.write( "\n" )
1741             md5_value = "801f80980d171dd6425610833a22dbe6"
1742             file_value = "${COMMON_LICENSE_DIR}/GPL-2.0"
1743             file_chksum_text = "LIC_FILES_CHKSUM ??= \"file://%s;md5=%s\"\n"
1744             # should be generat
1745             file_d.write( file_chksum_text % ( file_value, md5_value ) )
1746             file_d.write( "\n" )
1747             command_source = "SRC_URI += \"" + GIT_COMMAND + "\"\n"
1748             file_d.write( command_source % ( self.__package_git_srv_src ,
1749                                              self.__package_git_srv_path ,
1750                                              self.__git_tag ) )
1751             #file_d.write( "require %s\n" % self.__extra_oe_conf_file )
1752             file_d.write( "\n" )
1753             if  self.__package_name not in MetaSpec.mNativePackageBlacklist:
1754                 file_d.write( "BBCLASSEXTEND += \" native \"" )
1755             file_d.write( "\n\n" )
1756
1757     def __createRecipes( self ):
1758         '''
1759         generate all bb file.
1760         '''
1761         if self.__package_recipes_dir is  None:
1762             return
1763
1764         if not os.path.isdir( self.__package_recipes_dir ):
1765             os.makedirs( self.__package_recipes_dir )
1766
1767         # Just touch a file
1768         #rdepends_path = os.path.join( self.__package_recipes_dir, self.__base_rdepends_file )
1769         #open( rdepends_path, "a" ).close()
1770         #depends_path = os.path.join( self.__package_recipes_dir, self.__base_depends_file )
1771         #open( depends_path, "a" ).close()
1772         #provides_path = os.path.join( self.__package_recipes_dir, self.__base_provides_file )
1773         #open( provides_path, "a" ).close()
1774
1775         extra_conf_file_path = os.path.join( self.__package_recipes_dir, self.__extra_conf_file )
1776         open( extra_conf_file_path, "a" ).close()
1777
1778         #extranative_path = os.path.join( self.__package_recipes_dir, self.__extra_native_conf_file )
1779         #open( extranative_path, "a" ).close()
1780         #extra_oe_conf_path = os.path.join( self.__package_recipes_dir, self.__extra_oe_conf_file )
1781         #open( extra_oe_conf_path, "a" ).close()
1782
1783         self.__create_base_file()
1784
1785         if  not self.__package_name not in MetaSpec.mNativePackageBlacklist:
1786             bb_native_path = os.path.join( self.__package_recipes_dir, self.__git_native_file )
1787             if os.path.isfile( bb_native_path ):
1788                 os.unlink( bb_native_path )
1789
1790         #self.__create_provides_file()
1791
1792         if self.__package_name not in MetaSpec.mOePackageBlacklist:
1793             self.__create_git_oe_file()
1794         else:
1795             bb_oe_path = os.path.join( self.__package_recipes_dir, self.__git_oe_file )
1796             if os.path.isfile( bb_oe_path ):
1797                 os.unlink( bb_oe_path )
1798
1799     def __create_rdepends( self ,file_d):
1800         '''
1801         generate rdepends file.
1802         '''
1803         if self.__package_recipes_dir is  None:
1804             return
1805
1806         if not os.path.isdir( self.__package_recipes_dir ):
1807             os.makedirs( self.__package_recipes_dir )
1808
1809         #rdepends_path = os.path.join( self.__package_recipes_dir, self.__base_rdepends_file )
1810
1811         package_replacement = SPEC2YOCTO_CONFIG.get_substitute()
1812
1813         if file_d is not None:
1814             file_d.write( "RDEPENDS = \"\"\n" )
1815
1816             for k_provide in self.__rdepends_dico.keys():
1817                 pkg_yocto_name=k_provide
1818                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1819                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1820
1821                 res_rdepends = set()
1822                 k_provide_replace = pkg_yocto_name.replace( self.__package_name, "${PN}" )
1823                 if len( self.__rdepends_dico[k_provide] ) > 0:
1824                     file_d.write( "#RDEPENDS of %s (%s)\n" % ( pkg_yocto_name, k_provide_replace ) )
1825
1826                 for provide in self.__rdepends_dico[k_provide]:
1827                     package_provide = provide[0]
1828
1829                     res = None
1830
1831                     for k_package_provide in MetaSpec.mExtraRProvidesDico.keys():
1832
1833                         if package_provide in MetaSpec.mExtraRProvidesDico[k_package_provide] \
1834                            or package_provide == k_package_provide:
1835                             res = k_package_provide
1836                             break
1837                     if res is None:
1838                         res = package_provide
1839
1840                     if res in package_replacement.keys():
1841                         res = package_replacement[res]
1842
1843                     res_rdepends.add( res )
1844
1845                 for pkg in res_rdepends:
1846                     res_pkg_devel = re.findall( RePattern.paternDevel, pkg )
1847
1848                     if len( res_pkg_devel ) > 0:
1849                         rdepends_value = "RDEPENDS_%s += \"%s\"\n"
1850                         file_d.write( rdepends_value % ( k_provide_replace, res_pkg_devel[0] + "-dev" ) )
1851                     else:
1852                         if not pkg in  SPEC2YOCTO_CONFIG.get_ignore_rdepend():
1853                             file_d.write( "RDEPENDS_%s += \"%s\"\n" % ( k_provide_replace, pkg ) )
1854
1855                 if len( self.__rdepends_dico[k_provide] ) > 0:
1856                     file_d.write( "\n" )
1857
1858             file_d.write( "\n" )
1859
1860     def __create_depends( self, file_d):
1861         '''
1862         create depends file.
1863         '''
1864         if self.__package_recipes_dir is  None:
1865             return
1866
1867         if not os.path.isdir( self.__package_recipes_dir ):
1868             os.makedirs( self.__package_recipes_dir )
1869
1870         depends_dico = self.__spec_parser.get_depends()
1871         #depends_path = os.path.join( self.__package_recipes_dir, self.__base_depends_file )
1872
1873         ignore_depend_list = SPEC2YOCTO_CONFIG.get_ignore_depend()
1874         native_depend_list = SPEC2YOCTO_CONFIG.get_native_depend()
1875         cross_depend_list = SPEC2YOCTO_CONFIG.get_cross_depend()
1876
1877
1878         if file_d is not None:
1879             file_d.write( "DEPENDS = \"\"\n" )
1880
1881             res_depends = set()
1882             for k_provide in depends_dico.keys():
1883                 if len( depends_dico[k_provide] ) > 0:
1884                     file_d.write( "#DEPENDS of %s\n" % k_provide )
1885
1886                 for p_provide in depends_dico[k_provide]:
1887                     pp_provide = p_provide[0]
1888                     res = None
1889
1890                     if pp_provide in ignore_depend_list:
1891                         continue
1892
1893                     for k in MetaSpec.mProvidesDico.keys():
1894                         if pp_provide in MetaSpec.mProvidesDico[k] or pp_provide == k:
1895                             res = k
1896                             break
1897                     for k_package_provide in MetaSpec.mExtraRProvidesDico.keys():
1898                         if pp_provide in MetaSpec.mExtraRProvidesDico[k_package_provide]:
1899                             res = k_package_provide
1900                             break
1901
1902                     if res is None:
1903                         if pp_provide not in SPEC2YOCTO_CONFIG.get_inherit_gettext() and \
1904                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit("python") and \
1905                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit("cmake") and \
1906                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit("perl") and \
1907                           pp_provide not in ignore_depend_list and \
1908                           pp_provide not in native_depend_list and \
1909                           pp_provide not in cross_depend_list:
1910
1911                             erro_msg = "No direct provider for package DEPENDS %s : \"%s\"."
1912                             print erro_msg % ( self.__package_name, pp_provide )
1913                         res = pp_provide
1914                     if res != self.__package_name :
1915                         res_depends.add( res )
1916
1917             # should be from a configue file.
1918             for res in res_depends:
1919                 pkg_yocto_name=res
1920                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1921                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1922
1923                 if pkg_yocto_name == "readline-dev":
1924                     pkg_yocto_name="readline"
1925
1926                 if pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit_gettext():
1927                     file_d.write( "#Replace \"DEPENDS\" on gettext by \"inherit gettext\"\n" )
1928                     file_d.write( "inherit gettext\n" )
1929                 elif pkg_yocto_name in native_depend_list:
1930                     file_d.write( "DEPENDS_append_class-native = \" %s-native\"\n" % pkg_yocto_name )
1931                     file_d.write( "DEPENDS_append_class-target = \" %s-native\"\n" % pkg_yocto_name )
1932                 elif pkg_yocto_name in cross_depend_list:
1933                     file_d.write( "DEPENDS_append_class-native = \" %s\"\n" % pkg_yocto_name )
1934                     file_d.write( "DEPENDS_append_class-target = \" %s-cross\"\n" % pkg_yocto_name )
1935                 elif pkg_yocto_name in ignore_depend_list:
1936                     pass
1937                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_libtool_cross():
1938                     file_d.write( "DEPENDS += \"libtool-cross\"\n" )
1939                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit("perl"):
1940                     file_d.write( "inherit perlnative\n"  )
1941                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit("python"):
1942                     file_d.write( "inherit pythonnative\n"  )
1943                 else:
1944                     file_d.write( "DEPENDS += \"%s\"\n" % pkg_yocto_name )
1945
1946         file_d.write( "\n"  )
1947
1948 def parse_manifest_xml( src ):
1949     primaryFile = open( src, "r" )
1950     primaryXML = primaryFile.read()
1951     primaryFile.close()
1952
1953     aElement = ElementTree.fromstring( primaryXML )
1954     remote = ""
1955     packages_dico = {}
1956     for value in aElement:
1957         for project in value.getiterator():
1958             if project.tag == "project":
1959                 name =  project.attrib['name']
1960                 c_name = clean_name( project.attrib['name'] )
1961                 revision = clean_revision( project.attrib['revision'] )
1962                 packages_dico[c_name] = [name, revision]
1963             elif project.tag == "default":
1964                   remote = project.attrib['remote']
1965             elif project.tag == "remote":
1966                 fetch = project.attrib['fetch']
1967                 name = project.attrib['name']
1968                 review = project.attrib['review']
1969             else:
1970                 print "ERROR"
1971
1972     return remote, packages_dico
1973
1974 class HTTPAccessFailure( Exception ):
1975     '''Indicate the http access failed'''
1976
1977 def download_url( url ):
1978     r = urlopen( url )
1979     if r.code != 200:
1980         raise HTTPAccessFailure()
1981     page = r.read()
1982
1983     return page
1984
1985 def download_manifest_url( url ):
1986     r = urlopen( url )
1987     if r.code != 200:
1988         print "ERROR %s " % url
1989         raise HTTPAccessFailure()
1990     page = r.read()
1991
1992     return page
1993
1994 def download_build_xml( url ):
1995     return download_url( url + "/build.xml" )
1996
1997 def get_project_id( xml ):
1998     aElement = ElementTree.fromstring( xml )
1999
2000     for value in aElement:
2001         for project in value.getiterator():
2002             if project.tag == "id":
2003                 return project.text
2004
2005 def get_project_arch( xml ):
2006     aElement = ElementTree.fromstring( xml )
2007     arch_list = []
2008     for value in aElement:
2009         for project in value.getiterator():
2010             if project.tag == "archs":
2011                 for arch in project.getiterator():
2012                     if arch.tag == "arch":
2013                         arch_list.append( arch.text )
2014
2015     return arch_list
2016
2017
2018 def clean_name( raw_name ):
2019     if "_" in raw_name:
2020         raw_name = raw_name.replace( "_", "-" )
2021
2022     if "/" in raw_name:
2023         return raw_name.split( "/" )[-1]
2024     else:
2025         return raw_name
2026
2027 def clean_revision( raw_name ):
2028     if "-" in raw_name:
2029         return raw_name.split( "-" )[0]
2030     else:
2031         return raw_name
2032
2033 def patch_the_spec_file( package_spec_path,
2034                          patch_path,
2035                          dest_spec_dir,
2036                          dest_spec_path ):
2037
2038     if not package_spec_path == dest_spec_path:
2039         shutil.copy2( package_spec_path, dest_spec_path )
2040
2041     if dest_spec_dir.endswith( "/packaging" ):
2042         dest_spec_dir = dest_spec_dir[:-len( "/packaging" )]
2043
2044     patch_command = "patch -s -p1 --fuzz=2 -d %s -i %s" % ( dest_spec_dir, patch_path )
2045
2046     a_sub_command = SubprocessCrt()
2047     res = a_sub_command.exec_subprocess( patch_command )
2048
2049     if res == 1:
2050             msg = "The patch \"%s\" can't be apply in directory \"%s\"."
2051             msg = msg % ( patch_path, dest_spec_dir )
2052             print >> sys.stderr, colorize( msg, "red" )
2053             print >> sys.stderr, colorize( "command: \"%s\"" % patch_command, "red" )
2054             sys.exit( 1 )
2055
2056     return dest_spec_path
2057
2058
2059 def specfile_patcher( package_spec_path, project, package_name_list , dest_spec_path ):
2060     working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2061     source_spec_patch_dir = os.path.join( working_dir, "specfile-patch" )
2062
2063     patch_path_list = findSpecPatchFiles( source_spec_patch_dir, package_name_list )
2064
2065     if len( patch_path_list ) > 0:
2066
2067         dest_spec_dir = os.path.dirname( dest_spec_path )
2068         if not os.path.isdir( dest_spec_dir ):
2069             os.makedirs( dest_spec_dir )
2070
2071         for patch_path in patch_path_list:
2072             package_spec_path = patch_the_spec_file( package_spec_path,
2073                                                      patch_path,
2074                                                      dest_spec_dir,
2075                                                      dest_spec_path )
2076
2077     return package_spec_path
2078
2079 class package_def:
2080
2081     def __init__( self, project, name, path, revision, priority, git_src ):
2082         self.__project = project
2083         self.name = name
2084         self.git_path = path
2085         self.git_revision = revision
2086         self.priority = priority
2087         self.git_src = git_src
2088         self.__my_meta_spec = None
2089
2090     def printMe( self ):
2091         print "%s %s %s %s" % ( self.name , self.git_path, self.git_revision, self.git_src )
2092
2093     def create_MetaSpec( self , package_recipes_dir, source_spec_dir ):
2094         source_path = os.path.join( source_spec_dir , self.name , "packaging" )
2095         package_spec_path = findBestSpecFile( source_path, self.name )
2096
2097         if package_spec_path == -1:
2098             msg = "no initial spec file for package \"%s\" in directory \"%s\"."
2099             msg = msg % ( self.name, source_path )
2100             print >> sys.stderr, colorize( msg, "red" )
2101             sys.exit( 1 )
2102
2103         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__project )
2104         specfile_patched_dir = os.path.join( working_dir, "specfile-patched" )
2105         dest_spec_dir = os.path.join( specfile_patched_dir , self.name )
2106         dest_spec_packaging_dir = os.path.join( dest_spec_dir , "packaging" )
2107         dest_spec_path = os.path.join( dest_spec_packaging_dir ,
2108                                        os.path.basename( package_spec_path ) )
2109
2110
2111         package_spec_path = specfile_patcher( package_spec_path,
2112                                               self.__project,
2113                                               [self.name, self.name + "-initial"],
2114                                                dest_spec_path )
2115
2116         self.__my_meta_spec = MetaSpec( os.path.join( package_recipes_dir, self.name ),
2117                                         self.name,
2118                                         package_spec_path,
2119                                         self.git_src,
2120                                         self.git_path,
2121                                         self.git_revision )
2122
2123 def make_alias_package( project, packages_dico ):
2124     alias_package = {}
2125     #TO DO need to be do in conf file.
2126     alias_package["python-libxml2"] = "libxml2"
2127     alias_package["python-magic"] = "file"
2128     alias_package["cross-arm-binutils"] = "binutils"
2129     alias_package["cross-armv7hl-gcc47-icecream-backend"] = "gcc47"
2130     alias_package["libffi47"] = "gcc47"
2131
2132     for alias in alias_package.keys():
2133         alias_to = alias_package[alias]
2134         if alias_to in packages_dico.keys() and alias not in packages_dico.keys():
2135             a_package_def = packages_dico[alias_to]
2136             packages_dico[alias] = package_def( project,
2137                                                 alias,
2138                                                 a_package_def.git_path,
2139                                                 a_package_def.git_revision,
2140                                                 a_package_def.priority,
2141                                                 a_package_def.git_src )
2142
2143     return packages_dico
2144
2145 class manifestCollection:
2146     '''
2147     class for all package in a distro.
2148     '''
2149     def __init__( self , project ):
2150         '''
2151         init all manifest
2152         '''
2153         self.__my_project = project
2154
2155         self.__recipes_list = None
2156
2157         if not SPEC2YOCTO_CONFIG.is_valide_project( self.__my_project ):
2158             msg = "\"%s\" has no configuration in file \"%s\"."
2159             msg = msg % ( self.__my_project, CONFIGURATION_FILE_PATH )
2160             print >> sys.stderr, colorize( msg, "red" )
2161             sys.exit( 1 )
2162
2163         #Just get the list of manifest uri.
2164         self.__my_manifest_meta_list = SPEC2YOCTO_CONFIG.get_manifest_meta_list( self.__my_project )
2165
2166         self.__my_manifest_file_list = {}
2167         #Load the project manifest.
2168         self.__update_meta_manifests()
2169
2170         self.__my_package_dico = {}
2171         self.__generate_package()
2172
2173         self.__my_package_dico = make_alias_package( self.__my_project, self.__my_package_dico )
2174
2175     def parse_manifest_xml( self, src ):
2176         primaryFile = open( src, "r" )
2177         primaryXML = primaryFile.read()
2178         primaryFile.close()
2179
2180         aElement = ElementTree.fromstring( primaryXML )
2181         remote = ""
2182         packages_dico = {}
2183         for value in aElement:
2184             for project in value.getiterator():
2185                 if project.tag == "project":
2186                     name =  project.attrib['name']
2187                     short_name=clean_name( name )
2188                     revision = clean_revision( project.attrib['revision'] )
2189                     packages_dico[short_name] = [name, revision]
2190                 elif project.tag == "default":
2191                       remote = project.attrib['remote']
2192                 elif project.tag == "remote":
2193                     fetch = project.attrib['fetch']
2194                     name = project.attrib['name']
2195                 else:
2196                     print "ERROR"
2197
2198         return remote, packages_dico
2199
2200     def print_list( self ):
2201         pkg_list = self.__my_package_dico.keys()
2202         pkg_list.sort()
2203         for package in pkg_list:
2204             self.__my_package_dico[package].printMe()
2205
2206     def __generate_package( self ):
2207         for meta_manifest in self.__my_manifest_file_list.keys():
2208             manifest_uri = self.__my_manifest_file_list[meta_manifest]
2209             manifest_git = SPEC2YOCTO_CONFIG.get_manifest_default_git_src( meta_manifest )
2210             manifest_priority = SPEC2YOCTO_CONFIG.get_manifest_priority( meta_manifest )
2211             remote, packages_dico = self.parse_manifest_xml( manifest_uri )
2212
2213             if manifest_git is not None:
2214                 remote = manifest_git
2215
2216             whitelist = SPEC2YOCTO_CONFIG.get_list(self.__my_project, "whitelist")
2217             if len( whitelist ) != 0:
2218                 list_packages = set(whitelist)
2219             else:
2220                 list_packages = set(packages_dico.keys())
2221
2222             blacklist = set(SPEC2YOCTO_CONFIG.get_list(self.__my_project, "blacklist"))
2223
2224             list_packages=list_packages.difference(blacklist)
2225
2226             for package in list_packages:
2227                 if package in packages_dico.keys():
2228                     [path, revision] = packages_dico[package]
2229
2230                     if package in self.__my_package_dico.keys():
2231                         if manifest_priority > self.__my_package_dico[package].priority:
2232                             self.__my_package_dico[package] = package_def( self.__my_project,
2233                                                                            package,
2234                                                                            path,
2235                                                                            revision,
2236                                                                            manifest_priority,
2237                                                                            remote )
2238                         elif manifest_priority == self.__my_package_dico[package].priority:
2239                             msg = "most of one occurence of package \"%s\" ."
2240                             msg = msg % ( package )
2241                             print >> sys.stderr, colorize( msg, "red" )
2242                             sys.exit( 1 )
2243                     else:
2244                         self.__my_package_dico[package] = package_def( self.__my_project,
2245                                                                        package,
2246                                                                        path,
2247                                                                        revision,
2248                                                                        manifest_priority,
2249                                                                        remote )
2250         for package in whitelist:
2251             if package not in self.__my_package_dico.keys():
2252                 msg = "package \"%s\" is in the white list but not in the manifest."
2253                 msg = msg % ( package )
2254                 print >> sys.stderr, colorize( msg, "red" )
2255                 sys.exit( 1 )
2256
2257     def __update_meta_manifests( self ):
2258         '''
2259         find/download all manifest.xml file.
2260         '''
2261         for meta_manifest in self.__my_manifest_meta_list:
2262             meta_manifest_uri = SPEC2YOCTO_CONFIG.get_manifest_uri( meta_manifest )
2263             if meta_manifest_uri is None:
2264                 msg = "\"%s\" has no URI configuration in file \"%s\"."
2265                 msg = msg % ( meta_manifest_uri, CONFIGURATION_FILE_PATH )
2266                 print >> sys.stderr, colorize( msg, "red" )
2267                 sys.exit( 1 )
2268             if meta_manifest_uri.startswith( "http" ):
2269                 if meta_manifest_uri.endswith( ".xml" ):
2270                     meta_manifest_url_path = meta_manifest_uri
2271                     manifest_name = os.path.basename(meta_manifest_uri)
2272                 else:
2273                     xml_str = download_build_xml( meta_manifest_uri )
2274                     project_id = get_project_id( xml_str )
2275                     list_arch = get_project_arch( xml_str )
2276
2277                     arch = SPEC2YOCTO_CONFIG.get_project_arch( self.__my_project )
2278                     buildtarget = "x86_64-wayland"
2279
2280                     if ( arch == "i586" ) and ( "ia32" in list_arch ):
2281                         arch = "ia32"
2282                         buildtarget ="ia32-wayland"
2283
2284                     elif ( arch is None ) and ( len( list_arch ) > 0 ):
2285                         arch = list_arch[0]
2286
2287                     elif ( arch not in list_arch ):
2288                         arch = list_arch[0]
2289
2290                     manifest_name = "%s_%s.xml" % ( project_id, buildtarget )
2291                     meta_manifest_url_path = "%s/builddata/manifest/%s"
2292                     meta_manifest_url_path = meta_manifest_url_path % ( meta_manifest_uri,
2293                                                                         manifest_name )
2294
2295                 manifest_xml = download_manifest_url( meta_manifest_url_path )
2296                 working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__my_project )
2297
2298                 meta_manifest_dir = os.path.join( working_dir, "manifest_file" )
2299                 meta_manifest_path = os.path.join( meta_manifest_dir, manifest_name )
2300
2301                 if not os.path.isdir( meta_manifest_dir ):
2302                     os.makedirs( meta_manifest_dir )
2303
2304                 with open( meta_manifest_path, "w" ) as manifest_xml_file:
2305                     manifest_xml_file.write( manifest_xml )
2306             else:
2307                 if not os.path.isfile( meta_manifest_uri ):
2308                     msg = "In the project \"%s\" the manifest \"%s\" is not a valid file."
2309                     msg = msg % ( self.__my_project, meta_manifest_uri )
2310                     print >> sys.stderr, colorize( msg, "red" )
2311                     sys.exit( 1 )
2312                 else:
2313                     meta_manifest_path = meta_manifest_uri
2314
2315             self.__my_manifest_file_list[ meta_manifest ] = meta_manifest_path
2316
2317     def createRecipes( self ):
2318         '''
2319         generate recipises.
2320         '''
2321         self.__recipes_dir_dest = SPEC2YOCTO_CONFIG.get_recipes_sources_directory( self.__my_project )
2322
2323         self.__clean_old_bb_files(self.__recipes_dir_dest)
2324
2325         if self.__recipes_dir_dest is None:
2326             msg = "In the project \"%s\" recipes_dir_sources is  not define."
2327             msg = msg % ( self.__my_project )
2328             print >> sys.stderr, colorize( msg, "red" )
2329             sys.exit( 1 )
2330         elif not os.path.isdir( self.__recipes_dir_dest ):
2331             os.makedirs( self.__recipes_dir_dest )
2332
2333         self.__meta_spec_dico = {}
2334         self.__meta_spec_boot_strap_dico = {}
2335
2336         self.__set_oe_package_blacklist()
2337         self.__set_native_package_blacklist()
2338
2339         self.__init_depends()
2340         self.__init_MetaSpec()
2341
2342
2343     def __clean_old_bb_files( self ,path):
2344         for root, dirs, files in os.walk(path):
2345             for a_file in files:
2346                 if a_file.endswith(".bb"):
2347                     os.unlink( os.path.join(path, root, a_file) )
2348
2349
2350     def __set_oe_package_blacklist( self ):
2351         '''
2352         load oe_package_blacklist
2353         '''
2354         list_package = SPEC2YOCTO_CONFIG.get_list(self.__my_project, "runtime_blacklist")
2355         MetaSpec.mOePackageBlacklist.extend( list_package )
2356
2357     def __set_native_package_blacklist( self ):
2358         '''
2359         load oe_package_blacklist
2360         '''
2361         list_package = SPEC2YOCTO_CONFIG.get_list(self.__my_project, "native_blacklist")
2362         MetaSpec.mNativePackageBlacklist.extend( list_package )
2363
2364
2365     def __init_MetaSpec( self ):
2366         pkg_list = self.__my_package_dico.keys()
2367         pkg_list.sort()
2368
2369         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__my_project )
2370         source_spec_dir = os.path.join( working_dir, "specfile-initial" )
2371
2372         for package in pkg_list:
2373             self.__my_package_dico[package].create_MetaSpec( self.__recipes_dir_dest,
2374                                                              source_spec_dir )
2375
2376     def __init_depends( self ):
2377         '''
2378         init depends
2379         '''
2380         self.__load_package_provided_extra()
2381
2382         pkg_list = self.__my_package_dico.keys()
2383         pkg_list.sort()
2384
2385     def __load_package_provided_extra( self ):
2386         '''
2387         load_package_provided_extra
2388         '''
2389         provided_extra_dico = SPEC2YOCTO_CONFIG.get_provided_extra( self.__my_project )
2390
2391         for k_package in provided_extra_dico.keys():
2392             raw_list=provided_extra_dico[k_package]
2393
2394             if k_package not in MetaSpec.mProvidesDico.keys():
2395                 MetaSpec.mProvidesDico[k_package] = []
2396
2397             MetaSpec.mProvidesDico[k_package].extend( raw_list )
2398
2399             if k_package not in MetaSpec.mExtraRProvidesDico.keys():
2400                 MetaSpec.mExtraRProvidesDico[k_package] = []
2401             MetaSpec.mExtraRProvidesDico[k_package].extend( raw_list )
2402
2403 TERMINAL_COLORS = {"black": "\033[30;1m",
2404                    "red": "\033[31;1m",
2405                    "green": "\033[32;1m",
2406                    "yellow": "\033[33;1m",
2407                    "blue": "\033[34;1m",
2408                    "magenta": "\033[35;1m",
2409                    "cyan": "\033[36;1m",
2410                    "white": "\033[37;1m",
2411                    "default": "\033[0m"}
2412
2413 def colorize( text, color = "green" ):
2414     """
2415     Return a colorized copy of `text`.
2416     See Utils.TERMINAL_COLORS.keys() for available colors.
2417     """
2418     return TERMINAL_COLORS.get( color, "" ) + text + TERMINAL_COLORS["default"]
2419
2420
2421 def check_group_file( project ):
2422     working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2423
2424     group_uri = SPEC2YOCTO_CONFIG.get_group_uri( project )
2425
2426     if group_uri.startswith( "http" ):
2427         group_file_path = os.path.join( working_dir, "group/group.xml" )
2428         group_xml = download_url( group_uri )
2429
2430         with open( group_file_path, "w" ) as group_file:
2431             group_file.write( group_xml )
2432
2433         return group_file_path
2434     else:
2435         return group_uri
2436
2437 def parse_group_xml( src ):
2438     groupFile = open( src, "r" )
2439     groupXML = groupFile.read()
2440     groupFile.close()
2441
2442     aElement = ElementTree.fromstring( groupXML )
2443     packages_dico = {}
2444
2445     for group in aElement:
2446         if group.tag == "group":
2447             group_name=None
2448             list_package=[]
2449             for element in group:
2450                 if element.tag == "name":
2451                     group_name = element.text
2452                 elif element.tag == "packagelist":
2453                     for packagereq in element:
2454                         list_package.append(packagereq.text)
2455
2456             packages_dico[group_name]=list_package
2457     return packages_dico
2458
2459 def dump_group(project,group_dico):
2460
2461     recipes_group_directory = SPEC2YOCTO_CONFIG.get_recipes_group_directory( project )
2462
2463     for group in group_dico.keys():
2464         group_str = group.replace( " ", "-" )
2465         path = os.path.join( recipes_group_directory, "packagegroup-tizen-%s.bb" % group_str )
2466
2467         with open(path,"w") as group_file:
2468             group_file.write( "SUMMARY = \"%s\"\n" % group )
2469             group_file.write( "DESCRIPTION = \"%s\"\n" % group )
2470             group_file.write( "LICENSE = \"MIT\"\n" )
2471             group_file.write( "DEPENDS = \"virtual/kernel\"\n" )
2472             group_file.write( "PR = \"r1\"\n" )
2473
2474             group_file.write( "inherit packagegroup\n" )
2475             group_file.write( "\n" )
2476             group_file.write( "PACKAGE_ARCH = \"${MACHINE_ARCH}\"\n" )
2477             group_file.write( "\n" )
2478
2479             group_file.write( "RDEPENDS_${PN} = \"\" \n\n" )
2480             for pkg in group_dico[group]:
2481                 group_file.write( "RDEPENDS_${PN} += \"%s\"\n" % pkg )
2482
2483 def generateBuildStatus( project_path ):
2484     res_native = {}
2485     res = {}
2486     if not os.path.isdir( project_path ):
2487             msg = "The path \"%s\" is not a directory."
2488             msg = msg % ( project_path )
2489             print >> sys.stderr, colorize( msg, "red" )
2490             sys.exit( 1 )
2491
2492     for package_path in os.listdir( project_path ):
2493         project_full_path = os.path.join( project_path, package_path )
2494         if  ( package_path == "build_stats" ) and os.path.isfile( project_full_path )  :
2495             pass
2496
2497         elif os.path.isdir( project_full_path ):
2498             BN, PV, PR = cleanPackageName( package_path )
2499             res_status = check_package_status( project_full_path )
2500
2501             if BN.endswith("-native"):
2502                 res_native[BN] = [PV ] + res_status
2503             else:
2504                 res[BN] = [PV ] + res_status
2505
2506         # ignorefiles
2507         elif package_path in ["."]:
2508             pass
2509
2510         else:
2511             msg = "This directory should not contain the file \"%s\"."
2512             msg = msg % ( package_path )
2513             print >> sys.stderr, colorize( msg, "red" )
2514             sys.exit( 1 )
2515
2516     return res_native, res
2517
2518 def cleanPackageName( package_path ):
2519     if  package_path.count( "-" ) < 2:
2520         msg = "unknow format for package \"%s\"."
2521         msg = msg % ( package_path )
2522         print >> sys.stderr, colorize( msg, "red" )
2523         sys.exit( 1 )
2524
2525     PR=package_path[package_path.rindex("-")+1:]
2526     package_path=package_path[:package_path.rindex("-")]
2527     PV=package_path[package_path.rindex("-")+1:]
2528     BN=package_path[:package_path.rindex("-")]
2529
2530     return BN, PV, PR
2531
2532
2533 def check_package_status( project_full_path ):
2534     tasks_order = ["do_fetch",
2535                    "do_unpack",
2536                    "do_patch",
2537                    "do_populate_lic",
2538                    "do_configure",
2539                    "do_compile",
2540                    "do_install",
2541                    "do_populate_sysroot",
2542                    "do_package",
2543                    "do_packagedata",
2544                    "do_package_write_rpm",
2545                    "do_rootfs"]
2546
2547     max_index=-1
2548     for package_task in os.listdir( project_full_path ):
2549         if package_task in tasks_order:
2550             task_index = tasks_order.index( package_task )
2551
2552             if task_index > max_index:
2553                 max_index = task_index
2554
2555     if max_index == -1:
2556         msg = "No log task in \"%s\"."
2557         msg = msg % ( project_full_path )
2558         print >> sys.stderr, colorize( msg, "red" )
2559         sys.exit( 1 )
2560
2561     last_task = tasks_order[max_index][3:]
2562
2563     task_status = ""
2564     status = "unknow"
2565     with open( os.path.join( project_full_path, tasks_order[max_index] ) ) as status_file:
2566         for line in status_file:
2567             if line.startswith( "Status: " ):
2568                 status = line[len( "Status: " ):].replace( "\n", "" ).replace( " ", "" )
2569                 break
2570     if last_task == "package_write_rpm" and status == "PASSED":
2571         status = "OK"
2572
2573     return [last_task, status]
2574
2575 def clean_Packagegroup( project,group_dico ):
2576     group_dico_tmp = {}
2577
2578     package_replacement = SPEC2YOCTO_CONFIG.get_substitute( project )
2579
2580     for group in group_dico.keys():
2581         group_dico_tmp[group] = []
2582         for package in group_dico[group]:
2583             if package in package_replacement.keys():
2584                 group_dico_tmp[group].append( package_replacement[package] )
2585             else:
2586                 group_dico_tmp[group].append( package )
2587
2588     return group_dico_tmp
2589
2590
2591 def check_debugmode( opts_debug ):
2592     global DEBUG_RUN
2593     if opts_debug == "no":
2594         DEBUG_RUN = False
2595     elif opts_debug == "yes":
2596         DEBUG_RUN = True
2597
2598
2599 class spec2yoctoCommandline( cmdln.Cmdln ):
2600     name = "spec2yocto"
2601     version = "0.1"
2602
2603     def do_manifestToList( self, subcmd, opts, project = None ):
2604         """${cmd_name}: print the list of package in projects.
2605
2606         ${cmd_usage}--
2607         ${cmd_option_list}
2608         """
2609         if project is None:
2610             project = SPEC2YOCTO_CONFIG.get_current_project()
2611
2612         pkg_co = manifestCollection( project )
2613         pkg_co.print_list()
2614
2615     def do_createRecipes( self, subcmd, opts, project = None ):
2616         """${cmd_name}: create all packages recipes.
2617
2618         ${cmd_usage}--
2619         ${cmd_option_list}
2620         """
2621         if project is None:
2622             project = SPEC2YOCTO_CONFIG.get_current_project()
2623
2624         pkg_co = manifestCollection( project )
2625         pkg_co.createRecipes()
2626
2627     @cmdln.option( "--package_pn",
2628                   action = "store",
2629                   default = None,
2630                   help = "select the package_pn." )
2631     def do_findBestSpecFile( self, subcmd, opts, package_path ):
2632         """${cmd_name}: print the speec file associate to package.
2633
2634         ${cmd_usage}--
2635         ${cmd_option_list}
2636         """
2637         res = findBestSpecFile( package_path, opts.package_pn )
2638         print res
2639
2640     @cmdln.option( "--package_pn",
2641                   action = "append",
2642                   default = None,
2643                   help = "select the package_pn." )
2644     def do_findSpecPatchFiles( self, subcmd, opts, patch_dir, ):
2645         """${cmd_name}: print patch from "specfile-patch" directory associate to package.
2646
2647         ${cmd_usage}--
2648         ${cmd_option_list}
2649         """
2650         res = findSpecPatchFiles( patch_dir, opts.package_pn )
2651         print " ".join( res )
2652
2653     @cmdln.option( "--package_pn",
2654                   action = "append",
2655                   default = None,
2656                   help = "select the package_pn." )
2657     @cmdln.option( "--project",
2658                   action = "store",
2659                   default = None,
2660                   help = "select the package_pn." )
2661     def do_specfile_patcher( self, subcmd, opts, package_spec_path ):
2662         """${cmd_name}: patch the spec file with patch from "specfile-patch" directory.
2663
2664         ${cmd_usage}--
2665         ${cmd_option_list}
2666         """
2667         if opts.project is None:
2668             project = SPEC2YOCTO_CONFIG.get_current_project()
2669         else:
2670             project = opts.project
2671
2672         res = specfile_patcher( package_spec_path, project, opts.package_pn, package_spec_path )
2673
2674
2675     def do_createPackagegroup( self, subcmd, opts, project = None ):
2676         """${cmd_name}: print the list of package in projects.
2677
2678         ${cmd_usage}--
2679         ${cmd_option_list}
2680         """
2681         if project is None:
2682             project = SPEC2YOCTO_CONFIG.get_current_project()
2683
2684
2685         res = SPEC2YOCTO_CONFIG.get_group( project )
2686         group_file_path = check_group_file( project )
2687         group_dico= parse_group_xml( group_file_path )
2688
2689         group_dico = clean_Packagegroup( project, group_dico )
2690
2691         dump_group(project,group_dico)
2692
2693     @cmdln.option( "--debug",
2694                   action = "store",
2695                   default = None,
2696                   help = "run the in debug mode.[yes/no]" )
2697     @cmdln.option( "--project",
2698                   action = "store",
2699                   default = None,
2700                   help = "select the project." )
2701     @cmdln.option( "--package_pn",
2702                   action = "store",
2703                   default = None,
2704                   help = "select the package_pn." )
2705     def do_prep( self, subcmd, opts, spec_path ):
2706         """${cmd_name}: print the bash code of the %prep section of a spec file.
2707
2708         ${cmd_usage}--
2709         ${cmd_option_list}
2710         """
2711         check_debugmode( opts.debug )
2712
2713         if opts.project is None:
2714             project = SPEC2YOCTO_CONFIG.get_current_project()
2715         else:
2716             project = opts.project
2717
2718         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_prep_section()
2719         print res
2720         res = 0
2721
2722     @cmdln.option( "--debug",
2723                   action = "store",
2724                   default = None,
2725                   help = "run the in debug mode.[yes/no]" )
2726     @cmdln.option( "--project",
2727                   action = "store",
2728                   default = None,
2729                   help = "select the project." )
2730     @cmdln.option( "--package_pn",
2731                   action = "store",
2732                   default = None,
2733                   help = "select the package_pn." )
2734     def do_compile( self, subcmd, opts, spec_path ):
2735         """${cmd_name}: print the bash code of the %build section of a spec file.
2736
2737         ${cmd_usage}--
2738         ${cmd_option_list}
2739         """
2740         check_debugmode( opts.debug )
2741
2742         if opts.project is None:
2743             project = SPEC2YOCTO_CONFIG.get_current_project()
2744         else:
2745             project = opts.project
2746
2747         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_build_section()
2748         if res != 1:
2749             print res
2750
2751     @cmdln.option( "--debug",
2752                   action = "store",
2753                   default = None,
2754                   help = "run the in debug mode.[yes/no]" )
2755     @cmdln.option( "--project",
2756                   action = "store",
2757                   default = None,
2758                   help = "select the project." )
2759     @cmdln.option( "--package_pn",
2760                   action = "store",
2761                   default = None,
2762                   help = "select the package_pn." )
2763     def do_install( self, subcmd, opts, spec_path ):
2764         """${cmd_name}: print the bash code of the %install section of a spec file.
2765
2766         ${cmd_usage}--
2767         ${cmd_option_list}
2768         """
2769         check_debugmode( opts.debug )
2770
2771
2772         if opts.project is None:
2773             project = SPEC2YOCTO_CONFIG.get_current_project()
2774         else:
2775             project = opts.project
2776
2777         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_install_section()
2778         if res != 1:
2779             print res
2780
2781     @cmdln.option( "--debug",
2782                   action = "store",
2783                   default = None,
2784                   help = "run the in debug mode.[yes/no]" )
2785     def do_generateBuildStatus( self, subcmd, opts, project_path ):
2786         """${cmd_name}: print the status and the the build state of packages,
2787         builded in a single command.
2788         exemple:
2789             build/tmp-eglibc/buildstats/core-image-minimal-qemux86/XXXX/
2790         ${cmd_usage}--
2791         ${cmd_option_list}
2792         """
2793         check_debugmode( opts.debug )
2794
2795         res_native, res = generateBuildStatus( project_path )
2796
2797         res_native_keys = res_native.keys()
2798         res_keys = res.keys()
2799
2800         res_native_keys.sort()
2801         res_keys.sort()
2802
2803         for r in res_native_keys:
2804             print r + "\t" + "\t".join( res_native[r] )
2805         print
2806         for r in res_keys:
2807             print r + "\t" + "\t".join( res[r] )
2808
2809
2810     @cmdln.option( "--debug",
2811                   action = "store",
2812                   default = None,
2813                   help = "run the in debug mode.[yes/no]" )
2814     def do_generatePseudoSpecfile( self, subcmd, opts, spec_path ):
2815         """${cmd_name}: generate a spec file use by yocto, for packaging rpm.
2816
2817         ${cmd_usage}--
2818         ${cmd_option_list}
2819         """
2820         check_debugmode( opts.debug )
2821
2822         a_spec_parser = SpecParser( spec_path )
2823         a_spec_parser.parse_raw_spec_file()
2824         res = a_spec_parser.get_clean_raw()
2825         if res != 1:
2826             print res
2827
2828     @cmdln.option( "--debug",
2829                   action = "store",
2830                   default = None,
2831                   help = "run the in debug mode.[yes/no]" )
2832     @cmdln.option( "--project",
2833                   action = "store",
2834                   default = None,
2835                   help = "select the project." )
2836     def do_working_dir( self, subcmd, opts ):
2837         """${cmd_name}: return the proto directory.
2838
2839         ${cmd_usage}--
2840         ${cmd_option_list}
2841         """
2842         check_debugmode( opts.debug )
2843
2844         if opts.project is None:
2845             project = SPEC2YOCTO_CONFIG.get_current_project()
2846         else:
2847             project = opts.project
2848
2849         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2850         if working_dir != 1:
2851             print working_dir
2852
2853 def main():
2854     commandline = spec2yoctoCommandline()
2855
2856     try:
2857         res = commandline.main()
2858     except ValueError as ve:
2859         print
2860         print >> sys.stderr, colorize( str( ve ), "red" )
2861         res = 1
2862     except EnvironmentError as ioe:
2863 #        commandline.do_help([sys.argv[0]])
2864         print
2865         print >> sys.stderr, colorize( str( ioe ), "red" )
2866         if hasattr( ioe, "spec2yocto_config_error" ):
2867             msg = "See '--config' option"
2868             print >> sys.stderr, colorize( msg, "red" )
2869         res = 1
2870 #     except Exception as e_all :
2871 #         print
2872 #         print >> sys.stderr, colorize( str( e_all ), "red" )
2873 #         res = 1
2874     sys.exit( res )
2875
2876 if __name__ == '__main__':
2877     main()