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 all 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
4 changes: 3 additions & 1 deletion internal-tasks/subgrunt.js
@@ -1,11 +1,13 @@
'use strict';

var asyncLib = require('async');

module.exports = function(grunt) {

// Run sub-grunt files, because right now, testing tasks is a pain.
grunt.registerMultiTask('subgrunt', 'Run a sub-gruntfile.', function() {
var path = require('path');
grunt.util.async.forEachSeries(this.filesSrc, function(gruntfile, next) {
asyncLib.forEachSeries(this.filesSrc, function(gruntfile, next) {
grunt.log.write('Loading ' + gruntfile + '...');
grunt.util.spawn({
grunt: true,
Expand Down
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);
});
6 changes: 5 additions & 1 deletion lib/grunt.js
Expand Up @@ -2,6 +2,7 @@

// Nodejs libs.
var path = require('path');
var exit = require('exit');

// This allows grunt to require() .coffee files.
require('coffeescript/register');
Expand Down Expand Up @@ -37,6 +38,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 Expand Up @@ -142,7 +146,7 @@ grunt.tasks = function(tasks, options, done) {
done();
} else {
// Otherwise, explicitly exit.
util.exit(0);
exit(0);
}
}
});
Expand Down
10 changes: 6 additions & 4 deletions lib/grunt/config.js
@@ -1,6 +1,8 @@
'use strict';

var grunt = require('../grunt');
var _ = require('lodash');
var getobject = require('getobject');

// Get/set config data. If value was passed, set. Otherwise, get.
var config = module.exports = function(prop, value) {
Expand Down Expand Up @@ -30,7 +32,7 @@ config.getPropString = function(prop) {
config.getRaw = function(prop) {
if (prop) {
// Prop was passed, get that specific property's value.
return grunt.util.namespace.get(config.data, config.getPropString(prop));
return getobject.get(config.data, config.getPropString(prop));
} else {
// No prop was passed, return the entire config.data object.
return config.data;
Expand Down Expand Up @@ -69,12 +71,12 @@ config.process = function(raw) {

// Set config data.
config.set = function(prop, value) {
return grunt.util.namespace.set(config.data, config.getPropString(prop), value);
return getobject.set(config.data, config.getPropString(prop), value);
};

// Deep merge config data.
config.merge = function(obj) {
grunt.util._.merge(config.data, obj);
_.merge(config.data, obj);
return config.data;
};

Expand All @@ -89,7 +91,7 @@ config.init = function(obj) {
// exception (use this inside of a task).
config.requires = function() {
var p = grunt.util.pluralize;
var props = grunt.util.toArray(arguments).map(config.getPropString);
var props = _.toArray(arguments).map(config.getPropString);
var msg = 'Verifying propert' + p(props.length, 'y/ies') +
' ' + grunt.log.wordlist(props) + ' exist' + p(props.length, 's') +
' in config...';
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;
5 changes: 3 additions & 2 deletions lib/grunt/fail.js
@@ -1,6 +1,7 @@
'use strict';

var grunt = require('../grunt');
var exit = require('exit');

// The module to be exported.
var fail = module.exports = {};
Expand Down Expand Up @@ -45,7 +46,7 @@ function dumpStack(e) {
fail.fatal = function(e, errcode) {
writeln(e, 'fatal');
dumpStack(e);
grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.FATAL_ERROR);
exit(typeof errcode === 'number' ? errcode : fail.code.FATAL_ERROR);
};

// Keep track of error and warning counts.
Expand All @@ -61,7 +62,7 @@ fail.warn = function(e, errcode) {
if (!grunt.option('force')) {
dumpStack(e);
grunt.log.writeln().fail('Aborted due to warnings.');
grunt.util.exit(typeof errcode === 'number' ? errcode : fail.code.WARNING);
exit(typeof errcode === 'number' ? errcode : fail.code.WARNING);
}
};

Expand Down
15 changes: 8 additions & 7 deletions lib/grunt/file.js
Expand Up @@ -5,12 +5,13 @@ var grunt = require('../grunt');
// Nodejs libs.
var fs = require('fs');
var path = require('path');
var _ = require('lodash');

// The module to be exported.
var file = module.exports = {};

// External libs.
file.glob = require('glob');
var glob = file.glob = require('glob');
file.minimatch = require('minimatch');
file.findup = require('findup-sync');
var YAML = require('js-yaml');
Expand Down Expand Up @@ -42,7 +43,7 @@ var processPatterns = function(patterns, fn) {
// Filepaths to return.
var result = [];
// Iterate over flattened patterns array.
grunt.util._.flattenDeep(patterns).forEach(function(pattern) {
_.flattenDeep(patterns).forEach(function(pattern) {
// If the first character is ! it should be omitted
var exclusion = pattern.indexOf('!') === 0;
// If the pattern is an exclusion, remove the !
Expand All @@ -51,10 +52,10 @@ var processPatterns = function(patterns, fn) {
var matches = fn(pattern);
if (exclusion) {
// If an exclusion, remove matching files.
result = grunt.util._.difference(result, matches);
result = _.difference(result, matches);
} else {
// Otherwise add matching files.
result = grunt.util._.union(result, matches);
result = _.union(result, matches);
}
});
return result;
Expand Down Expand Up @@ -89,7 +90,7 @@ file.isMatch = function() {

// Return an array of all file paths that match the given wildcard patterns.
file.expand = function() {
var args = grunt.util.toArray(arguments);
var args = _.toArray(arguments);
// If the first argument is an options object, save those options to pass
// into the file.glob.sync method.
var options = grunt.util.kindOf(args[0]) === 'object' ? args.shift() : {};
Expand All @@ -101,7 +102,7 @@ file.expand = function() {
// Return all matching filepaths.
var matches = processPatterns(patterns, function(pattern) {
// Find all matching files for this pattern.
return file.glob.sync(pattern, options);
return glob.sync(pattern, options);
});
// Filter result set?
if (options.filter) {
Expand Down Expand Up @@ -134,7 +135,7 @@ var extDotRe = {

// Build a multi task "files" object dynamically.
file.expandMapping = function(patterns, destBase, options) {
options = grunt.util._.defaults({}, options, {
options = _.defaults({}, options, {
extDot: 'first',
rename: function(destBase, destPath) {
return path.join(destBase || '', destPath);
Expand Down
3 changes: 2 additions & 1 deletion lib/grunt/help.js
Expand Up @@ -4,6 +4,7 @@ var grunt = require('../grunt');

// Nodejs libs.
var path = require('path');
var _ = require('lodash');

// Set column widths.
var col1len = 0;
Expand All @@ -18,7 +19,7 @@ exports.initWidths = function() {
// Render an array in table form.
exports.table = function(arr) {
arr.forEach(function(item) {
grunt.log.writetableln(exports.widths, ['', grunt.util._.pad(item[0], col1len), '', item[1]]);
grunt.log.writetableln(exports.widths, ['', _.pad(item[0], col1len), '', item[1]]);
});
};

Expand Down