Files
SpineParticlesWeb/DateToSpine/src/editor/SpineVersionAvailability.cpp
T
2026-09-07 23:48:20 +08:00

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