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