Skip to content

Commit

Permalink
Save cached config to standard directories
Browse files Browse the repository at this point in the history
Instead of placing the configuration file in the home directory it should be placed in the [appropriate directory](https://wiki.archlinux.org/index.php/XDG_Base_Directory_support) per OS.

Breaking change: resolves issue #37
  • Loading branch information
Siilwyn authored and phated committed Dec 17, 2018
1 parent 1fb8d6e commit 7bfa22b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 10 deletions.
33 changes: 33 additions & 0 deletions config-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const path = require('path');
const userHome = require('user-home');

const env = process.env;
const name = 'js-v8flags';

function macos () {
const library = path.join(userHome, 'Library');
return path.join(library, 'Caches', name);
}

function windows () {
const appData = env.LOCALAPPDATA || path.join(userHome, 'AppData', 'Local');
return path.join(appData, name, 'Cache');
}

// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
function linux () {
const username = path.basename(userHome);
return path.join(env.XDG_CACHE_HOME || path.join(userHome, '.cache'), name);
}

module.exports = function (platform) {
if (platform === 'darwin') {
return macos();
}

if (platform === 'win32') {
return windows();
}

return linux();
};
12 changes: 8 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const execFile = require('child_process').execFile;
const configPath = require('./config-path.js')(process.platform);
const env = process.env;
const user = env.LOGNAME || env.USER || env.LNAME || env.USERNAME || '';
const exclusions = ['--help'];
Expand All @@ -33,10 +34,12 @@ function openConfig (cb) {
return tryOpenConfig(path.join(os.tmpdir(), configfile), cb);
}

tryOpenConfig(path.join(userHome, configfile), function (err, fd) {
if (err) return tryOpenConfig(path.join(os.tmpdir(), configfile), cb);
return cb(null, fd);
});
fs.mkdir(configPath, function () {
tryOpenConfig(path.join(configPath, configfile), function (err, fd) {
if (err) return tryOpenConfig(path.join(os.tmpdir(), configfile), cb);
return cb(null, fd);
});
})
}

function tryOpenConfig (configpath, cb) {
Expand Down Expand Up @@ -131,3 +134,4 @@ module.exports = function (cb) {
};

module.exports.configfile = configfile;
module.exports.configPath = configPath;
56 changes: 50 additions & 6 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function eraseHome() {
delete env.USER;
delete env.LNAME;
delete env.USERNAME;
delete env.XDG_CACHE_HOME;
delete env.LOCALAPPDATA;
}

function setTemp(dir) {
Expand All @@ -24,11 +26,9 @@ function setTemp(dir) {

function cleanup () {
var v8flags = require('./');
var userHome = require('user-home');
if (userHome === null) userHome = __dirname;

var files = [
path.resolve(userHome, v8flags.configfile),
path.resolve(v8flags.configPath, v8flags.configfile),
path.resolve(os.tmpdir(), v8flags.configfile),
];
files.forEach(function (file) {
Expand All @@ -47,7 +47,7 @@ describe('v8flags', function () {

it('should cache and call back with the v8 flags for the running process', function (done) {
var v8flags = require('./');
var configfile = path.resolve(require('user-home'), v8flags.configfile);
var configfile = path.resolve(v8flags.configPath, v8flags.configfile);
v8flags(function (err, flags) {
expect(flags).to.be.a('array');
expect(fs.existsSync(configfile)).to.be.true;
Expand All @@ -62,7 +62,7 @@ describe('v8flags', function () {

it('should not append the file when multiple calls happen concurrently and the config file does not yet exist', function (done) {
var v8flags = require('./');
var configfile = path.resolve(require('user-home'), v8flags.configfile);
var configfile = path.resolve(v8flags.configPath, v8flags.configfile);
async.parallel([v8flags, v8flags, v8flags], function (err, result) {
v8flags(function (err2, res) {
done();
Expand All @@ -83,7 +83,11 @@ describe('v8flags', function () {
it('should fall back to writing to a temp dir if user home is unwriteable', function (done) {
eraseHome();
env.HOME = path.join(__dirname, 'does-not-exist');
// Clear require cached modules so the modified environment variable HOME is used
delete require.cache[require.resolve('./')];
delete require.cache[require.resolve('./config-path.js')];
var v8flags = require('./');
v8flags.configPath = env.HOME;
var configfile = path.resolve(os.tmpdir(), v8flags.configfile);
v8flags(function (err, flags) {
expect(fs.existsSync(configfile)).to.be.true;
Expand Down Expand Up @@ -133,6 +137,46 @@ describe('v8flags', function () {
v8flags(function (err, flags) {
expect(err).to.be.null;
done();
})
});
});
});

describe('config-path', function () {
const moduleName = 'js-v8flags';

beforeEach(function() {
env.HOME = 'somehome';
cleanup();
});
afterEach(cleanup);

it('should return default linux path in other environments', function(done) {
delete require.cache[require.resolve('./config-path.js')];
const configPath = require('./config-path.js')('other');

expect(configPath).to.equal(
path.join(env.HOME, '.cache', moduleName)
);
done();
});

it('should return default macos path in darwin environment', function(done) {
delete require.cache[require.resolve('./config-path.js')];
const configPath = require('./config-path.js')('darwin');

expect(configPath).to.equal(
path.join(env.HOME, 'Library', 'Caches', moduleName)
);
done();
});

it('should return default windows path in win32 environment', function(done) {
delete require.cache[require.resolve('./config-path.js')];
const configPath = require('./config-path.js')('win32');

expect(configPath).to.equal(
path.join(env.HOME, 'AppData', 'Local', moduleName, 'Cache')
);
done();
});
});

0 comments on commit 7bfa22b

Please sign in to comment.