diff --git a/lib/commands/install.js b/lib/commands/install.js index 67cffe7..ff5938d 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -69,7 +69,8 @@ exports.run = function (settings, args) { var a = argParse(args, { 'repository': {match: ['-r', '--repository'], value: true}, 'target_dir': {match: ['-d', '--package-dir'], value: true}, - 'baseurl': {match: ['-b', '--baseurl'], value: true} + 'baseurl': {match: ['-b', '--baseurl'], value: true}, + 'save': {match: ['-S', '--save'], value: false} }); var opt = a.options; @@ -117,6 +118,8 @@ exports.run = function (settings, args) { exports.extendOptions = function (proj_dir, settings, cfg, opt) { + opt.proj_dir = proj_dir; + if (!opt.target_dir) { if (cfg.jam && cfg.jam.packageDir) { opt.target_dir = path.resolve(proj_dir, cfg.jam.packageDir); @@ -159,7 +162,6 @@ exports.reinstallPackages = function (cfg, opt, callback) { if (err) { return logger.error(err); } - // TODO: write package.json if --save option provided project.updateRequireConfig(opt.target_dir, opt.baseurl, function (err) { if (err) { @@ -187,7 +189,6 @@ exports.installPackages = function (cfg, names, opt, callback) { if (err) { return callback(err); } - // TODO: write package.json if --save option provided project.updateRequireConfig(opt.target_dir, opt.baseurl, callback); }); }; @@ -406,7 +407,45 @@ exports.installRepo = function (name, range, opt, callback) { if (err) { return callback(err); } - exports.cpDir(name, v, from_cache, cdir, opt, callback); + if (opt.save) { + exports.cpDir(name, v, from_cache, cdir, opt, function(err) { + var package; + + if (err) { + return callback(err); + } + + package = path.resolve(opt.proj_dir, 'package.json'); + + fs.readFile(path.resolve(package), function(err, data) { + try { + data = JSON.parse(data.toString('utf8')); + } catch(e) { + err = e; + } + if (err) { + return callback(); + } + if (!data.dependencies && !data.jam) { + data.jam = {}; + } + // if jam namespace exists + if (data.jam) { + data.jam.dependencies = data.jam.dependencies || {}; + data.jam.dependencies[name] = v; + } else { + data.dependencies[name] = v; + } + + data = JSON.stringify(data, null, 2) + '\n'; + fs.writeFile(package, data, function(err) { + callback(err); + }); + }); + }); + } else { + exports.cpDir(name, v, from_cache, cdir, opt, callback); + } } ); }; diff --git a/package.json b/package.json index 4c553e7..40f7900 100644 --- a/package.json +++ b/package.json @@ -34,5 +34,8 @@ "bugs": {"url": "http://github.com/caolan/jam/issues"}, "bin": { "jam": "./bin/jam.js" + }, + "scripts": { + "test": "test/all.sh" } } diff --git a/test/integration/test-install-save.js b/test/integration/test-install-save.js new file mode 100644 index 0000000..b0e473c --- /dev/null +++ b/test/integration/test-install-save.js @@ -0,0 +1,116 @@ +/** + * Test description + * ================ + * + * Tests that jam install --save adds to package.json + * + * Starting with project with *ranged* deps in package.json + * - jam publish package-one @ 0.0.1 + * - jam publish package-two @ 0.0.1 + * - jam install package-one --save, test package.json updated + */ + + +var couchdb = require('../../lib/couchdb'), + logger = require('../../lib/logger'), + env = require('../../lib/env'), + utils = require('../utils'), + async = require('async'), + http = require('http'), + path = require('path'), + ncp = require('ncp').ncp, + fs = require('fs'), + _ = require('underscore'); + + +var pathExists = fs.exists || path.exists; + + +logger.clean_exit = true; + +// CouchDB database URL to use for testing +var TESTDB = process.env['JAM_TEST_DB'], + BIN = path.resolve(__dirname, '../../bin/jam.js'), + ENV = {JAM_TEST: 'true', JAM_TEST_DB: TESTDB}; + +if (!TESTDB) { + throw 'JAM_TEST_DB environment variable not set'; +} + +// remove trailing-slash from TESTDB URL +TESTDB = TESTDB.replace(/\/$/, ''); + + +exports.setUp = function (callback) { + // change to integration test directory before running test + this._cwd = process.cwd(); + process.chdir(__dirname); + + // recreate any existing test db + couchdb(TESTDB).deleteDB(function (err) { + if (err && err.error !== 'not_found') { + return callback(err); + } + // create test db + couchdb(TESTDB).createDB(callback); + }); +}; + +exports.tearDown = function (callback) { + // change back to original working directory after running test + process.chdir(this._cwd); + // delete test db + couchdb(TESTDB).deleteDB(callback); +}; + + +exports['project with ranged dependencies in package.json'] = { + + setUp: function (callback) { + this.project_dir = path.resolve(env.temp, 'jamtest-' + Math.random()); + // set current project to empty directory + ncp('./fixtures/project-rangedeps', this.project_dir, callback); + }, + + /* + tearDown: function (callback) { + var that = this; + // clear current project + //utils.myrimraf(that.project_dir, callback); + }, + */ + + 'publish, install, ls, remove': function (test) { + test.expect(1); + var that = this; + process.chdir(that.project_dir); + + async.series([ + async.apply( + utils.runJam, + ['publish', path.resolve(__dirname, 'fixtures', 'package-one')], + {env: ENV} + ), + async.apply( + utils.runJam, + ['publish', path.resolve(__dirname, 'fixtures', 'package-two')], + {env: ENV} + ), + async.apply(utils.runJam, ['install', 'package-one', '--save'], {env: ENV}), + function (cb) { + fs.readFile(path.resolve(that.project_dir, 'package.json'), function(err, data) { + data = JSON.parse(data); + + test.same(data.jam.dependencies, { + "package-one": "0.0.1", + "package-two": "<=0.0.2" + }); + cb(); + }); + } + ], + test.done); + } + +}; +