]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/RmPkg.py
BaseTools: Clear build versions to sync with buildtools/BaseTools
[mirror_edk2.git] / BaseTools / Source / Python / UPT / RmPkg.py
CommitLineData
4234283c
LG
1## @file\r
2# Install distribution package.\r
3#\r
4# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15'''\r
16RmPkg\r
17'''\r
18\r
19##\r
20# Import Modules\r
21#\r
22import os.path\r
23from stat import S_IWUSR\r
24from traceback import format_exc\r
25from platform import python_version\r
26import md5\r
27from sys import stdin\r
28from sys import platform\r
29\r
30from Core.DependencyRules import DependencyRules\r
31from Library.Misc import CheckEnvVariable\r
32from Library import GlobalData\r
33from Logger import StringTable as ST\r
34import Logger.Log as Logger\r
35from Logger.ToolError import OPTION_MISSING\r
36from Logger.ToolError import UNKNOWN_ERROR\r
37from Logger.ToolError import ABORT_ERROR\r
38from Logger.ToolError import CODE_ERROR\r
39from Logger.ToolError import FatalError\r
40\r
41\r
42## CheckDpDepex\r
43#\r
44# Check if the Depex is satisfied\r
45# @param Dep: Dep\r
46# @param Guid: Guid of Dp\r
47# @param Version: Version of Dp\r
48# @param WorkspaceDir: Workspace Dir\r
49#\r
50def CheckDpDepex(Dep, Guid, Version, WorkspaceDir):\r
51 (Removable, DependModuleList) = Dep.CheckDpDepexForRemove(Guid, Version)\r
52 if not Removable:\r
53 Logger.Info(ST.MSG_CONFIRM_REMOVE)\r
54 Logger.Info(ST.MSG_USER_DELETE_OP)\r
55 Input = stdin.readline()\r
56 Input = Input.replace('\r', '').replace('\n', '')\r
57 if Input.upper() != 'Y':\r
58 Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
59 return 1\r
60 else:\r
61 #\r
62 # report list of modules that are not valid due to force \r
63 # remove,\r
64 # also generate a log file for reference\r
65 #\r
66 Logger.Info(ST.MSG_INVALID_MODULE_INTRODUCED)\r
67 LogFilePath = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gINVALID_MODULE_FILE))\r
68 Logger.Info(ST.MSG_CHECK_LOG_FILE % LogFilePath)\r
69 try:\r
70 LogFile = open(LogFilePath, 'w')\r
71 try:\r
72 for ModulePath in DependModuleList:\r
73 LogFile.write("%s\n"%ModulePath)\r
74 Logger.Info(ModulePath)\r
75 except IOError:\r
76 Logger.Warn("\nRmPkg", ST.ERR_FILE_WRITE_FAILURE, \r
77 File=LogFilePath)\r
78 except IOError:\r
79 Logger.Warn("\nRmPkg", ST.ERR_FILE_OPEN_FAILURE, \r
80 File=LogFilePath)\r
81 finally: \r
82 LogFile.close()\r
83\r
84## Remove Path\r
85#\r
86# removing readonly file on windows will get "Access is denied"\r
87# error, so before removing, change the mode to be writeable\r
88#\r
89# @param Path: The Path to be removed \r
90#\r
91def RemovePath(Path):\r
92 Logger.Info(ST.MSG_REMOVE_FILE % Path)\r
93 if not os.access(Path, os.W_OK):\r
94 os.chmod(Path, S_IWUSR)\r
95 os.remove(Path)\r
96 try:\r
97 os.removedirs(os.path.split(Path)[0])\r
98 except OSError:\r
99 pass\r
100## GetCurrentFileList\r
101#\r
102# @param DataBase: DataBase of UPT\r
103# @param Guid: Guid of Dp\r
104# @param Version: Version of Dp\r
105# @param WorkspaceDir: Workspace Dir\r
106#\r
107def GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir):\r
108 NewFileList = []\r
109 for Dir in DataBase.GetDpInstallDirList(Guid, Version):\r
110 RootDir = os.path.normpath(os.path.join(WorkspaceDir, Dir))\r
111 for Root, Dirs, Files in os.walk(RootDir):\r
112 Logger.Debug(0, Dirs)\r
113 for File in Files:\r
114 FilePath = os.path.join(Root, File)\r
115 if FilePath not in NewFileList:\r
116 NewFileList.append(FilePath)\r
117 return NewFileList\r
118\r
119\r
120## Tool entrance method\r
121#\r
122# This method mainly dispatch specific methods per the command line options.\r
123# If no error found, return zero value so the caller of this tool can know\r
124# if it's executed successfully or not.\r
125#\r
126# @param Options: command option \r
127#\r
128def Main(Options = None):\r
129\r
130 try:\r
131 DataBase = GlobalData.gDB \r
132 if not Options.DistributionFile:\r
133 Logger.Error("RmPkg", \r
134 OPTION_MISSING, \r
135 ExtraData=ST.ERR_SPECIFY_PACKAGE)\r
136 CheckEnvVariable()\r
137 WorkspaceDir = GlobalData.gWORKSPACE\r
138 #\r
139 # Prepare check dependency\r
140 #\r
141 Dep = DependencyRules(DataBase)\r
142 \r
143 if Options.DistributionFile:\r
144 (Guid, Version, NewDpFileName) = \\r
145 DataBase.GetDpByName(os.path.split(Options.DistributionFile)[1])\r
146 if not Guid:\r
147 Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % Options.DistributionFile)\r
148 else:\r
149 Guid = Options.PackageGuid\r
150 Version = Options.PackageVersion\r
151 #\r
152 # Check Dp existing\r
153 #\r
154 if not Dep.CheckDpExists(Guid, Version):\r
155 Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_DISTRIBUTION_NOT_INSTALLED)\r
156 #\r
157 # Check for Distribution files existence in /conf/upt, if not exist, \r
158 # Warn user and go on.\r
159 #\r
160 StoredDistFile = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR, NewDpFileName))\r
161 if not os.path.isfile(StoredDistFile):\r
162 Logger.Warn("RmPkg", ST.WRN_DIST_NOT_FOUND%StoredDistFile)\r
163 StoredDistFile = None\r
164 \r
165 # \r
166 # Check Dp depex\r
167 #\r
168 CheckDpDepex(Dep, Guid, Version, WorkspaceDir)\r
169\r
170 #\r
171 # Get Current File List\r
172 #\r
173 NewFileList = GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir)\r
174\r
175 #\r
176 # Remove all files\r
177 #\r
178 MissingFileList = []\r
179 for (Path, Md5Sum) in DataBase.GetDpFileList(Guid, Version):\r
180 if os.path.isfile(Path):\r
181 if Path in NewFileList:\r
182 NewFileList.remove(Path)\r
183 if not Options.Yes:\r
184 #\r
185 # check whether modified by users\r
186 #\r
187 Md5Sigature = md5.new(open(str(Path), 'rb').read())\r
188 if Md5Sum != Md5Sigature.hexdigest():\r
189 Logger.Info(ST.MSG_CONFIRM_REMOVE2 % Path)\r
190 Input = stdin.readline()\r
191 Input = Input.replace('\r', '').replace('\n', '')\r
192 if Input.upper() != 'Y':\r
193 continue\r
194 RemovePath(Path)\r
195 else:\r
196 MissingFileList.append(Path)\r
197 \r
198 for Path in NewFileList:\r
199 if os.path.isfile(Path):\r
200 if (not Options.Yes) and (not os.path.split(Path)[1].startswith('.')):\r
201 Logger.Info(ST.MSG_CONFIRM_REMOVE3 % Path)\r
202 Input = stdin.readline()\r
203 Input = Input.replace('\r', '').replace('\n', '')\r
204 if Input.upper() != 'Y':\r
205 continue\r
206 RemovePath(Path)\r
207\r
208 #\r
209 # Remove distribution files in /Conf/.upt\r
210 #\r
211 if StoredDistFile is not None:\r
212 os.remove(StoredDistFile)\r
213\r
214 #\r
215 # update database\r
216 #\r
217 Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)\r
218 DataBase.RemoveDpObj(Guid, Version)\r
219 Logger.Quiet(ST.MSG_FINISH)\r
220 \r
221 ReturnCode = 0\r
222 \r
223 except FatalError, XExcept:\r
224 ReturnCode = XExcept.args[0] \r
225 if Logger.GetLevel() <= Logger.DEBUG_9:\r
226 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \\r
227 format_exc())\r
228 except KeyboardInterrupt:\r
229 ReturnCode = ABORT_ERROR\r
230 if Logger.GetLevel() <= Logger.DEBUG_9:\r
231 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \\r
232 format_exc())\r
233 except:\r
234 Logger.Error(\r
235 "\nRmPkg",\r
236 CODE_ERROR,\r
237 ST.ERR_UNKNOWN_FATAL_REMOVING_ERR,\r
238 ExtraData=ST.MSG_SEARCH_FOR_HELP,\r
239 RaiseError=False\r
240 )\r
241 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \\r
242 format_exc())\r
243 ReturnCode = CODE_ERROR\r
244 return ReturnCode\r
245 \r
246\r