eslint: Add a rule to disallow using cockpit.all()

cockpit.all() is deprecated and should not be used in new code.

Add an eslint exception and a comment to all call sites for which using
Promise.all() is not yet possible (see previous commit).

Closes #10949
This commit is contained in:
Lars Karlitski 2019-01-11 09:32:25 +01:00 committed by Martin Pitt
parent f83c353d86
commit c5868236fb
20 changed files with 119 additions and 5 deletions

View File

@ -12,7 +12,7 @@
},
"sourceType": "module"
},
"plugins": ["flowtype", "react"],
"plugins": ["flowtype", "react", "cockpit"],
"rules": {
"indent": ["error", 4,
{
@ -44,7 +44,9 @@
"eqeqeq": "off",
"import/no-webpack-loader-syntax": "off",
"object-property-newline": "off",
"react/jsx-no-bind": "off"
"react/jsx-no-bind": "off",
"cockpit/no-cockpit-all": "error"
},
"globals": {
"require": false,

View File

@ -0,0 +1,16 @@
'use strict'
module.exports = {
rules: {
"no-cockpit-all": {
create: function(context) {
return {
MemberExpression(node) {
if (node.object.name === 'cockpit' && node.property.name === 'all')
context.report(node, 'Use Promise.all() instead of cockpit.all()');
}
};
}
}
}
};

View File

@ -0,0 +1,5 @@
{
"name": "eslint-plugin-cockpit",
"version": "0.0.1",
"main": "index.js"
}

View File

@ -53,6 +53,7 @@
"copy-webpack-plugin": "^4.5.2",
"css-loader": "^0.28.10",
"eslint": "^4.18",
"eslint-plugin-cockpit": "file:eslint-plugin-cockpit",
"eslint-config-standard": "^11.0.0",
"eslint-config-standard-react": "^6.0.0",
"eslint-loader": "^2.1.0",

View File

@ -87,6 +87,10 @@ PageContainerDetails.prototype = {
var prom = self.client.change_cpu_priority(self.container_id, self.cpu_priority.value);
if (self.client.info.MemoryLimit) {
mem = self.client.change_memory_limit(self.container_id, self.memory_limit.value);
// Can't use Promise.all() here, because dialog expects
// a promise with a progress() method (see pkg/lib/patterns.js)
// eslint-disable-next-line cockpit/no-cockpit-all
prom = cockpit.all(mem, prom);
}
$('#container-resources-dialog').dialog('promise', prom);

View File

@ -282,6 +282,10 @@ function Machines() {
mod = update_saved_machine(host, values);
if (call)
// Can't use Promise.all() here, because this promise is sometimes
// passed to the dialog() function from pkg/lib/patterns.js, which
// expects a promise with a progress() method
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all([call, mod]);
return mod;

View File

@ -601,6 +601,9 @@ export function unknownConnectionName(action, libvirtServiceName) {
connectionName => canLoggedUserConnectSession(connectionName, loggedUser))
.map(connectionName => dispatch(action(connectionName, libvirtServiceName)));
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(promises);
});
};

View File

@ -334,6 +334,10 @@ LIBVIRT_DBUS_PROVIDER = {
call(connectionName, storageVolPaths[i][0], 'org.libvirt.StorageVol', 'Delete', [0], TIMEOUT)
);
}
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(storageVolPathsPromises);
})
.then(() => {
@ -432,6 +436,9 @@ LIBVIRT_DBUS_PROVIDER = {
return dispatch => {
call(connectionName, '/org/libvirt/QEMU', 'org.libvirt.Connect', 'ListNetworks', [0], TIMEOUT)
.then(objPaths => {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(objPaths[0].map((path) => dispatch(getNetwork({connectionName, id:path}))));
})
.fail(ex => console.warn('GET_ALL_NETWORKS action failed:', JSON.stringify(ex)));
@ -444,6 +451,9 @@ LIBVIRT_DBUS_PROVIDER = {
return dispatch => {
call(connectionName, '/org/libvirt/QEMU', 'org.libvirt.Connect', 'ListStoragePools', [0], TIMEOUT)
.then(objPaths => {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(objPaths[0].map((path) => dispatch(getStoragePool({connectionName, id:path}))));
})
.fail(ex => console.warn('GET_ALL_STORAGE_POOLS action failed:', JSON.stringify(ex)));
@ -842,6 +852,9 @@ function doGetAllVms(dispatch, connectionName) {
dispatch(deleteUnlistedVMs(connectionName, [], objPaths[0]));
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(objPaths[0].map((path) => dispatch(getVm({connectionName, id:path}))));
})
.fail(ex => console.warn("ListDomains failed:", JSON.stringify(ex)));

View File

@ -200,6 +200,9 @@ LIBVIRT_PROVIDER = {
});
logDebug(`GET_ALL_STORAGE_POOLS: vmNames: ${JSON.stringify(storagePoolNames)}`);
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(storagePoolNames.map((name) => dispatch(getStoragePool({connectionName, name}))));
});
},
@ -460,7 +463,9 @@ function doGetAllVms (dispatch, connectionName) {
// remove undefined domains
dispatch(deleteUnlistedVMs(connectionName, vmNames));
// read VM details
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(vmNames.map((name) => dispatch(getVm({connectionName, name}))));
});
}

View File

