Project

General

Profile

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

root / .drush / drush_make / drush_make.project.inc @ e0b49768

1
<?php
2
// $Id: drush_make.project.inc,v 1.1.2.48 2010/09/06 15:56:59 dmitrig01 Exp $
3

    
4
/**
5
 * The base project class.
6
 */
7
class DrushMakeProject {
8
  /**
9
   * Set attributes and retrieve project information.
10
   */
11
  function __construct($project) {
12
    $project['base_contrib_destination'] = $project['contrib_destination'];
13
    foreach ($project as $key => $value) {
14
      $this->{$key} = $value;
15
    }
16
  }
17

    
18
  /**
19
   * Build a project.
20
   */
21
  function make() {
22
    if (!empty($this->made)) {
23
      return FALSE;
24
    }
25
    $download_location = $this->findDownloadLocation();
26
    if (drush_make_download_factory($this->download['type'], $this->name, $this->download, $download_location) === FALSE) {
27
      return FALSE;
28
    }
29
    if (!$this->applyPatches($download_location)) {
30
      return FALSE;
31
    }
32
    if (!$this->getTranslations($download_location)) {
33
      return FALSE;
34
    }
35
    if (!$this->recurse($download_location)) {
36
      return FALSE;
37
    }
38
    $this->made = TRUE;
39
    return TRUE;
40
  }
41

    
42
  function findDownloadLocation() {
43
    $this->path = $this->generatePath();
44
    $this->project_directory = !empty($this->directory_name) ? $this->directory_name : $this->name;
45
    $this->download_location = $this->path . '/' . $this->project_directory;
46
    // This directory shouldn't exist yet -- if it does, stop.
47
    if (is_dir($this->download_location)) {
48
      drush_set_error(dt('Directory not empty: %directory', array('%directory' => $this->download_location)));
49
      return FALSE;
50
    }
51
    else {
52
      drush_make_mkdir($this->download_location);
53
    }
54
    return $this->download_location;
55
  }
56

    
57
  /**
58
   * Retrieve and apply any patches specified by the makefile to this project.
59
   */
60
  function applyPatches($project_directory) {
61
    if (!empty($this->patch)) {
62
      $patches_txt = '';
63
      foreach ($this->patch as $url) {
64
        // Download the patch.
65
        if ($filename = _drush_make_download_file($url)) {
66
          $patched = drush_shell_exec("patch -p0 -d %s < %s", $project_directory, $filename);
67
          if ($patched) {
68
            $patches_txt .= '- ' . $url . "\n";
69
          }
70
          drush_log($this->name . ' patched with ' . basename($filename) . '.', $patched ? 'ok' : 'error');
71
          drush_op('unlink', $filename);
72
        }
73
        else {
74
          drush_make_error('Unable to download ' . $url . '.');
75
          return FALSE;
76
        }
77
      }
78
      if (!empty($patches_txt) && !drush_get_option('no-patch-txt') && !file_exists($project_directory . '/PATCHES.txt')) {
79
        $patches_txt = "The following patches have been applied to this project:\n" .
80
          $patches_txt .
81
          "\nThis file was automatically generated by Drush Make (http://drupal.org/project/drush_make).";
82
        file_put_contents($project_directory . '/PATCHES.txt', $patches_txt);
83
        drush_log('Generated PATCHES.txt file for ' . $this->name, 'ok');
84
      }
85
    }
86
    return TRUE;
87
  }
88

    
89
  /**
90
   * Retrieve translations for this project.
91
   */
92
  function getTranslations($project_directory) {
93
    static $cache = array();
94
    $langcodes = drush_get_option('translations', FALSE);
95
    if ($langcodes && $this->version !== drush_get_option('drush-make-version-best') && in_array($this->type, array('core', 'module', 'profile', 'theme'), TRUE)) {
96
      // Support the l10n_path, l10n_url keys from l10n_update. Note that the
97
      // l10n_server key is not supported.
98
      if (isset($this->l10n_path)) {
99
        $update_url = $this->l10n_path;
100
      }
101
      else {
102
        if (isset($this->l10n_url)) {
103
          $l10n_server = $this->l10n_url;
104
        }
105
        elseif ($this->location === drush_get_option('drush-make-update-default-url')) {
106
          $l10n_server = 'http://localize.drupal.org/l10n_server.xml';
107
        }
108
        else {
109
          $l10n_server = FALSE;
110
        }
111
        if ($l10n_server) {
112
          if (!isset($cache[$l10n_server])) {
113
            if ($filename = _drush_make_download_file($l10n_server)) {
114
              $server_info = simplexml_load_string(file_get_contents($filename));
115
              $cache[$l10n_server] = !empty($server_info->update_url) ? $server_info->update_url : FALSE;
116
              drush_op('unlink', $filename);
117
            }
118
          }
119
          if ($cache[$l10n_server]) {
120
            $update_url = $cache[$l10n_server];
121
          }
122
          else {
123
            drush_make_error('XML_ERROR', dt("Could not retrieve l10n update url for %project.", array('%project' => $project['name'])));
124
            return FALSE;
125
          }
126
        }
127
      }
128
      if ($update_url) {
129
        $failed = array();
130
        $langcodes = explode(',', $langcodes);
131
        foreach ($langcodes as $langcode) {
132
          $variables = array(
133
            '%project' => $this->name,
134
            '%release' => $this->type === 'core' ? $this->version : "{$this->core}-{$this->version}",
135
            '%core' => $this->core,
136
            '%language' => $langcode,
137
            '%filename' => '%filename',
138
          );
139
          $url = strtr($update_url, $variables);
140

    
141
          // Download the translation file.
142
          if ($filename = _drush_make_download_file($url)) {
143
            // If this is the core project type, download the translation file
144
            // and create two copies:
145
            // 1. To profiles/default/translations. It must be named
146
            //    langcode.po to be used properly by the installer.
147
            // 2. To modules/system/translations where it can be detected for
148
            //    import by other non-default install profiles.
149
            if ($this->type === 'core') {
150
              drush_make_mkdir($project_directory . '/profiles/default/translations');
151
              drush_make_mkdir($project_directory . '/modules/system/translations');
152
              drush_shell_exec("cp %s %s", $filename, $project_directory . '/profiles/default/translations/' . $langcode . '.po');
153
              drush_shell_exec("mv %s %s", $filename, $project_directory . '/modules/system/translations');
154
            }
155
            else {
156
              drush_make_mkdir($project_directory . '/translations');
157
              drush_shell_exec("mv %s %s", $filename, $project_directory . '/translations');
158
            }
159
          }
160
          else {
161
            $failed[] = $langcode;
162
          }
163
        }
164
        if (empty($failed)) {
165
          drush_log('All translations downloaded for ' . $this->name, 'ok');
166
        }
167
        else {
168
          drush_log('Unable to download translations for '. $this->name .': ' . implode(', ', $failed), 'warning');
169
        }
170
      }
171
    }
172
    return TRUE;
173
  }
174

    
175
  /**
176
   * Generate the proper path for this project type.
177
   *
178
   * @param $base
179
   *   Whether include the base part (tmp dir). Defaults to TRUE.
180
   */
181
  protected function generatePath($base = TRUE) {
182
    $path = array();
183
    if ($base) {
184
      $path[] = drush_make_tmp();
185
      $path[] = '__build__';
186
    }
187
    if (!empty($this->contrib_destination)) {
188
      $path[] = $this->contrib_destination;
189
    }
190
    if (!empty($this->subdir)) {
191
      $path[] = $this->subdir;
192
    }
193
    return implode('/', $path);
194
  }
195

    
196
  /**
197
   * Return the proper path for dependencies to be placed in.
198
   *
199
   * @return
200
   *   The path that dependencies will be placed in.
201
   */
202
  protected function buildPath() {
203
    return $this->base_contrib_destination;
204
  }
205

    
206
  function recurse($path) {
207
    if (!empty($this->directory_name)) {
208
      $directory = $this->directory_name;
209
    }
210
    $makefile = $this->download_location . '/' . $this->name . '.make';
211
    if (!file_exists($makefile)) {
212
      $makefile = $this->download_location . '/drupal-org.make';
213
      if (!file_exists($makefile)) {
214
        return;
215
      }
216
    }
217
    drush_log(dt("Found makefile: %makefile", array("%makefile" => basename($makefile))), 'ok');
218

    
219
    $info = drush_make_parse_info_file($makefile);
220
    if (!($info = drush_make_validate_info_file($info))) {
221
      return FALSE;
222
    }
223
    $build_path = $this->buildPath($this->name);
224
    drush_make_projects(TRUE, trim($build_path, '/'), $info, $this->build_path);
225
    drush_make_libraries(trim($build_path, '/'), $info, $this->build_path);
226
  }
227
}
228

    
229
class DrushMakeProject_Core extends DrushMakeProject {
230
  function __construct(&$project) {
231
    parent::__construct($project);
232
    $this->contrib_destination = '';
233
  }
234

    
235
  function findDownloadLocation() {
236
    $this->path = $this->download_location = $this->generatePath();
237
    $this->project_directory = '';
238
    if (is_dir($this->download_location)) {
239
      drush_set_error(dt('Directory not empty: %directory', array('%directory' => $this->download_location)));
240
      return FALSE;
241
    }
242
    else {
243
      drush_make_mkdir($this->download_location);
244
    }
245
    return $this->download_location;
246
  }
247
}
248

    
249
class DrushMakeProject_Library extends DrushMakeProject {
250
  public function __construct(&$project) {
251
    parent::__construct($project);
252
    // Allow libraries to specify where they should live in the build path.
253
    if (isset($project['destination'])) {
254
      $project_path = $project['destination'];
255
    }
256
    else {
257
      $project_path = 'libraries';
258
    }
259

    
260
    $this->contrib_destination = ($this->base_contrib_destination != '.' ? $this->base_contrib_destination . '/' : '') . $project_path;
261
  }
262
  // No recursion for libraries, sorry :-(
263
  function recurse() {}
264
}
265

    
266
class DrushMakeProject_Module extends DrushMakeProject {
267
  public function __construct(&$project) {
268
    parent::__construct($project);
269
    $this->contrib_destination = ($this->base_contrib_destination != '.' ? $this->base_contrib_destination . '/' : '') . 'modules';
270
  }
271
}
272

    
273
class DrushMakeProject_Profile extends DrushMakeProject {
274
  public function __construct(&$project) {
275
    parent::__construct($project);
276
    $this->contrib_destination = 'profiles';
277
  }
278

    
279
  protected function buildPath($directory) {
280
    return $this->generatePath(FALSE) . '/' . $directory;
281
  }
282
}
283

    
284
class DrushMakeProject_Theme extends DrushMakeProject {
285
  public function __construct(&$project) {
286
    parent::__construct($project);
287
    $this->contrib_destination = ($this->base_contrib_destination != '.' ? $this->base_contrib_destination . '/' : '') . 'themes';
288
  }
289
}
290

    
291
class DrushMakeProject_Translation extends DrushMakeProject {
292
  public function __construct(&$project) {
293
    parent::__construct($project);
294
    switch($project['core']) {
295
      case '5.x':
296
        // Don't think there's an automatic place we can put 5.x translations,
297
        // so we'll toss them in a translations directory in the Drupal root.
298
        $this->contrib_destination = ($this->base_contrib_destination != '.' ? $this->base_contrib_destination . '/' : '') . 'translations';
299
        break;
300
      default:
301
        $this->contrib_destination = '';
302
        break;
303
    }
304
  }
305
}
306