-
Notifications
You must be signed in to change notification settings - Fork 124
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
User directory config files #534
Conversation
src/osvr/Server/ConfigFilePaths.cpp
Outdated
std::string configSubpath = "config"; | ||
|
||
#if defined(OSVR_LINUX) | ||
// There's currently no great location for storing log files in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can delete the first paragraph of the comment and update the second para to reflect XDG_CONFIG_HOME
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
src/osvr/Server/ConfigFilePaths.cpp
Outdated
// specific non-essential data files should be stored. If | ||
// $XDG_CACHE_HOME is either not set or empty, a default equal to | ||
// $HOME/.cache should be used. | ||
auto xdg_cache_dir = getEnvironmentVariable("XDG_CONFIG_HOME"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Linux, if you're searching for an existing configuration file (as opposed to determining where to write a new one), then you will want to check the XDG_CONFIG_DIRS
paths as well. From the XDG Base Directory Specification:
$XDG_CONFIG_DIRS
defines the preference-ordered set of base directories to search for configuration files in addition to the$XDG_CONFIG_HOME
base directory. The directories in$XDG_CONFIG_DIRS
should be separated with a colon:
.If
$XDG_CONFIG_DIRS
is either not set or empty, a value equal to/etc/xdg
should be used.The order of base directories denotes their importance; the first directory listed is the most important. When the same information is defined in multiple places the information defined relative to the more important base directory takes precedent. [...] The base directory defined by
$XDG_CONFIG_HOME
is considered more important than any of the base directories defined by$XDG_CONFIG_DIRS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to put this as a TODO for now. The function this is in currently only returns one directory, and this change would require it to return multiple directories.
apps/osvr_server.cpp
Outdated
log->error() << "'" << configName << "' is special file."; | ||
return -1; | ||
} | ||
log->error() << "Could not find specified config file."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message could be more specific (or removed if configureServerFromFirstFileInList()
prints a better one). Possible failure cases: file not found, file couldn't be opened, file couldn't be prased, etc.
inc/osvr/Server/ConfigFilePaths.h
Outdated
|
||
// Standard includes | ||
#include <vector> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget #include <string>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
namespace osvr { | ||
namespace server { | ||
|
||
ServerPtr configureServerFromString(std::string const &json) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for moving this to the .cpp
file. I meant to do that when I was originally refactoring and it slipped my mind later.
} | ||
log->error() << "Could not open config file!"; | ||
log->error() << "Attempted the following files:"; | ||
for (auto i = configNames.begin(); i != configNames.end(); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the more succinct C++11 loop: for (const auto& configName : configName) { log->error() << configName; }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was removed - the config file attempts are logged elsewhere so this was redundant.
@@ -38,130 +38,30 @@ | |||
#include <exception> | |||
#include <fstream> | |||
#include <iostream> | |||
#include <sstream> | |||
#include <vector> | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need #include <string>
. And it looks like you can ditch iostream
and fstream
and exception
(move 'em to the .cpp
file). Same with the Log headers above.
src/osvr/Server/ConfigFilePaths.cpp
Outdated
#if defined(OSVR_LINUX) | ||
// $XDG_CONFIG_HOME defines the base directory relative to which user | ||
// specific non-essential data files should be stored. If | ||
// $XDG_CACHE_HOME is either not set or empty, a default equal to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/XDG_CACHE_HOME/XDG_CONFIG_HOME/
src/osvr/Server/ConfigFilePaths.cpp
Outdated
// $XDG_CONFIG_HOME defines the base directory relative to which user | ||
// specific non-essential data files should be stored. If | ||
// $XDG_CACHE_HOME is either not set or empty, a default equal to | ||
// $HOME/.cache should be used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/cache/config/g
throughout, I think.
|
||
names.push_back(userConfig.string()); | ||
names.push_back(configFileName); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are more places worth checking, too.
On Linux:
$XDG_CONFIG_HOME/osvr/osvr_server_config.json
- For each colon-separated dir in
$XDG_CONFIG_DIRS
:$prefix/osvr/osvr_server_config.json
/etc/xdg
if$XDG_CONFIG_DIRS
is not set or empty./etc/osvr_server_config.json
for old-school paths/usr/local/etc/osvr_server_config.json
for old-school paths
On macOS:
$HOME/Library/Application Support/OSVR/config/osvr_server_config.json
/Library/Application Support/OSVR/config/osvr_server_config.json
- wherever brew installs it by default (I think
/usr/local/Cellar/osvr-core/bin/osvr_server_config.json
, maybe) /etc/osvr_server_config.json
for old-school paths/usr/local/etc/osvr_server_config.json
for old-school paths
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to new issue: #537
@@ -47,23 +47,6 @@ | |||
|
|||
namespace osvr { | |||
namespace server { | |||
namespace detail { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, wow! This is ancient. I thought we killed it ages ago.
|
||
for (const auto name : configNames) { | ||
std::ifstream config(name); | ||
if (config.good()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log which file you're running with so it's easier to troubleshoot later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's logged in configureServerFromFile
, but I adjusted the log there to be more consistent with the others in wording.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we even need to check the member good()
or can we just use the explicit bool conversion operator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
operator bool
would return true
at EOF while good()
would return false. So calling good()
avoids reading an empty file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alrighty then, things I didn't know about iostreams.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple minor quibbles, but otherwise I think it looks good!
apps/osvr_server.cpp
Outdated
@@ -92,7 +83,7 @@ int main(int argc, char *argv[]) { | |||
} | |||
|
|||
if (values.count("help")) { | |||
std::cout << optionsVisible << std::endl; | |||
log->info() << optionsVisible << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case, we should use std::cout instead of a logger because we don't want the output lines prefixed with timestamps, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -0,0 +1,73 @@ | |||
// Internal Includes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add standard copyright header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date and indentation don't match but...
inc/osvr/Server/ConfigFilePaths.h
Outdated
@@ -0,0 +1,45 @@ | |||
/** @file | |||
@brief Auto-generated configuration header - do not edit! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header file isn't auto-generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Looks good to me!
apps/osvr_server.cpp
Outdated
log->info() << "Using config file " << configFileArgument << " from command line argument."; | ||
configPaths = { configFileArgument }; | ||
} else { | ||
log->info() << "Using default config files - pass a filename on the command " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the word "files" here a typo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor itty bitty nitpicks.
apps/osvr_server.cpp
Outdated
<< "' not found. Using empty configuration."; | ||
configPath = boost::none; | ||
server = osvr::server::configureServerFromFirstFileInList(configPaths); | ||
if (!server) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you've got trailing spaces - did you clang format your changes?
apps/osvr_server.cpp
Outdated
if (!server) { | ||
// only attempt to load the empty config if no arguments are passed. | ||
if (!values.count("config")) { | ||
log->info() << "Could not find a valid config file. Using default config object."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this maybe better phrased "could not find config file with default name" or something like that? The user seeing this message wouldn't have passed a config file, so they might be confused as to why they're seeing this.
inc/osvr/Server/ConfigFilePaths.h
Outdated
<http://sensics.com/osvr> | ||
*/ | ||
|
||
// Copyright 2015 Sensics, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this 2015 code?
@@ -0,0 +1,73 @@ | |||
// Internal Includes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date and indentation don't match but...
return nullptr; | ||
} | ||
|
||
std::stringstream sstr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming this is how you load a whole file in a single gulp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rpavlik Yeah, this just loads the whole file into a string. It's the best way I could find to do it.
|
||
for (const auto name : configNames) { | ||
std::ifstream config(name); | ||
if (config.good()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we even need to check the member good()
or can we just use the explicit bool conversion operator?
👍 |
Do not merge yet. Please merge this PR first:
#529
Then I'll rebase this on those changes.
This pull request includes and supersedes this one:
#265
This adds search-paths behavior for the osvr config file, including prioritizing a user-specific configuration if present, before falling back to the current CWD behavior.