diff --git a/lib/debuglet.js b/lib/debuglet.js index a39a9308..64a582ca 100644 --- a/lib/debuglet.js +++ b/lib/debuglet.js @@ -25,7 +25,6 @@ var semver = require('semver'); var v8debugapi = require('./v8debugapi.js'); var DebugletApi = require('./debugletapi.js'); var scanner = require('./scanner.js'); -var uid = require('./uid.js'); var Logger = require('@google/cloud-diagnostics-common').logger; var StatusMessage = require('./apiclasses.js').StatusMessage; @@ -90,7 +89,12 @@ Debuglet.prototype.start = function() { that.emit('error', new Error('No package.json found.')); return; } - scanner.scan(that.config_.workingDirectory, function(err, hash, fileStats) { + var id; + if (process.env.GAE_MINOR_VERSION) { + id = 'GAE-' + process.env.GAE_MINOR_VERSION; + } + scanner.scan(!!id, that.config_.workingDirectory, + function(err, fileStats, hash) { if (err) { that.logger_.error('Error scanning the filesystem.', err); that.emit('error', err); @@ -98,7 +102,7 @@ Debuglet.prototype.start = function() { } that.v8debug_ = v8debugapi.create(that.logger_, that.config_, fileStats); - var id = uid.get(hash); + id = id || hash; that.logger_.info('Unique ID for this Application: ' + id); diff --git a/lib/scanner.js b/lib/scanner.js index a513986d..64a47804 100644 --- a/lib/scanner.js +++ b/lib/scanner.js @@ -25,13 +25,13 @@ module.exports = { scan: scan }; -function scan(baseDir, callback) { +function scan(shouldHash, baseDir, callback) { findJSFiles(baseDir, function(err, fileList) { if (err) { callback(err); return; } - computeStats(fileList, callback); + computeStats(fileList, shouldHash, callback); }); } @@ -40,36 +40,43 @@ function scan(baseDir, callback) { * based on the contents. * * @param {!Array} fileList array of filenames - * @param {!function(?Error, string, Object)} callback error-back style callback + * @param {Boolean} shouldHash whether a hash should be computed + * @param {!function(?Error, ?string, Object)} callback error-back style callback * returning the hash-code and an object containing file statistics. */ -function computeStats(fileList, callback) { +function computeStats(fileList, shouldHash, callback) { var pending = fileList.length; // return a valid, if fake, result when there are no js files to hash. if (pending === 0) { - callback(null, 'EMPTY-no-js-files', {}); + callback(null, {}, 'EMPTY-no-js-files'); return; } var hashes = []; var statistics = {}; fileList.forEach(function(filename) { - stats(filename, function(err, fileStats) { + stats(filename, shouldHash, function(err, fileStats) { if (err) { callback(err); return; } pending--; - hashes.push(fileStats.hash); + if (shouldHash) { + hashes.push(fileStats.hash); + } statistics[filename] = fileStats; if (pending === 0) { - // Sort the hashes to get a deterministic order as the files may not - // be in the same order each time we scan the disk. - var buffer = hashes.sort().join(); - var sha1 = crypto.createHash('sha1').update(buffer).digest('hex'); - callback(null, 'SHA1-' + sha1, statistics); + var hash; + if (shouldHash) { + // Sort the hashes to get a deterministic order as the files may not + // be in the same order each time we scan the disk. + var buffer = hashes.sort().join(); + var sha1 = crypto.createHash('sha1').update(buffer).digest('hex'); + hash = 'SHA1-' + sha1; + } + callback(null, statistics, hash); } }); }); @@ -126,11 +133,15 @@ function findJSFiles(baseDir, callback) { /** * Compute a sha hash for the given file and record line counts along the way. * @param {string} filename + * @param {Boolean} shouldHash whether a hash should be computed * @param {function} cb errorback style callback which returns the sha string * @private */ -function stats(filename, cb) { - var shasum = crypto.createHash('sha1'); +function stats(filename, shouldHash, cb) { + var shasum; + if (shouldHash) { + shasum = crypto.createHash('sha1'); + } var s = fs.ReadStream(filename); var lines = 0; var byLine = s.pipe(split()); @@ -138,11 +149,16 @@ function stats(filename, cb) { cb(e); }); byLine.on('data', function(d) { - shasum.update(d); + if (shouldHash) { + shasum.update(d); + } lines++; }); byLine.on('end', function() { - var d = shasum.digest('hex'); + var d; + if (shouldHash) { + d = shasum.digest('hex'); + } cb(null, { hash: d, lines: lines}); }); } diff --git a/lib/uid.js b/lib/uid.js deleted file mode 100644 index 9eaa9d27..00000000 --- a/lib/uid.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - 'use strict'; - -/** - * Find a unique id that can be used to identify this application to the - * cloud debug server. The UID may be computed by either looking at the GAE - * or GKE environment (cheap) or, if running locally using a hash of the - * contents of your js files. - * - * @param {string} baseDir top level with package.json - * @param {string} hash a hash of filesystem rooted at the working directory - */ -module.exports.get = function (hash) { - // Running on Google App Engine? - if (process.env.GAE_MINOR_VERSION) { - return 'GAE-' + process.env.GAE_MINOR_VERSION; - } - - // Running on Google Container Engine? - // TODO: check the Kubernetes API - - return hash; -}; diff --git a/test/standalone/test-duplicate-expressions.js b/test/standalone/test-duplicate-expressions.js index 03df7574..3c04b5f9 100644 --- a/test/standalone/test-duplicate-expressions.js +++ b/test/standalone/test-duplicate-expressions.js @@ -47,7 +47,7 @@ describe('v8debugapi', function() { beforeEach(function(done) { if (!api) { - scanner.scan(config.workingDirectory, function(err, hash, fileStats) { + scanner.scan(true, config.workingDirectory, function(err, fileStats, hash) { assert(!err); api = v8debugapi.create(logger, config, fileStats); assert.ok(api, 'should be able to create the api'); diff --git a/test/test-scanner.js b/test/test-scanner.js index 3df67a68..9746e5fd 100644 --- a/test/test-scanner.js +++ b/test/test-scanner.js @@ -30,14 +30,14 @@ describe('scanner', function() { describe('scan', function() { it('should complain when called without a path', function(done) { - scanner.scan(null, function(err) { + scanner.scan(true, null, function(err) { assert.ok(err); done(); }); }); it('should error when called on a bad path', function(done) { - scanner.scan('./this directory does not exist', + scanner.scan(true, './this directory does not exist', function(err) { assert(err); done(); @@ -46,10 +46,10 @@ describe('scanner', function() { it('should return the same hash if the files don\'t change', function(done) { - scanner.scan(process.cwd(), function(err1, hash1, filesStats1) { + scanner.scan(true, process.cwd(), function(err1, filesStats1, hash1) { var files1 = Object.keys(filesStats1); assert.ifError(err1); - scanner.scan(process.cwd(), function(err2, hash2, filesStats2) { + scanner.scan(true, process.cwd(), function(err2, filesStats2, hash2) { var files2 = Object.keys(filesStats2); assert.ifError(err2); assert.deepEqual(files1.sort(), files2.sort()); @@ -59,8 +59,17 @@ describe('scanner', function() { }); }); + it('should return undefined hash if shouldHash is false', + function(done) { + scanner.scan(false, process.cwd(), function(err, filesStats, hash) { + assert.ifError(err); + assert(!hash); + done(); + }); + }); + it('should work with relative paths', function(done) { - scanner.scan(fixtureDir, function(err, hash, fileStats) { + scanner.scan(true, fixtureDir, function(err, fileStats, hash) { var files = Object.keys(fileStats); assert.ifError(err); assert.ok(hash); @@ -71,7 +80,7 @@ describe('scanner', function() { it('should return a valid hash even when there are no javascript files', function(done) { - scanner.scan(fixture('nojs'), function(err, hash, fileStats) { + scanner.scan(true, fixture('nojs'), function(err, fileStats, hash) { var files = Object.keys(fileStats); assert.ifError(err); assert.ok(hash); @@ -83,12 +92,12 @@ describe('scanner', function() { it('should return a different hash if the files contents change', function(done) { fs.writeFileSync(fixture('tmp.js'), '1 + 1'); - scanner.scan(fixtureDir, function(err1, hash1, filesStats1) { + scanner.scan(true, fixtureDir, function(err1, filesStats1, hash1) { var files1 = Object.keys(filesStats1); assert.ifError(err1); assert.ok(hash1); fs.writeFileSync(fixture('tmp.js'), '1 + 2'); - scanner.scan(fixtureDir, function(err2, hash2, filesStats2) { + scanner.scan(true, fixtureDir, function(err2, filesStats2, hash2) { var files2 = Object.keys(filesStats2); assert.ifError(err2); assert.ok(hash2); @@ -102,19 +111,19 @@ describe('scanner', function() { it('should return an updated file list when file list changes', function(done) { - scanner.scan(fixtureDir, function(err1, hash1, fileStats1) { + scanner.scan(true, fixtureDir, function(err1, fileStats1, hash1) { var files1 = Object.keys(fileStats1); assert.ifError(err1); assert.ok(hash1); fs.writeFileSync(fixture('tmp.js'), ''); // empty. - scanner.scan(fixtureDir, function(err2, hash2, fileStats2) { + scanner.scan(true, fixtureDir, function(err2, fileStats2, hash2) { var files2 = Object.keys(fileStats2); assert.ifError(err2); assert.ok(hash2); assert.notStrictEqual(hash1, hash2); assert.ok(files1.length === files2.length - 1); fs.unlinkSync(fixture('tmp.js')); - scanner.scan(fixtureDir, function(err3, hash3, fileStats3) { + scanner.scan(true, fixtureDir, function(err3, fileStats3, hash3) { var files3 = Object.keys(fileStats3); assert.ifError(err3); assert.ok(hash3); diff --git a/test/test-uid.js b/test/test-uid.js deleted file mode 100644 index 193df828..00000000 --- a/test/test-uid.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - 'use strict'; - -var assert = require('assert'); - -describe('uid', function() { - var uid = require('../lib/uid.js'); - - it('should return a GAE hash when GAE_MINOR_VERSION is set', function() { - var test_gae_minor_version = '123456-test'; - process.env.GAE_MINOR_VERSION = test_gae_minor_version; - var result = uid.get('testHash'); - assert.strictEqual(result, 'GAE-' + test_gae_minor_version); - }); - - it('should return a full file-contents based hash otherwise', function() { - delete process.env.GAE_MINOR_VERSION; - var result = uid.get('testHash'); - assert.ok(result); - assert.strictEqual(false, /^(GAE|GKE)-/.test(result)); - }); -}); diff --git a/test/test-v8debugapi.js b/test/test-v8debugapi.js index 7a57a5e1..5db49508 100644 --- a/test/test-v8debugapi.js +++ b/test/test-v8debugapi.js @@ -46,7 +46,7 @@ describe('v8debugapi', function() { beforeEach(function(done) { if (!api) { - scanner.scan(config.workingDirectory, function(err, hash, fileStats) { + scanner.scan(true, config.workingDirectory, function(err, fileStats, hash) { assert(!err); api = v8debugapi.create(logger, config, fileStats); assert.ok(api, 'should be able to create the api');