Skip to content

Instantly share code, notes, and snippets.

@akhoury
Last active August 29, 2015 14:05
Show Gist options
  • Save akhoury/c6104082c06749895535 to your computer and use it in GitHub Desktop.
Save akhoury/c6104082c06749895535 to your computer and use it in GitHub Desktop.
node v0.10.3, npm v1.4.4 A test script to install module via npm, that when attempting to uninstall a module (which was installed from the npm registry) then installing the same module from a URL (github.com), the 2nd call to require attempts to execute the old main script which does not execute, even after clearing require's cache.
var fs = require('fs');
var getModuleShortName = function(giturlORname) {
if (giturlORname.indexOf('git://github.com') > -1) {
return giturlORname.split('/').pop().split('#')[0];
}
return giturlORname.split('@')[0];
};
var searchModulesCache = function(moduleName, callback) {
var mod = require.resolve(moduleName);
if (mod && ((mod = require.cache[mod]) !== undefined)) {
(function run(mod) {
mod.children.forEach(function (child) {
run(child);
});
callback(mod);
})(mod);
}
};
var reloadModule = function(moduleName) {
searchModulesCache(moduleName, function(mod) {
delete require.cache[mod.id];
});
return require(moduleName);
};
var isCompatible = function(myModule) {
return typeof myModule.teardown == 'function' && typeof myModule.setup === 'function';
};
var install = function(moduleName, config, callback) {
var npm = require('npm');
if (typeof config === 'function') {
callback = config;
config = {};
}
callback = typeof callback === 'function' ? callback : function(){};
npm.load(config || {}, function(err) {
if (err) {
callback(err);
}
npm.config.set('spin', false);
npm.config.set('force', true);
npm.config.set('verbose', false);
npm.commands.install([moduleName], function(err) {
if (err) {
callback(err);
}
// just in case it's a URL, i.e. git://github.com/someone/something#master
var moduleShortName = getModuleShortName(moduleName);
console.log('\n\n\n\n\nMODULE: ' + moduleName);
console.log('\nRESOLVED PATH OF THE MAIN SCRIPT: >>>> ' + require.resolve(moduleShortName));
var packageJson = JSON.parse(fs.readFileSync( __dirname + '/node_modules/' + moduleShortName + '/package.json'));
console.log('\npackage.json ==> { main: ' + packageJson.main + ', version: ' + packageJson.version + ' }\n\n\n\n\n');
try {
var myModule = reloadModule(moduleShortName);
} catch (e) {
console.log('\n\nWhy is it trying to execute the old main script?? even though it was replaced by a new module, scroll up the logs compare both attempts.\n\n');
throw e;
}
if (! isCompatible(myModule) ) {
// not compatible? let's try the latest on github.com, it might be compatible
// if it has the github url in it, then we already tried that
if (moduleName.indexOf('github.com/akhoury') === -1) {
// uninstall them first
npm.commands.uninstall([moduleShortName], function(err) {
if(err) {
callback(err);
}
install('git://github.com/akhoury/' + moduleShortName + '#master', {}, callback);
});
} else {
callback({error: moduleName + ' is not compatible.'});
}
} else {
callback();
}
});
});
};
install('nodebb-plugin-import-ubb@0.0.4', {force: true}, function(err) {
if (err) {
console.error(err);
}
});
@akhoury
Copy link
Author

akhoury commented Aug 26, 2014

SAMPLE OUTPUT

[558] > node npm-mod-install-fail.js
npm WARN using --force I sure hope you know what you are doing.
nodebb-plugin-import-ubb@0.0.4 node_modules/nodebb-plugin-import-ubb
├── fs-extra@0.8.1 (jsonfile@1.1.1, rimraf@2.2.8, ncp@0.4.2, mkdirp@0.3.5)
├── node-persist@0.0.1
└── mysql@2.0.1 (require-all@0.0.3, readable-stream@1.1.13, bignumber.js@1.0.1)





MODULE: nodebb-plugin-import-ubb@0.0.4

RESOLVED PATH OF THE MAIN SCRIPT: >>>> /Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/node_modules/nodebb-plugin-import-ubb/lib/export.js

package.json ==> { main: ./lib/export.js, version: 0.0.4 }





unbuild nodebb-plugin-import-ubb@0.0.4
npm WARN using --force I sure hope you know what you are doing.
nodebb-plugin-import-ubb@0.1.0 node_modules/nodebb-plugin-import-ubb
├── underscore@1.6.0
├── async@0.9.0
├── marked@0.3.2
└── mysql@2.4.3 (require-all@0.0.8, bignumber.js@1.4.0, readable-stream@1.1.13)





MODULE: git://github.com/akhoury/nodebb-plugin-import-ubb#master

RESOLVED PATH OF THE MAIN SCRIPT: >>>> /Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/node_modules/nodebb-plugin-import-ubb/lib/export.js

package.json ==> { main: ./index.js, version: 0.1.0 }







Why is it trying to execute the old main script?? even though it was replaced by a new module, scroll up the logs compare both attempts.



/Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/test-mod-reload.js:69
                throw e;
                      ^
Error: ENOENT, no such file or directory '/Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/node_modules/nodebb-plugin-import-ubb/lib/export.js'
    at Object.fs.openSync (fs.js:427:18)
    at Object.fs.readFileSync (fs.js:284:15)
    at Object.Module._extensions..js (module.js:473:44)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at reloadModule (/Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/test-mod-reload.js:26:12)
    at /Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/test-mod-reload.js:66:32
    at save (/Users/akhoury/code/akhoury-NodeBB/node_modules/nodebb-plugin-import/node_modules/npm/lib/install.js:338:12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment