Add 'Tizen Assembly Cache' feature
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / tactool.cc
index e932dc0..98be18c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
  * you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@
 #include <fstream>
 #include <vector>
 
+#include <json/json.h>
 #include <pkgmgr-info.h>
 #include <pkgmgr_installer_info.h>
-#include <json/json.h>
 
 #ifdef  LOG_TAG
 #undef  LOG_TAG
@@ -46,121 +46,48 @@ const std::string mdKey = "http://tizen.org/metadata/prefer_nuget_cache";
 const std::string mdValue = "true";
 
 static sqlite3 *tac_db = NULL;
-std::string execPath;
 std::vector<std::string> restoreNuget;
 
-std::vector<std::string> getCmdArgs(char** begin, char** end)
-{
-       std::vector<std::string> list;
-       for (char** itr = begin+1; itr != end; itr++) {
-               if (strncmp(*itr, "--", 2) != 0) {
-                       list.push_back(*itr);
-               }
-       }
-       return list;
-}
-
-bool cmdOptionExists(char** begin, char** end, const std::string& option)
-{
-       return std::find(begin, end, option) != end;
-}
-
 static void help(const char *argv0)
 {
        const char* helpDesc =
                "Usage: %s [args] <root paths or pkg name>\n"
-               "       --help              - Display this screen\n"
-               "       --restore-db        - Restore TAC Database\n"
+               "          --help                       - Display this screen\n"
+               "          --restore-db         - Restore TAC Database\n"
                "\n";
        printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
 }
 
-static int getRootPath(std::string pkgId, std::string& rootPath)
+void cleanupDirectory()
 {
-       int ret = 0;
-       char *path = 0;
-       uid_t uid = 0;
-
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return -1;
-       }
-
-       pkgmgrinfo_pkginfo_h handle;
-       if (uid == 0) {
-               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
-               }
-       } else {
-               ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
-               }
-       }
-
-       ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
-       if (ret != PMINFO_R_OK) {
-               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-               return -1;
-       }
-       rootPath = path;
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return 0;
-}
-
-static int getExecName(std::string pkgId, std::string& execName)
-{
-       int ret = 0;
-       uid_t uid = 0;
-
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return 0;
-       }
-
-       pkgmgrinfo_pkginfo_h handle;
-       if (uid == 0) {
-               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
+       std::vector<std::string> removeNuget;
+       for (auto& nuget : bf::recursive_directory_iterator(bf::path(mOptUsrDotnet))) {
+               bool isExist = false;
+               for (auto& restore : restoreNuget) {
+                       if (!bf::is_directory(nuget.path())) {
+                               isExist = true;
+                       }
+                       if (strstr(nuget.path().c_str(), restore.c_str()) != NULL) {
+                               isExist = true;
+                               break;
+                       }
                }
-       } else {
-               ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
+               if (!isExist) {
+                       removeNuget.push_back(nuget.path().string());
                }
        }
 
-       auto execCB = [](pkgmgrinfo_appinfo_h handle, void *userData) -> int {
-               int ret = 0;
-               char *exec = 0;
-               ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
-               if (ret != PMINFO_R_OK) {
-                       _ERR("Failed to get exec : %s", exec);
-                       return 0;
-               }
-               execPath = exec;
-               return 0;
-       };
-
-       if (uid == 0) {
-               ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP, execCB, NULL);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
-               }
-       } else {
-               ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, execCB, NULL, uid);
-               if (ret != PMINFO_R_OK) {
-                       return -1;
+       for (auto& rm : removeNuget) {
+               if (bf::exists(rm)) {
+                       if (!removeAll(rm)) {
+                               _ERR("Failed to remove of %s", rm.c_str());
+                       }
                }
        }
-       execName = bf::path(execPath).filename().string();
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return 0;
+       removeNuget.clear();
 }
 
