Add --loot-data-path parameter to LOOT

It sets the path used for LOOT's local application data storage,
overriding the default (%LOCALAPPDATA%\LOOT on Windows).
Closes #700.
This commit is contained in:
Oliver Hamlet
2016-11-19 12:00:28 +00:00
parent 50035cca90
commit 769f3dd313
9 changed files with 69 additions and 39 deletions
+7 -1
View File
@@ -4,7 +4,13 @@ Initialisation
When LOOT is run, it will attempt to detect which of the supported games are installed. If a :ref:`default game <default-game>` has been set, LOOT will run for it, otherwise it will run for the same game as it last ran for. If the relevant game cannot be detected, or if there is no record of the last game LOOT ran for, it will run for the first detected game.
LOOT can also be launched with the ``--game=<game folder name>`` command line parameter to set the game to run for. If the supplied game folder name is valid, the default and last game values are ignored. The default folder names are ``Oblivion``, ``Skyrim``, ``Fallout3``, ``FalloutNV`` and ``Fallout4``.
LOOT's initialisation can be customised using command line parameters:
``--game=<game folder name>``:
Set the game to run for. If the supplied game folder name is valid, the default and last game values are ignored. The default folder names are ``Oblivion``, ``Skyrim``, ``Fallout3``, ``FalloutNV`` and ``Fallout4``.
``--loot-data-path=<path>``:
Set the path to use for LOOT's application data storage. If this is an empty string or not specified, defaults to ``%LOCALAPPDATA%\LOOT`` on Windows and (in order of decreasing preference) ``$XDG_CONFIG_HOME/LOOT``, ``$HOME/.config/LOOT`` or the current path on Linux.
If LOOT cannot detect any supported game installs, it will immediately open the :doc:`Settings dialog <settings>`. There you can edit LOOTs settings to provide a path to a supported game, after which you can select it from the game menu.
+10 -2
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LOOT 0.10.0\n"
"Report-Msgid-Bugs-To: https://github.com/loot/loot/issues\n"
"POT-Creation-Date: 2016-11-12 08:53+0000\n"
"POT-Creation-Date: 2016-11-19 11:59+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -21,6 +21,10 @@ msgstr ""
msgid "Identifying conflicting plugins..."
msgstr ""
#: src/gui/html/js/events.js:80
msgid "Updating and parsing masterlist..."
msgstr ""
#: src/gui/html/js/events.js:100
msgid "No masterlist update was necessary."
msgstr ""
@@ -45,6 +49,10 @@ msgstr ""
msgid "Redate"
msgstr ""
#: src/gui/html/js/events.js:185
msgid "Plugins were successfully redated."
msgstr ""
#: src/gui/html/js/events.js:191
msgid ""
"Are you sure you want to clear all existing user-added metadata from all "
@@ -633,7 +641,7 @@ msgstr ""
msgid "Sorting load order..."
msgstr ""
#: src/backend/app/loot_paths.cpp:84
#: src/backend/app/loot_paths.cpp:88
msgid "Failed to get %LOCALAPPDATA% path."
msgstr ""
+1 -1
View File
@@ -50,7 +50,7 @@ LOOT_API bool IsCompatible(const unsigned int versionMajor, const unsigned int v
LOOT_API std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game,
const std::string& gamePath,
const std::string& gameLocalPath) {
loot::LootPaths::initialise();
loot::LootPaths::initialise("");
//Disable logging or else stdout will get overrun.
boost::log::core::get()->set_logging_enabled(false);
+6 -2
View File
@@ -66,13 +66,17 @@ boost::filesystem::path LootPaths::getLogPath() {
return lootDataPath_ / "LOOTDebugLog.txt";
}
void LootPaths::initialise() {
void LootPaths::initialise(const std::string& lootDataPath) {
// Set the locale to get UTF-8 conversions working correctly.
std::locale::global(boost::locale::generator().generate(""));
boost::filesystem::path::imbue(std::locale());
lootAppPath_ = boost::filesystem::current_path();
lootDataPath_ = getLocalAppDataPath() / "LOOT";
if (!lootDataPath.empty())
lootDataPath_ = lootDataPath;
else
lootDataPath_ = getLocalAppDataPath() / "LOOT";
}
boost::filesystem::path LootPaths::getLocalAppDataPath() {
+3 -3
View File
@@ -37,9 +37,9 @@ public:
static boost::filesystem::path getSettingsPath();
static boost::filesystem::path getLogPath();
// Sets the app path to the current path, and the data path to the user
// local app data path / "LOOT".
static void initialise();
// Sets the app path to the current path, and the data path to the given
// path or (if it is an empty string), local app data path / "LOOT".
static void initialise(const std::string& lootDataPath);
private:
//Get the local application data path.
static boost::filesystem::path getLocalAppDataPath();
+3 -6
View File
@@ -35,12 +35,9 @@
#include "gui/loot_scheme_handler_factory.h"
namespace loot {
LootApp::LootApp() {
LootPaths::initialise();
}
void LootApp::Initialise(const std::string& commandLineGameArg) {
lootState_.init(commandLineGameArg);
void LootApp::Initialise(const std::string& defaultGame, const std::string& lootDataPath) {
LootPaths::initialise(lootDataPath);
lootState_.init(defaultGame);
}
void LootApp::OnBeforeCommandLineProcessing(const CefString& process_type,
+1 -2
View File
@@ -36,8 +36,7 @@ class LootApp : public CefApp,
public CefBrowserProcessHandler,
public CefRenderProcessHandler {
public:
LootApp();
void Initialise(const std::string& commandLineGameArg);
void Initialise(const std::string& defaultGame, const std::string& lootDataPath);
// Override CefApp methods.
virtual void OnBeforeCommandLineProcessing(const CefString& process_type,
+24 -14
View File
@@ -76,6 +76,27 @@ int XIOErrorHandlerImpl(Display *display) {
}
#endif
void processCommandLineArguments(CefRefPtr<loot::LootApp> app) {
std::string defaultGame;
std::string lootDataPath;
// Record command line arguments.
CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
#ifdef _WIN32
command_line->InitFromString(::GetCommandLineW());
#endif
if (command_line->HasSwitch("game")) { // Format is: --game=<game>
defaultGame = command_line->GetSwitchValue("game");
}
if (command_line->HasSwitch("loot-data-path")) {
lootDataPath = command_line->GetSwitchValue("loot-data-path");
}
app.get()->Initialise(defaultGame, lootDataPath);
}
#ifdef _WIN32
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
#else
@@ -124,21 +145,10 @@ int main(int argc, char* argv[]) {
}
#endif
// Handle command line args (not CEF args)
//----------------------------------------
// Handle command line args (not CEF args)
//----------------------------------------
std::string gameStr;
// Record command line arguments.
CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
#ifdef _WIN32
command_line->InitFromString(::GetCommandLineW());
#endif
if (command_line->HasSwitch("game")) { // Format is: --game=<game>
gameStr = command_line->GetSwitchValue("game");
}
app.get()->Initialise(gameStr);
processCommandLineArguments(app);
// Back to CEF
//------------
+14 -8
View File
@@ -32,43 +32,43 @@ along with LOOT. If not, see
namespace loot {
namespace test {
TEST(LootPaths, getReadmePathShouldUseLootAppPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(boost::filesystem::current_path() / "docs" / "index.html", LootPaths::getReadmePath());
}
TEST(LootPaths, getResourcesPathShouldUseLootAppPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(boost::filesystem::current_path() / "resources", LootPaths::getResourcesPath());
}
TEST(LootPaths, getL10nPathShouldUseLootAppPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(boost::filesystem::current_path() / "resources" / "l10n", LootPaths::getL10nPath());
}
TEST(LootPaths, getSettingsPathShouldUseLootDataPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(LootPaths::getLootDataPath() / "settings.yaml", LootPaths::getSettingsPath());
}
TEST(LootPaths, getLogPathShouldUseLootDataPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(LootPaths::getLootDataPath() / "LOOTDebugLog.txt", LootPaths::getLogPath());
}
TEST(LootPaths, initialiseShouldSetTheAppPathToTheCurrentPath) {
LootPaths::initialise();
LootPaths::initialise("");
EXPECT_EQ(boost::filesystem::current_path(), LootPaths::getReadmePath().parent_path().parent_path());
}
TEST(LootPaths, initialiseShouldSetTheDataPathToTheLocalAppDataPathSlashLoot) {
LootPaths::initialise();
TEST(LootPaths, initialiseShouldSetTheDataPathToTheLocalAppDataPathSlashLootIfGivenAnEmptyString) {
LootPaths::initialise("");
// Can't actually know what the path should be, but we can check
// its properties.
@@ -76,6 +76,12 @@ TEST(LootPaths, initialiseShouldSetTheDataPathToTheLocalAppDataPathSlashLoot) {
EXPECT_FALSE(LootPaths::getLootDataPath().parent_path().empty());
EXPECT_TRUE(boost::filesystem::exists(LootPaths::getLootDataPath().parent_path()));
}
TEST(LootPaths, initialiseShouldSetTheDataPathToGivenStringIfNonEmpty) {
LootPaths::initialise("foo");
EXPECT_EQ("foo", LootPaths::getLootDataPath());
}
}
}