2 # Install distribution package.
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials are licensed and made available
7 # under the terms and conditions of the BSD License which accompanies this
8 # distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 Install a distribution package
22 from os
import SEEK_SET
23 from os
import SEEK_END
27 from sys
import platform
28 from shutil
import rmtree
29 from shutil
import copyfile
30 from traceback
import format_exc
31 from platform
import python_version
33 from Logger
import StringTable
as ST
34 from Logger
.ToolError
import UNKNOWN_ERROR
35 from Logger
.ToolError
import FILE_UNKNOWN_ERROR
36 from Logger
.ToolError
import OPTION_MISSING
37 from Logger
.ToolError
import UPT_ALREADY_INSTALLED_ERROR
38 from Logger
.ToolError
import FatalError
39 from Logger
.ToolError
import ABORT_ERROR
40 from Logger
.ToolError
import CODE_ERROR
41 from Logger
.ToolError
import FORMAT_INVALID
42 from Logger
.ToolError
import FILE_TYPE_MISMATCH
43 import Logger
.Log
as Logger
45 from Library
.Misc
import CheckEnvVariable
46 from Library
.Misc
import Sdict
47 from Library
.Misc
import ConvertPath
48 from Library
.ParserValidate
import IsValidInstallPath
49 from Xml
.XmlParser
import DistributionPackageXml
50 from GenMetaFile
.GenDecFile
import PackageToDec
51 from GenMetaFile
.GenInfFile
import ModuleToInf
52 from Core
.PackageFile
import PackageFile
53 from Core
.PackageFile
import FILE_NOT_FOUND
54 from Core
.PackageFile
import FILE_CHECKSUM_FAILURE
55 from Core
.PackageFile
import CreateDirectory
56 from Core
.DependencyRules
import DependencyRules
57 from Library
import GlobalData
61 # @param WorkspaceDir: Workspace Directory
62 # @param Path: Package Path
63 # @param CustomPath: whether need to customize path at first
65 def InstallNewPackage(WorkspaceDir
, Path
, CustomPath
= False):
66 if os
.path
.isabs(Path
):
67 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%Path
)
69 Logger
.Info(ST
.MSG_NEW_PKG_PATH
)
71 Path
= ConvertPath(Path
)
72 Path
= os
.path
.normpath(Path
)
73 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
74 if os
.path
.exists(FullPath
):
75 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%FullPath
)
79 Input
= stdin
.readline()
80 Input
= Input
.replace('\r', '').replace('\n', '')
82 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
83 Input
= Input
.replace('\r', '').replace('\n', '')
84 return InstallNewPackage(WorkspaceDir
, Input
, False)
89 # @param WorkspaceDir: Workspace Directory
90 # @param Path: Standalone Module Path
91 # @param PathList: The already installed standalone module Path list
93 def InstallNewModule(WorkspaceDir
, Path
, PathList
= None):
96 Path
= ConvertPath(Path
)
97 Path
= os
.path
.normpath(Path
)
98 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
99 if os
.path
.exists(FullPath
) and FullPath
not in PathList
:
100 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%Path
)
101 elif Path
== FullPath
:
102 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%FullPath
)
106 Input
= stdin
.readline()
107 Input
= Input
.replace('\r', '').replace('\n', '')
109 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
110 Input
= Input
.replace('\r', '').replace('\n', '')
111 return InstallNewModule(WorkspaceDir
, Input
, PathList
)
116 # @param WorkspaceDir: Workspace Direction
119 def InstallNewFile(WorkspaceDir
, File
):
120 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, File
))
121 if os
.path
.exists(FullPath
):
122 Logger
.Info(ST
.ERR_FILE_ALREADY_EXIST
%File
)
123 Input
= stdin
.readline()
124 Input
= Input
.replace('\r', '').replace('\n', '')
126 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
127 Input
= Input
.replace('\r', '').replace('\n', '')
128 return InstallNewFile(WorkspaceDir
, Input
)
136 def UnZipDp(WorkspaceDir
, Options
, DataBase
):
137 ContentZipFile
= None
138 Logger
.Quiet(ST
.MSG_UZIP_PARSE_XML
)
139 DpPkgFileName
= Options
.PackageFile
140 DistFile
= PackageFile(DpPkgFileName
)
142 DpDescFileName
, ContentFileName
= GetDPFile(DistFile
.GetZipFile())
144 GlobalData
.gUNPACK_DIR
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, ".tmp"))
145 DistPkgFile
= DistFile
.UnpackFile(DpDescFileName
,
146 os
.path
.normpath(os
.path
.join(GlobalData
.gUNPACK_DIR
, DpDescFileName
)))
148 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_FILE_BROKEN
%DpDescFileName
)
153 DistPkgObj
= DistributionPackageXml()
154 DistPkg
= DistPkgObj
.FromXml(DistPkgFile
)
155 if DistPkg
.Header
.RePackage
== '':
156 DistPkg
.Header
.RePackage
= False
157 if DistPkg
.Header
.ReadOnly
== '':
158 DistPkg
.Header
.ReadOnly
= False
161 # prepare check dependency
163 Dep
= DependencyRules(DataBase
)
165 # Check distribution package installed or not
167 if Dep
.CheckDpExists(DistPkg
.Header
.GetGuid(),
168 DistPkg
.Header
.GetVersion()):
169 Logger
.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR
,
170 ST
.WRN_DIST_PKG_INSTALLED
)
172 # Check distribution dependency (all module dependency should be
175 if not Dep
.CheckDpDepexSatisfied(DistPkg
):
176 Logger
.Error("InstallPkg", UNKNOWN_ERROR
,
177 ST
.ERR_PACKAGE_NOT_MATCH_DEPENDENCY
,
178 ExtraData
=DistPkg
.Header
.Name
)
180 # unzip contents.zip file
182 ContentFile
= DistFile
.UnpackFile(ContentFileName
,
183 os
.path
.normpath(os
.path
.join(GlobalData
.gUNPACK_DIR
, ContentFileName
)))
185 Logger
.Error("InstallPkg", FILE_NOT_FOUND
,
186 ST
.ERR_FILE_BROKEN
% ContentFileName
)
188 FilePointer
= open(ContentFile
, "rb")
190 # Assume no archive comment.
192 FilePointer
.seek(0, SEEK_SET
)
193 FilePointer
.seek(0, SEEK_END
)
197 FileSize
= FilePointer
.tell()
201 ContentZipFile
= PackageFile(ContentFile
)
204 # verify MD5 signature when existed
206 if DistPkg
.Header
.Signature
!= '':
207 Md5Sigature
= md5
.new(open(ContentFile
, 'rb').read())
208 if DistPkg
.Header
.Signature
!= Md5Sigature
.hexdigest():
209 ContentZipFile
.Close()
210 Logger
.Error("InstallPkg", FILE_CHECKSUM_FAILURE
,
211 ExtraData
=ContentFile
)
213 return DistPkg
, Dep
, ContentZipFile
, DpPkgFileName
219 def GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
, ContentZipFile
, ModuleList
, PackageList
):
221 for Guid
, Version
, Path
in DistPkg
.PackageSurfaceArea
:
223 Package
= DistPkg
.PackageSurfaceArea
[Guid
, Version
, Path
]
224 Logger
.Info(ST
.MSG_INSTALL_PACKAGE
% Package
.GetName())
225 if Dep
.CheckPackageExists(Guid
, Version
):
226 Logger
.Info(ST
.WRN_PACKAGE_EXISTED
%(Guid
, Version
))
227 NewPackagePath
= InstallNewPackage(WorkspaceDir
, PackagePath
, Options
.CustomPath
)
228 InstallPackageContent(PackagePath
, NewPackagePath
, Package
, ContentZipFile
, Dep
, WorkspaceDir
, ModuleList
,
229 DistPkg
.Header
.ReadOnly
)
230 PackageList
.append(Package
)
232 NewDict
[Guid
, Version
, Package
.GetPackagePath()] = Package
235 # Now generate meta-data files, first generate all dec for package
236 # dec should be generated before inf, and inf should be generated after
237 # all packages installed, else hard to resolve modules' package
238 # dependency (Hard to get the location of the newly installed package)
240 for Package
in PackageList
:
241 FilePath
= PackageToDec(Package
)
242 Md5Sigature
= md5
.new(open(str(FilePath
), 'rb').read())
243 Md5Sum
= Md5Sigature
.hexdigest()
244 if (FilePath
, Md5Sum
) not in Package
.FileList
:
245 Package
.FileList
.append((FilePath
, Md5Sum
))
253 def GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
):
255 # ModulePathList will keep track of the standalone module path that
256 # we just installed. If a new module's path in that list
257 # (only multiple INF in one directory will be so), we will
258 # install them directly. If not, we will try to create a new directory
264 # Check module exist and install
268 for Guid
, Version
, Name
, Path
in DistPkg
.ModuleSurfaceArea
:
270 Module
= DistPkg
.ModuleSurfaceArea
[Guid
, Version
, Name
, Path
]
271 Logger
.Info(ST
.MSG_INSTALL_MODULE
% Module
.GetName())
272 if Dep
.CheckModuleExists(Guid
, Version
, Name
, Path
):
273 Logger
.Quiet(ST
.WRN_MODULE_EXISTED
%Path
)
275 # here check for the multiple inf share the same module path cases:
276 # they should be installed into the same directory
279 os
.path
.normpath(os
.path
.join(WorkspaceDir
, ModulePath
))
280 if ModuleFullPath
not in ModulePathList
:
281 NewModulePath
= InstallNewModule(WorkspaceDir
, ModulePath
, ModulePathList
)
282 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewModulePath
))
283 ModulePathList
.append(NewModuleFullPath
)
285 NewModulePath
= ModulePath
287 InstallModuleContent(ModulePath
, NewModulePath
, '', Module
, ContentZipFile
, WorkspaceDir
, ModuleList
, None,
288 DistPkg
.Header
.ReadOnly
)
292 Module
.SetModulePath(Module
.GetModulePath().replace(Path
, NewModulePath
, 1))
294 NewDict
[Guid
, Version
, Name
, Module
.GetModulePath()] = Module
297 # generate all inf for modules
299 for (Module
, Package
) in ModuleList
:
300 FilePath
= ModuleToInf(Module
)
301 Md5Sigature
= md5
.new(open(str(FilePath
), 'rb').read())
302 Md5Sum
= Md5Sigature
.hexdigest()
304 if (FilePath
, Md5Sum
) not in Package
.FileList
:
305 Package
.FileList
.append((FilePath
, Md5Sum
))
307 if (FilePath
, Md5Sum
) not in Module
.FileList
:
308 Module
.FileList
.append((FilePath
, Md5Sum
))
317 def GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
):
318 ToolObject
= DistPkg
.Tools
319 MiscObject
= DistPkg
.MiscellaneousFiles
320 DistPkg
.FileList
= []
324 RootDir
= WorkspaceDir
327 # FileList stores both tools files and misc files
328 # Misc file list must be appended to FileList *AFTER* Tools file list
331 FileList
+= ToolObject
.GetFileList()
332 ToolFileNum
= len(ToolObject
.GetFileList())
333 if 'EDK_TOOLS_PATH' in os
.environ
:
334 RootDir
= os
.environ
['EDK_TOOLS_PATH']
336 FileList
+= MiscObject
.GetFileList()
337 for FileObject
in FileList
:
339 if FileNum
> ToolFileNum
:
341 # Misc files, root should be changed to WORKSPACE
343 RootDir
= WorkspaceDir
344 File
= ConvertPath(FileObject
.GetURI())
345 ToFile
= os
.path
.normpath(os
.path
.join(RootDir
, File
))
346 if os
.path
.exists(ToFile
):
347 Logger
.Info( ST
.WRN_FILE_EXISTED
% ToFile
)
349 # ask for user input the new file name
351 Logger
.Info( ST
.MSG_NEW_FILE_NAME
)
352 Input
= stdin
.readline()
353 Input
= Input
.replace('\r', '').replace('\n', '')
354 OrigPath
= os
.path
.split(ToFile
)[0]
355 ToFile
= os
.path
.normpath(os
.path
.join(OrigPath
, Input
))
356 FromFile
= os
.path
.join(FileObject
.GetURI())
357 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, DistPkg
.Header
.ReadOnly
, FileObject
.GetExecutable())
358 DistPkg
.FileList
.append((ToFile
, Md5Sum
))
360 ## Tool entrance method
362 # This method mainly dispatch specific methods per the command line options.
363 # If no error found, return zero value so the caller of this tool can know
364 # if it's executed successfully or not.
366 # @param Options: command Options
368 def Main(Options
= None):
369 ContentZipFile
, DistFile
= None, None
372 DataBase
= GlobalData
.gDB
374 WorkspaceDir
= GlobalData
.gWORKSPACE
375 if not Options
.PackageFile
:
376 Logger
.Error("InstallPkg", OPTION_MISSING
, ExtraData
=ST
.ERR_SPECIFY_PACKAGE
)
379 # unzip dist.pkg file
381 DistPkg
, Dep
, ContentZipFile
, DpPkgFileName
= UnZipDp(WorkspaceDir
, Options
, DataBase
)
384 # PackageList, ModuleList record the information for the meta-data
385 # files that need to be generated later
389 DistPkg
.PackageSurfaceArea
= GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
,
390 ContentZipFile
, ModuleList
, PackageList
)
392 DistPkg
.ModuleSurfaceArea
= GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
)
395 GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
)
398 # copy "Distribution File" to directory $(WORKSPACE)/conf/upt
400 DistFileName
= os
.path
.split(DpPkgFileName
)[1]
401 DestDir
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, GlobalData
.gUPT_DIR
))
402 CreateDirectory(DestDir
)
403 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, DistFileName
))
404 if os
.path
.exists(DestFile
):
405 FileName
, Ext
= os
.path
.splitext(DistFileName
)
406 NewFileName
= FileName
+ '_' + DistPkg
.Header
.GetGuid() + '_' + DistPkg
.Header
.GetVersion() + Ext
407 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, NewFileName
))
408 if os
.path
.exists(DestFile
):
410 # ask for user input the new file name
412 Logger
.Info( ST
.MSG_NEW_FILE_NAME_FOR_DIST
)
413 Input
= stdin
.readline()
414 Input
= Input
.replace('\r', '').replace('\n', '')
415 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, Input
))
416 copyfile(DpPkgFileName
, DestFile
)
417 NewDpPkgFileName
= DestFile
[DestFile
.find(DestDir
) + len(DestDir
) + 1:]
422 Logger
.Quiet(ST
.MSG_UPDATE_PACKAGE_DATABASE
)
423 DataBase
.AddDPObject(DistPkg
, NewDpPkgFileName
, DistFileName
,
424 DistPkg
.Header
.RePackage
)
428 except FatalError
, XExcept
:
429 ReturnCode
= XExcept
.args
[0]
430 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
431 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(),
432 platform
) + format_exc())
433 except KeyboardInterrupt:
434 ReturnCode
= ABORT_ERROR
435 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
436 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(),
437 platform
) + format_exc())
439 ReturnCode
= CODE_ERROR
443 ST
.ERR_UNKNOWN_FATAL_INSTALL_ERR
% Options
.PackageFile
,
444 ExtraData
=ST
.MSG_SEARCH_FOR_HELP
,
447 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(),
448 platform
) + format_exc())
451 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_STARTED
)
455 ContentZipFile
.Close()
456 if GlobalData
.gUNPACK_DIR
:
457 rmtree(GlobalData
.gUNPACK_DIR
)
458 GlobalData
.gUNPACK_DIR
= None
459 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_DONE
)
462 Logger
.Quiet(ST
.MSG_FINISH
)
466 ## InstallModuleContent method
468 # If this is standalone module, then Package should be none,
469 # ModulePath should be ''
470 # @param FromPath: FromPath
471 # @param NewPath: NewPath
472 # @param ModulePath: ModulePath
473 # @param Module: Module
474 # @param ContentZipFile: ContentZipFile
475 # @param WorkspaceDir: WorkspaceDir
476 # @param ModuleList: ModuleList
477 # @param Package: Package
479 def InstallModuleContent(FromPath
, NewPath
, ModulePath
, Module
, ContentZipFile
,
480 WorkspaceDir
, ModuleList
, Package
= None, ReadOnly
= False):
482 if NewPath
.startswith("\\") or NewPath
.startswith("/"):
483 NewPath
= NewPath
[1:]
485 if not IsValidInstallPath(NewPath
):
486 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%NewPath
)
488 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewPath
,
489 ConvertPath(ModulePath
)))
490 Module
.SetFullPath(os
.path
.normpath(os
.path
.join(NewModuleFullPath
,
491 ConvertPath(Module
.GetName()) + '.inf')))
494 for MiscFile
in Module
.GetMiscFileList():
497 for Item
in MiscFile
.GetFileList():
499 if File
.startswith("\\") or File
.startswith("/"):
502 if not IsValidInstallPath(File
):
503 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
505 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
506 Executable
= Item
.GetExecutable()
507 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
508 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
509 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
510 Package
.FileList
.append((ToFile
, Md5Sum
))
513 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
514 Module
.FileList
.append((ToFile
, Md5Sum
))
515 for Item
in Module
.GetSourceFileList():
516 File
= Item
.GetSourceFile()
517 if File
.startswith("\\") or File
.startswith("/"):
520 if not IsValidInstallPath(File
):
521 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
523 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
524 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
525 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
526 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
527 Package
.FileList
.append((ToFile
, Md5Sum
))
530 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
531 Module
.FileList
.append((ToFile
, Md5Sum
))
532 for Item
in Module
.GetBinaryFileList():
533 FileNameList
= Item
.GetFileNameList()
534 for FileName
in FileNameList
:
535 File
= FileName
.GetFilename()
536 if File
.startswith("\\") or File
.startswith("/"):
539 if not IsValidInstallPath(File
):
540 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
542 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
543 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
544 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
545 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
546 Package
.FileList
.append((ToFile
, Md5Sum
))
549 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
550 Module
.FileList
.append((ToFile
, Md5Sum
))
552 InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
555 ## InstallModuleContentZipFile
557 # InstallModuleContentZipFile
559 def InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
562 # Extract other files under current module path in content Zip file but not listed in the description
565 for FileName
in ContentZipFile
.GetZipFile().namelist():
566 FileName
= os
.path
.normpath(FileName
)
567 CheckPath
= os
.path
.normpath(os
.path
.join(FromPath
, ModulePath
))
568 if FileUnderPath(FileName
, CheckPath
):
569 if FileName
.startswith("\\") or FileName
.startswith("/"):
570 FileName
= FileName
[1:]
572 if not IsValidInstallPath(FileName
):
573 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
576 ToFile
= os
.path
.normpath(os
.path
.join(WorkspaceDir
,
577 ConvertPath(FileName
.replace(FromPath
, NewPath
, 1))))
578 CheckList
= Module
.FileList
580 CheckList
+= Package
.FileList
581 for Item
in CheckList
:
582 if Item
[0] == ToFile
:
585 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
586 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
587 Package
.FileList
.append((ToFile
, Md5Sum
))
590 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
591 Module
.FileList
.append((ToFile
, Md5Sum
))
593 ModuleList
.append((Module
, Package
))
596 # Check whether FileName started with directory specified by CheckPath
598 # @param FileName: the FileName need to be checked
599 # @param CheckPath: the path need to be checked against
600 # @return: True or False
602 def FileUnderPath(FileName
, CheckPath
):
603 FileName
= FileName
.replace('\\', '/')
604 FileName
= os
.path
.normpath(FileName
)
605 CheckPath
= CheckPath
.replace('\\', '/')
606 CheckPath
= os
.path
.normpath(CheckPath
)
607 if FileName
.startswith(CheckPath
):
608 RemainingPath
= os
.path
.normpath(FileName
.replace(CheckPath
, '', 1))
609 while RemainingPath
.startswith('\\') or RemainingPath
.startswith('/'):
610 RemainingPath
= RemainingPath
[1:]
611 if FileName
== os
.path
.normpath(os
.path
.join(CheckPath
, RemainingPath
)):
617 # Extract File from Zipfile, set file attribute, and return the Md5Sum
619 # @return: True or False
621 def InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
=False):
622 if not ContentZipFile
or not ContentZipFile
.UnpackFile(FromFile
, ToFile
):
623 Logger
.Error("UPT", FILE_NOT_FOUND
, ST
.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT
%FromFile
)
627 chmod(ToFile
, stat
.S_IREAD
)
629 chmod(ToFile
, stat
.S_IREAD|stat
.S_IEXEC
)
631 chmod(ToFile
, stat
.S_IREAD|stat
.S_IWRITE|stat
.S_IEXEC
)
633 chmod(ToFile
, stat
.S_IREAD|stat
.S_IWRITE
)
635 Md5Sigature
= md5
.new(open(str(ToFile
), 'rb').read())
636 Md5Sum
= Md5Sigature
.hexdigest()
639 ## InstallPackageContent method
641 # @param FromPath: FromPath
642 # @param ToPath: ToPath
643 # @param Package: Package
644 # @param ContentZipFile: ContentZipFile
646 # @param WorkspaceDir: WorkspaceDir
647 # @param ModuleList: ModuleList
649 def InstallPackageContent(FromPath
, ToPath
, Package
, ContentZipFile
, Dep
,
650 WorkspaceDir
, ModuleList
, ReadOnly
= False):
653 Package
.FileList
= []
655 if ToPath
.startswith("\\") or ToPath
.startswith("/"):
658 if not IsValidInstallPath(ToPath
):
659 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%ToPath
)
661 if FromPath
.startswith("\\") or FromPath
.startswith("/"):
662 FromPath
= FromPath
[1:]
664 if not IsValidInstallPath(FromPath
):
665 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FromPath
)
667 PackageFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, ToPath
))
668 for MiscFile
in Package
.GetMiscFileList():
669 for Item
in MiscFile
.GetFileList():
670 FileName
= Item
.GetURI()
671 if FileName
.startswith("\\") or FileName
.startswith("/"):
672 FileName
= FileName
[1:]
674 if not IsValidInstallPath(FileName
):
675 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
677 FromFile
= os
.path
.join(FromPath
, FileName
)
678 Executable
= Item
.GetExecutable()
679 ToFile
= (os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
680 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
681 if (ToFile
, Md5Sum
) not in Package
.FileList
:
682 Package
.FileList
.append((ToFile
, Md5Sum
))
683 PackageIncludeArchList
= []
684 for Item
in Package
.GetPackageIncludeFileList():
685 FileName
= Item
.GetFilePath()
686 if FileName
.startswith("\\") or FileName
.startswith("/"):
687 FileName
= FileName
[1:]
689 if not IsValidInstallPath(FileName
):
690 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
692 FromFile
= os
.path
.join(FromPath
, FileName
)
693 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
694 RetFile
= ContentZipFile
.UnpackFile(FromFile
, ToFile
)
697 # a non-exist path in Zipfile will return '', which means an include directory in our case
698 # save the information for later DEC creation usage and also create the directory
700 PackageIncludeArchList
.append([Item
.GetFilePath(), Item
.GetSupArchList()])
701 CreateDirectory(ToFile
)
704 chmod(ToFile
, stat
.S_IREAD
)
706 chmod(ToFile
, stat
.S_IREAD|stat
.S_IWRITE
)
707 Md5Sigature
= md5
.new(open(str(ToFile
), 'rb').read())
708 Md5Sum
= Md5Sigature
.hexdigest()
709 if (ToFile
, Md5Sum
) not in Package
.FileList
:
710 Package
.FileList
.append((ToFile
, Md5Sum
))
711 Package
.SetIncludeArchList(PackageIncludeArchList
)
713 for Item
in Package
.GetStandardIncludeFileList():
714 FileName
= Item
.GetFilePath()
715 if FileName
.startswith("\\") or FileName
.startswith("/"):
716 FileName
= FileName
[1:]
718 if not IsValidInstallPath(FileName
):
719 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
721 FromFile
= os
.path
.join(FromPath
, FileName
)
722 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
723 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
724 if (ToFile
, Md5Sum
) not in Package
.FileList
:
725 Package
.FileList
.append((ToFile
, Md5Sum
))
730 Package
.SetPackagePath(Package
.GetPackagePath().replace(FromPath
,
732 Package
.SetFullPath(os
.path
.normpath(os
.path
.join(PackageFullPath
,
733 ConvertPath(Package
.GetName()) + '.dec')))
736 # Install files in module
739 ModuleDict
= Package
.GetModuleDict()
740 for ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
in ModuleDict
:
741 Module
= ModuleDict
[ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
]
742 InstallModuleContent(FromPath
, ToPath
, ModulePath
, Module
,
743 ContentZipFile
, WorkspaceDir
, ModuleList
, Package
, ReadOnly
)
747 # @param ZipFile: A ZipFile
749 def GetDPFile(ZipFile
):
752 for FileName
in ZipFile
.namelist():
753 if FileName
.endswith('.content'):
755 ContentFile
= FileName
757 elif FileName
.endswith('.pkg'):
764 Logger
.Error("PackagingTool", FILE_TYPE_MISMATCH
,
765 ExtraData
=ST
.ERR_DIST_FILE_TOOMANY
)
766 if not DescFile
or not ContentFile
:
767 Logger
.Error("PackagingTool", FILE_UNKNOWN_ERROR
,
768 ExtraData
=ST
.ERR_DIST_FILE_TOOFEW
)
769 return DescFile
, ContentFile