@ -99,6 +99,9 @@ firewalld_service.addEventListener('changed', () => {
});
function fetchServiceInfos(services) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
var promises = cockpit.all(services.map(service => {
if (firewall.services[service])
return firewall.services[service];

View File

@ -2397,14 +2397,20 @@ PageNetworkInterface.prototype = {
var self = this;
function delete_connection_and_slaves(con) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(con.delete_(),
// eslint-disable-next-line cockpit/no-cockpit-all
cockpit.all(con.Slaves.map(function (s) {
return free_slave_connection(s);
})));
}
function delete_connections(cons) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(cons.map(delete_connection_and_slaves));
}

View File

@ -155,6 +155,9 @@ function doRefreshEvents(dispatch, getState) {
.forEach(id => promises.push(doRefreshTemplates(dispatch, getState, id)));
}
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
cockpit.all(promises)
.then(() => deferred.resolve())
.catch((r) => deferred.reject(r));

View File

@ -566,6 +566,9 @@ class OsUpdates extends React.Component {
let promises = transactions.map(transactionPath => PK.call(
transactionPath, "org.freedesktop.DBus.Properties", "Get", [PK.transactionInterface, "Role"]));
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
cockpit.all(promises)
.then(roles => {
// any transaction with UPDATE_PACKAGES role?

View File

@ -459,6 +459,9 @@ function init_model(callback) {
};
if (client.manager.SupportedFilesystems && client.manager.CanResize) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(client.manager.SupportedFilesystems.map(function (fs) {
return client.manager.CanFormat(fs).then(
function (canformat_result) {

View File

@ -58,6 +58,10 @@ class MDRaidSidebar extends React.Component {
action: function(vals) {
return utils.prepare_available_spaces(client, vals.disks).then(function() {
var paths = Array.prototype.slice.call(arguments);
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(paths.map(function(p) {
return mdraid.AddDevice(p, {});
}));
@ -268,6 +272,9 @@ export class MDRaidDetails extends React.Component {
// members.
function wipe_members() {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(client.mdraids_members[mdraid.path].map(member => member.Format('empty', { })));
}

View File

@ -444,6 +444,10 @@ export function prepare_available_spaces(client, spcs) {
return block_ptable.CreatePartition(spc.start, spc.size, "", "", { });
}
}
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(spcs.map(prepare));
}
@ -684,6 +688,9 @@ export function teardown_active_usage(client, usage) {
// condition upfront by reshuffling the data structures.
function unmount(mounteds) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(mounteds.map(function (m) {
if (m.fsys.MountPoints.length > 0)
return m.fsys.Unmount({});
@ -693,6 +700,9 @@ export function teardown_active_usage(client, usage) {
}
function mdraid_remove(members) {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(members.map(function (m) {
return m.mdraid.RemoveDevice(m.block.path, { wipe: { t: 'b', v: true } });
}));
@ -716,6 +726,9 @@ export function teardown_active_usage(client, usage) {
return vg.Delete({ 'tear-down': { t: 'b', v: true }
});
} else {
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(pvs.map(function (pv) {
return vg.RemoveDevice(pv.path, true, {});
}));
@ -726,6 +739,9 @@ export function teardown_active_usage(client, usage) {
handle_vg(p);
}
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all([ unmount(usage.raw.filter(function(use) { return use.usage == "mounted" })),
mdraid_remove(usage.raw.filter(function(use) { return use.usage == "mdraid-member" })),
pvol_remove(usage.raw.filter(function(use) { return use.usage == "pvol" }))

View File

@ -64,6 +64,10 @@ class VGroupSidebar extends React.Component {
action: function(vals) {
return utils.prepare_available_spaces(client, vals.disks).then(function() {
var paths = Array.prototype.slice.call(arguments);
// We can't use Promise.all() here until cockpit is able to dispatch es2015 promises
// https://github.com/cockpit-project/cockpit/issues/10956
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(paths.map(function(p) {
return vgroup.AddDevice(p, {});
}));

View File

@ -927,6 +927,10 @@ PageSystemInformationChangeHostname.prototype = {
var one = self.hostname_proxy.call("SetStaticHostname", [new_name, true]);
var two = self.hostname_proxy.call("SetPrettyHostname", [new_full_name, true]);
// We can't use Promise.all() here, because dialg expects a promise
// with a progress() method (see pkg/lib/patterns.js)
// eslint-disable-next-line cockpit/no-cockpit-all
$("#system_information_change_hostname").dialog("promise", cockpit.all([one, two]));
},
@ -1344,6 +1348,9 @@ PageSystemInformationChangeSystime.prototype = {
}));
}
// We can't use Promise.all() here, because dialg expects a promise
// with a progress() method (see pkg/lib/patterns.js)
// eslint-disable-next-line cockpit/no-cockpit-all
$("#system_information_change_systime").dialog("promise", cockpit.all(promises));
},

View File

@ -481,6 +481,10 @@ PageAccountsCreate.prototype = {
ex.target = "#accounts-create-user-name";
});
// Can't use Promise.all() here, because this promise is passed to
// dialog(), which expects a promise with a progress() method (see
// pkg/lib/patterns.js)
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(dfd.promise(), promise_password, promise_username);
},
@ -1414,6 +1418,10 @@ PageAccountSetPassword.prototype = {
}
});
// Can't use Promise.all() here, because this promise is passed to
// dialog(), which expects a promise with a progress() method (see
// pkg/lib/patterns.js)
// eslint-disable-next-line cockpit/no-cockpit-all
return cockpit.all(dfd.promise(), promise);
},

View File

@ -1409,7 +1409,7 @@ function factory() {
return result.promise.then(fulfilled, rejected, updated);
};
cockpit.all = function all(promises) {
cockpit.all = function all(promises) { // eslint-disable-line cockpit/no-cockpit-all
var deferred = cockpit.defer();
var counter = 0;
var results = [];
@ -4333,6 +4333,7 @@ function factory() {
if (self.user && self.is_superuser !== null) {
self.allowed = decide(self.user);
} else {
// eslint-disable-next-line cockpit/no-cockpit-all
cockpit.all(cockpit.user(), check_superuser())
.done(function (user, is_superuser) {
self.user = user;