65 lines
2.6 KiB
C++
65 lines
2.6 KiB
C++
#include "editor/SpineVersionAvailability.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <cstdlib>
|
|
#include <system_error>
|
|
|
|
namespace dts {
|
|
namespace fs = std::filesystem;
|
|
|
|
std::vector<fs::path> SpineVersionAvailability::defaultCacheRoots() const {
|
|
std::vector<fs::path> roots;
|
|
#if defined(__APPLE__)
|
|
if (const char* userHome = std::getenv("HOME"))
|
|
roots.emplace_back(fs::path(userHome) / "Library/Application Support/Spine/updates");
|
|
#elif defined(_WIN32)
|
|
if (const char* roaming = std::getenv("APPDATA"))
|
|
roots.emplace_back(fs::path(roaming) / "Spine/updates");
|
|
if (const char* local = std::getenv("LOCALAPPDATA"))
|
|
roots.emplace_back(fs::path(local) / "Spine/updates");
|
|
// Spine Launcher also keeps its update cache directly under the user's
|
|
// profile directory (e.g. C:\Users\<name>\Spine\updates).
|
|
if (const char* userProfile = std::getenv("USERPROFILE"))
|
|
roots.emplace_back(fs::path(userProfile) / "Spine/updates");
|
|
#endif
|
|
return roots;
|
|
}
|
|
|
|
std::vector<SpineVersion> SpineVersionAvailability::discover(
|
|
const std::vector<fs::path>& cacheRoots) const {
|
|
std::vector<SpineVersion> versions;
|
|
const auto roots = cacheRoots.empty() ? defaultCacheRoots() : cacheRoots;
|
|
for (const auto& root : roots) {
|
|
std::error_code error;
|
|
fs::directory_iterator iterator(root, error);
|
|
for (const auto& entry : iterator) {
|
|
if (!entry.is_regular_file(error) || entry.file_size(error) == 0) continue;
|
|
const auto parsed = SpineVersion::parse(entry.path().filename().string());
|
|
if (parsed && std::find(versions.begin(), versions.end(), *parsed) == versions.end())
|
|
versions.push_back(*parsed);
|
|
}
|
|
}
|
|
std::sort(versions.begin(), versions.end(), [](const auto& left, const auto& right) {
|
|
if (left.major != right.major) return left.major < right.major;
|
|
if (left.minor != right.minor) return left.minor < right.minor;
|
|
return left.patch < right.patch;
|
|
});
|
|
return versions;
|
|
}
|
|
|
|
std::optional<SpineVersion> SpineVersionAvailability::newestForLine(
|
|
std::string_view versionLine, const std::vector<fs::path>& cacheRoots) const {
|
|
std::optional<SpineVersion> result;
|
|
for (const auto& version : discover(cacheRoots))
|
|
if (version.line() == versionLine) result = version;
|
|
return result;
|
|
}
|
|
|
|
bool SpineVersionAvailability::isCached(
|
|
const SpineVersion& version, const std::vector<fs::path>& cacheRoots) const {
|
|
const auto versions = discover(cacheRoots);
|
|
return std::find(versions.begin(), versions.end(), version) != versions.end();
|
|
}
|
|
|
|
} // namespace dts
|