GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Package   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 340
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 31
eloc 118
dl 0
loc 340
rs 9.92
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A makeCore() 0 9 1
A execute() 0 15 1
A __construct() 0 3 1
A buildPackage() 0 20 3
A isLibrary() 0 2 1
A buildLibrary() 0 5 1
B make() 0 49 6
A isDrupalPackage() 0 11 2
B buildProject() 0 68 9
A isLightning() 0 4 2
A makeFix() 0 23 4
1
<?php
2
3
namespace Acquia\DF\Composer;
4
5
use Acquia\DF\IniEncoder;
6
use Composer\Package\Locker;
7
use Composer\Package\RootPackageInterface;
8
use Composer\Script\Event;
9
10
/**
11
 * Generates Drush make files for drupal.org's ancient packaging system.
12
 */
13
class Package {
14
15
  /**
16
   * The root Composer package (i.e., this composer.json).
17
   *
18
   * @var \Composer\Package\RootPackageInterface
19
   */
20
  protected $rootPackage;
21
22
  /**
23
   * The locker.
24
   *
25
   * @var \Composer\Package\Locker
26
   */
27
  protected $locker;
28
29
  /**
30
   * Package constructor.
31
   *
32
   * @param \Composer\Package\RootPackageInterface $root_package
33
   *   The root package (i.e., this composer.json).
34
   * @param \Composer\Package\Locker $locker
35
   *   The locker.
36
   */
37
  public function __construct(RootPackageInterface $root_package, Locker $locker) {
38
    $this->rootPackage = $root_package;
39
    $this->locker = $locker;
40
  }
41
42
  /**
43
   * Script entry point.
44
   *
45
   * @param \Composer\Script\Event $event
46
   *   The script event.
47
   */
48
  public static function execute(Event $event) {
49
    $composer = $event->getComposer();
50
51
    $handler = new static(
52
      $composer->getPackage(),
53
      $composer->getLocker()
54
    );
55
56
    $encoder = new IniEncoder();
57
58
    $make = $handler->make();
59
    $handler->makeFix($make);
60
    $core = $handler->makeCore($make);
61
    file_put_contents('drupal-org-core.make', $encoder->encode($core));
62
    file_put_contents('drupal-org.make', $encoder->encode($make));
63
  }
64
65
  /**
66
   * Extracts a core-only make file from a complete make file.
67
   *
68
   * @param array $make
69
   *   The complete make file.
70
   *
71
   * @return array
72
   *   The core-only make file structure.
73
   */
74
  protected function makeCore(array &$make) {
75
    $project = $make['projects']['drupal'];
76
    unset($make['projects']['drupal']);
77
78
    return [
79
      'core' => $make['core'],
80
      'api' => $make['api'],
81
      'projects' => [
82
        'drupal' => $project,
83
      ],
84
    ];
85
  }
86
87
  /**
88
   * Generates a complete make file structure from the root package.
89
   *
90
   * @return array
91
   *   The complete make file structure.
92
   */
93
  protected function make() {
94
    $info = [
95
      'core' => '8.x',
96
      'api' => 2,
97
      'defaults' => [
98
        'projects' => [
99
          'subdir' => 'contrib',
100
        ],
101
      ],
102
      'projects' => [],
103
      'libraries' => [],
104
    ];
105
    $lock = $this->locker->getLockData();
106
107
    foreach ($lock['packages'] as $package) {
108
      list(, $name) = explode('/', $package['name'], 2);
109
110
      if ($this->isDrupalPackage($package)) {
111
        if ($package['type'] == 'drupal-core') {
112
          $name = 'drupal';
113
        }
114
        $info['projects'][$name] = $this->buildProject($package);
115
      }
116
      elseif ($this->isLightning($package)) {
117
        $info['projects'][$name] = $this->buildProject($package);
118
119
        // The Lightning project uses semantic versioning.
120
        $sem_ver = explode('.', $package['version']);
121
        list($major, $minor, $patch) = $sem_ver;
122
123
        // drupal.org doesn't currently support semantic versioning, so
124
        // Lightning uses a custom release naming convention where 'patch' is
125
        // padded with leading zeros to two digits.
126
        // For example, version '3.0.3' becomes '3.003'.
127
        $padded_patch = str_pad($patch, 2, "0", STR_PAD_LEFT);
128
129
        $info['projects'][$name]['version'] = "$major.$minor$padded_patch";
130
131
        // Override the default 'contrib' subdirectory set above in order to
132
        // prevent the profile from being placed in a 'contrib' folder.
133
        $info['projects'][$name]['subdir'] = '""';
134
      }
135
      // Include any non-drupal libraries that exist in both .lock and .json.
136
      elseif ($this->isLibrary($package)) {
137
        $info['libraries'][$name] = $this->buildLibrary($package);
138
      }
139
    }
140
141
    return $info;
142
  }
143
144
  /**
145
   * 'Fixes' a make file by manually adjusting known package inaccuracies.
146
   *
147
   * @param array $make
148
   *   The complete make file.
149
   */
150
  protected function makeFix(array &$make) {
151
    // Build a whitelist of libraries which are approved for distribution via
152
    // drupal.org.
153
    // Composer supports adding libraries from anywhere, while drupal.org only
154
    // allows distributions to include libraries that have been specifically
155
    // approved. See the Packaging Whitelist for a list of approved libraries
156
    // (https://www.drupal.org/packaging-whitelist).
157
    $whitelist = ['dropzone', 'masonry', 'imagesloaded', 'ckeditor-track-changes', 'slick-carousel', 'lightbox2', 'cropper'];
158
159
    foreach ($make['libraries'] as $name => $info) {
160
      // Libraries must be located in the root 'libraries' folder.
161
      $make['libraries'][$name]['destination'] = "../../libraries";
162
      // Remove any libraries that are not specifically whitelisted above.
163
      // Users will need to download these libraries manually.
164
      if (!in_array($name, $whitelist)) {
165
        unset($make['libraries'][$name]);
166
      }
167
    }
168
169
    // The ckeditor-track-changes library is designed to be renamed, after
170
    // download, to 'lite'.
171
    if (isset($make['libraries']['ckeditor-track-changes'])) {
172
      $make['libraries']['ckeditor-track-changes']['directory_name'] = 'lite';
173
    }
174
  }
175
176
  /**
177
   * Builds a make structure for a library (i.e., not a Drupal project).
178
   *
179
   * @param array $package
180
   *   The Composer package definition.
181
   *
182
   * @return array
183
   *   The generated make structure.
184
   */
185
  protected function buildLibrary(array $package) {
186
    $info = [
187
      'type' => 'library',
188
    ];
189
    return $info + $this->buildPackage($package);
190
  }
191
192
  /**
193
   * Builds a make structure for a Drupal module, theme, profile, or core.
194
   *
195
   * @param array $package
196
   *   The Composer package definition.
197
   *
198
   * @return array
199
   *   The generated make structure.
200
   */
201
  protected function buildProject(array $package) {
202
    $info = [];
203
204
    switch ($package['type']) {
205
      case 'drupal-core':
206
      case 'drupal-profile':
207
      case 'drupal-theme':
208
      case 'drupal-module':
209
        $info['type'] = substr($package['type'], 7);
210
        break;
211
    }
212
    $info += $this->buildPackage($package);
213
214
    // Dev versions should use git branch + revision, otherwise a tag is used.
215
    if (strstr($package['version'], 'dev')) {
216
      // 'dev-' prefix indicates a branch-alias. Stripping the dev prefix from
217
      // the branch name is sufficient.
218
      // @see https://getcomposer.org/doc/articles/aliases.md
219
      if (strpos($package['version'], 'dev-') === 0) {
220
        $info['download']['branch'] = substr($package['version'], 4);
221
      }
222
      // Otherwise, leave as is. Version may already use '-dev' suffix.
223
      else {
224
        $info['download']['branch'] = $package['version'];
225
      }
226
      $info['download']['revision'] = $package['source']['reference'];
227
    }
228
    // Core should always use git branch + revision, or patches won't apply
229
    // correctly.
230
    elseif ($package['type'] == 'drupal-core') {
231
      // Composer downloads core from its subtree split on GitHub, but the
232
      // packaging system will choke on that.
233
      $info['download']['url'] = 'https://git.drupal.org/project/drupal.git';
234
      // Derive the branch from the version string.
235
      $info['download']['branch'] = preg_replace(
236
        // 8.4.2 --> 8.4.x
237
        // 8.6.0-beta2 --> 8.6.x
238
        ['/\.\d(-\w+\d+)?$/', '/-dev$/'],
239
        // 8.5.x-dev --> 8.5.x
240
        ['.x', NULL],
241
        $package['version']
242
      );
243
      // We never want to specify a commit hash, regardless of whether this is
244
      // a dev branch or tagged release.
245
      unset($info['download']['revision']);
246
      // But, if it is a tagged release (i.e., there's no -dev suffix in the
247
      // version), we do want to specify that tag.
248
      if (strpos($package['version'], '-dev') === FALSE) {
249
        $info['download']['tag'] = $package['version'];
250
      }
251
    }
252
    // Any other type of package can use a standard Drupal version number.
253
    else {
254
      // Drupalize the tag versioning, e.g. 8.1.0-alpha1 => 8.x-1.0-alpha1.
255
      $version = sprintf(
256
        '%d.x-%s',
257
        $package['version'][0],
258
        substr($package['version'], 2)
259
      );
260
      // Make the version Drush make-compatible: 1.x-13.0-beta2 --> 1.13-beta2
261
      $info['version'] = preg_replace(
262
        '/^([0-9]+)\.x-([0-9]+)\.[0-9]+(-.+)?/',
263
        '$1.$2$3',
264
        $version
265
      );
266
      unset($info['download']);
267
    }
268
    return $info;
269
  }
270
271
  /**
272
   * Builds a make structure for any kind of package.
273
   *
274
   * @param array $package
275
   *   The Composer package definition.
276
   *
277
   * @return array
278
   *   The generated make structure.
279
   */
280
  protected function buildPackage(array $package) {
281
    if ($package['type'] == 'npm-asset') {
282
      $download = [
283
        'type' => 'get',
284
        'url' => $package['dist']['url'],
285
      ];
286
    }
287
    else {
288
      $download = [
289
        'type' => 'git',
290
        'url' => str_replace('[email protected]:', 'https://github.com/', $package['source']['url']),
291
        'branch' => $package['version'],
292
        'revision' => $package['source']['reference'],
293
      ];
294
    }
295
    $info = ['download' => $download];
296
    if (isset($package['extra']['patches_applied'])) {
297
      $info['patch'] = array_values($package['extra']['patches_applied']);
298
    }
299
    return $info;
300
  }
301
302
  /**
303
   * Determines if a package is a Drupal core, module, theme, or profile.
304
   *
305
   * @param array $package
306
   *   The package info.
307
   *
308
   * @return bool
309
   *   TRUE if the package is a Drupal core, module, theme, or profile;
310
   *   otherwise FALSE.
311
   */
312
  protected function isDrupalPackage(array $package) {
313
    $package_types = [
314
      'drupal-core',
315
      'drupal-module',
316
      'drupal-theme',
317
      'drupal-profile',
318
    ];
319
320
    return (
321
      strpos($package['name'], 'drupal/') === 0 &&
322
      in_array($package['type'], $package_types)
323
    );
324
  }
325
326
  /**
327
   * Determines if a package is the Lightning profile.
328
   *
329
   * @param array $package
330
   *   The package info.
331
   *
332
   * @return bool
333
   *   TRUE if the package is Lightning; otherwise FALSE.
334
   */
335
  protected function isLightning(array $package) {
336
    return (
337
      $package['name'] == 'acquia/lightning' &&
338
      $package['type'] == 'drupal-profile'
339
    );
340
  }
341
342
  /**
343
   * Determines if a package is an asset library.
344
   *
345
   * @param array $package
346
   *   The package info.
347
   *
348
   * @return bool
349
   *   TRUE if the package is an asset library, otherwise FALSE.
350
   */
351
  protected function isLibrary(array $package) {
352
    return in_array($package['type'], ['drupal-library', 'bower-asset', 'npm-asset'], TRUE);
353
  }
354
355
}
356