diff --git a/include/bottles.hpp b/include/bottles.hpp index ea68db0..95a76a0 100644 --- a/include/bottles.hpp +++ b/include/bottles.hpp @@ -22,6 +22,14 @@ namespace cellar { bottle_steam }; + enum bottle_manager { + manager_error, + manager_cellar, + manager_steam + }; + + extern std::string bottle_home; + /** * Bottles are the internal name for WINE prefixes. In addition to standard WINE contents, * bottles contain a configuration file managed by cellar, which labels the bottle as well @@ -31,6 +39,7 @@ namespace cellar { public: // public members bottle_type type; + bottle_manager manager; json config; string path; string canonical_path; diff --git a/include/internal/bottles.hpp.cog b/include/internal/bottles.hpp.cog index 2e8851b..ccd7f53 100644 --- a/include/internal/bottles.hpp.cog +++ b/include/internal/bottles.hpp.cog @@ -21,6 +21,8 @@ namespace cellar { cog.outl("extern void {0} (int, vector);".format(item[1])) ]]]*/ //[[[end]]] + + extern void setup_bottle_home(); } namespace commands { extern map bottles_commands(); diff --git a/src/bottles/active.cpp b/src/bottles/active.cpp index 93b1f3e..d5e25f5 100644 --- a/src/bottles/active.cpp +++ b/src/bottles/active.cpp @@ -17,6 +17,7 @@ void cellar::bottles::print_active_bottle(int argc, vector argv) { string bottlepath = active_bottle.canonical_path; stringstream outstr; bool cellar_managed = true; + bool external_managed = false; if (active_bottle.type == bottle_symlink) { outstr << "symlink to "; string homedir = getenv("HOME"); @@ -24,6 +25,8 @@ void cellar::bottles::print_active_bottle(int argc, vector argv) { if (active_bottle.canonical_path.substr(0, bottlerack.length()) == bottlerack) { bottlepath.replace(0, bottlerack.length() + 1, ""); // should convert "/home/someone/.wine.example" to ".wine.example" active_bottle = bottlemap[bottlepath]; + active_bottle.set_config("manager", "cellar"); + active_bottle.save_config(); } else { outstr << active_bottle.canonical_path; cellar_managed = false; diff --git a/src/bottles/bottles.cpp b/src/bottles/bottles.cpp index 960ac79..af59655 100644 --- a/src/bottles/bottles.cpp +++ b/src/bottles/bottles.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -33,6 +34,21 @@ Bottle::Bottle() { // strings handle themselves config = json({}); type = bottle_anonymous; + manager = manager_error; +} + +std::string cellar::bottles::bottle_home; + +/** + * @brief Sets up bottle home. + * Called once from early mainloop. + * @todo Have this not be an effectively hardcoded path. Respect xdg paths. + */ +void cellar::bottles::setup_bottle_home() { + stringstream sstr_bottle_home; + sstr_bottle_home << std::getenv("HOME"); + sstr_bottle_home << "/.local/share/cellar/bottles"; + bottle_home = sstr_bottle_home.str(); } /** @@ -45,20 +61,39 @@ Bottle::Bottle(string patharg) { config = json({}); path = patharg; - boost::filesystem::file_status path_status = boost::filesystem::symlink_status(path); - bool symlink = boost::filesystem::is_symlink(path_status); + //boost::filesystem::file_status path_status = boost::filesystem::symlink_status(path); + //bool symlink = boost::filesystem::is_symlink(path_status); + auto path_status = std::filesystem::path(path); + auto path_canon = std::filesystem::canonical(path_status); + canonical_path = path_canon.string(); - if (symlink) { - boost::filesystem::path realpath = boost::filesystem::canonical(path); - canonical_path = realpath.string(); + if (std::filesystem::is_symlink(path_canon)) { type = bottle_symlink; } else { - canonical_path = path; try { - if (load_config()) { - type = bottle_labelled; - } else { - type = bottle_anonymous; + load_config(); + auto cur_manager = get_config("manager"); + if (cur_manager == "cellar") { + manager = manager_cellar; + + if (get_config("name") != "") { + type = bottle_labelled; + } else { + type = bottle_anonymous; + } + } else if (path_canon.parent_path() == bottle_home) { + manager = manager_cellar; + set_config("manager", "cellar"); // migrate from older cellar (or correct for something weird happening) + save_config(); + + if (get_config("name") != "") { + type = bottle_labelled; + } else { + type = bottle_anonymous; + } + } else if (cur_manager == "steam") { + type = bottle_steam; + manager = manager_steam; } } catch (const exception &exc) { diff --git a/src/core/cellar.cpp.cog b/src/core/cellar.cpp.cog index 85a9c00..b6a4d45 100644 --- a/src/core/cellar.cpp.cog +++ b/src/core/cellar.cpp.cog @@ -10,6 +10,7 @@ #include "nlohmann/json.hpp" #include "bottles.hpp" +#include "internal/bottles.hpp" #include "cellar.hpp" #include "commands.hpp" #include "output.hpp" @@ -45,6 +46,7 @@ int main(int argc, char* argv[]) { cout << "\n(try \"cellar help\" if you're confused)" << endl; return 0; } + cellar::bottles::setup_bottle_home(); try { const string desc = "bottle management tool for WINE connoisseurs"; const string versionstr = version::short_version(); @@ -70,7 +72,7 @@ int main(int argc, char* argv[]) { dryrun = dryrunarg.getValue(); verbose = dryrun || verbosearg.getValue(); - // BULLSHIT: trying to use str.format on this string causes bizarre compiler errors + // TODO: i'm sure stdlib has come a long way in formatting strings since this ancient hack was put in /*[[[cog import cog @@ -103,7 +105,7 @@ int main(int argc, char* argv[]) { if (bottlechoice.substr(0,1) == "/" || bottlechoice.substr(0,1) == ".") { // absolute or relative path bottles::active_bottle = bottles::Bottle(bottlechoice); } else if (bottlechoice.substr(0,1) == "~") { // "absolute" path in home directory, not expanded by the shell for some reason (i've seen some shit) - // this is a naive replacement and will fail if the user tries something like ~nick/.wine + // this is a naive replacement and will fail if the user tries something like ~nicole/.wine // i'm figuring at that point if you're doing that, you'll also recognize if your shell // isn't actually expanding your path... bottlechoice.replace(0,1,getenv("HOME")); diff --git a/src/steam/bottles.cpp b/src/steam/bottles.cpp index b368a80..3f1782f 100644 --- a/src/steam/bottles.cpp +++ b/src/steam/bottles.cpp @@ -46,6 +46,7 @@ std::map cellar::steam::get_app_bottles() auto curbottle = cellar::bottles::Bottle((pth_appid / "pfx").string()); curbottle.type = cellar::bottles::bottle_steam; curbottle.set_config("name", str_gamename); + curbottle.set_config("manager", "steam"); curbottle.save_config(); result[std::string("steam:" + pth_appid.filename().string())] = curbottle; }