Project

General

Profile

Paste
Download (22.9 KB) Statistics
| Branch: | Revision:

root / .drush / drush_make / drush_make.download.inc @ master

1
<?php
2
// $Id: drush_make.download.inc,v 1.1.2.87 2010/09/06 15:54:23 dmitrig01 Exp $
3

    
4
function drush_make_download_factory($type, $name, $download, $download_location) {
5
  $function = 'drush_make_download_' . $type;
6
  if (function_exists($function)) {
7
    return $function($name, $download, $download_location);
8
  }
9
  else {
10
    return FALSE;
11
  }
12
}
13

    
14
function drush_make_download_cvs($name, $download, $download_location) {
15
  if (!empty($download['module'])) {
16
    if (drush_get_option('working-copy')) {
17
      if ($download['module'] == 'drupal') {
18
        $download['root'] = ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal";
19
      }
20
      elseif (isset($_ENV['CVSROOT'])) {
21
        $download['root'] = trim($_ENV['CVSROOT']);
22
      }
23
      else {
24
        drush_log(dt('Please set the CVSROOT variable in your shell environment when using the --working-copy option.'), 'ok');
25
      }
26
    }
27
    // Fallback to anonymous @ cvs.drupal.org
28
    if (!isset($download['root'])) {
29
      $download['root'] = ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib";
30
    }
31
  
32
    // Checkout or export the module. CVS can't use absolute paths for named
33
    // directories, so change into the directory just above the final
34
    // destination for the checkout. 
35
    $cd_to_directory = dirname($download_location);
36
    $destination_directory = basename($download_location);
37
  
38
    $command = 'cvs -d%s ' . (drush_get_option('working-copy') ? 'checkout' : 'export') . ' -d%s';
39
    $args = array($download['root'], $destination_directory);
40
    if (isset($download['revision'])) {
41
      $command .= ' -r %s';
42
      $args[] = $download['revision'];
43
    }
44
    if (isset($download['date'])) {
45
      $command .= ' -D %s';
46
      $args[] = $download['date'];
47
    }
48
    $args[] = $download['module'];
49
    $command .= ' %s';
50
  
51
    array_unshift($args, $command);
52
    array_unshift($args, dirname($download_location));
53
    if (call_user_func_array('drush_shell_cd_and_exec', $args)) {
54
       drush_log(dt('%project downloaded from %module.', array('%project' => $name, '%module' => $download['module'])), 'ok');
55
      return $download_location;
56
    }
57
  }
58
  else {
59
    $download['module'] = dt("unspecified module");
60
  }
61
  drush_make_error('DOWNLOAD_ERROR', dt('Unable to download %project from %root %module.', array('%project' => $name, '%root' => $download['root'], '%module' => $download['module'])));
62
  return FALSE;
63
}
64

    
65
function drush_make_download_file($name, $download, $download_location) {
66
  if ($filename = _drush_make_download_file($download)) {
67
    drush_log(dt('%project downloaded from %url.', array('%project' => $name, '%url' => $download['url'])), 'ok');
68
    return drush_make_download_file_unpack($filename, $download_location);
69
  }
70
  drush_make_error('DOWNLOAD_ERROR', dt('Unable to download %project from %url.', array('%project' => $name, '%url' => $download['url'])));
71
  return FALSE;
72
}
73

    
74
function _drush_make_download_file($download) {
75
  // Static variable to keep track of whether to use curl or wget.
76
  static $download_mechanism;
77

    
78
  $tmp_path = drush_make_tmp();
79
  $filename = FALSE;
80
  if (is_string($download)) {
81
    $download = array('url' => $download);
82
  }
83
  if (!isset($download['request_type'])) {
84
    $download['request_type'] = 'get';
85
  }
86
  if (!empty($download['url'])) {
87
    $url = $download['url'];
88
    if (drush_get_context('DRUSH_SIMULATE')) {
89
      $filename = t('file');
90
    }
91
    else {
92
      // For first try or if wget was detected already, try using wget 
93
      // for downloading.
94
      $success = FALSE;
95
      $download_path = $tmp_path . '/__download__';
96
      drush_make_mkdir($download_path);
97

    
98
      if (!isset($download_mechanism) || $download_mechanism == 'curl') {
99
        $header_file = $tmp_path . '/__header__';
100
        drush_shell_exec("ls %s", $download_path);
101
        $files = drush_shell_exec_output();
102
        if ($download['request_type'] == 'get' && drush_shell_cd_and_exec($download_path, 'curl -LOD %s %s', $header_file, $url)) {
103
          $download_mechanism = 'curl';
104
          $success = TRUE;
105
        }
106
        elseif ($download['request_type'] == 'post' && drush_shell_cd_and_exec($download_path, 'curl -d %s -LOD %s %s', $download['data'], $header_file, $url)) {
107
          $download_mechanism = 'curl';
108
          $success = TRUE;
109
        }
110

    
111
        drush_shell_exec("ls %s", $download_path);
112
        $files_new = drush_shell_exec_output();
113
        // Can't use list beacuse it's not guarenteed to be at offset 0.
114
        $diff = array_diff($files_new, $files);
115
        $filename = $tmp_path . '/__download__/' . array_shift($diff);
116
        // Determine the proper filename, or at least, the extension.
117
        $header = explode("\n", trim(str_replace("\r", '', file_get_contents($header_file))));
118
        $current_header = array();
119
        $headers = array();
120
        $first = TRUE;
121
        foreach ($header as $h) {
122
          if ($h == '') {
123
            $headers[] = $current_header;
124
            $current_header = array();
125
            $first = TRUE;
126
          }
127
          else {
128
            if (!$first) {
129
              list($name, $value) = explode(': ', $h, 2);
130
              $current_header[$name] = $value;
131
            }
132
            else {
133
              $first = FALSE;
134
            }
135
          }
136
        }
137
        if (!empty($current_header)) {
138
          $headers[] = $current_header;
139
        }
140
      }
141

    
142
      if (!isset($download_mechanism) || $download_mechanism == 'drush_make') {
143
        $retry = 5;
144
        $url = $download['url'];
145
        $filename = $download_path . '/__destination__';
146
        $request_type = strtoupper($download['request_type']);
147
        $data = (isset($download['data']) ? $download['data'] : '');
148
        $headers = array();
149
        while ($retry) {
150
          $result = drush_make_http_request($url, $filename, array(), $request_type, $data);
151
          switch ($result->code) {
152
            case 200: // OK
153
            case 304: // Not modified
154
              $retry = FALSE;
155
              break;
156
            case 301: // Moved permanently
157
            case 302: // Moved temporarily
158
            case 307: // Moved temporarily
159
              $retry--;
160

    
161
              if ($retry) {
162
                $url = $result->headers['Location'];
163
                $request_type = 'GET';
164
                $data = NULL;
165
              }
166
              break;
167
            default:
168
              // Oops, error.
169
              drush_make_error('BUILD_ERROR', $result->message);
170
              return;
171
          }
172
          $download_mechanism = 'drush_make';
173
          $headers[] = $result->headers;
174
          $success = TRUE;
175
        }
176
      }
177

    
178
      if (!$success) {
179
        return;
180
      }
181
      // Much more useful in reverse order.
182
      $headers = array_reverse($headers);
183
      $content_type = '';
184
      $file = '';
185
      foreach ($headers as $header) {
186
        if (isset($header['Location'])) {
187
          $file = basename($header['Location']);
188
          break;
189
        }
190
      }
191
      if (isset($headers[0]['Content-Disposition'])) {
192
        $parts = explode(';', $headers[0]['Content-Disposition']);
193
        foreach ($parts as $part) {
194
          list($name, $value) = explode('=', $part, 2);
195
          if ($inner_parts[0] == 'filename') {
196
            $file = $value;
197
            break;
198
          }
199
        }
200
      }
201
      if (isset($headers[0]['Content-Type'])) {
202
        // These still need finalizing.
203
        switch ($headers[0]['Content-Type']) {
204
          case 'application/zip':
205
            $content_type = 'zip';
206
            break;
207
          case 'application/x-gzip':
208
            $content_type = 'tar.gz';
209
            break;
210
          case 'application/x-tar':
211
            $content_type = 'tar';
212
            break;
213
        }
214
      }
215
      if (!$file) {
216
        $file = basename($url);
217
      }
218
      if ($content_type) {
219
        $file .= '.' . $content_type;
220
      }
221
      drush_shell_exec('mv %s %s', $filename, $tmp_path . '/' . $file);
222
      drush_shell_exec('rm -f %s', $tmp_path . '/__header__');
223
      drush_shell_exec('rm -rf %s', $tmp_path . '/__download__');
224
      return $tmp_path . '/' . $file;
225
    }
226
  }
227
  return FALSE;
228
}
229

    
230
function drush_make_download_file_unpack($filename, $download_location) {
231
  $extension = array_pop(explode('.', $filename));
232
  $gzip = FALSE;
233
  switch ($extension) {
234
    case 'gz':
235
    case 'tgz':
236
      // I'd like to just use tar -z, but apparently it breaks on windoze. Why do they always have to ruin everything?
237
      drush_make_download_file_unpack_gzip($filename, $download_location);
238
      break;
239
    case 'tar':
240
      drush_make_download_file_unpack_tar($filename, $download_location);
241
      break;
242
    case 'zip':
243
      drush_make_download_file_unpack_zip($filename, $download_location);
244
      break;
245
    default:
246
      drush_make_error('DOWNLOAD_ERROR', dt('Unable to unpack %file', array('%file' => $filename)));
247
  }
248
}
249

    
250
function drush_make_download_file_unpack_tar($filename, $download_location) {
251
  $tmp_path = drush_make_tmp();
252
  // Tarbomb detection.
253
  drush_shell_exec('tar -tf %s', $filename);
254
  $lines = drush_shell_exec_output();
255
  if (!$lines) {
256
    return FALSE;
257
  }
258
  $directory = drush_make_download_file_protect_bomb($lines);
259
  if (!$directory) {
260
    drush_shell_exec('tar -x -C %s -f %s', $download_location, $filename);
261
  }
262
  else {
263
    list($main_directory) = array_reverse(explode('/', $download_location));
264
    drush_make_mkdir($tmp_path . '/__unzip__');
265
    drush_shell_exec('tar -x -C %s -f %s', $tmp_path . '/__unzip__', $filename);
266
    if ($directory != $main_directory) {
267
      drush_shell_exec('mv %s %s', $tmp_path . '/__unzip__/' . $directory, $tmp_path . '/__unzip__/' . $main_directory);
268
    }
269
    drush_shell_exec('cp -Rf %s %s', $tmp_path . '/__unzip__/' . $main_directory, dirname($download_location));
270
    drush_shell_exec('rm -rf %s', $tmp_path . '/__unzip__');
271
  }
272

    
273
  // Remove the tarball.
274
  if (file_exists($filename)) {
275
    drush_shell_exec('rm %s', $filename);
276
  }
277
}
278

    
279
function drush_make_download_file_unpack_gzip($filename, $download_location) {
280
  // Find out where contents will end up. Retrieve last column of output using awk.
281
  drush_shell_exec("gzip --list %s | awk '{print $4;}'", $filename);
282
  $info = drush_shell_exec_output();
283
  if ($info) {
284
    $info = array_pop($info);
285
    $matches = array();
286
    preg_match('/[a-zA-Z0-9.\-_,]*.tar/', $info, $matches);
287
    if (isset($matches[0])) {
288
      $file = dirname($filename) . '/' . $matches[0];
289
      // Unzip it and then delete the tar file.
290
      drush_shell_exec('gzip -d %s', $filename);
291
      $filename = $file;
292
      return drush_make_download_file_unpack_tar($filename, $download_location);
293
    }
294
  }
295
  drush_make_error('PACKAGE_ERROR', dt('Could not retrieve package information for %filename.', array('%filename' => $filename)));
296
  return;
297
}
298

    
299
function drush_make_download_file_unpack_zip($filename, $download_location) {
300
  $tmp_path = drush_make_tmp();
301
  // Find the main directory in the zip file.
302
  drush_shell_exec("unzip -l %s", $filename);
303
  $info = drush_shell_exec_output();
304
  if ($info) {
305
    foreach ($info as $line) {
306
      $matches = array();
307
      preg_match('/^\s+[0-9]+\s+[0-9-]+\s+[0-9:]+\s+(.*)$/', $line, $matches);
308
      if (isset($matches[1])) {
309
        $lines[] = $matches[1];
310
      }
311
    }
312
    $directory = drush_make_download_file_protect_bomb($lines);
313
    if ($directory) {
314
      list($main_directory) = array_reverse(explode('/', $download_location));
315
      if ($main_directory == $directory) {
316
        // Directory names match up.
317
        drush_shell_exec("unzip %s -d %s", $filename, dirname($download_location));
318
      }
319
      else {
320
        // Directories don't match up. Use cp.
321
        drush_make_mkdir($tmp_path . '/__unzip__');
322
        drush_shell_exec('unzip %s -d %s', $filename, $tmp_path . '/__unzip__');
323
        if (file_exists($filename)) {
324
          drush_shell_exec('rm %s', $filename);
325
        }
326
        if (is_dir($tmp_path . '/__unzip__' . $directory . '/__MACOSX')) {
327
          drush_shell_exec('rm -rf %s', $tmp_path . '/__unzip__' . $directory . '/__MACOSX');
328
        }
329
        drush_shell_exec('mv %s %s', $tmp_path . '/__unzip__/' . $directory, $tmp_path . '/__unzip__/' . $main_directory);
330
        drush_shell_exec('cp -Rf %s %s', $tmp_path . '/__unzip__/' . $main_directory, dirname($download_location));
331
        drush_shell_exec('rm -rf %s', $tmp_path . '/__unzip__');
332
      }
333
    }
334
    else {
335
      // It's a bomb, so we can just unpack it right at its destination.
336
      drush_shell_exec("unzip %s -d %s", $filename, $download_location);
337
    }
338
    if (file_exists($filename)) {
339
      drush_shell_exec('rm %s', $filename);
340
    }
341
    if (is_dir($download_location . '/__MACOSX')) {
342
      drush_shell_exec('rm -rf %s', $download_location . '/__MACOSX');
343
    }
344
  }
345
  else {
346
    drush_make_error('PACKAGE_ERROR', dt('Could not retrieve package information for %filename.', array('%filename' => $filename)));
347
  }
348
  return;
349
}
350

    
351
function drush_make_download_file_protect_bomb($lines) {
352
  $directory = FALSE;
353
  foreach ($lines as $line) {
354
    if (strpos($line, '/') !== FALSE) {
355
      list($dir) = explode('/', $line);
356
      if (!$directory) {
357
        $directory = $dir;
358
      }
359
      elseif ($dir != $directory) {
360
        // More than one root-level item detected. We're not safe - BOMB!
361
        return FALSE;
362
      }
363
    }
364
  }
365
  if (!$directory) {
366
    // If we didn't come upon anything, that is to say, they were only
367
    // root-level files, it's a bomb.
368
    return FALSE;
369
  }
370
  return $directory;
371
}
372

    
373

    
374
// Backwards compatibility.
375
function drush_make_download_get($name, $download, $download_location) {
376
  return drush_make_download_file($name, $download, $download_location);
377
}
378

    
379
function drush_make_download_post($name, $download, $download_location) {
380
  $download['request_type'] = 'post';
381
  $download['data'] = $download['post_data'];
382
  return drush_make_download_file($name, $download, $download_location);
383
}
384

    
385
function drush_make_download_git($name, $download, $download_location) {
386
  $tmp_path = drush_make_tmp();
387
  $wc = drush_get_option('working-copy');
388

    
389
  // check if branch option is set in info file, otherwise set default to master branch
390
  $download['branch'] = isset($download['branch']) ? $download['branch'] : 'master';
391
  // check if tag option is set in info file, otherwise we set it to false
392
  $download['tag'] = isset($download['tag']) ? $download['tag'] : FALSE;
393
  // check if specific revision is set in info file
394
  $download['revision'] = isset($download['revision']) ? $download['revision'] : FALSE;
395

    
396
  // only progress if we have a download url...
397
  if (!empty($download['url'])) {
398
    // split the given download url into pieces
399
    $url_array = array();
400

    
401
    // Get the protocol, site and resource parts of the URL
402
    // original url = http://example.com/blog/index?name=foo
403
    // protocol = http://
404
    // site = example.com/
405
    // resource = blog/index?name=foo
406
    $regex = '#^(.*?//)*([\w\.\d]*)(:(\d+))*(/*)(.*)$#';
407
    $matches = array();
408
    preg_match($regex, $download['url'], $matches);
409

    
410
    // Assign the matched parts of url to the result array
411
    $url_array['protocol'] = $matches[1];
412
    $url_array['port']     = $matches[4];
413
    $url_array['host']     = $matches[2];
414
    $url_array['resource'] = $matches[6];
415

    
416
    // clean up the site portion by removing the trailing /
417
    $url_array['host'] = preg_replace('#/$#', '', $result['host']);
418

    
419
    // clean up the protocol portion by removing the trailing ://
420
    $url_array['protocol'] = preg_replace('#://$#', '', $result['protocol']);
421

    
422
    if (empty($url_array['protocol'])) {
423
      // If protocol is not given, assume an SSH URL.
424
      $url = $download['url'];
425
    }
426
    else {
427
      // build url for git clone to support different protocols
428
      // currently all protocols seems to use the same url schema
429
      switch ($url_array['protocol']) {
430
        case 'git':
431
          // github uses two different urls, working copy urls using scp format
432
          // git@domain:repo export url format are git://domain/repo
433
          if ($wc) {
434
            // working copy is set
435
            $url = 'git@'. $url_array['host'] .':'. $url_array['resource'];
436
            break;
437
          }
438
        case 'ssh':
439
        case 'http':
440
        case 'https':
441
        case 'ftp':
442
        case 'ftps':
443
        case 'rsync':
444
        case 'file':
445
          // @TODO: implement port & user options
446
          $url = $url_array['protocol'] .'://'. $url_array['host'] .'/'. $url_array['resource'];
447
          break;
448

    
449
        default:
450
          drush_make_error('DOWNLOAD_ERROR', dt('unknown protocol @protocol in %project', array('@protocol' => $url_array['protocol'], '%project' => $name)));
451
          return false;
452
      }
453
    }
454

    
455
    $tmp_location = $tmp_path . '/__git__/' . basename($download_location);
456

    
457
    drush_make_mkdir($tmp_path . '/__git__/');
458

    
459
    // clone the given repository
460
    if (drush_shell_exec("git clone %s %s", $url, $tmp_location)) {
461
      drush_log(dt('%project cloned from %url.', array('%project' => $name, '%url' => $url)), 'ok');
462

    
463
      // GIT Checkout only work on a ready cloned repo. So we switch to branch or to tag (only if we have no branch) after cloneing.
464
      if ($download['branch'] !== 'master' || $download['tag'] || $download['revision'] || !empty($download['submodule'])) {
465

    
466
        // get current directory (for move back later)
467
        $cwd = getcwd();
468
        // change path to working copy of cloned repo
469
        chdir($tmp_location);
470

    
471
        // Progress branch / tag / revision download. Ensure that only one option ist set (branch OR tag OR revision)
472
        // check if branch a other than master
473
        if ($download['branch'] !== 'master' && !$download['tag'] && !$download['revision']) {
474
          if (drush_shell_exec("git checkout -b %s %s", $download['branch'], 'origin/' . $download['branch'])) {
475
            drush_log(dt("Checked out branch %branch.", array('%branch' => $download['branch'])), 'ok');
476
          }
477
          else {
478
            drush_make_error('DOWNLOAD_ERROR', dt("Unable to check out branch %branch.", array('%branch' => $download['branch'])));
479
          }
480
        }
481
        // progress if: tag is set but not the others
482
        elseif ($download['branch'] == 'master' && $download['tag'] && !$download['revision']) {
483
          // @TODO: change checkout to refs path
484
          if (drush_shell_exec("git checkout %s", 'refs/tags/' . $download['tag'])) {
485
            drush_log(dt("Checked out tag %tag.", array('%tag' => $download['tag'])), 'ok');
486
          }
487
          else {
488
            drush_make_error('DOWNLOAD_ERROR', dt("Unable to check out tag %tag.", array('%tag' => $download['tag'])));
489
          }
490
        }
491
        // progress if: revision is set but not the others
492
        elseif ($download['branch'] == 'master' && !$download['tag'] && $download['revision']) {
493
          if (drush_shell_exec("git checkout %s", $download['revision'])) {
494
            drush_log(dt("Checked out revision %revision.", array('%revision' => $download['revision'])), 'ok');
495
          }
496
          else {
497
            drush_make_error('DOWNLOAD_ERROR', dt("Unable to checkout revision %revision", array('%revision' => $download['revision'])));
498
          }
499
        }
500
        // more than one option is set so we throw a error message
501
        elseif ($download['branch'] !== 'master' || $download['tag'] || $download['revision']) {
502
          drush_make_error('DOWNLOAD_ERROR', dt("You can only specific branch or tag or revision but not combined in make file."));
503
          return false;
504
        }
505
        if (!empty($download['submodule'])) {
506
          $command = 'git submodule update';
507
          foreach ($download['submodule'] as $option) {
508
            $command .= ' --%s';
509
          }
510
          if (call_user_func_array('drush_shell_exec', array_merge(array($command), $download['submodule']))) {
511
            drush_log(dt('Initialized registered submodules.'), 'ok');
512
          }
513
          else {
514
            drush_make_error('DOWNLOAD_ERROR', dt('Unable to initialize submodules.'));
515
          }
516
        }
517
        // move back to last current directory (first line)
518
        chdir($cwd);
519
      }
520

    
521
      // Remove .git/ directory if working-copy flag was not specified.
522
      if (!$wc && file_exists($tmp_location . '/.git')) {
523
        drush_shell_exec("rm -rf %s", $tmp_location . '/.git');
524
      }
525
      drush_shell_exec('cp -Rf %s %s', $tmp_location, dirname($download_location));
526
      drush_shell_exec("rm -rf %s", dirname($tmp_location));
527
      return dirname($tmp_location);
528
    }
529
    else {
530
      drush_make_error('DOWNLOAD_ERROR', dt('Unable to clone %project from %url.', array('%project' => $name, '%url' => $url)));
531
    }
532
  }
533
  else {
534
    $download['url'] = dt("unspecified location");
535
  }
536
  return FALSE;
537
}
538

    
539
function drush_make_download_bzr($name, $download, $download_location) {
540
  $tmp_path = drush_make_tmp();
541
  $tmp_location = $tmp_path . '/__bzr__/' . basename($download_location);
542
  drush_make_mkdir(dirname($tmp_location));
543
  if (!empty($download['url'])) {
544
    $args = array();
545
    $command = 'bzr';
546
    if (drush_get_option('working-copy')) {
547
      $command .= ' branch  --use-existing-dir';
548
    }
549
    else {
550
      $command .= ' export';
551
    }
552
    if (isset($download['revision'])) {
553
      $command .= ' -r %s';
554
      $args[] = $download['revision'];
555
    }
556
    $command .= ' %s %s';
557
    if (drush_get_option('working-copy')) {
558
      $args[] = $download['url'];
559
      $args[] = $tmp_location;
560
    }
561
    else {
562
      $args[] = $tmp_location;
563
      $args[] = $download['url'];
564
    }
565
    array_unshift($args, $command);
566
    if (call_user_func_array('drush_shell_exec', $args)) {
567
      drush_log(dt('%project downloaded from %url.', array('%project' => $name, '%url' => $download['url'])), 'ok');
568
      drush_shell_exec('cp -Rf %s %s', $tmp_location, dirname($download_location));
569
      drush_shell_exec('rm -rf %s', dirname($tmp_location));
570
      return dirname($download_location);
571
    }
572
  }
573
  else {
574
    $download['url'] = dt("unspecified location");
575
  }
576
  drush_make_error('DOWNLOAD_ERROR', dt('Unable to download %project from %url.', array('%project' => $name, '%url' => $download['url'])));
577
  drush_shell_exec('rm -rf %s', dirname($tmp_location));
578
  return FALSE;
579
}
580

    
581

    
582
function drush_make_download_svn($name, $download, $download_location) {
583
  $command = 'svn  --force --non-interactive export';
584
  if (!empty($download['url'])) {
585
    if (drush_get_option('working-copy')) {
586
      $command = 'svn  --force --non-interactive checkout';
587
    }
588
    $args = array();
589

    
590
    if (isset($download['revision'])) {
591
      $command .= ' -r%s';
592
      $args[] = $download['revision'];
593
    }
594

    
595
    $command .= ' %s %s';
596
    $args[] = $download['url'];
597
    $args[] = $download_location;
598

    
599
    if (!empty($download['username'])) {
600
      $command .= ' --username %s --password %s';
601
      $args[] = $download['username'];
602
      $args[] = $download['password'];
603
    }
604
    array_unshift($args, $command);
605
    $result = call_user_func_array('drush_shell_exec', $args);
606
    if ($result) {
607
      drush_log(dt('%project @command from %url.', array('%project' => $name, '@command' => $command, '%url' => $download['url'])), 'ok');
608
      return $download_location;
609
    }
610
    else {
611
      $download['url'] = dt("unspecified location");
612
    }
613
  }
614
  else {
615
    drush_make_error('DOWNLOAD_ERROR', dt('Unable to download %project from %url.', array('%project' => $name, '%url' => $download['url'])));
616
    return FALSE;
617
  }
618
}
619