Skip to content

Commit

Permalink
Breaking: Save cached config to standard directories (closes #37)
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.
  • Loading branch information
Siilwyn authored and phated committed Dec 17, 2018
1 parent 94118f0 commit 7f29e82
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 7f29e82

Please sign in to comment.