17ff3a2ada2996cf6fa1eab2913536b96e95cafe
[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         self.__package_git_srv_src = package_git_srv_src
1468         self.__package_git_srv_path = package_git_srv_path
1469
1470         self.__package_spec_path = package_spec_path
1471         self.__git_tag = package_git_tag
1472
1473         self.__spec_parser = SpecParser( self.__package_spec_path )
1474
1475         self.__packages_dico = self.__spec_parser.get_files_packages()
1476         self.__provides_dico = self.__spec_parser.get_provides()
1477
1478         self.setm_provided_dico()
1479         self.__rdepends_dico = self.__spec_parser.get_rdepends()
1480
1481         self.__base_file = self.__package_name + ".inc"
1482         #self.__base_depends_file = self.__package_name + "-depends.inc"
1483         #self.__base_rdepends_file = self.__package_name + "-rdepends.inc"
1484         #self.__base_provides_file = self.__package_name + "-rprovides.inc"
1485
1486         self.__extra_conf_file = self.__package_name + "-extraconf.inc"
1487         #self.__extra_native_conf_file = self.__package_name + "-native-extraconf.inc"
1488         #self.__extra_oe_conf_file = self.__package_name + "-oe-extraconf.inc"
1489
1490         self.__git_native_file = self.__package_name + "-native_git.bb"
1491         self.__git_oe_file = self.__package_name + "_git.bb"
1492
1493         self.__createRecipes()
1494
1495     def setm_provided_dico( self ):
1496         '''
1497         add provides_list for package_name to mProvidesDico
1498         '''
1499         provides_list = []
1500         for k_provide in self.__provides_dico.keys():
1501             for p_provide in self.__provides_dico[k_provide]:
1502                 provides_list.append( p_provide[0] )
1503         for p_provide in self.__packages_dico.keys():
1504             provides_list.extend( self.__packages_dico[p_provide] )
1505
1506         for package in self.__packages_dico.keys():
1507             for pkg_file in self.__packages_dico[package]:
1508                 pkgconfig_name_res = re.findall( RePattern.pkgconfig_name, pkg_file )
1509                 for tmp_res in pkgconfig_name_res:
1510                     provides_list.append( "pkgconfig(%s)" % tmp_res )
1511
1512         MetaSpec.mProvidesDico[self.__package_name] = provides_list
1513
1514     def set_mextra_provided_dico( self ):
1515         '''
1516         add provides_list for package_name to mExtraRProvidesDico
1517         '''
1518         provides_list = []
1519         for k_provide in self.__provides_dico.keys():
1520             for p_provide in self.__provides_dico[k_provide]:
1521                 provides_list.append( p_provide[0] )
1522         for p_provide in self.__packages_dico.keys():
1523             provides_list.extend( self.__packages_dico[p_provide] )
1524
1525         MetaSpec.mExtraRProvidesDico[self.__package_name] = provides_list
1526
1527     def __create_base_file( self ):
1528         '''
1529         create the base file of the bb file.
1530         '''
1531         bb_path = os.path.join( self.__package_recipes_dir, self.__base_file )
1532         with open( bb_path, "w" ) as file_d:
1533
1534             _description = self.__spec_parser.get_description()
1535             _homepage = self.__spec_parser.get_homepage()
1536             _section = self.__spec_parser.get_section()
1537             _priority = "10"
1538             _license = self.__spec_parser.get_license()
1539
1540             file_d.write( "DESCRIPTION = \"%s\"\n" % _description )
1541             if len( _homepage ) < 2:
1542                 _homepage = "http://nohomepage.org"
1543             file_d.write( "HOMEPAGE = \"%s\"\n" % _homepage )
1544             file_d.write( "SECTION = \"%s\"\n" % _section )
1545
1546             file_d.write( "LICENSE = \"%s\"\n" % _license )
1547             file_d.write( "\n" )
1548             file_d.write( "SRC_URI = \"\"\n" )
1549             file_d.write( "\n" )
1550             file_d.write( "S = \"${WORKDIR}/git\"\n" )
1551             file_d.write( "\n" )
1552
1553             file_d.write( "inherit autotools-brokensep\n" )
1554             file_d.write( "\n" )
1555             file_d.write( "BBCLASSEXTEND = \"\"\n"  )
1556
1557             self.__create_provides_file( file_d)
1558             self.__create_rdepends( file_d)
1559             self.__create_depends( file_d)
1560
1561             self.__create_patch( file_d)
1562             self.__create_configure( file_d)
1563             self. __create_compile( file_d)
1564             self.__create_install( file_d)
1565
1566             self.__create_script_file( file_d)
1567
1568             self.__create_files_packaging( file_d )
1569
1570             file_d.write( "require %s\n\n" % self.__extra_conf_file )
1571
1572     def __create_files_packaging(self,file_d):
1573             for package in self.__packages_dico.keys():
1574                 pkg_yocto_name=package
1575                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1576                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1577
1578                 if  pkg_yocto_name not in [self.__package_name+"-dbg",
1579                         self.__package_name+"-dev",
1580                         self.__package_name+"-doc",
1581                         self.__package_name+"-locale",
1582                         self.__package_name,
1583                         ]:
1584
1585                     file_d.write( "PACKAGES += \" %s \"\n" % pkg_yocto_name )
1586
1587             file_d.write( "\n" )
1588
1589             package_name = self.__spec_parser.get_name()
1590             _license = self.__spec_parser.get_license()
1591
1592             for package in self.__packages_dico.keys():
1593                 pkg_yocto_name=package
1594                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1595                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1596
1597                 file_d.write( "%s_files = \"\"\n" % pkg_yocto_name )
1598
1599 #                if "-debugsource" in package:
1600 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/src/debug" ) )
1601 #                elif "-debug" in package:
1602 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/bin/.debug" ) )
1603 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/bin/.debug" ) )
1604 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/lib/.debug" ) )
1605 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/lib/.debug" ) )
1606 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/sbin/.debug" ) )
1607 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/sbin/.debug" ) )
1608 #                elif "-docs" in package:
1609 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/info" ) )
1610 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/man" ) )
1611 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/man/man*" ) )
1612 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/man/*/man/*" ) )
1613 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/gtk-doc/html/*" ) )
1614 #                    file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, "/usr/share/info/*\info*" ) )
1615
1616                 for pkg_f in self.__packages_dico[package]:
1617                     pkg_f=pkg_f.strip()
1618                     #if pkg_f.startswith("%attr"):
1619                     #    pkg_f_clean=pkg_f.split(")")
1620                     #    pkg_f=pkg_f_clean[1].strip()
1621                     #    file_d.write( "#Remove rpm attribut \"%s)\"\n" % ( pkg_f_clean[0].strip()) )
1622
1623                     if  pkg_f.startswith( _license ):
1624                         pass
1625                     else:
1626                         pkg_yocto_name = package.replace("-devel","-dev")
1627                         file_d.write( "%s_files += \"%s\"\n" % ( pkg_yocto_name, pkg_f ) )
1628
1629                 file_d.write( "\n" )
1630
1631             for package in self.__packages_dico.keys():
1632                 p_parse = package.replace( package_name, "${PN}" )
1633                 p_parse = p_parse.replace("-devel","-dev")
1634                 pkg_yocto_name = package.replace("-devel","-dev")
1635                 file_d.write( "FILES_%s = \"${%s_files}\"\n" % ( p_parse, pkg_yocto_name ) )
1636             file_d.write( "\n" )
1637
1638             for package in self.__packages_dico.keys():
1639                 pkg_yocto_name = package.replace("-devel","-dev")
1640                 file_d.write( "PKG_%s= \"%s\"\n" % (pkg_yocto_name,pkg_yocto_name) )
1641             file_d.write( "\n" )
1642
1643     def __create_patch( self ,file_d):
1644         code=self.__spec_parser.get_prep_section()
1645         code=code.replace("\n","\n ")
1646         file_d.write( "do_prep() {\n" )
1647         file_d.write( " %s\n" % code )
1648         file_d.write( "}\n" )
1649         file_d.write( "do_patch_append() {\n" )
1650         file_d.write( "    bb.build.exec_func('do_prep', d)\n" )
1651         file_d.write( "}\n" )
1652         file_d.write( "\n" )
1653
1654     def __create_configure( self ,file_d):
1655         file_d.write( "do_configure() {\n" )
1656         file_d.write( "}\n" )
1657         file_d.write( "\n" )
1658
1659     def __create_compile( self ,file_d):
1660         code=self.__spec_parser.get_build_section()
1661         code=code.replace("\n","\n ")
1662         file_d.write( "do_compile() {\n" )
1663         file_d.write( " %s\n" % code )
1664         file_d.write( "}\n" )
1665         file_d.write( "\n" )
1666
1667     def __create_install( self ,file_d):
1668         code=self.__spec_parser.get_install_section()
1669         code=code.replace("\n","\n ")
1670         code=code.replace("\n EOF","\nEOF")
1671         file_d.write( "do_install() {\n" )
1672         file_d.write( " echo export RPM_BUILD_ROOT=${D}\n" )
1673         file_d.write( " %s\n" % code )
1674         file_d.write( "}\n" )
1675         file_d.write( "\n" )
1676
1677     def __create_script_file_section_code( self, spec_section):
1678         '''
1679         Returns the command executed in one of the %pre, %post, %preun
1680         or %postun section of a spec file.
1681         '''
1682         code = self.__spec_parser.get_script_from_section(spec_section)
1683         command_list = code.split("\n")
1684         formated_code = ""
1685         for line in command_list:
1686             if line != "":
1687                 formated_code += "    " + line + "\n"
1688
1689         return formated_code
1690
1691     def __create_script_file_write( self, file_d, code, recipe_section, package_name):
1692         '''
1693         Writes the pre/post (un)install sections of the recipe.
1694         '''
1695         file_d.write("%s%s() {\n" % (recipe_section, package_name))
1696         file_d.write("    #!/bin/sh -e\n\n")
1697         file_d.write("%s\n" % code)
1698         file_d.write("}\n")
1699         file_d.write("\n")
1700
1701     def __create_script_file_session(self, file_d, flag, script_name, script_sections):
1702         '''
1703         Add script for the given flag.
1704         '''
1705         for section in script_sections:
1706             code = ""
1707             # If %section is a one line script such as: "%post -p /sbin/ldconfig"
1708             if "-p" in section:
1709                 # Remove the package name if present to only keep the command
1710                 section_split = section.split("-p")[1].split("-n")
1711                 code = "    " + section_split[0].strip()
1712             else:
1713                 code = self.__create_script_file_section_code(section)
1714             if code != "":
1715                 # Set the package name
1716                 package_name = "${PN}"
1717                 # If the package name is not the project name
1718                 if "-n" in section:
1719                     # Remove the command if any to only keep the package name
1720                     section_split = section.split("-n")[1].split("-p")
1721                     package_name = section_split[0].strip()
1722                 self.__create_script_file_write(file_d, code, script_name, package_name)
1723
1724     def __create_script_file(self, file_d):
1725         '''
1726         Add the pre/post install/uninstall sections of a spec file to
1727         the recipe.
1728         '''
1729         script_sections = self.__spec_parser.get_script_section_key_pre()
1730         self.__create_script_file_session(file_d, "%pre", "pkg_preinst_", script_sections)
1731
1732         script_sections = self.__spec_parser.get_script_section_key_post()
1733         self.__create_script_file_session(file_d, "%post", "pkg_postinst_", script_sections)
1734
1735         script_sections = self.__spec_parser.get_section_key("%preun")
1736         self.__create_script_file_session(file_d, "%preun", "pkg_prerm_", script_sections)
1737
1738         script_sections = self.__spec_parser.get_section_key("%postun")
1739         self.__create_script_file_session(file_d, "%postun", "pkg_postrm_", script_sections)
1740
1741     def __create_provides_file( self ,file_d):
1742         '''
1743         generate provide file.
1744         '''
1745         file_d.write( "PROVIDES = \"\"\n" )
1746         file_d.write( "\n" )
1747
1748         for k_provide in self.__provides_dico.keys():
1749             pkg_yocto_name=k_provide
1750             for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1751                 pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1752
1753             if len( self.__provides_dico[k_provide] ) > 0:
1754                 file_d.write( "#PROVIDES by %s \n" % pkg_yocto_name )
1755
1756             for p_provide in self.__provides_dico[k_provide]:
1757                 pkg = p_provide[0]
1758                 pkg_yocto=pkg
1759                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto ):
1760                      pkg_yocto=pkg_yocto.replace("-devel","-dev")
1761
1762                 if not len( p_provide ) == 1:
1763                     provide_text = "# the PROVIDES rules is ignore \"%s %s %s\"\n"
1764                     file_d.write( provide_text % ( pkg_yocto, p_provide[1], p_provide[2] ) )
1765
1766                 if ( pkg == "mktemp" and self.__package_name == "tizen-coreutils" ):
1767                     continue
1768
1769
1770                 if pkg_yocto_name != pkg_yocto:
1771                    file_d.write( "PROVIDES += \"%s\"\n" % ( pkg_yocto ) )
1772                    file_d.write( "RPROVIDES_%s += \"%s\"\n" % ( pkg_yocto_name, pkg_yocto ) )
1773
1774                 #for res_pkg_devel in re.findall( RePattern.paternDevel, pkg ):
1775                 #    rprovide_text = "RPROVIDES_%s += \"%s\"\n"
1776                 #    file_d.write( rprovide_text % ( k_provide, res_pkg_devel + "-dev" ) )
1777
1778             if len( self.__provides_dico[k_provide] ) > 0:
1779                 file_d.write( "\n\n" )
1780
1781     def __create_git_native_file( self ):
1782         '''
1783         create bb native file.
1784         '''
1785         bb_native_path = os.path.join( self.__package_recipes_dir, self.__git_native_file )
1786         with open( bb_native_path, "w" ) as file_d:
1787             file_d.write( "require %s\n" % self.__base_file )
1788             file_d.write( "\n" )
1789             file_d.write( "PRIORITY = \"9\"\n" )
1790             file_d.write( "\n" )
1791             file_d.write( "inherit native\n" )
1792             file_d.write( "\n" )
1793             file_d.write( "S = \"${WORKDIR}/git\"\n" )
1794             file_d.write( "\n" )
1795
1796             md5_value = "801f80980d171dd6425610833a22dbe6"
1797             file_value = "${COMMON_LICENSE_DIR}/GPL-2.0"
1798             file_chksum_text = "LIC_FILES_CHKSUM ??= \"file://%s;md5=%s\"\n"
1799             # should be generat
1800             file_d.write( file_chksum_text % ( file_value, md5_value ) )
1801             file_d.write( "\n" )
1802             command_source = "SRC_URI += \"%s\"\n" % GIT_COMMAND
1803             file_d.write( command_source % ( self.__package_git_srv_src ,
1804                                              self.__package_git_srv_path ,
1805                                              self.__git_tag ) )
1806             #file_d.write( "require %s\n" % self.__extra_native_conf_file )
1807             file_d.write( "\n" )
1808
1809     def __create_git_oe_file( self ):
1810         '''
1811         generate  bb file.
1812         '''
1813         bb_path = os.path.join( self.__package_recipes_dir, self.__git_oe_file )
1814         with open( bb_path, "w" ) as file_d:
1815             file_d.write( "require %s\n" % self.__base_file )
1816             file_d.write( "\n" )
1817             file_d.write( "PRIORITY = \"10\"\n" )
1818             file_d.write( "\n" )
1819             md5_value = "801f80980d171dd6425610833a22dbe6"
1820             file_value = "${COMMON_LICENSE_DIR}/GPL-2.0"
1821             file_chksum_text = "LIC_FILES_CHKSUM ??= \"file://%s;md5=%s\"\n"
1822             # should be generat
1823             file_d.write( file_chksum_text % ( file_value, md5_value ) )
1824             file_d.write( "\n" )
1825             command_source = "SRC_URI += \"" + GIT_COMMAND + "\"\n"
1826             file_d.write( command_source % ( self.__package_git_srv_src ,
1827                                              self.__package_git_srv_path ,
1828                                              self.__git_tag ) )
1829             #file_d.write( "require %s\n" % self.__extra_oe_conf_file )
1830             file_d.write( "\n" )
1831             if  self.__package_name not in MetaSpec.mNativePackageBlacklist:
1832                 file_d.write( "BBCLASSEXTEND += \" native \"" )
1833             file_d.write( "\n\n" )
1834
1835     def __createRecipes( self ):
1836         '''
1837         generate all bb file.
1838         '''
1839         if self.__package_recipes_dir is  None:
1840             return
1841
1842         if not os.path.isdir( self.__package_recipes_dir ):
1843             os.makedirs( self.__package_recipes_dir )
1844
1845         # Just touch a file
1846         #rdepends_path = os.path.join( self.__package_recipes_dir, self.__base_rdepends_file )
1847         #open( rdepends_path, "a" ).close()
1848         #depends_path = os.path.join( self.__package_recipes_dir, self.__base_depends_file )
1849         #open( depends_path, "a" ).close()
1850         #provides_path = os.path.join( self.__package_recipes_dir, self.__base_provides_file )
1851         #open( provides_path, "a" ).close()
1852
1853         extra_conf_file_path = os.path.join( self.__package_recipes_dir, self.__extra_conf_file )
1854         open( extra_conf_file_path, "a" ).close()
1855
1856         #extranative_path = os.path.join( self.__package_recipes_dir, self.__extra_native_conf_file )
1857         #open( extranative_path, "a" ).close()
1858         #extra_oe_conf_path = os.path.join( self.__package_recipes_dir, self.__extra_oe_conf_file )
1859         #open( extra_oe_conf_path, "a" ).close()
1860
1861         self.__create_base_file()
1862
1863         if  not self.__package_name not in MetaSpec.mNativePackageBlacklist:
1864             bb_native_path = os.path.join( self.__package_recipes_dir, self.__git_native_file )
1865             if os.path.isfile( bb_native_path ):
1866                 os.unlink( bb_native_path )
1867
1868         #self.__create_provides_file()
1869
1870         if self.__package_name not in MetaSpec.mOePackageBlacklist:
1871             self.__create_git_oe_file()
1872         else:
1873             bb_oe_path = os.path.join( self.__package_recipes_dir, self.__git_oe_file )
1874             if os.path.isfile( bb_oe_path ):
1875                 os.unlink( bb_oe_path )
1876
1877     def __create_rdepends( self ,file_d):
1878         '''
1879         generate rdepends file.
1880         '''
1881         if self.__package_recipes_dir is  None:
1882             return
1883
1884         if not os.path.isdir( self.__package_recipes_dir ):
1885             os.makedirs( self.__package_recipes_dir )
1886
1887         #rdepends_path = os.path.join( self.__package_recipes_dir, self.__base_rdepends_file )
1888
1889         package_replacement = SPEC2YOCTO_CONFIG.get_substitute()
1890
1891         if file_d is not None:
1892             file_d.write( "RDEPENDS = \"\"\n" )
1893
1894             for k_provide in self.__rdepends_dico.keys():
1895                 pkg_yocto_name=k_provide
1896                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1897                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
1898
1899                 res_rdepends = set()
1900                 k_provide_replace = pkg_yocto_name.replace( self.__package_name, "${PN}" )
1901                 if len( self.__rdepends_dico[k_provide] ) > 0:
1902                     file_d.write( "#RDEPENDS of %s (%s)\n" % ( pkg_yocto_name, k_provide_replace ) )
1903
1904                 for provide in self.__rdepends_dico[k_provide]:
1905                     package_provide = provide[0]
1906
1907                     res = None
1908
1909                     for k_package_provide in MetaSpec.mExtraRProvidesDico.keys():
1910
1911                         if package_provide in MetaSpec.mExtraRProvidesDico[k_package_provide] \
1912                            or package_provide == k_package_provide:
1913                             res = k_package_provide
1914                             break
1915                     if res is None:
1916                         res = package_provide
1917
1918                     if res in package_replacement.keys():
1919                         res = package_replacement[res]
1920
1921                     res_rdepends.add( res )
1922
1923                 for pkg in res_rdepends:
1924                     res_pkg_devel = re.findall( RePattern.paternDevel, pkg )
1925
1926                     if len( res_pkg_devel ) > 0:
1927                         rdepends_value = "RDEPENDS_%s += \"%s\"\n"
1928                         file_d.write( rdepends_value % ( k_provide_replace, res_pkg_devel[0] + "-dev" ) )
1929                     else:
1930                         if not pkg in  SPEC2YOCTO_CONFIG.get_ignore_rdepend():
1931                             file_d.write( "RDEPENDS_%s += \"%s\"\n" % ( k_provide_replace, pkg ) )
1932
1933                 if len( self.__rdepends_dico[k_provide] ) > 0:
1934                     file_d.write( "\n" )
1935
1936             file_d.write( "\n" )
1937
1938     def __create_depends( self, file_d):
1939         '''
1940         create depends file.
1941         '''
1942         if self.__package_recipes_dir is  None:
1943             return
1944
1945         if not os.path.isdir( self.__package_recipes_dir ):
1946             os.makedirs( self.__package_recipes_dir )
1947
1948         depends_dico = self.__spec_parser.get_depends()
1949         #depends_path = os.path.join( self.__package_recipes_dir, self.__base_depends_file )
1950
1951         ignore_depend_list = SPEC2YOCTO_CONFIG.get_ignore_depend()
1952         native_depend_list = SPEC2YOCTO_CONFIG.get_native_depend()
1953         cross_depend_list = SPEC2YOCTO_CONFIG.get_cross_depend()
1954
1955
1956         if file_d is not None:
1957             file_d.write( "DEPENDS = \"\"\n" )
1958
1959             res_depends = set()
1960             for k_provide in depends_dico.keys():
1961                 if len( depends_dico[k_provide] ) > 0:
1962                     file_d.write( "#DEPENDS of %s \n" % k_provide )
1963
1964                 for p_provide in depends_dico[k_provide]:
1965                     pp_provide = p_provide[0]
1966                     res = None
1967
1968                     if pp_provide in ignore_depend_list:
1969                         continue
1970
1971                     for k in MetaSpec.mProvidesDico.keys():
1972                         if pp_provide in MetaSpec.mProvidesDico[k] or pp_provide == k:
1973                             res = k
1974                             break
1975                     for k_package_provide in MetaSpec.mExtraRProvidesDico.keys():
1976                         if pp_provide in MetaSpec.mExtraRProvidesDico[k_package_provide]:
1977                             res = k_package_provide
1978                             break
1979
1980                     if res is None:
1981                         if pp_provide not in SPEC2YOCTO_CONFIG.get_inherit_gettext() and \
1982                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit_python() and \
1983                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit_tizen_cmake() and \
1984                           pp_provide not in SPEC2YOCTO_CONFIG.get_inherit_perl() and \
1985                           pp_provide not in ignore_depend_list and \
1986                           pp_provide not in native_depend_list and \
1987                           pp_provide not in cross_depend_list:
1988
1989                             erro_msg = "No direct provider for package DEPENDS %s : \"%s\"."
1990                             print erro_msg % ( self.__package_name, pp_provide )
1991                         res = pp_provide
1992                     if res != self.__package_name :
1993                         res_depends.add( res )
1994
1995             # should be from a configue file.
1996             for res in res_depends:
1997                 pkg_yocto_name=res
1998                 for res_pkg_devel in re.findall( RePattern.paternDevel, pkg_yocto_name ):
1999                     pkg_yocto_name=pkg_yocto_name.replace("-devel","-dev")
2000
2001                 if pkg_yocto_name == "readline-dev":
2002                     pkg_yocto_name="readline"
2003
2004                 if pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit_gettext():
2005                     file_d.write( "#Replace \"DEPENDS\" on gettext by \"inherit gettext\"\n" )
2006                     file_d.write( "inherit gettext\n" )
2007                 elif pkg_yocto_name in native_depend_list:
2008                     file_d.write( "DEPENDS_append_class-native = \" %s-native\"\n" % pkg_yocto_name )
2009                     file_d.write( "DEPENDS_append_class-target = \" %s-native\"\n" % pkg_yocto_name )
2010                 elif pkg_yocto_name in cross_depend_list:
2011                     file_d.write( "DEPENDS_append_class-native = \" %s\"\n" % pkg_yocto_name )
2012                     file_d.write( "DEPENDS_append_class-target = \" %s-cross\"\n" % pkg_yocto_name )
2013                 elif pkg_yocto_name in ignore_depend_list:
2014                     pass
2015                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_libtool_cross():
2016                     file_d.write( "DEPENDS += \"libtool-cross\"\n" )
2017                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit_perl():
2018                     file_d.write( "inherit perlnative\n"  )
2019                 elif pkg_yocto_name in SPEC2YOCTO_CONFIG.get_inherit_python():
2020                     file_d.write( "inherit pythonnative\n"  )
2021                 else:
2022                     file_d.write( "DEPENDS += \"%s\"\n" % pkg_yocto_name )
2023
2024         file_d.write( "\n"  )
2025
2026 def parse_manifest_xml( src ):
2027     primaryFile = open( src, "r" )
2028     primaryXML = primaryFile.read()
2029     primaryFile.close()
2030
2031     aElement = ElementTree.fromstring( primaryXML )
2032     remote = ""
2033     packages_dico = {}
2034     for value in aElement:
2035         for project in value.getiterator():
2036             if project.tag == "project":
2037                 name =  project.attrib['name']
2038                 c_name = clean_name( project.attrib['name'] )
2039                 revision = clean_revision( project.attrib['revision'] )
2040                 packages_dico[c_name] = [name, revision]
2041             elif project.tag == "default":
2042                   remote = project.attrib['remote']
2043             elif project.tag == "remote":
2044                 fetch = project.attrib['fetch']
2045                 name = project.attrib['name']
2046                 review = project.attrib['review']
2047             else:
2048                 print "ERROR"
2049
2050     return remote, packages_dico
2051
2052 class HTTPAccessFailure( Exception ):
2053     '''Indicate the http access failed'''
2054
2055 def download_url( url ):
2056     r = urlopen( url )
2057     if r.code != 200:
2058         raise HTTPAccessFailure()
2059     page = r.read()
2060
2061     return page
2062
2063 def download_manifest_url( url ):
2064     r = urlopen( url )
2065     if r.code != 200:
2066         print "ERROR %s " % url
2067         raise HTTPAccessFailure()
2068     page = r.read()
2069
2070     return page
2071
2072 def download_build_xml( url ):
2073     return download_url( url + "/builddata/build.xml" )
2074
2075 def get_project_id( xml ):
2076     aElement = ElementTree.fromstring( xml )
2077
2078     for value in aElement:
2079         for project in value.getiterator():
2080             if project.tag == "id":
2081                 return project.text
2082
2083 def get_project_arch( xml ):
2084     aElement = ElementTree.fromstring( xml )
2085     arch_list = []
2086     for value in aElement:
2087         for project in value.getiterator():
2088             if project.tag == "archs":
2089                 for arch in project.getiterator():
2090                     if arch.tag == "arch":
2091                         arch_list.append( arch.text )
2092
2093     return arch_list
2094
2095
2096 def clean_name( raw_name ):
2097     if "_" in raw_name:
2098         raw_name = raw_name.replace( "_", "-" )
2099
2100     if "/" in raw_name:
2101         return raw_name.split( "/" )[-1]
2102     else:
2103         return raw_name
2104
2105 def clean_revision( raw_name ):
2106     if "-" in raw_name:
2107         return raw_name.split( "-" )[0]
2108     else:
2109         return raw_name
2110
2111 def patch_the_spec_file( package_spec_path,
2112                          patch_path,
2113                          dest_spec_dir,
2114                          dest_spec_path ):
2115
2116     if not package_spec_path == dest_spec_path:
2117         shutil.copy2( package_spec_path, dest_spec_path )
2118
2119     if dest_spec_dir.endswith( "/packaging" ):
2120         dest_spec_dir = dest_spec_dir[:-len( "/packaging" )]
2121
2122     patch_command = "patch -s -p1 --fuzz=2 -d %s -i %s" % ( dest_spec_dir, patch_path )
2123
2124     a_sub_command = SubprocessCrt()
2125     res = a_sub_command.exec_subprocess( patch_command )
2126
2127     if res == 1:
2128             msg = "The patch \"%s\" can't be apply in directory \"%s\"."
2129             msg = msg % ( patch_path, dest_spec_dir )
2130             print >> sys.stderr, colorize( msg, "red" )
2131             print >> sys.stderr, colorize( "command: \"%s\"" % patch_command, "red" )
2132             sys.exit( 1 )
2133
2134     return dest_spec_path
2135
2136
2137 def specfile_patcher( package_spec_path, project, package_name_list , dest_spec_path ):
2138     working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2139     source_spec_patch_dir = os.path.join( working_dir, "specfile-patch" )
2140
2141     patch_path_list = findSpecPatchFiles( source_spec_patch_dir, package_name_list )
2142
2143     if len( patch_path_list ) > 0:
2144
2145         dest_spec_dir = os.path.dirname( dest_spec_path )
2146         if not os.path.isdir( dest_spec_dir ):
2147             os.makedirs( dest_spec_dir )
2148
2149         for patch_path in patch_path_list:
2150             package_spec_path = patch_the_spec_file( package_spec_path,
2151                                                      patch_path,
2152                                                      dest_spec_dir,
2153                                                      dest_spec_path )
2154
2155     return package_spec_path
2156
2157 class package_def:
2158
2159     def __init__( self, project, name, path, revision, priority, git_src ):
2160         self.__project = project
2161         self.name = name
2162         self.git_path = path
2163         self.git_revision = revision
2164         self.priority = priority
2165         self.git_src = git_src
2166         self.__my_meta_spec = None
2167
2168     def printMe( self ):
2169         print "%s %s %s %s" % ( self.name , self.git_path, self.git_revision, self.git_src )
2170
2171     def create_MetaSpec( self , package_recipes_dir, source_spec_dir ):
2172         source_path = os.path.join( source_spec_dir , self.name , "packaging" )
2173         package_spec_path = findBestSpecFile( source_path, self.name )
2174
2175         if package_spec_path == -1:
2176             msg = "no initial spec file for package \"%s\" in directory \"%s\"."
2177             msg = msg % ( self.name, source_path )
2178             print >> sys.stderr, colorize( msg, "red" )
2179             sys.exit( 1 )
2180
2181         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__project )
2182         specfile_patched_dir = os.path.join( working_dir, "specfile-patched" )
2183         dest_spec_dir = os.path.join( specfile_patched_dir , self.name )
2184         dest_spec_packaging_dir = os.path.join( dest_spec_dir , "packaging" )
2185         dest_spec_path = os.path.join( dest_spec_packaging_dir ,
2186                                        os.path.basename( package_spec_path ) )
2187
2188
2189         package_spec_path = specfile_patcher( package_spec_path,
2190                                               self.__project,
2191                                               [self.name, self.name + "-initial"],
2192                                                dest_spec_path )
2193
2194         self.__my_meta_spec = MetaSpec( os.path.join( package_recipes_dir, self.name ),
2195                                         self.name,
2196                                         package_spec_path,
2197                                         self.git_src,
2198                                         self.git_path,
2199                                         self.git_revision )
2200
2201 def make_alias_package( project, packages_dico ):
2202     alias_package = {}
2203     #TO DO need to be do in conf file.
2204     alias_package["python-libxml2"] = "libxml2"
2205     alias_package["python-magic"] = "file"
2206     alias_package["cross-arm-binutils"] = "binutils"
2207     alias_package["cross-armv7hl-gcc47-icecream-backend"] = "gcc47"
2208     alias_package["libffi47"] = "gcc47"
2209
2210     for alias in alias_package.keys():
2211         alias_to = alias_package[alias]
2212         if alias_to in packages_dico.keys() and alias not in packages_dico.keys():
2213             a_package_def = packages_dico[alias_to]
2214             packages_dico[alias] = package_def( project,
2215                                                 alias,
2216                                                 a_package_def.git_path,
2217                                                 a_package_def.git_revision,
2218                                                 a_package_def.priority,
2219                                                 a_package_def.git_src )
2220
2221     return packages_dico
2222
2223 class manifestCollection:
2224     '''
2225     class for all package in a distro.
2226     '''
2227     def __init__( self , project ):
2228         '''
2229         init all manifest
2230         '''
2231         self.__my_project = project
2232
2233         self.__recipes_list = None
2234
2235         if not SPEC2YOCTO_CONFIG.is_valide_project( self.__my_project ):
2236             msg = "\"%s\" has no configuration in file \"%s\"."
2237             msg = msg % ( self.__my_project, CONFIGURATION_FILE_PATH )
2238             print >> sys.stderr, colorize( msg, "red" )
2239             sys.exit( 1 )
2240
2241         #Just get the list of manifest uri.
2242         self.__my_manifest_meta_list = SPEC2YOCTO_CONFIG.get_manifest_meta_list( self.__my_project )
2243
2244         self.__my_manifest_file_list = {}
2245         #Load the project manifest.
2246         self.__update_meta_manifests()
2247
2248         self.__my_package_dico = {}
2249         self.__generate_package()
2250
2251         self.__my_package_dico = make_alias_package( self.__my_project, self.__my_package_dico )
2252
2253     def parse_manifest_xml( self, src ):
2254         primaryFile = open( src, "r" )
2255         primaryXML = primaryFile.read()
2256         primaryFile.close()
2257
2258         aElement = ElementTree.fromstring( primaryXML )
2259         remote = ""
2260         packages_dico = {}
2261         for value in aElement:
2262             for project in value.getiterator():
2263                 if project.tag == "project":
2264                     name =  project.attrib['name']
2265                     short_name=clean_name( name )
2266                     revision = clean_revision( project.attrib['revision'] )
2267                     packages_dico[short_name] = [name, revision]
2268                 elif project.tag == "default":
2269                       remote = project.attrib['remote']
2270                 elif project.tag == "remote":
2271                     fetch = project.attrib['fetch']
2272                     name = project.attrib['name']
2273                 else:
2274                     print "ERROR"
2275
2276         return remote, packages_dico
2277
2278     def print_list( self ):
2279         pkg_list = self.__my_package_dico.keys()
2280         pkg_list.sort()
2281         for package in pkg_list:
2282             self.__my_package_dico[package].printMe()
2283
2284     def __generate_package( self ):
2285         for meta_manifest in self.__my_manifest_file_list.keys():
2286             manifest_uri = self.__my_manifest_file_list[meta_manifest]
2287             manifest_git = SPEC2YOCTO_CONFIG.get_manifest_default_git_src( meta_manifest )
2288             manifest_priority = SPEC2YOCTO_CONFIG.get_manifest_priority( meta_manifest )
2289             remote, packages_dico = self.parse_manifest_xml( manifest_uri )
2290
2291             if manifest_git is not None:
2292                 remote = manifest_git
2293
2294             whitelist = SPEC2YOCTO_CONFIG.get_whitelist( self.__my_project )
2295             if len( whitelist ) != 0:
2296                 list_packages = set(whitelist)
2297             else:
2298                 list_packages = set(packages_dico.keys())
2299
2300             blacklist = set(SPEC2YOCTO_CONFIG.get_blacklist( self.__my_project ))
2301
2302             list_packages=list_packages.difference(blacklist)
2303
2304             for package in list_packages:
2305                 if package in packages_dico.keys():
2306                     [path, revision] = packages_dico[package]
2307
2308                     if package in self.__my_package_dico.keys():
2309                         if manifest_priority > self.__my_package_dico[package].priority:
2310                             self.__my_package_dico[package] = package_def( self.__my_project,
2311                                                                            package,
2312                                                                            path,
2313                                                                            revision,
2314                                                                            manifest_priority,
2315                                                                            remote )
2316                         elif manifest_priority == self.__my_package_dico[package].priority:
2317                             msg = "most of one occurence of package \"%s\" ."
2318                             msg = msg % ( package )
2319                             print >> sys.stderr, colorize( msg, "red" )
2320                             sys.exit( 1 )
2321                     else:
2322                         self.__my_package_dico[package] = package_def( self.__my_project,
2323                                                                        package,
2324                                                                        path,
2325                                                                        revision,
2326                                                                        manifest_priority,
2327                                                                        remote )
2328         for package in whitelist:
2329             if package not in self.__my_package_dico.keys():
2330                 msg = "package \"%s\" is in the white list but not in the manifest."
2331                 msg = msg % ( package )
2332                 print >> sys.stderr, colorize( msg, "red" )
2333                 sys.exit( 1 )
2334
2335     def __update_meta_manifests( self ):
2336         '''
2337         find/download all manifest.xml file.
2338         '''
2339         for meta_manifest in self.__my_manifest_meta_list:
2340             meta_manifest_uri = SPEC2YOCTO_CONFIG.get_manifest_uri( meta_manifest )
2341             if meta_manifest_uri is None:
2342                 msg = "\"%s\" has no URI configuration in file \"%s\"."
2343                 msg = msg % ( meta_manifest_uri, CONFIGURATION_FILE_PATH )
2344                 print >> sys.stderr, colorize( msg, "red" )
2345                 sys.exit( 1 )
2346             if meta_manifest_uri.startswith( "http" ):
2347                 if meta_manifest_uri.endswith( ".xml" ):
2348                     meta_manifest_url_path = meta_manifest_uri
2349                     manifest_name = os.path.basename(meta_manifest_uri)
2350                 else:
2351                     xml_str = download_build_xml( meta_manifest_uri )
2352                     project_id = get_project_id( xml_str )
2353                     list_arch = get_project_arch( xml_str )
2354
2355                     arch = SPEC2YOCTO_CONFIG.get_project_arch( self.__my_project )
2356
2357                     if ( arch == "i586" ) and ( "ia32" in list_arch ):
2358                         arch = "ia32"
2359                     elif ( arch is None ) and ( len( list_arch ) > 0 ):
2360                         arch = list_arch[0]
2361                     elif ( arch not in list_arch ):
2362                         arch = list_arch[0]
2363
2364                     manifest_name = "%s_%s.xml" % ( project_id, arch )
2365                     meta_manifest_url_path = "%s/builddata/manifest/%s"
2366                     meta_manifest_url_path = meta_manifest_url_path % ( meta_manifest_uri,
2367                                                                         manifest_name )
2368
2369                 manifest_xml = download_manifest_url( meta_manifest_url_path )
2370                 working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__my_project )
2371
2372                 meta_manifest_dir = os.path.join( working_dir, "manifest_file" )
2373                 meta_manifest_path = os.path.join( meta_manifest_dir, manifest_name )
2374
2375                 if not os.path.isdir( meta_manifest_dir ):
2376                     os.makedirs( meta_manifest_dir )
2377
2378                 with open( meta_manifest_path, "w" ) as manifest_xml_file:
2379                     manifest_xml_file.write( manifest_xml )
2380             else:
2381                 if not os.path.isfile( meta_manifest_uri ):
2382                     msg = "In the project \"%s\" the manifest \"%s\" is not a valid file."
2383                     msg = msg % ( self.__my_project, meta_manifest_uri )
2384                     print >> sys.stderr, colorize( msg, "red" )
2385                     sys.exit( 1 )
2386                 else:
2387                     meta_manifest_path = meta_manifest_uri
2388
2389             self.__my_manifest_file_list[ meta_manifest ] = meta_manifest_path
2390
2391     def createRecipes( self ):
2392         '''
2393         generate recipises.
2394         '''
2395         self.__recipes_dir_dest = SPEC2YOCTO_CONFIG.get_recipes_sources_directory( self.__my_project )
2396
2397         self.__clean_old_bb_files(self.__recipes_dir_dest)
2398
2399         if self.__recipes_dir_dest is None:
2400             msg = "In the project \"%s\" recipes_dir_sources is  not define."
2401             msg = msg % ( self.__my_project )
2402             print >> sys.stderr, colorize( msg, "red" )
2403             sys.exit( 1 )
2404         elif not os.path.isdir( self.__recipes_dir_dest ):
2405             os.makedirs( self.__recipes_dir_dest )
2406
2407         self.__meta_spec_dico = {}
2408         self.__meta_spec_boot_strap_dico = {}
2409
2410         self.__set_oe_package_blacklist()
2411         self.__set_native_package_blacklist()
2412
2413         self.__init_depends()
2414         self.__init_MetaSpec()
2415
2416
2417     def __clean_old_bb_files( self ,path):
2418         for root, dirs, files in os.walk(path):
2419             for a_file in files:
2420                 if a_file.endswith(".bb"):
2421                     os.unlink( os.path.join(path, root, a_file) )
2422
2423
2424     def __set_oe_package_blacklist( self ):
2425         '''
2426         load oe_package_blacklist
2427         '''
2428         list_package = SPEC2YOCTO_CONFIG.get_runtime_blacklist( self.__my_project )
2429         MetaSpec.mOePackageBlacklist.extend( list_package )
2430
2431     def __set_native_package_blacklist( self ):
2432         '''
2433         load oe_package_blacklist
2434         '''
2435         list_package = SPEC2YOCTO_CONFIG.get_native_blacklist( self.__my_project )
2436         MetaSpec.mNativePackageBlacklist.extend( list_package )
2437
2438
2439     def __init_MetaSpec( self ):
2440         pkg_list = self.__my_package_dico.keys()
2441         pkg_list.sort()
2442
2443         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( self.__my_project )
2444         source_spec_dir = os.path.join( working_dir, "specfile-initial" )
2445
2446         for package in pkg_list:
2447             self.__my_package_dico[package].create_MetaSpec( self.__recipes_dir_dest,
2448                                                              source_spec_dir )
2449
2450     def __init_depends( self ):
2451         '''
2452         init depends
2453         '''
2454         self.__load_package_provided_extra()
2455
2456         pkg_list = self.__my_package_dico.keys()
2457         pkg_list.sort()
2458
2459     def __load_package_provided_extra( self ):
2460         '''
2461         load_package_provided_extra
2462         '''
2463         provided_extra_dico = SPEC2YOCTO_CONFIG.get_provided_extra( self.__my_project )
2464
2465         for k_package in provided_extra_dico.keys():
2466             raw_list=provided_extra_dico[k_package]
2467
2468             if k_package not in MetaSpec.mProvidesDico.keys():
2469                 MetaSpec.mProvidesDico[k_package] = []
2470
2471             MetaSpec.mProvidesDico[k_package].extend( raw_list )
2472
2473             if k_package not in MetaSpec.mExtraRProvidesDico.keys():
2474                 MetaSpec.mExtraRProvidesDico[k_package] = []
2475             MetaSpec.mExtraRProvidesDico[k_package].extend( raw_list )
2476
2477 TERMINAL_COLORS = {"black": "\033[30;1m",
2478                    "red": "\033[31;1m",
2479                    "green": "\033[32;1m",
2480                    "yellow": "\033[33;1m",
2481                    "blue": "\033[34;1m",
2482                    "magenta": "\033[35;1m",
2483                    "cyan": "\033[36;1m",
2484                    "white": "\033[37;1m",
2485                    "default": "\033[0m"}
2486
2487 def colorize( text, color = "green" ):
2488     """
2489     Return a colorized copy of `text`.
2490     See Utils.TERMINAL_COLORS.keys() for available colors.
2491     """
2492     return TERMINAL_COLORS.get( color, "" ) + text + TERMINAL_COLORS["default"]
2493
2494
2495 def check_group_file( project ):
2496     working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2497
2498     group_uri = SPEC2YOCTO_CONFIG.get_group_uri( project )
2499
2500     if group_uri.startswith( "http" ):
2501         group_file_path = os.path.join( working_dir, "group/group.xml" )
2502         group_xml = download_url( group_uri )
2503
2504         with open( group_file_path, "w" ) as group_file:
2505             group_file.write( group_xml )
2506
2507         return group_file_path
2508     else:
2509         return group_uri
2510
2511 def parse_group_xml( src ):
2512     groupFile = open( src, "r" )
2513     groupXML = groupFile.read()
2514     groupFile.close()
2515
2516     aElement = ElementTree.fromstring( groupXML )
2517     packages_dico = {}
2518
2519     for group in aElement:
2520         if group.tag == "group":
2521             group_name=None
2522             list_package=[]
2523             for element in group:
2524                 if element.tag == "name":
2525                     group_name = element.text
2526                 elif element.tag == "packagelist":
2527                     for packagereq in element:
2528                         list_package.append(packagereq.text)
2529
2530             packages_dico[group_name]=list_package
2531     return packages_dico
2532
2533 def dump_group(project,group_dico):
2534
2535     recipes_group_directory = SPEC2YOCTO_CONFIG.get_recipes_group_directory( project )
2536
2537     for group in group_dico.keys():
2538         group_str = group.replace( " ", "-" )
2539         path = os.path.join( recipes_group_directory, "packagegroup-tizen-%s.bb" % group_str )
2540
2541         with open(path,"w") as group_file:
2542             group_file.write( "SUMMARY = \"%s\"\n" % group )
2543             group_file.write( "DESCRIPTION = \"%s\"\n" % group )
2544             group_file.write( "LICENSE = \"MIT\"\n" )
2545             group_file.write( "DEPENDS = \"virtual/kernel\"\n" )
2546             group_file.write( "PR = \"r1\"\n" )
2547
2548             group_file.write( "inherit packagegroup\n" )
2549             group_file.write( "\n" )
2550             group_file.write( "PACKAGE_ARCH = \"${MACHINE_ARCH}\"\n" )
2551             group_file.write( "\n" )
2552
2553             group_file.write( "RDEPENDS_${PN} = \"\" \n\n" )
2554             for pkg in group_dico[group]:
2555                 group_file.write( "RDEPENDS_${PN} += \"%s\"\n" % pkg )
2556
2557 def generateBuildStatus( project_path ):
2558     res_native = {}
2559     res = {}
2560     if not os.path.isdir( project_path ):
2561             msg = "The path \"%s\" is not a directory."
2562             msg = msg % ( project_path )
2563             print >> sys.stderr, colorize( msg, "red" )
2564             sys.exit( 1 )
2565
2566     for package_path in os.listdir( project_path ):
2567         project_full_path = os.path.join( project_path, package_path )
2568         if  ( package_path == "build_stats" ) and os.path.isfile( project_full_path )  :
2569             pass
2570
2571         elif os.path.isdir( project_full_path ):
2572             BN, PV, PR = cleanPackageName( package_path )
2573             res_status = check_package_status( project_full_path )
2574
2575             if BN.endswith("-native"):
2576                 res_native[BN] = [PV ] + res_status
2577             else:
2578                 res[BN] = [PV ] + res_status
2579
2580         # ignorefiles
2581         elif package_path in ["."]:
2582             pass
2583
2584         else:
2585             msg = "This directory should not contain the file \"%s\"."
2586             msg = msg % ( package_path )
2587             print >> sys.stderr, colorize( msg, "red" )
2588             sys.exit( 1 )
2589
2590     return res_native, res
2591
2592 def cleanPackageName( package_path ):
2593     if  package_path.count( "-" ) < 2:
2594         msg = "unknow format for package \"%s\"."
2595         msg = msg % ( package_path )
2596         print >> sys.stderr, colorize( msg, "red" )
2597         sys.exit( 1 )
2598
2599     PR=package_path[package_path.rindex("-")+1:]
2600     package_path=package_path[:package_path.rindex("-")]
2601     PV=package_path[package_path.rindex("-")+1:]
2602     BN=package_path[:package_path.rindex("-")]
2603
2604     return BN, PV, PR
2605
2606
2607 def check_package_status( project_full_path ):
2608     tasks_order = ["do_fetch",
2609                    "do_unpack",
2610                    "do_patch",
2611                    "do_populate_lic",
2612                    "do_configure",
2613                    "do_compile",
2614                    "do_install",
2615                    "do_populate_sysroot",
2616                    "do_package",
2617                    "do_packagedata",
2618                    "do_package_write_rpm",
2619                    "do_rootfs"]
2620
2621     max_index=-1
2622     for package_task in os.listdir( project_full_path ):
2623         if package_task in tasks_order:
2624             task_index = tasks_order.index( package_task )
2625
2626             if task_index > max_index:
2627                 max_index = task_index
2628
2629     if max_index == -1:
2630         msg = "No log task in \"%s\"."
2631         msg = msg % ( project_full_path )
2632         print >> sys.stderr, colorize( msg, "red" )
2633         sys.exit( 1 )
2634
2635     last_task = tasks_order[max_index][3:]
2636
2637     task_status = ""
2638     status = "unknow"
2639     with open( os.path.join( project_full_path, tasks_order[max_index] ) ) as status_file:
2640         for line in status_file:
2641             if line.startswith( "Status: " ):
2642                 status = line[len( "Status: " ):].replace( "\n", "" ).replace( " ", "" )
2643                 break
2644     if last_task == "package_write_rpm" and status == "PASSED":
2645         status = "OK"
2646
2647     return [last_task, status]
2648
2649 def clean_Packagegroup( project,group_dico ):
2650     group_dico_tmp = {}
2651
2652     package_replacement = SPEC2YOCTO_CONFIG.get_substitute( project )
2653
2654     for group in group_dico.keys():
2655         group_dico_tmp[group] = []
2656         for package in group_dico[group]:
2657             if package in package_replacement.keys():
2658                 group_dico_tmp[group].append( package_replacement[package] )
2659             else:
2660                 group_dico_tmp[group].append( package )
2661
2662     return group_dico_tmp
2663
2664
2665 def check_debugmode( opts_debug ):
2666     global DEBUG_RUN
2667     if opts_debug == "no":
2668         DEBUG_RUN = False
2669     elif opts_debug == "yes":
2670         DEBUG_RUN = True
2671
2672
2673 class spec2yoctoCommandline( cmdln.Cmdln ):
2674     name = "spec2yocto"
2675     version = "0.1"
2676
2677     def do_manifestToList( self, subcmd, opts, project = None ):
2678         """${cmd_name}: print the list of package in projects.
2679
2680         ${cmd_usage}--
2681         ${cmd_option_list}
2682         """
2683         if project is None:
2684             project = SPEC2YOCTO_CONFIG.get_current_project()
2685
2686         pkg_co = manifestCollection( project )
2687         pkg_co.print_list()
2688
2689     def do_createRecipes( self, subcmd, opts, project = None ):
2690         """${cmd_name}: create all packages recipes.
2691
2692         ${cmd_usage}--
2693         ${cmd_option_list}
2694         """
2695         if project is None:
2696             project = SPEC2YOCTO_CONFIG.get_current_project()
2697
2698         pkg_co = manifestCollection( project )
2699         pkg_co.createRecipes()
2700
2701     @cmdln.option( "--package_pn",
2702                   action = "store",
2703                   default = None,
2704                   help = "select the package_pn." )
2705     def do_findBestSpecFile( self, subcmd, opts, package_path ):
2706         """${cmd_name}: print the speec file associate to package.
2707
2708         ${cmd_usage}--
2709         ${cmd_option_list}
2710         """
2711         res = findBestSpecFile( package_path, opts.package_pn )
2712         print res
2713
2714     @cmdln.option( "--package_pn",
2715                   action = "append",
2716                   default = None,
2717                   help = "select the package_pn." )
2718     def do_findSpecPatchFiles( self, subcmd, opts, patch_dir, ):
2719         """${cmd_name}: print patch from "specfile-patch" directory associate to package.
2720
2721         ${cmd_usage}--
2722         ${cmd_option_list}
2723         """
2724         res = findSpecPatchFiles( patch_dir, opts.package_pn )
2725         print " ".join( res )
2726
2727     @cmdln.option( "--package_pn",
2728                   action = "append",
2729                   default = None,
2730                   help = "select the package_pn." )
2731     @cmdln.option( "--project",
2732                   action = "store",
2733                   default = None,
2734                   help = "select the package_pn." )
2735     def do_specfile_patcher( self, subcmd, opts, package_spec_path ):
2736         """${cmd_name}: patch the spec file with patch from "specfile-patch" directory.
2737
2738         ${cmd_usage}--
2739         ${cmd_option_list}
2740         """
2741         if opts.project is None:
2742             project = SPEC2YOCTO_CONFIG.get_current_project()
2743         else:
2744             project = opts.project
2745
2746         res = specfile_patcher( package_spec_path, project, opts.package_pn, package_spec_path )
2747
2748
2749     def do_createPackagegroup( self, subcmd, opts, project = None ):
2750         """${cmd_name}: print the list of package in projects.
2751
2752         ${cmd_usage}--
2753         ${cmd_option_list}
2754         """
2755         if project is None:
2756             project = SPEC2YOCTO_CONFIG.get_current_project()
2757
2758
2759         res = SPEC2YOCTO_CONFIG.get_group( project )
2760         group_file_path = check_group_file( project )
2761         group_dico= parse_group_xml( group_file_path )
2762
2763         group_dico = clean_Packagegroup( project, group_dico )
2764
2765         dump_group(project,group_dico)
2766
2767     @cmdln.option( "--debug",
2768                   action = "store",
2769                   default = None,
2770                   help = "run the in debug mode.[yes/no]" )
2771     @cmdln.option( "--project",
2772                   action = "store",
2773                   default = None,
2774                   help = "select the project." )
2775     @cmdln.option( "--package_pn",
2776                   action = "store",
2777                   default = None,
2778                   help = "select the package_pn." )
2779     def do_prep( self, subcmd, opts, spec_path ):
2780         """${cmd_name}: print the bash code of the %prep section of a spec file.
2781
2782         ${cmd_usage}--
2783         ${cmd_option_list}
2784         """
2785         check_debugmode( opts.debug )
2786
2787         if opts.project is None:
2788             project = SPEC2YOCTO_CONFIG.get_current_project()
2789         else:
2790             project = opts.project
2791
2792         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_prep_section()
2793         print res
2794         res = 0
2795
2796     @cmdln.option( "--debug",
2797                   action = "store",
2798                   default = None,
2799                   help = "run the in debug mode.[yes/no]" )
2800     @cmdln.option( "--project",
2801                   action = "store",
2802                   default = None,
2803                   help = "select the project." )
2804     @cmdln.option( "--package_pn",
2805                   action = "store",
2806                   default = None,
2807                   help = "select the package_pn." )
2808     def do_compile( self, subcmd, opts, spec_path ):
2809         """${cmd_name}: print the bash code of the %build section of a spec file.
2810
2811         ${cmd_usage}--
2812         ${cmd_option_list}
2813         """
2814         check_debugmode( opts.debug )
2815
2816         if opts.project is None:
2817             project = SPEC2YOCTO_CONFIG.get_current_project()
2818         else:
2819             project = opts.project
2820
2821         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_build_section()
2822         if res != 1:
2823             print res
2824
2825     @cmdln.option( "--debug",
2826                   action = "store",
2827                   default = None,
2828                   help = "run the in debug mode.[yes/no]" )
2829     @cmdln.option( "--project",
2830                   action = "store",
2831                   default = None,
2832                   help = "select the project." )
2833     @cmdln.option( "--package_pn",
2834                   action = "store",
2835                   default = None,
2836                   help = "select the package_pn." )
2837     def do_install( self, subcmd, opts, spec_path ):
2838         """${cmd_name}: print the bash code of the %install section of a spec file.
2839
2840         ${cmd_usage}--
2841         ${cmd_option_list}
2842         """
2843         check_debugmode( opts.debug )
2844
2845
2846         if opts.project is None:
2847             project = SPEC2YOCTO_CONFIG.get_current_project()
2848         else:
2849             project = opts.project
2850
2851         res = SpecParser( spec_path, package_pn = opts.package_pn ).get_install_section()
2852         if res != 1:
2853             print res
2854
2855     @cmdln.option( "--debug",
2856                   action = "store",
2857                   default = None,
2858                   help = "run the in debug mode.[yes/no]" )
2859     def do_generateBuildStatus( self, subcmd, opts, project_path ):
2860         """${cmd_name}: print the status and the the build state of packages,
2861         builded in a single command.
2862         exemple:
2863             build/tmp-eglibc/buildstats/core-image-minimal-qemux86/XXXX/
2864         ${cmd_usage}--
2865         ${cmd_option_list}
2866         """
2867         check_debugmode( opts.debug )
2868
2869         res_native, res = generateBuildStatus( project_path )
2870
2871         res_native_keys = res_native.keys()
2872         res_keys = res.keys()
2873
2874         res_native_keys.sort()
2875         res_keys.sort()
2876
2877         for r in res_native_keys:
2878             print r + "\t" + "\t".join( res_native[r] )
2879         print
2880         for r in res_keys:
2881             print r + "\t" + "\t".join( res[r] )
2882
2883
2884     @cmdln.option( "--debug",
2885                   action = "store",
2886                   default = None,
2887                   help = "run the in debug mode.[yes/no]" )
2888     def do_generatePseudoSpecfile( self, subcmd, opts, spec_path ):
2889         """${cmd_name}: generate a spec file use by yocto, for packaging rpm.
2890
2891         ${cmd_usage}--
2892         ${cmd_option_list}
2893         """
2894         check_debugmode( opts.debug )
2895
2896         a_spec_parser = SpecParser( spec_path )
2897         a_spec_parser.parse_raw_spec_file()
2898         res = a_spec_parser.get_clean_raw()
2899         if res != 1:
2900             print res
2901
2902     @cmdln.option( "--debug",
2903                   action = "store",
2904                   default = None,
2905                   help = "run the in debug mode.[yes/no]" )
2906     @cmdln.option( "--project",
2907                   action = "store",
2908                   default = None,
2909                   help = "select the project." )
2910     def do_working_dir( self, subcmd, opts ):
2911         """${cmd_name}: return the proto directory.
2912
2913         ${cmd_usage}--
2914         ${cmd_option_list}
2915         """
2916         check_debugmode( opts.debug )
2917
2918         if opts.project is None:
2919             project = SPEC2YOCTO_CONFIG.get_current_project()
2920         else:
2921             project = opts.project
2922
2923         working_dir = SPEC2YOCTO_CONFIG.get_working_dir( project )
2924         if working_dir != 1:
2925             print working_dir
2926
2927 def main():
2928     commandline = spec2yoctoCommandline()
2929
2930     try:
2931         res = commandline.main()
2932     except ValueError as ve:
2933         print
2934         print >> sys.stderr, colorize( str( ve ), "red" )
2935         res = 1
2936     except EnvironmentError as ioe:
2937 #        commandline.do_help([sys.argv[0]])
2938         print
2939         print >> sys.stderr, colorize( str( ioe ), "red" )
2940         if hasattr( ioe, "spec2yocto_config_error" ):
2941             msg = "See '--config' option"
2942             print >> sys.stderr, colorize( msg, "red" )
2943         res = 1
2944 #     except Exception as e_all :
2945 #         print
2946 #         print >> sys.stderr, colorize( str( e_all ), "red" )
2947 #         res = 1
2948     sys.exit( res )
2949
2950 if __name__ == '__main__':
2951     main()