Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[runSofa,Helper] Changes screenshots and config directories location #5096

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
100 changes: 64 additions & 36 deletions Sofa/framework/Helper/src/sofa/helper/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,42 +234,28 @@ std::map<std::string, std::string> Utils::readBasicIniFile(const std::string& pa
}

// no standard/portable way
const std::string& Utils::getUserLocalDirectory()
const std::string& Utils::getUserHomeDirectory()
{

auto computeUserHomeDirectory = []()
{
// Windows: "LocalAppData" directory i.e ${HOME}\AppData\Local
#ifdef WIN32
std::wstring wresult;
wchar_t* path = nullptr;
const auto hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path);
if (SUCCEEDED(hr))
{
wresult = std::wstring(path);
}
if (path)
{
CoTaskMemFree(path);
}

return Utils::narrowString(wresult);

#ifdef WIN32 // Windows: ${HOME}
const char* homeDir = std::getenv("USERPROFILE");
return std::string(homeDir);
#elif defined(__APPLE__) // macOS : ${HOME}/Library/Application Support
// https://stackoverflow.com/questions/5123361/finding-library-application-support-from-c
// https://stackoverflow.com/questions/5123361/finding-library-application-support-from-c

char path[PATH_MAX];
auto state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_APPLICATION_SUPPORT,
SYSDIR_DOMAIN_MASK_USER);
if ((state = sysdir_get_next_search_path_enumeration(state, path)))
{
glob_t globbuf;
if (glob(path, GLOB_TILDE, nullptr, &globbuf) == 0)
if (glob(path, GLOB_TILDE, nullptr, &globbuf) == 0)
{
std::string result(globbuf.gl_pathv[0]);
globfree(&globbuf);
return result;
}
}
else
{
// "Unable to expand tilde"
Expand All @@ -281,34 +267,76 @@ const std::string& Utils::getUserLocalDirectory()
// "Failed to get settings folder"
return std::string("");
}


#else // Linux: ${HOME}

const char* homeDir;

// if HOME is defined
if ((homeDir = std::getenv("HOME")) == nullptr)
{
// else system calls are used
homeDir = getpwuid(getuid())->pw_dir;
}

return std::string(homeDir);

#endif
};

static std::string homeDir = FileSystem::cleanPath(computeUserHomeDirectory());
return homeDir;
}

const std::string& Utils::getSofaDataDirectory()
{
constexpr std::string_view sofaDataDirSuffix = "SOFAData";

static std::string sofaDataDirectory = FileSystem::cleanPath(FileSystem::findOrCreateAValidPath(
FileSystem::append(getUserHomeDirectory(), sofaDataDirSuffix)));

return sofaDataDirectory;
}


// no standard/portable way
const std::string& Utils::getUserLocalDirectory()
{
auto computeUserLocalDirectory = []()
{
#ifdef WIN32 // Windows: "LocalAppData" directory i.e ${HOME}\AppData\Local
std::wstring wresult;
wchar_t* path = nullptr;
const auto hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path);
if (SUCCEEDED(hr))
{
wresult = std::wstring(path);
}
if (path)
{
CoTaskMemFree(path);
}

return Utils::narrowString(wresult);
#elif defined(__APPLE__) // macOS : ${HOME}/Library/Application Support
return getUserHomeDirectory();
#else // Linux: either ${XDG_CONFIG_HOME} if defined, or ${HOME}/.config (should be equivalent)
const char* configDir;

// if env.var XDG_CONFIG_HOME is defined
if ((configDir = std::getenv("XDG_CONFIG_HOME")) == nullptr)
{
const char* homeDir;

// else if HOME is defined
if ((homeDir = std::getenv("HOME")) == nullptr)
{
// else system calls are used
homeDir = getpwuid(getuid())->pw_dir;
}

return std::string(homeDir) + std::string("/.config");
return FileSystem::append(getUserHomeDirectory(), ".config");
}
else
{
return std::string(configDir);
}

#endif
};

static std::string homeDir = FileSystem::cleanPath(computeUserHomeDirectory());
return homeDir;
static std::string userLocalDir = FileSystem::cleanPath(computeUserLocalDirectory());
return userLocalDir;
}

const std::string& Utils::getSofaUserLocalDirectory()
Expand Down
6 changes: 6 additions & 0 deletions Sofa/framework/Helper/src/sofa/helper/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ static const std::string& getExecutablePath();
/// @brief Get the path to the directory of the executable that is currently running.
static const std::string& getExecutableDirectory();

/// @brief Get the path to the current user home directory.
static const std::string& getUserHomeDirectory();

/// @brief Get the path to the SOFA data directory into the current user home directory.
static const std::string& getSofaDataDirectory();

/// @brief Get the path to the current user local config directory.
static const std::string& getUserLocalDirectory();

Expand Down
30 changes: 30 additions & 0 deletions Sofa/framework/Helper/test/Utils_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,36 @@ TEST(UtilsTest, getSofaUserLocalDirectory)
EXPECT_TRUE(path.find("SOFA") != std::string::npos);
}

// This test is expected to fail outside the CI environment
bool testGetUserHomeDirectory()
{
bool result = false;

const std::string path = Utils::getUserHomeDirectory();
#if defined(WIN32)
result = (path == "J:/jenkins2");
#elif defined (__APPLE__)
result = (path.find("Library") != std::string::npos);
result = result && (path.find("Application Support") != std::string::npos);
#else // Linux
result = (path == "/home/runner");
#endif

std::cout<<"Utils::getUserHomeDirectory(): "<<path<<std::endl;
return result;
}

TEST(UtilsTest, getUserHomeDirectory)
{
EXPECT_TRUE(testGetUserHomeDirectory());
}

TEST(UtilsTest, getSofaDataDirectory)
{
const std::string path = Utils::getSofaDataDirectory();
EXPECT_TRUE(path.find("SOFAData") != std::string::npos);
}

TEST(UtilsTest, readBasicIniFile_nonexistentFile)
{
// this test will raise an error on purpose
Expand Down
4 changes: 2 additions & 2 deletions applications/projects/runSofa/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ int main(int argc, char** argv)
msg_info(appName) << "GuiDataRepository paths = " << GuiDataRepository.getPathsJoined();

// Initialise paths
BaseGUI::setConfigDirectoryPath(Utils::getSofaPathPrefix() + "/config", true);
BaseGUI::setScreenshotDirectoryPath(Utils::getSofaPathPrefix() + "/screenshots", true);
BaseGUI::setConfigDirectoryPath(FileSystem::append(Utils::getSofaUserLocalDirectory(), "config"), true);
BaseGUI::setScreenshotDirectoryPath(FileSystem::append(Utils::getSofaDataDirectory(), "screenshots"), true);

// Add Batch GUI (runSofa without any GUIs won't be useful)
sofa::gui::batch::init();
Expand Down