MatN work for versatile appimage creation for all types of os
[goodguy/cinelerra.git] / cinelerra-5.1 / tools / makeappimagetool / core.cpp
1 #include <iostream>
2 #include <boost/filesystem/path.hpp>
3
4 #include "includes/appdir.h"
5 #include "includes/log.h"
6
7 #include "includes/core.h"
8
9 using namespace linuxdeploy::core;
10 using namespace linuxdeploy::core::log;
11 using namespace linuxdeploy::desktopfile;
12 namespace bf = boost::filesystem;
13
14 namespace linuxdeploy {
15     class DeployError : public std::runtime_error {
16     public:
17         explicit DeployError(const std::string& what) : std::runtime_error(what) {};
18     };
19
20     /**
21      * Resolve the 'MAIN' desktop file from all the available.
22      *
23      * @param desktopFilePaths
24      * @param deployedDesktopFiles
25      * @return the MAIN DesktopFile
26      * @throw DeployError in case of 'deployed desktop file not found'
27      */
28     desktopfile::DesktopFile getMainDesktopFile(const std::vector<std::string>& desktopFilePaths,
29                                                 const std::vector<desktopfile::DesktopFile>& deployedDesktopFiles) {
30         if (desktopFilePaths.empty()) {
31             ldLog() << LD_WARNING << "No desktop file specified, using first desktop file found:"
32                     << deployedDesktopFiles[0].path() << std::endl;
33             return deployedDesktopFiles[0];
34         }
35
36         auto firstDeployedDesktopFileName = boost::filesystem::path(desktopFilePaths.front()).filename().string();
37
38         auto desktopFileMatchingName = find_if(
39             deployedDesktopFiles.begin(),
40             deployedDesktopFiles.end(),
41             [&firstDeployedDesktopFileName](const desktopfile::DesktopFile& desktopFile) {
42                 auto fileName = bf::path(desktopFile.path()).filename().string();
43                 return fileName == firstDeployedDesktopFileName;
44             }
45         );
46
47         if (desktopFileMatchingName != deployedDesktopFiles.end()) {
48             return  *desktopFileMatchingName;
49         } else {
50             ldLog() << LD_ERROR << "Could not find desktop file deployed earlier any more:"
51                     << firstDeployedDesktopFileName << std::endl;
52             throw DeployError("Old desktop file is not reachable.");
53         }
54     }
55
56     bool deployAppDirRootFiles(std::vector<std::string> desktopFilePaths,
57                                std::string customAppRunPath, appdir::AppDir& appDir) {
58         ldLog() << std::endl << "-- Deploying files into AppDir root directory --" << std::endl;
59
60         if (!customAppRunPath.empty()) {
61             ldLog() << LD_INFO << "Deploying custom AppRun: " << customAppRunPath << std::endl;
62
63             const auto& appRunPathInAppDir = appDir.path() / "AppRun";
64             if (bf::exists(appRunPathInAppDir)) {
65                 ldLog() << LD_WARNING << "File exists, replacing with custom AppRun" << std::endl;
66                 bf::remove(appRunPathInAppDir);
67             }
68
69             appDir.deployFile(customAppRunPath, appDir.path() / "AppRun");
70             appDir.executeDeferredOperations();
71         }
72
73         auto deployedDesktopFiles = appDir.deployedDesktopFiles();
74         if (deployedDesktopFiles.empty()) {
75             ldLog() << LD_WARNING << "Could not find desktop file in AppDir, cannot create links for AppRun, "
76                                      "desktop file and icon in AppDir root" << std::endl;
77             return true;
78         }
79
80         try {
81             desktopfile::DesktopFile desktopFile = getMainDesktopFile(desktopFilePaths, deployedDesktopFiles);
82             ldLog() << "Deploying files to AppDir root using desktop file:" << desktopFile.path() << std::endl;
83             return appDir.setUpAppDirRoot(desktopFile, customAppRunPath);
84         } catch (const DeployError& er) {
85             return false;
86         }
87     }
88
89     bool addDefaultKeys(DesktopFile& desktopFile, const std::string& executableFileName) {
90         ldLog() << "Adding default values to desktop file:" << desktopFile.path() << std::endl;
91
92         auto rv = true;
93
94         auto setDefault = [&rv, &desktopFile](const std::string& section, const std::string& key, const std::string& value) {
95             if (desktopFile.entryExists(section, key)) {
96                 DesktopFileEntry entry;
97
98                 // this should never return false
99                 auto entryExists = desktopFile.getEntry(section, key, entry);
100                 assert(entryExists);
101
102                 ldLog() << LD_WARNING << "Key exists, not modified:" << key << "(current value:" << entry.value() << LD_NO_SPACE << ")" << std::endl;
103                 rv = false;
104             } else {
105                 auto entryOverwritten = desktopFile.setEntry(section, DesktopFileEntry(key, value));
106                 assert(!entryOverwritten);
107             }
108         };
109
110         setDefault("Desktop Entry", "Name", executableFileName);
111         setDefault("Desktop Entry", "Exec", executableFileName);
112         setDefault("Desktop Entry", "Icon", executableFileName);
113         setDefault("Desktop Entry", "Type", "Application");
114         setDefault("Desktop Entry", "Categories", "Utility;");
115
116         return rv;
117     }
118 }