I recently ran up against this same issue: programmatically setting grunt options and running tasks multiple times from within a single parent task. As @Raphael Verger mentions, this is not possible, as grunt.task.run defers the running of the task until the current task is finished:
grunt.option('color', 'red');
grunt.task.run(['logColor']);
grunt.option('color', 'blue');
grunt.task.run(['logColor']);
Will result in the color blue being logged twice.
After some fiddling, I came up with a grunt task that allows dynamically specifying a different option/config for each sub-task to be run. I've published the task as grunt-galvanize. Here's how it works:
var galvanizeConfig = [
{options: {color: 'red'}, configs: {}},
{options: {color: 'blue'}, configs: {}}
];
grunt.option('galvanizeConfig', galvanizeConfig);
grunt.task.run(['galvanize:log']);
This will log red then blue, as desired by running the log task with each of the options/configs specified in galvanizeConfig.