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