log: Fall back to CWD-relative .nvimlog

If if the resolved $NVIM_LOG_FILE *and* stdpath("data")/log cannot be
created (e.g. because the XDG data directory does not exist), fall back
to .nvimlog in the current direcrtory.
This commit is contained in:
Justin M. Keyes
2017-05-31 18:12:26 +02:00
parent a49c92fc5b
commit d07661b9a3
2 changed files with 57 additions and 17 deletions

View File

@@ -25,6 +25,19 @@ static uv_mutex_t mutex;
# include "log.c.generated.h" # include "log.c.generated.h"
#endif #endif
static bool log_try_create(char *fname)
{
if (fname == NULL || fname[0] == '\0') {
return false;
}
FILE *log_file = fopen(fname, "a");
if (log_file == NULL) {
return false;
}
fclose(log_file);
return true;
}
/// Initializes path to log file. Sets $NVIM_LOG_FILE if empty. /// Initializes path to log file. Sets $NVIM_LOG_FILE if empty.
/// ///
/// Tries $NVIM_LOG_FILE, or falls back to $XDG_DATA_HOME/nvim/log. Path to log /// Tries $NVIM_LOG_FILE, or falls back to $XDG_DATA_HOME/nvim/log. Path to log
@@ -43,17 +56,22 @@ static bool log_path_init(void)
(int)size - 1); (int)size - 1);
if (strequal("$" LOG_FILE_ENV, log_file_path) if (strequal("$" LOG_FILE_ENV, log_file_path)
|| log_file_path[0] == '\0' || log_file_path[0] == '\0'
|| os_isdir((char_u *)log_file_path)) { || os_isdir((char_u *)log_file_path)
|| !log_try_create(log_file_path)) {
// Invalid $NVIM_LOG_FILE or failed to expand; fall back to default. // Invalid $NVIM_LOG_FILE or failed to expand; fall back to default.
memset(log_file_path, 0, size);
char *defaultpath = stdpaths_user_data_subpath("log", 0, true); char *defaultpath = stdpaths_user_data_subpath("log", 0, true);
size_t len = xstrlcpy(log_file_path, defaultpath, size); size_t len = xstrlcpy(log_file_path, defaultpath, size);
if (len >= size) { // Fall back to stderr. xfree(defaultpath);
memset(log_file_path, 0, size); // Fall back to .nvimlog
if (len >= size || !log_try_create(log_file_path)) {
len = xstrlcpy(log_file_path, ".nvimlog", size);
}
// Fall back to stderr
if (len >= size || !log_try_create(log_file_path)) {
log_file_path[0] = '\0';
return false; return false;
} }
os_setenv(LOG_FILE_ENV, log_file_path, true); os_setenv(LOG_FILE_ENV, log_file_path, true);
xfree(defaultpath);
} }
return true; return true;
} }

View File

@@ -8,6 +8,8 @@ local clear = helpers.clear
local eval = helpers.eval local eval = helpers.eval
local eq = helpers.eq local eq = helpers.eq
local neq = helpers.neq local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
local function init_session(...) local function init_session(...)
local args = { helpers.nvim_prog, '-i', 'NONE', '--embed', local args = { helpers.nvim_prog, '-i', 'NONE', '--embed',
@@ -123,32 +125,52 @@ describe('startup defaults', function()
end) end)
describe('$NVIM_LOG_FILE', function() describe('$NVIM_LOG_FILE', function()
-- TODO(jkeyes): use stdpath('data') instead.
local datasubdir = helpers.iswin() and 'nvim-data' or 'nvim'
local xdgdir = 'Xtest-startup-xdg-logpath'
local xdgdatadir = xdgdir..'/'..datasubdir
after_each(function() after_each(function()
os.remove('Xtest-logpath') os.remove('Xtest-logpath')
rmdir(xdgdir)
end) end)
it('is used if expansion succeeds', function() it('is used if expansion succeeds', function()
clear({env={ clear({env={
NVIM_LOG_FILE='Xtest-logpath', NVIM_LOG_FILE='Xtest-logpath',
}}) }})
eq('Xtest-logpath', eval('$NVIM_LOG_FILE')) eq('Xtest-logpath', eval('$NVIM_LOG_FILE'))
end) end)
it('defaults to stdpath("data")/log', function() it('defaults to stdpath("data")/log if empty', function()
eq(true, mkdir(xdgdir) and mkdir(xdgdatadir))
clear({env={ clear({env={
XDG_DATA_HOME='Xtest-startup-logpath', XDG_DATA_HOME=xdgdir,
NVIM_LOG_FILE='', -- Empty value is considered invalid. NVIM_LOG_FILE='', -- Empty is invalid.
}}) }})
-- TODO(jkeyes): use stdpath('data') instead. -- server_start() calls ELOG, which tickles log_path_init().
local dir = helpers.iswin() and 'nvim-data' or 'nvim' pcall(command, 'call serverstart(serverlist()[0])')
eq('Xtest-startup-logpath/'..dir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
end) end)
it('if invalid, falls back to default', function() it('defaults to stdpath("data")/log if invalid', function()
eq(true, mkdir(xdgdir) and mkdir(xdgdatadir))
clear({env={ clear({env={
XDG_DATA_HOME='Xtest-startup-logpath', XDG_DATA_HOME=xdgdir,
NVIM_LOG_FILE='.', -- Directory is considered invalid. NVIM_LOG_FILE='.', -- Any directory is invalid.
}}) }})
-- TODO(jkeyes): use stdpath('data') instead. -- server_start() calls ELOG, which tickles log_path_init().
local dir = helpers.iswin() and 'nvim-data' or 'nvim' pcall(command, 'call serverstart(serverlist()[0])')
eq('Xtest-startup-logpath/'..dir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
end)
it('defaults to .nvimlog if stdpath("data") is invalid', function()
clear({env={
XDG_DATA_HOME='Xtest-missing-xdg-dir',
NVIM_LOG_FILE='.', -- Any directory is invalid.
}})
-- server_start() calls ELOG, which tickles log_path_init().
pcall(command, 'call serverstart(serverlist()[0])')
eq('.nvimlog', eval('$NVIM_LOG_FILE'))
end) end)
end) end)
end) end)