Skip to content

User directory config files - #534

Merged
JeroMiya merged 10 commits into
masterfrom
user-config
May 1, 2017
Merged

JeroMiya merged 10 commits into
masterfrom
user-config

Conversation

@JeroMiya

@JeroMiya JeroMiya commented Apr 6, 2017

Copy link
Copy Markdown
Contributor

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.

Comment thread 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

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// 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");

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

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.

Comment thread apps/osvr_server.cpp Outdated
log->error() << "'" << configName << "' is special file.";
return -1;
}
log->error() << "Could not find specified config file.";

Copy link
Copy Markdown
Contributor

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.


// Standard includes
#include <vector>

Copy link
Copy Markdown
Contributor

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>.

Copy link
Copy Markdown
Contributor Author

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) {

Copy link
Copy Markdown
Contributor

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++) {

Copy link
Copy Markdown
Contributor

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; }.

Copy link
Copy Markdown
Contributor Author

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.

#include <iostream>
#include <sstream>
#include <vector>

Copy link
Copy Markdown
Contributor

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.

Comment thread 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

Copy link
Copy Markdown
Contributor

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/

Comment thread 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.

Copy link
Copy Markdown
Contributor

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);

Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Contributor Author

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


namespace osvr {
namespace server {
namespace detail {

Copy link
Copy Markdown
Contributor

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()) {

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

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.

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Member

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.

@godbyk godbyk left a comment

Copy link
Copy Markdown
Contributor

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!

Comment thread apps/osvr_server.cpp Outdated

if (values.count("help")) {
std::cout << optionsVisible << std::endl;
log->info() << optionsVisible << std::endl;

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add standard copyright header.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Member

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...

Comment thread inc/osvr/Server/ConfigFilePaths.h Outdated
@@ -0,0 +1,45 @@
/** @file
@brief Auto-generated configuration header - do not edit!

Copy link
Copy Markdown
Contributor

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the comment

@godbyk godbyk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me!

Comment thread 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 "

Copy link
Copy Markdown
Member

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?

@rpavlik rpavlik left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor itty bitty nitpicks.

Comment thread apps/osvr_server.cpp Outdated
<< "' not found. Using empty configuration.";
configPath = boost::none;
server = osvr::server::configureServerFromFirstFileInList(configPaths);
if (!server) {

Copy link
Copy Markdown
Member

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?

Comment thread 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.";

Copy link
Copy Markdown
Member

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.

Comment thread inc/osvr/Server/ConfigFilePaths.h Outdated
<http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.

Copy link
Copy Markdown
Member

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

Copy link
Copy Markdown
Member

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;

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor

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()) {

Copy link
Copy Markdown
Member

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?

@rpavlik

rpavlik commented May 1, 2017

Copy link
Copy Markdown
Member

👍

@JeroMiya
JeroMiya merged commit ef4b572 into master May 1, 2017
@JeroMiya
JeroMiya deleted the user-config branch May 1, 2017 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants