1b8a72a62Sopenharmony_ci/* 2b8a72a62Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3b8a72a62Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b8a72a62Sopenharmony_ci * you may not use this file except in compliance with the License. 5b8a72a62Sopenharmony_ci * You may obtain a copy of the License at 6b8a72a62Sopenharmony_ci * 7b8a72a62Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b8a72a62Sopenharmony_ci * 9b8a72a62Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b8a72a62Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b8a72a62Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b8a72a62Sopenharmony_ci * See the License for the specific language governing permissions and 13b8a72a62Sopenharmony_ci * limitations under the License. 14b8a72a62Sopenharmony_ci */ 15b8a72a62Sopenharmony_ci 16b8a72a62Sopenharmony_ci#include "packager.h" 17b8a72a62Sopenharmony_ci 18b8a72a62Sopenharmony_ci#include <filesystem> 19b8a72a62Sopenharmony_ci#include <fstream> 20b8a72a62Sopenharmony_ci#include <random> 21b8a72a62Sopenharmony_ci#include <sstream> 22b8a72a62Sopenharmony_ci#include <string> 23b8a72a62Sopenharmony_ci#include <unordered_set> 24b8a72a62Sopenharmony_ci 25b8a72a62Sopenharmony_ci#include "json/json_utils.h" 26b8a72a62Sopenharmony_ci#include "log.h" 27b8a72a62Sopenharmony_ci#include "utils.h" 28b8a72a62Sopenharmony_ci#include "zip_utils.h" 29b8a72a62Sopenharmony_ci 30b8a72a62Sopenharmony_cinamespace OHOS { 31b8a72a62Sopenharmony_cinamespace AppPackingTool { 32b8a72a62Sopenharmony_cinamespace { 33b8a72a62Sopenharmony_ciconst std::string EN_US_UTF_8 = "en_US.UTF-8"; 34b8a72a62Sopenharmony_ci} 35b8a72a62Sopenharmony_ci 36b8a72a62Sopenharmony_ciPackager::Packager(const std::map<std::string, std::string> ¶meterMap, std::string &resultReceiver) 37b8a72a62Sopenharmony_ci : parameterMap_(parameterMap), resultReceiver_(resultReceiver) 38b8a72a62Sopenharmony_ci{} 39b8a72a62Sopenharmony_ci 40b8a72a62Sopenharmony_ciPackager::~Packager() 41b8a72a62Sopenharmony_ci{} 42b8a72a62Sopenharmony_ci 43b8a72a62Sopenharmony_cistd::string Packager::MakePackage() 44b8a72a62Sopenharmony_ci{ 45b8a72a62Sopenharmony_ci if (InitAllowedParam() != ERR_OK) { 46b8a72a62Sopenharmony_ci LOGE("InitAllowedParam err"); 47b8a72a62Sopenharmony_ci return ""; 48b8a72a62Sopenharmony_ci } 49b8a72a62Sopenharmony_ci 50b8a72a62Sopenharmony_ci if (PreProcess() != ERR_OK) { 51b8a72a62Sopenharmony_ci LOGE("PreProcess err"); 52b8a72a62Sopenharmony_ci return ""; 53b8a72a62Sopenharmony_ci } 54b8a72a62Sopenharmony_ci 55b8a72a62Sopenharmony_ci if (Process() != ERR_OK) { 56b8a72a62Sopenharmony_ci LOGE("Process err"); 57b8a72a62Sopenharmony_ci return ""; 58b8a72a62Sopenharmony_ci } 59b8a72a62Sopenharmony_ci 60b8a72a62Sopenharmony_ci if (PostProcess() != ERR_OK) { 61b8a72a62Sopenharmony_ci LOGE("PostProcess err"); 62b8a72a62Sopenharmony_ci return ""; 63b8a72a62Sopenharmony_ci } 64b8a72a62Sopenharmony_ci return "OHOS::ERR_OK"; 65b8a72a62Sopenharmony_ci} 66b8a72a62Sopenharmony_ci 67b8a72a62Sopenharmony_ciint32_t Packager::PreProcess() 68b8a72a62Sopenharmony_ci{ 69b8a72a62Sopenharmony_ci resultReceiver_.append("do PreProcess\n"); 70b8a72a62Sopenharmony_ci return ERR_OK; 71b8a72a62Sopenharmony_ci} 72b8a72a62Sopenharmony_ci 73b8a72a62Sopenharmony_ciint32_t Packager::Process() 74b8a72a62Sopenharmony_ci{ 75b8a72a62Sopenharmony_ci resultReceiver_.append("do Process\n"); 76b8a72a62Sopenharmony_ci return ERR_OK; 77b8a72a62Sopenharmony_ci} 78b8a72a62Sopenharmony_ci 79b8a72a62Sopenharmony_ciint32_t Packager::PostProcess() 80b8a72a62Sopenharmony_ci{ 81b8a72a62Sopenharmony_ci resultReceiver_.append("do PostProcess\n"); 82b8a72a62Sopenharmony_ci return ERR_OK; 83b8a72a62Sopenharmony_ci} 84b8a72a62Sopenharmony_ci 85b8a72a62Sopenharmony_cibool Packager::CheckForceFlag() 86b8a72a62Sopenharmony_ci{ 87b8a72a62Sopenharmony_ci auto it = parameterMap_.find(Constants::PARAM_FORCE); 88b8a72a62Sopenharmony_ci if (it != parameterMap_.end() && it->second != "false" && it->second != "true") { 89b8a72a62Sopenharmony_ci LOGE("Packager::commandVerify forceRewrite is invalid."); 90b8a72a62Sopenharmony_ci return false; 91b8a72a62Sopenharmony_ci } 92b8a72a62Sopenharmony_ci return true; 93b8a72a62Sopenharmony_ci} 94b8a72a62Sopenharmony_ci 95b8a72a62Sopenharmony_cibool Packager::IsPathValid(const std::string &path, const bool &isFile, const std::string suffix) 96b8a72a62Sopenharmony_ci{ 97b8a72a62Sopenharmony_ci if (isFile && fs::is_regular_file(path)) { 98b8a72a62Sopenharmony_ci std::string name = fs::path(path).filename(); 99b8a72a62Sopenharmony_ci std::locale englishLocale(EN_US_UTF_8); 100b8a72a62Sopenharmony_ci std::transform(name.begin(), name.end(), name.begin(), 101b8a72a62Sopenharmony_ci [&englishLocale](unsigned char c) { return std::tolower(c); }); 102b8a72a62Sopenharmony_ci if (Utils::EndsWith(name, suffix)) { 103b8a72a62Sopenharmony_ci return true; 104b8a72a62Sopenharmony_ci } 105b8a72a62Sopenharmony_ci } 106b8a72a62Sopenharmony_ci return (!isFile) && fs::is_directory(path); 107b8a72a62Sopenharmony_ci} 108b8a72a62Sopenharmony_ci 109b8a72a62Sopenharmony_cibool Packager::SplitDirList(const std::string &dirList, std::list<std::string> &fileList) 110b8a72a62Sopenharmony_ci{ 111b8a72a62Sopenharmony_ci std::list<std::string> pathList; 112b8a72a62Sopenharmony_ci RemoveDuplicatePath(dirList, pathList); 113b8a72a62Sopenharmony_ci for (const std::string &pathItem : pathList) { 114b8a72a62Sopenharmony_ci std::string formattedPathItem; 115b8a72a62Sopenharmony_ci if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) { 116b8a72a62Sopenharmony_ci LOGE("GetFormattedPath failed for %s", pathItem.c_str()); 117b8a72a62Sopenharmony_ci return false; 118b8a72a62Sopenharmony_ci }; 119b8a72a62Sopenharmony_ci if (!IsPathValid(formattedPathItem, false)) { 120b8a72a62Sopenharmony_ci return false; 121b8a72a62Sopenharmony_ci } 122b8a72a62Sopenharmony_ci fileList.push_back(formattedPathItem); 123b8a72a62Sopenharmony_ci } 124b8a72a62Sopenharmony_ci return true; 125b8a72a62Sopenharmony_ci} 126b8a72a62Sopenharmony_ci 127b8a72a62Sopenharmony_civoid Packager::RemoveDuplicatePath(const std::string &path, std::list<std::string> &pathList) 128b8a72a62Sopenharmony_ci{ 129b8a72a62Sopenharmony_ci std::string pathItem; 130b8a72a62Sopenharmony_ci std::istringstream pathStream(path); 131b8a72a62Sopenharmony_ci while (std::getline(pathStream, pathItem, Constants::COMMA_SPLIT)) { 132b8a72a62Sopenharmony_ci pathList.push_back(pathItem); 133b8a72a62Sopenharmony_ci } 134b8a72a62Sopenharmony_ci std::unordered_set<std::string> uniqueTokens(pathList.begin(), pathList.end()); 135b8a72a62Sopenharmony_ci pathList.assign(uniqueTokens.begin(), uniqueTokens.end()); 136b8a72a62Sopenharmony_ci} 137b8a72a62Sopenharmony_ci 138b8a72a62Sopenharmony_cibool Packager::CompatibleProcess(const std::string &inputPath, std::list<std::string> &fileList, 139b8a72a62Sopenharmony_ci const std::string &suffix) 140b8a72a62Sopenharmony_ci{ 141b8a72a62Sopenharmony_ci if (IsPathValid(inputPath, false)) { 142b8a72a62Sopenharmony_ci for (const auto& fileItem : fs::recursive_directory_iterator(inputPath)) { 143b8a72a62Sopenharmony_ci std::string name = fileItem.path().filename(); 144b8a72a62Sopenharmony_ci std::locale englishLocale(EN_US_UTF_8); 145b8a72a62Sopenharmony_ci std::transform(name.begin(), name.end(), name.begin(), 146b8a72a62Sopenharmony_ci [&englishLocale](unsigned char c) { return std::tolower(c); }); 147b8a72a62Sopenharmony_ci if (Utils::EndsWith(name, suffix)) { 148b8a72a62Sopenharmony_ci fileList.push_back(fileItem.path().string()); 149b8a72a62Sopenharmony_ci } 150b8a72a62Sopenharmony_ci } 151b8a72a62Sopenharmony_ci return true; 152b8a72a62Sopenharmony_ci } else { 153b8a72a62Sopenharmony_ci std::string formattedPathItem; 154b8a72a62Sopenharmony_ci std::list<std::string> pathList; 155b8a72a62Sopenharmony_ci RemoveDuplicatePath(inputPath, pathList); 156b8a72a62Sopenharmony_ci for (std::string pathItem : pathList) { 157b8a72a62Sopenharmony_ci if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) { 158b8a72a62Sopenharmony_ci LOGE("GetFormattedPath failed for %s", pathItem.c_str()); 159b8a72a62Sopenharmony_ci return false; 160b8a72a62Sopenharmony_ci }; 161b8a72a62Sopenharmony_ci if (!IsPathValid(formattedPathItem, true, suffix)) { 162b8a72a62Sopenharmony_ci return false; 163b8a72a62Sopenharmony_ci } 164b8a72a62Sopenharmony_ci fileList.push_back(formattedPathItem); 165b8a72a62Sopenharmony_ci } 166b8a72a62Sopenharmony_ci return true; 167b8a72a62Sopenharmony_ci } 168b8a72a62Sopenharmony_ci} 169b8a72a62Sopenharmony_ci 170b8a72a62Sopenharmony_cibool Packager::CompatibleProcess(const std::string &inputPath, std::list<std::string> &fileList, 171b8a72a62Sopenharmony_ci const std::string &suffix, const std::string &extraSuffix) 172b8a72a62Sopenharmony_ci{ 173b8a72a62Sopenharmony_ci if (IsPathValid(inputPath, false)) { 174b8a72a62Sopenharmony_ci for (const auto& fileItem : fs::recursive_directory_iterator(inputPath)) { 175b8a72a62Sopenharmony_ci std::string name = fileItem.path().filename(); 176b8a72a62Sopenharmony_ci std::locale englishLocale(EN_US_UTF_8); 177b8a72a62Sopenharmony_ci std::transform(name.begin(), name.end(), name.begin(), 178b8a72a62Sopenharmony_ci [&englishLocale](unsigned char c) { return std::tolower(c); }); 179b8a72a62Sopenharmony_ci if (Utils::EndsWith(name, suffix) || Utils::EndsWith(name, extraSuffix)) { 180b8a72a62Sopenharmony_ci fileList.push_back(fileItem.path().string()); 181b8a72a62Sopenharmony_ci } 182b8a72a62Sopenharmony_ci } 183b8a72a62Sopenharmony_ci return true; 184b8a72a62Sopenharmony_ci } else { 185b8a72a62Sopenharmony_ci std::string formattedPathItem; 186b8a72a62Sopenharmony_ci std::list<std::string> pathList; 187b8a72a62Sopenharmony_ci RemoveDuplicatePath(inputPath, pathList); 188b8a72a62Sopenharmony_ci for (std::string pathItem : pathList) { 189b8a72a62Sopenharmony_ci if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) { 190b8a72a62Sopenharmony_ci LOGE("GetFormattedPath failed for %s", pathItem.c_str()); 191b8a72a62Sopenharmony_ci return false; 192b8a72a62Sopenharmony_ci }; 193b8a72a62Sopenharmony_ci if (!IsPathValid(formattedPathItem, true, suffix) && 194b8a72a62Sopenharmony_ci !IsPathValid(formattedPathItem, true, extraSuffix)) { 195b8a72a62Sopenharmony_ci return false; 196b8a72a62Sopenharmony_ci } 197b8a72a62Sopenharmony_ci fileList.push_back(formattedPathItem); 198b8a72a62Sopenharmony_ci } 199b8a72a62Sopenharmony_ci return true; 200b8a72a62Sopenharmony_ci } 201b8a72a62Sopenharmony_ci} 202b8a72a62Sopenharmony_ci 203b8a72a62Sopenharmony_cibool Packager::IsOutPathValid(const std::string &outPath, const std::string &forceRewrite, const std::string &suffix) 204b8a72a62Sopenharmony_ci{ 205b8a72a62Sopenharmony_ci fs::path filePath(outPath); 206b8a72a62Sopenharmony_ci 207b8a72a62Sopenharmony_ci if ("false" == forceRewrite && fs::exists(filePath)) { 208b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out file already existed."); 209b8a72a62Sopenharmony_ci return false; 210b8a72a62Sopenharmony_ci } 211b8a72a62Sopenharmony_ci 212b8a72a62Sopenharmony_ci if (suffix == Constants::HAP_SUFFIX) { 213b8a72a62Sopenharmony_ci if (!Utils::EndsWith(filePath.filename().string(), Constants::HAP_SUFFIX)) { 214b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out-path must end with .hap."); 215b8a72a62Sopenharmony_ci return false; 216b8a72a62Sopenharmony_ci } else { 217b8a72a62Sopenharmony_ci return true; 218b8a72a62Sopenharmony_ci } 219b8a72a62Sopenharmony_ci } else if (suffix == Constants::HAR_SUFFIX) { 220b8a72a62Sopenharmony_ci if (!Utils::EndsWith(filePath.filename().string(), Constants::HAR_SUFFIX)) { 221b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out-path must end with .har."); 222b8a72a62Sopenharmony_ci return false; 223b8a72a62Sopenharmony_ci } else { 224b8a72a62Sopenharmony_ci return true; 225b8a72a62Sopenharmony_ci } 226b8a72a62Sopenharmony_ci } else if (suffix == Constants::APP_SUFFIX) { 227b8a72a62Sopenharmony_ci if (!Utils::EndsWith(filePath.filename().string(), Constants::APP_SUFFIX)) { 228b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out-path must end with .app."); 229b8a72a62Sopenharmony_ci return false; 230b8a72a62Sopenharmony_ci } else { 231b8a72a62Sopenharmony_ci return true; 232b8a72a62Sopenharmony_ci } 233b8a72a62Sopenharmony_ci } else if (suffix == Constants::RES_SUFFIX) { 234b8a72a62Sopenharmony_ci if (!Utils::EndsWith(filePath.filename().string(), Constants::RES_SUFFIX)) { 235b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out-path must end with .res."); 236b8a72a62Sopenharmony_ci return false; 237b8a72a62Sopenharmony_ci } else { 238b8a72a62Sopenharmony_ci return true; 239b8a72a62Sopenharmony_ci } 240b8a72a62Sopenharmony_ci } else if (suffix == Constants::HSP_SUFFIX) { 241b8a72a62Sopenharmony_ci if (!Utils::EndsWith(filePath.filename().string(), Constants::HSP_SUFFIX)) { 242b8a72a62Sopenharmony_ci LOGE("Packager::isOutPathValid out-path must end with .hsp."); 243b8a72a62Sopenharmony_ci return false; 244b8a72a62Sopenharmony_ci } else { 245b8a72a62Sopenharmony_ci return true; 246b8a72a62Sopenharmony_ci } 247b8a72a62Sopenharmony_ci } 248b8a72a62Sopenharmony_ci return false; 249b8a72a62Sopenharmony_ci} 250b8a72a62Sopenharmony_ci 251b8a72a62Sopenharmony_cibool Packager::SetGenerateBuildHash(std::string &jsonPath, bool &generateBuildHash, bool &buildHashFinish) 252b8a72a62Sopenharmony_ci{ 253b8a72a62Sopenharmony_ci if (!fs::exists(jsonPath)) { 254b8a72a62Sopenharmony_ci LOGE("Packager::setGenerateBuildHash failed for json file not exist"); 255b8a72a62Sopenharmony_ci return false; 256b8a72a62Sopenharmony_ci } 257b8a72a62Sopenharmony_ci ModuleJson moduleJson; 258b8a72a62Sopenharmony_ci moduleJson.ParseFromFile(jsonPath); 259b8a72a62Sopenharmony_ci 260b8a72a62Sopenharmony_ci if (buildHashFinish || !moduleJson.GetGenerateBuildHash(generateBuildHash)) { 261b8a72a62Sopenharmony_ci return true; 262b8a72a62Sopenharmony_ci } 263b8a72a62Sopenharmony_ci 264b8a72a62Sopenharmony_ci if (!CopyFileToTempDir(jsonPath)) { 265b8a72a62Sopenharmony_ci return false; 266b8a72a62Sopenharmony_ci } 267b8a72a62Sopenharmony_ci 268b8a72a62Sopenharmony_ci if (!fs::exists(jsonPath)) { 269b8a72a62Sopenharmony_ci LOGE("Packager::setGenerateBuildHash failed for json file not exist"); 270b8a72a62Sopenharmony_ci return false; 271b8a72a62Sopenharmony_ci } 272b8a72a62Sopenharmony_ci 273b8a72a62Sopenharmony_ci ModuleJson moduleJsonTemp; 274b8a72a62Sopenharmony_ci moduleJsonTemp.ParseFromFile(jsonPath); 275b8a72a62Sopenharmony_ci if (!moduleJsonTemp.GetGenerateBuildHash(generateBuildHash)) { 276b8a72a62Sopenharmony_ci LOGE("ModuleJson::GetGenerateBuildHash failed"); 277b8a72a62Sopenharmony_ci return false; 278b8a72a62Sopenharmony_ci } 279b8a72a62Sopenharmony_ci 280b8a72a62Sopenharmony_ci if (!moduleJsonTemp.RemoveGenerateBuildHash()) { 281b8a72a62Sopenharmony_ci LOGE("ModuleJson::RemoveGenerateBuildHash failed"); 282b8a72a62Sopenharmony_ci return false; 283b8a72a62Sopenharmony_ci } 284b8a72a62Sopenharmony_ci 285b8a72a62Sopenharmony_ci std::string prettyJsonString = moduleJsonTemp.ToString(); 286b8a72a62Sopenharmony_ci if (prettyJsonString.empty()) { 287b8a72a62Sopenharmony_ci LOGE("ModuleJson::ToString failed"); 288b8a72a62Sopenharmony_ci return false; 289b8a72a62Sopenharmony_ci } 290b8a72a62Sopenharmony_ci 291b8a72a62Sopenharmony_ci std::string realJsonPath; 292b8a72a62Sopenharmony_ci if (!Utils::GetRealPath(jsonPath, realJsonPath)) { 293b8a72a62Sopenharmony_ci LOGE("get real json Path failed! jsonPath=%s", jsonPath.c_str()); 294b8a72a62Sopenharmony_ci return false; 295b8a72a62Sopenharmony_ci } 296b8a72a62Sopenharmony_ci std::ofstream outFile(realJsonPath); 297b8a72a62Sopenharmony_ci if (outFile.is_open()) { 298b8a72a62Sopenharmony_ci outFile << prettyJsonString.c_str(); 299b8a72a62Sopenharmony_ci outFile.close(); 300b8a72a62Sopenharmony_ci } else { 301b8a72a62Sopenharmony_ci LOGE("Failed to open file for writing"); 302b8a72a62Sopenharmony_ci return false; 303b8a72a62Sopenharmony_ci } 304b8a72a62Sopenharmony_ci return true; 305b8a72a62Sopenharmony_ci} 306b8a72a62Sopenharmony_ci 307b8a72a62Sopenharmony_cibool Packager::CopyFileToTempDir(std::string &jsonPath) 308b8a72a62Sopenharmony_ci{ 309b8a72a62Sopenharmony_ci if (!fs::exists(jsonPath)) { 310b8a72a62Sopenharmony_ci LOGE("Packager::copyFileToTempDir failed for json file not found."); 311b8a72a62Sopenharmony_ci return false; 312b8a72a62Sopenharmony_ci } 313b8a72a62Sopenharmony_ci fs::path oldFileParent = fs::path(jsonPath).parent_path(); 314b8a72a62Sopenharmony_ci std::string tempDir = Constants::COMPRESSOR_TEMP_DIR + fs::path::preferred_separator + Utils::GenerateUUID(); 315b8a72a62Sopenharmony_ci fs::path tempDirFs(tempDir); 316b8a72a62Sopenharmony_ci tempDir = oldFileParent.string() + fs::path::preferred_separator + tempDirFs.string(); 317b8a72a62Sopenharmony_ci fs::create_directories(tempDir); 318b8a72a62Sopenharmony_ci fs::path fileName = JsonUtils::IsModuleJson(jsonPath) ? Constants::MODULE_JSON : Constants::CONFIG_JSON; 319b8a72a62Sopenharmony_ci std::string tempPath = tempDir + fs::path::preferred_separator + fileName.string(); 320b8a72a62Sopenharmony_ci if (!Utils::CopyFile(jsonPath, tempPath)) { 321b8a72a62Sopenharmony_ci return false; 322b8a72a62Sopenharmony_ci } 323b8a72a62Sopenharmony_ci jsonPath = tempPath; 324b8a72a62Sopenharmony_ci return true; 325b8a72a62Sopenharmony_ci} 326b8a72a62Sopenharmony_ci 327b8a72a62Sopenharmony_cibool Packager::BuildHash(bool &buildHashFinish, const bool &generateBuildHash, 328b8a72a62Sopenharmony_ci const std::map<std::string, std::string> ¶meterMap, const std::string &jsonPath) 329b8a72a62Sopenharmony_ci{ 330b8a72a62Sopenharmony_ci if (buildHashFinish || !generateBuildHash) { 331b8a72a62Sopenharmony_ci return true; 332b8a72a62Sopenharmony_ci } 333b8a72a62Sopenharmony_ci std::map<std::string, std::string>::const_iterator it = parameterMap.find(Constants::PARAM_OUT_PATH); 334b8a72a62Sopenharmony_ci if (it == parameterMap.end()) { 335b8a72a62Sopenharmony_ci LOGE("out-path not found"); 336b8a72a62Sopenharmony_ci return false; 337b8a72a62Sopenharmony_ci } 338b8a72a62Sopenharmony_ci std::string filePath = it->second; 339b8a72a62Sopenharmony_ci std::string hash = Utils::GetSha256File(filePath); 340b8a72a62Sopenharmony_ci return PutBuildHash(jsonPath, hash, buildHashFinish); 341b8a72a62Sopenharmony_ci} 342b8a72a62Sopenharmony_ci 343b8a72a62Sopenharmony_cibool Packager::PutBuildHash(const std::string &jsonPath, const std::string &hash, bool &buildHashFinish) 344b8a72a62Sopenharmony_ci{ 345b8a72a62Sopenharmony_ci if (buildHashFinish) { 346b8a72a62Sopenharmony_ci return true; 347b8a72a62Sopenharmony_ci } 348b8a72a62Sopenharmony_ci 349b8a72a62Sopenharmony_ci ModuleJson moduleJson; 350b8a72a62Sopenharmony_ci moduleJson.ParseFromFile(jsonPath); 351b8a72a62Sopenharmony_ci moduleJson.SetBuildHash(hash); 352b8a72a62Sopenharmony_ci std::string prettyJsonString = moduleJson.ToString(); 353b8a72a62Sopenharmony_ci if (prettyJsonString.empty()) { 354b8a72a62Sopenharmony_ci LOGE("ModuleJson::ToString failed"); 355b8a72a62Sopenharmony_ci return false; 356b8a72a62Sopenharmony_ci } 357b8a72a62Sopenharmony_ci 358b8a72a62Sopenharmony_ci std::string realJsonPath; 359b8a72a62Sopenharmony_ci if (!Utils::GetRealPath(jsonPath, realJsonPath)) { 360b8a72a62Sopenharmony_ci LOGE("get real json path failed! jsonFile=%s", jsonPath.c_str()); 361b8a72a62Sopenharmony_ci return false; 362b8a72a62Sopenharmony_ci } 363b8a72a62Sopenharmony_ci std::ofstream outFile(realJsonPath); 364b8a72a62Sopenharmony_ci if (outFile.is_open()) { 365b8a72a62Sopenharmony_ci outFile << prettyJsonString.c_str(); 366b8a72a62Sopenharmony_ci outFile.close(); 367b8a72a62Sopenharmony_ci } else { 368b8a72a62Sopenharmony_ci LOGE("Failed to open file for writing"); 369b8a72a62Sopenharmony_ci return false; 370b8a72a62Sopenharmony_ci } 371b8a72a62Sopenharmony_ci 372b8a72a62Sopenharmony_ci buildHashFinish = true; 373b8a72a62Sopenharmony_ci return true; 374b8a72a62Sopenharmony_ci} 375b8a72a62Sopenharmony_ci 376b8a72a62Sopenharmony_cibool Packager::IsModuleHap(const std::string& hapPath) 377b8a72a62Sopenharmony_ci{ 378b8a72a62Sopenharmony_ci if (!Utils::EndsWith(hapPath, Constants::HAP_SUFFIX)) { 379b8a72a62Sopenharmony_ci return false; 380b8a72a62Sopenharmony_ci } 381b8a72a62Sopenharmony_ci if (!ZipUtils::IsFileExistsInZip(hapPath, Constants::MODULE_JSON)) { 382b8a72a62Sopenharmony_ci return false; 383b8a72a62Sopenharmony_ci } 384b8a72a62Sopenharmony_ci return true; 385b8a72a62Sopenharmony_ci} 386b8a72a62Sopenharmony_ci 387b8a72a62Sopenharmony_civoid Packager::CompressPackinfoIntoHap(const std::string& hapPathItem, const std::string& unzipPathString, 388b8a72a62Sopenharmony_ci const std::string& outPathString, const std::string& packInfoPath) 389b8a72a62Sopenharmony_ci{ 390b8a72a62Sopenharmony_ci if (!fs::exists(fs::path(unzipPathString))) { 391b8a72a62Sopenharmony_ci fs::create_directory(fs::path(unzipPathString)); 392b8a72a62Sopenharmony_ci } 393b8a72a62Sopenharmony_ci ZipUtils::Unzip(hapPathItem, unzipPathString); 394b8a72a62Sopenharmony_ci for (const auto& entry : fs::directory_iterator(unzipPathString)) { 395b8a72a62Sopenharmony_ci if (entry.path().filename() == Constants::PACK_INFO) { 396b8a72a62Sopenharmony_ci fs::remove(entry.path()); 397b8a72a62Sopenharmony_ci } 398b8a72a62Sopenharmony_ci } 399b8a72a62Sopenharmony_ci 400b8a72a62Sopenharmony_ci std::string realPackInfoPath; 401b8a72a62Sopenharmony_ci if (!Utils::GetRealPath(packInfoPath, realPackInfoPath)) { 402b8a72a62Sopenharmony_ci LOGE("get real pack info path failed! packInfoPath=%s", packInfoPath.c_str()); 403b8a72a62Sopenharmony_ci return; 404b8a72a62Sopenharmony_ci } 405b8a72a62Sopenharmony_ci std::string destFilePath = unzipPathString + fs::path::preferred_separator + Constants::PACK_INFO; 406b8a72a62Sopenharmony_ci std::string realDestFilePath; 407b8a72a62Sopenharmony_ci if (!Utils::GetRealPathOfNoneExistFile(destFilePath, realDestFilePath)) { 408b8a72a62Sopenharmony_ci LOGE("get real dest file path failed! destFilePath=%s", destFilePath.c_str()); 409b8a72a62Sopenharmony_ci return; 410b8a72a62Sopenharmony_ci } 411b8a72a62Sopenharmony_ci std::ifstream packInfoFile(realPackInfoPath, std::ios::binary); 412b8a72a62Sopenharmony_ci std::ofstream destFile(realDestFilePath, std::ios::binary | std::ios::trunc); 413b8a72a62Sopenharmony_ci destFile << packInfoFile.rdbuf(); 414b8a72a62Sopenharmony_ci destFile.close(); 415b8a72a62Sopenharmony_ci packInfoFile.close(); 416b8a72a62Sopenharmony_ci ZipUtils::Zip(unzipPathString, outPathString); 417b8a72a62Sopenharmony_ci if (fs::exists(fs::path(unzipPathString))) { 418b8a72a62Sopenharmony_ci fs::remove_all(fs::path(unzipPathString)); 419b8a72a62Sopenharmony_ci } 420b8a72a62Sopenharmony_ci} 421b8a72a62Sopenharmony_ci 422b8a72a62Sopenharmony_cibool Packager::IsOutDirectoryValid() 423b8a72a62Sopenharmony_ci{ 424b8a72a62Sopenharmony_ci auto it = parameterMap_.find(Constants::PARAM_OUT_PATH); 425b8a72a62Sopenharmony_ci if (it == parameterMap_.end()) { 426b8a72a62Sopenharmony_ci LOGE("Validate out-path is empty"); 427b8a72a62Sopenharmony_ci return false; 428b8a72a62Sopenharmony_ci } else if (!Utils::IsDirectory(it->second)) { 429b8a72a62Sopenharmony_ci LOGE("Validate out-path is not a directory."); 430b8a72a62Sopenharmony_ci return false; 431b8a72a62Sopenharmony_ci } 432b8a72a62Sopenharmony_ci return true; 433b8a72a62Sopenharmony_ci} 434b8a72a62Sopenharmony_ci} // namespace AppPackingTool 435b8a72a62Sopenharmony_ci} // namespace OHOS