-static int restoreDB(std::string pkgId, std::string depsJsonPath, std::string execName)
+void restoreTACDB(std::string pkgId, std::string depsJsonPath, std::string execName)
 {
        std::ifstream ifs(depsJsonPath);
        Json::CharReaderBuilder reader;
@@ -170,7 +97,7 @@ static int restoreDB(std::string pkgId, std::string depsJsonPath, std::string ex
                if (!Json::parseFromStream(reader, ifs, &root, &error)) {
                        _INFO("Failed to parse of deps.json");
                        ifs.close();
-                       return -1;
+                       return;
                }
                const Json::Value runtimeTargetName = root["runtimeTarget"]["name"];
                std::string runtimeTarget_name = runtimeTargetName.asString();
@@ -178,28 +105,28 @@ static int restoreDB(std::string pkgId, std::string depsJsonPath, std::string ex
                for (auto& nuget : nugetPackages.getMemberNames()) {
                        if (strstr(nuget.c_str(), mTizenNET.c_str()) != NULL ||
                                strstr(nuget.c_str(), mTizenNETSdk.c_str()) != NULL ||
-                               strstr(nuget.c_str(), execName.c_str()) != NULL ||
-                               strstr(nuget.c_str(), (execName.substr(0, execName.find('.'))).c_str()) != NULL) {
+                               strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL ||
+                               strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) != NULL) {
                                continue;
                        } else {
                                const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"];
                                if (assemblies != Json::nullValue) {
                                        const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"];
-                                       std::string r2r = "";
+                                       bool isDependency = false;
                                        for (auto& dependency : dependencies.getMemberNames()) {
                                                if (strstr(dependency.c_str(), mTizenNET.c_str()) != NULL ||
                                                        strstr(dependency.c_str(), mNETStandardLibrary.c_str()) != NULL) {
                                                        continue;
                                                } else {
-                                                       r2r = "--r2r";
+                                                       isDependency = true;
                                                }
                                        }
-                                       if (strcmp(r2r.c_str(), "--r2r")) {
-                                               _INFO("Nuget package : %s", nuget.c_str());
+                                       if (!isDependency) {
+                                               _INFO("PackageId : [%s] / Nuget package : [%s]", pkgId.c_str(), nuget.c_str());
                                                std::string name = nuget.substr(0, nuget.find('/'));
                                                std::string version = nuget.substr(nuget.rfind('/') + 1);
                                                std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
-                                                               "VALUES ('" + std::string(pkgId) + "', '" + nuget + "', '" + name + "', '" + version + "');";
+                                                               "VALUES ('" + pkgId + "', '" + nuget + "', '" + name + "', '" + version + "');";
                                                dbInsert(tac_db, tacAppListRestoreDB, sql);
                                                restoreNuget.push_back(mOptUsrDotnet + "/" + name);
                                        }
@@ -208,13 +135,16 @@ static int restoreDB(std::string pkgId, std::string depsJsonPath, std::string ex
                }
                ifs.close();
        }
-       return 0;
 }
 
-static int tacDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
+static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        int ret = 0;
        char *pkgId = NULL;
+       char *root = NULL;
+       char *exec = NULL;
+       std::string rootPath;
+       std::string execName;
 
        ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
        if (ret != PMINFO_R_OK) {
@@ -222,25 +152,29 @@ static int tacDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
                return -1;
        }
 
-       std::string rootPath;
-       if (getRootPath(pkgId, rootPath) < 0) {
+       ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
+       if (ret != PMINFO_R_OK) {
+               fprintf(stderr, "Failed to get root path\n");
                return -1;
        }
+       rootPath = root;
 
-       std::string execName;
-       if (getExecName(pkgId, execName) < 0) {
+       ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+       if (ret != PMINFO_R_OK) {
+               fprintf(stderr, "Failed to get exec name\n");
                return -1;
        }
+       execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
 
        std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + mDepsJson;
        std::string depsJsonPath = rootPath + "/" + depsJsonName;
        if (bf::exists(depsJsonPath)) {
-               restoreDB(pkgId, depsJsonPath, execName);
+               restoreTACDB(pkgId, depsJsonPath, execName);
        }
        return 0;
 }
 
-int restoreTACDB()
+int restoreDB()
 {
        if (bf::exists(tacAppListRestoreDB)) {
                if (!removeFile(tacAppListRestoreDB)) {
@@ -278,7 +212,7 @@ int restoreTACDB()
                return -1;
        }
 
-       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, tacDBCb, NULL);
+       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, restoreDBCb, NULL);
        if (ret != PMINFO_R_OK) {
                fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
@@ -313,41 +247,20 @@ int restoreTACDB()
                }
        }
 
-       std::vector<std::string> removeNuget;
-       for (auto& nuget : bf::recursive_directory_iterator(bf::path(mOptUsrDotnet))) {
-               bool isExist = false;
-               for (auto& restore : restoreNuget) {
-                       if (!bf::is_directory(nuget.path())) {
-                               isExist = true;
-                       }
-                       if (strstr(nuget.path().c_str(), restore.c_str()) != NULL) {
-                               isExist = true;
-                               break;
-                       }
-               }
-               if (!isExist) {
-                       removeNuget.push_back(nuget.path().string());
-               }
-       }
-
-       for (auto& rm : removeNuget) {
-               if (bf::exists(rm)) {
-                       if (!removeAll(rm)) {
-                               _ERR("Failed to remove of %s", rm.c_str());
-                               return -1;
-                       }
-               }
-       }
-       removeNuget.clear();
+    cleanupDirectory();
        return 0;
 }
 
+// step 1. Remove original DB
+// step 2. Parsing the .deps.json for all apps
+// step 3. Create new DB
+// step 4. Cleanup unnecessary TAC directory
 int main(int argc, char* argv[])
 {
        if (cmdOptionExists(argv, argv + argc, "--help")) {
                help(argv[0]);
        } else if (cmdOptionExists(argv, argv + argc, "--restore-db")) {
-               restoreTACDB();
+               restoreDB();
        } else {
                help(argv[0]);
        }