Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement deprecate API and deprecate APIs #1625

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 85 additions & 0 deletions lib/deprecations.js
@@ -0,0 +1,85 @@
var grunt = require('./grunt');
var deprecate = require('./grunt/deprecate');

var deprecations = [
{
obj: grunt.util,
property: '_',
message: 'grunt.util._ has been deprecated. Please install and require ' +
'"lodash" directly. https://www.npmjs.com/package/lodash'
},
{
obj: grunt.util,
property: 'async',
message: 'grunt.util.async has been deprecated. Please install and require ' +
'"async" directly. https://www.npmjs.com/package/async'
},
{
obj: grunt.util,
property: 'namespace',
message: 'grunt.util.namespace has been deprecated. Please install and ' +
'require "getobject" directly. https://www.npmjs.com/package/getobject'
},
{
obj: grunt.util,
property: 'hooker',
message: 'grunt.util.hooker has been deprecated. Please install and require ' +
'"hooker" directly. https://www.npmjs.com/package/hooker'
},
{
obj: grunt.util,
property: 'exit',
message: 'grunt.util.exit has been deprecated. Please install and require ' +
'"exit" directly. https://www.npmjs.com/package/exit'
},
{
obj: grunt.util,
property: 'toArray',
message: 'grunt.util.toArray has been deprecated. Please install and ' +
'require "lodash.toarray" directly. https://www.npmjs.com/package/lodash.toarray'
},
{
obj: grunt.util,
property: 'repeat',
message: 'grunt.util.repeat has been deprecated. Please use ' +
'`new Array(num + 1).join(str || \' \')` or another library.'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, didn't know this existed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grunt.util.repeat that is

},
{
obj: grunt.file,
property: 'glob',
message: 'grunt.file.glob has been deprecated. Please install and require ' +
'"glob" directly. https://www.npmjs.com/package/glob'
},
{
obj: grunt.file,
property: 'minimatch',
message: 'grunt.file.minimatch has been deprecated. Please install and ' +
'require "minimatch" directly. https://www.npmjs.com/package/minimatch'
},
{
obj: grunt.file,
property: 'findup',
message: 'grunt.file.findup has been deprecated. Please install and require ' +
'"findup-sync" directly. https://www.npmjs.com/package/findup-sync'
},
{
obj: grunt.file,
property: 'readYAML',
message: 'grunt.file.readYAML has been deprecated. Please install and ' +
'require "js-yaml" directly. https://www.npmjs.com/package/js-yaml'
},
{
obj: grunt.file,
property: 'readJSON',
message: 'grunt.file.readJSON has been deprecated. Please use require("file.json") directly.'
},
{
obj: grunt,
property: 'event',
message: 'grunt.event has been deprecated. Please install and require ' +
'"eventemitter2" directly. https://www.npmjs.com/package/eventemitter2'
},
];
deprecations.forEach(function(item) {
deprecate(item.obj, item.property, item.message);
});
3 changes: 3 additions & 0 deletions lib/grunt.js
Expand Up @@ -37,6 +37,9 @@ var verbose = grunt.verbose = log.verbose;
grunt.package = require('../package.json');
grunt.version = grunt.package.version;

// Apply deprecations.
require('./deprecations');

// Expose specific grunt lib methods on grunt.
function gExpose(obj, methodName, newMethodName) {
grunt[newMethodName || methodName] = obj[methodName].bind(obj);
Expand Down
29 changes: 29 additions & 0 deletions lib/grunt/deprecate.js
@@ -0,0 +1,29 @@
var grunt = require('../grunt');

function deprecate(obj, property, message) {
var logged = false;
function warn() {
var hideDeprecation = grunt.option('hide-deprecations');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you look at grunt.option('hide-deprecations') at the top of deprecate and just return there if it's true?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it in the warn to try to catch later calls to grunt.option('hide-deprecations', true). So you could have the option to potentially hide warnings from other modules but not your own (prevent your team from using deprecated APIs but can't fix deprecations in other APIs).

But I might be complicating it unnecessarily, let me know and I'll move it out.

if (!hideDeprecation && !logged) {
if (grunt.option('stack')) {
grunt.log.warn(Error(message).stack);
} else {
grunt.log.warn(message);
}
logged = true;
}
}
var orig = obj[property];
Object.defineProperty(obj, property, {
enumerable: true,
configurable: true,
set: function() {
warn();
},
get: function() {
warn();
return orig;
}
});
}
module.exports = deprecate;
66 changes: 66 additions & 0 deletions test/grunt/deprecate_test.js
@@ -0,0 +1,66 @@
'use strict';

var grunt = require('../../lib/grunt');
var deprecate = require('../../lib/grunt/deprecate');

exports.deprecate = {
setUp: function(done) {
this.oldGruntLogWarn = grunt.log.warn;
this.oldHideDeprecations = grunt.option('hide-deprecations');
this.oldStack = grunt.option('stack');
grunt.option('hide-deprecations', false);
grunt.option('stack', false);
var api = {val: function() {}};
var util = {api: api};
this.fixture = {util: util};
done();
},
tearDown: function(done) {
this.fixture = null;
grunt.log.warn = this.oldGruntLogWarn;
grunt.option('hide-deprecations', this.oldHideDeprecations);
grunt.option('stack', this.oldStack);
done();
},
'deprecate warning on get': function(test) {
test.expect(1);
grunt.log.warn = function(message) {
test.equal(message, 'this api is deprecated', 'grunt.log.warn should have got the deprecation message when getting a deprecated api.');
test.done();
};
deprecate(this.fixture.util, 'api', 'this api is deprecated');
this.fixture.util.api.val();
},
'deprecate warning on set': function(test) {
test.expect(1);
grunt.log.warn = function(message) {
test.equal(message, 'this api is deprecated', 'grunt.log.warn should have got the deprecation message when setting a deprecated api.');
test.done();
};
deprecate(this.fixture.util, 'api', 'this api is deprecated');
this.fixture.util.api = {};
},
'hide deprecations': function(test) {
test.expect(1);
grunt.option('hide-deprecations', true);
grunt.log.warn = function(message) {
test.equal(message, 'did not show deprecation message', 'grunt.log.warn should not have displayed a deprecation message with hide-deprecations enabled.');
test.done();
};
deprecate(this.fixture.util, 'api', 'this api is deprecated');
this.fixture.util.api.val();
grunt.log.warn('did not show deprecation message');
},
'deprecations with stack trace': function(test) {
test.expect(2);
grunt.option('stack', true);
grunt.log.warn = function(message) {
message = message.split('\n');
test.equal(message[0], 'Error: this api is deprecated', 'grunt.log.warn should not have displayed a deprecation message with stack trace.');
test.ok(message.length > 1);
test.done();
};
deprecate(this.fixture.util, 'api', 'this api is deprecated');
this.fixture.util.api.val();
},
};