mirror of
https://github.com/audacity/linuxdeploy.git
synced 2026-04-13 15:19:49 -05:00
Merge pull request #41 from linuxdeploy/integration_test
Improve AppDir root files deployment
This commit is contained in:
@@ -45,7 +45,7 @@ add_subdirectory(util)
|
||||
add_subdirectory(plugin)
|
||||
add_subdirectory(core)
|
||||
|
||||
add_executable(linuxdeploy main.cpp)
|
||||
add_executable(linuxdeploy main.cpp core.cpp)
|
||||
target_link_libraries(linuxdeploy linuxdeploy_core args)
|
||||
set_target_properties(linuxdeploy PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
|
||||
88
src/core.cpp
Normal file
88
src/core.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <iostream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <linuxdeploy/core/appdir.h>
|
||||
#include <linuxdeploy/core/log.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::log;
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace linuxdeploy {
|
||||
class DeployError : public std::runtime_error {
|
||||
public:
|
||||
explicit DeployError(const std::string& what) : std::runtime_error(what) {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve the 'MAIN' desktop file from all the available.
|
||||
*
|
||||
* @param desktopFilePaths
|
||||
* @param deployedDesktopFiles
|
||||
* @return the MAIN DesktopFile
|
||||
* @throw DeployError in case of 'deployed desktop file not found'
|
||||
*/
|
||||
desktopfile::DesktopFile getMainDesktopFile(const std::vector<std::string>& desktopFilePaths,
|
||||
const std::vector<desktopfile::DesktopFile>& deployedDesktopFiles) {
|
||||
if (desktopFilePaths.empty()) {
|
||||
ldLog() << LD_WARNING << "No desktop file specified, using first desktop file found:"
|
||||
<< deployedDesktopFiles[0].path() << std::endl;
|
||||
return deployedDesktopFiles[0];
|
||||
}
|
||||
|
||||
auto firstDeployedDesktopFileName = boost::filesystem::path(
|
||||
desktopFilePaths.front()).filename().string();
|
||||
|
||||
auto desktopFileMatchingName = find_if(
|
||||
deployedDesktopFiles.begin(),
|
||||
deployedDesktopFiles.end(),
|
||||
[&firstDeployedDesktopFileName](const desktopfile::DesktopFile& desktopFile) {
|
||||
auto fileName = desktopFile.path().filename().string();
|
||||
return fileName == firstDeployedDesktopFileName;
|
||||
}
|
||||
);
|
||||
|
||||
if (desktopFileMatchingName != deployedDesktopFiles.end()) {
|
||||
return *desktopFileMatchingName;
|
||||
} else {
|
||||
ldLog() << LD_ERROR << "Could not find desktop file deployed earlier any more:"
|
||||
<< firstDeployedDesktopFileName << std::endl;
|
||||
throw DeployError("Old desktop file is not reachable.");
|
||||
}
|
||||
}
|
||||
|
||||
bool deployAppDirRootFiles(std::vector<std::string> desktopFilePaths,
|
||||
std::string customAppRunPath, appdir::AppDir& appDir) {
|
||||
ldLog() << std::endl << "-- Deploying files into AppDir root directory --" << std::endl;
|
||||
|
||||
if (!customAppRunPath.empty()) {
|
||||
ldLog() << LD_INFO << "Deploying custom AppRun: " << customAppRunPath << std::endl;
|
||||
|
||||
const auto& appRunPathInAppDir = appDir.path() / "AppRun";
|
||||
if (bf::exists(appRunPathInAppDir)) {
|
||||
ldLog() << LD_WARNING << "File exists, replacing with custom AppRun" << std::endl;
|
||||
bf::remove(appRunPathInAppDir);
|
||||
}
|
||||
|
||||
appDir.deployFile(customAppRunPath, appDir.path() / "AppRun");
|
||||
appDir.executeDeferredOperations();
|
||||
}
|
||||
|
||||
auto deployedDesktopFiles = appDir.deployedDesktopFiles();
|
||||
if (deployedDesktopFiles.empty()) {
|
||||
ldLog() << LD_WARNING << "Could not find desktop file in AppDir, cannot create links for AppRun, "
|
||||
"desktop file and icon in AppDir root" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
desktopfile::DesktopFile desktopFile = getMainDesktopFile(desktopFilePaths, deployedDesktopFiles);
|
||||
ldLog() << "Deploying desktop file:" << desktopFile.path() << std::endl;
|
||||
return appDir.createLinksInAppDirRoot(desktopFile, customAppRunPath);
|
||||
} catch (const DeployError& er) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/core.h
Normal file
20
src/core.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include "linuxdeploy/core/appdir.h"
|
||||
|
||||
namespace linuxdeploy {
|
||||
/**
|
||||
* Deploy the application ".deskop", icon, and runnable files in the AppDir root path. According to the
|
||||
* AppDir spec at: https://docs.appimage.org/reference/appdir.html
|
||||
*
|
||||
* @param desktopFilePaths to be deployed in the AppDir root
|
||||
* @param customAppRunPath AppRun to be used, if empty the application executable will be used instead
|
||||
* @param appDir
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool deployAppDirRootFiles(std::vector<std::string> desktopFilePaths, std::string customAppRunPath,
|
||||
linuxdeploy::core::appdir::AppDir& appDir);
|
||||
}
|
||||
58
src/main.cpp
58
src/main.cpp
@@ -12,6 +12,7 @@
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "linuxdeploy/plugin/plugin.h"
|
||||
#include "linuxdeploy/util/util.h"
|
||||
#include "core.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::log;
|
||||
@@ -253,60 +254,8 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// search for desktop file and deploy it to AppDir root
|
||||
ldLog() << std::endl << "-- Deploying files into AppDir root directory --" << std::endl;
|
||||
|
||||
if (bf::is_regular_file(appDir.path() / "AppRun")) {
|
||||
if (customAppRunPath)
|
||||
ldLog() << LD_WARNING << "AppRun exists but custom AppRun specified, overwriting existing AppRun" << std::endl;
|
||||
else
|
||||
ldLog() << LD_WARNING << "AppRun exists, skipping deployment" << std::endl;
|
||||
} else {
|
||||
auto deployedDesktopFiles = appDir.deployedDesktopFiles();
|
||||
|
||||
desktopfile::DesktopFile desktopFile;
|
||||
|
||||
if (deployedDesktopFiles.empty()) {
|
||||
ldLog() << LD_WARNING << "Could not find desktop file in AppDir, cannot create links for AppRun, desktop file and icon in AppDir root" << std::endl;
|
||||
} else {
|
||||
if (!desktopFilePaths.Get().empty()) {
|
||||
auto firstDeployedDesktopFileName = bf::path(desktopFilePaths.Get().front()).filename().string();
|
||||
|
||||
auto desktopFileMatchingName = std::find_if(
|
||||
deployedDesktopFiles.begin(),
|
||||
deployedDesktopFiles.end(),
|
||||
[&firstDeployedDesktopFileName](const desktopfile::DesktopFile& desktopFile) {
|
||||
auto fileName = desktopFile.path().filename().string();
|
||||
return fileName == firstDeployedDesktopFileName;
|
||||
}
|
||||
);
|
||||
|
||||
if (desktopFileMatchingName != deployedDesktopFiles.end()) {
|
||||
desktopFile = *desktopFileMatchingName;
|
||||
} else {
|
||||
ldLog() << LD_ERROR << "Could not find desktop file deployed earlier any more:" << firstDeployedDesktopFileName << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
desktopFile = deployedDesktopFiles[0];
|
||||
ldLog() << LD_WARNING << "No desktop file specified, using first desktop file found:" << desktopFile.path() << std::endl;
|
||||
}
|
||||
|
||||
ldLog() << "Deploying desktop file:" << desktopFile.path() << std::endl;
|
||||
|
||||
bool rv;
|
||||
|
||||
if (customAppRunPath) {
|
||||
rv = appDir.createLinksInAppDirRoot(desktopFile, customAppRunPath.Get());
|
||||
} else {
|
||||
rv = appDir.createLinksInAppDirRoot(desktopFile);
|
||||
}
|
||||
|
||||
if (!rv)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!linuxdeploy::deployAppDirRootFiles(desktopFilePaths.Get(), customAppRunPath.Get(), appDir))
|
||||
return 1;
|
||||
|
||||
if (outputPlugins) {
|
||||
for (const auto& pluginName : outputPlugins.Get()) {
|
||||
@@ -342,3 +291,4 @@ int main(int argc, char** argv) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,3 +16,24 @@ add_test(test_appdir test_appdir)
|
||||
|
||||
# make sure library and executable are built before test_appdir
|
||||
add_dependencies(test_appdir simple_library simple_executable)
|
||||
|
||||
|
||||
|
||||
add_executable(test_linuxdeploy test_linuxdeploy.cpp ../../src/core.cpp)
|
||||
target_link_libraries(test_linuxdeploy PRIVATE linuxdeploy_core args gtest gtest_main)
|
||||
target_include_directories(test_linuxdeploy PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
# calculate paths to resources using CMake and hardcode them in the test binary
|
||||
target_compile_definitions(test_linuxdeploy PRIVATE
|
||||
-DSIMPLE_LIBRARY_PATH="$<TARGET_FILE:simple_library>"
|
||||
-DSIMPLE_EXECUTABLE_PATH="$<TARGET_FILE:simple_executable>"
|
||||
-DSIMPLE_DESKTOP_ENTRY_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../data/simple_app.desktop"
|
||||
-DSIMPLE_ICON_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../data/simple_icon.svg"
|
||||
-DSIMPLE_FILE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../data/simple_file.txt"
|
||||
)
|
||||
|
||||
# register in CTest
|
||||
add_test(test_linuxdeploy test_linuxdeploy)
|
||||
|
||||
# make sure library and executable are built before test_appdir
|
||||
add_dependencies(test_linuxdeploy simple_library simple_executable)
|
||||
|
||||
99
tests/core/test_linuxdeploy.cpp
Normal file
99
tests/core/test_linuxdeploy.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "core.h"
|
||||
|
||||
using namespace std;
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace LinuxDeployTest {
|
||||
class LinuxDeployTestsFixture : public ::testing::Test {
|
||||
public:
|
||||
bf::path tmpAppDir;
|
||||
bf::path source_executable_path;
|
||||
bf::path target_executable_path;
|
||||
|
||||
bf::path source_desktop_path;
|
||||
bf::path target_desktop_path;
|
||||
|
||||
bf::path source_icon_path;
|
||||
bf::path target_icon_path;
|
||||
|
||||
bf::path source_apprun_path;
|
||||
bf::path target_apprun_path;
|
||||
|
||||
void SetUp() override {
|
||||
tmpAppDir = bf::temp_directory_path() / bf::unique_path("linuxdeploy-tests-%%%%-%%%%-%%%%");
|
||||
source_executable_path = SIMPLE_EXECUTABLE_PATH;
|
||||
target_executable_path = tmpAppDir / "usr/bin" / source_executable_path.filename();
|
||||
|
||||
source_desktop_path = SIMPLE_DESKTOP_ENTRY_PATH;
|
||||
target_desktop_path = tmpAppDir / "usr/share/applications" / source_desktop_path.filename();
|
||||
source_icon_path = SIMPLE_ICON_PATH;
|
||||
target_icon_path = tmpAppDir / "usr/share/icons/hicolor/scalable/apps" / source_icon_path.filename();
|
||||
source_apprun_path = SIMPLE_FILE_PATH;
|
||||
target_apprun_path = tmpAppDir / "AppRun";
|
||||
|
||||
create_directories(tmpAppDir);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
remove_all(tmpAppDir);
|
||||
}
|
||||
|
||||
~LinuxDeployTestsFixture() override = default;
|
||||
|
||||
void listDeployedFiles() {
|
||||
std::cout << "Files deployed in AppDir:" << std::endl;
|
||||
bf::recursive_directory_iterator end_itr; // default construction yields past-the-end
|
||||
for (bf::recursive_directory_iterator itr(tmpAppDir); itr != end_itr; itr++) {
|
||||
std::cout << relative(itr->path(), tmpAppDir).string() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void fillRegularAppDir() {
|
||||
add_executable();
|
||||
add_desktop();
|
||||
add_icon();
|
||||
}
|
||||
|
||||
bf::path add_executable() const {
|
||||
create_directories(target_executable_path.parent_path());
|
||||
copy_file(source_executable_path, target_executable_path);
|
||||
|
||||
return target_executable_path;
|
||||
}
|
||||
|
||||
void add_desktop() const {
|
||||
create_directories(target_desktop_path.parent_path());
|
||||
copy_file(source_desktop_path, target_desktop_path);
|
||||
}
|
||||
|
||||
void add_icon() const {
|
||||
create_directories(target_icon_path.parent_path());
|
||||
copy_file(source_icon_path, target_icon_path);
|
||||
}
|
||||
|
||||
void add_apprun() const {
|
||||
copy_file(source_apprun_path, target_apprun_path);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LinuxDeployTestsFixture, deployAppDirRootFilesWithExistentAppRun) {
|
||||
fillRegularAppDir();
|
||||
add_apprun();
|
||||
|
||||
linuxdeploy::core::appdir::AppDir appDir(tmpAppDir);
|
||||
linuxdeploy::deployAppDirRootFiles({}, "", appDir);
|
||||
|
||||
ASSERT_TRUE(exists(tmpAppDir / source_desktop_path.filename()));
|
||||
ASSERT_TRUE(exists(tmpAppDir / source_icon_path.filename()));
|
||||
ASSERT_TRUE(exists(target_apprun_path));
|
||||
}
|
||||
|
||||
TEST_F(LinuxDeployTestsFixture, deployAppDirRootFilesWithCustomAppRun) {
|
||||
linuxdeploy::core::appdir::AppDir appDir(tmpAppDir);
|
||||
linuxdeploy::deployAppDirRootFiles({}, source_apprun_path.string(), appDir);
|
||||
|
||||
ASSERT_TRUE(exists(target_apprun_path));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user