Projet

Général

Profil

Paste
Télécharger (7,88 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / themes / bootstrap / grunt / sync.js @ 4da4932d

1 caf16a48 Assos Assos
module.exports = function (grunt) {
2
  'use strict';
3
4
  // Register the 'sync' task.
5
  grunt.registerTask('sync', 'Syncs necessary libraries for development purposes. Read more in: MAINTAINERS.md.', function () {
6
    var cwd = process.cwd();
7
    var force = grunt.option('force');
8
    var path = require('path');
9
    var pkg = require('../package');
10
11
    // Internal variables.
12
    var libraries = {};
13
    var librariesCache = path.join(cwd, pkg.caches.libraries);
14
    var librariesPath = path.join(cwd, pkg.paths.libraries);
15
    var exists = grunt.file.exists(librariesCache);
16
    var expired = false;
17
18
    // Determine the validity of any existing cached libraries file.
19
    if (!force && exists) {
20
      grunt.verbose.write('Cached library information detected, checking...');
21
      var fs = require('fs');
22
      var stat = fs.statSync(librariesCache);
23
      var now = new Date().getTime();
24
      var expire = new Date(stat.mtime);
25
      expire.setDate(expire.getDate() + 7); // 1 week
26
      expired = now > expire.getTime();
27
      grunt.verbose.writeln((expired ? 'EXPIRED' : 'VALID')[expired ? 'red' : 'green']);
28
    }
29
30
    // Register a private sub-task. Doing this inside the main task prevents
31
    // this private sub-task from being executed directly and also prevents it
32
    // from showing up on the list of available tasks on --help.
33
    grunt.registerTask('sync:api', function () {
34
      var done = this.async();
35
      var request = require('request');
36
      grunt.verbose.write(pkg.urls.jsdelivr + ' ');
37
      request(pkg.urls.jsdelivr, function (error, response, body) {
38
        if (!error && response.statusCode == 200) {
39
          grunt.verbose.ok();
40
          var json;
41
          grunt.verbose.write("\nParsing JSON response...");
42
          try {
43
            json = JSON.parse(body);
44
            grunt.verbose.ok();
45
          } catch (e) {
46
            grunt.verbose.error();
47
            throw grunt.util.error('Unable to parse the response value (' + e.message + ').', e);
48
          }
49
          grunt.verbose.write("\nExtracting versions and themes from libraries...");
50
          libraries = {};
51
          json.forEach(function (library) {
52
            if (library.name === 'bootstrap' || library.name === 'bootswatch') {
53
              library.assets.forEach(function (asset) {
54
                if (asset.version.match(/^3.\d\.\d$/)) {
55
                  if (!libraries[library.name]) libraries[library.name] = {};
56
                  if (!libraries[library.name][asset.version]) libraries[library.name][asset.version] = {};
57
                  asset.files.forEach(function (file) {
58
                    if (!file.match(/bootstrap\.min\.css$/)) return;
59
                    if (library.name === 'bootstrap') {
60
                      libraries[library.name][asset.version]['bootstrap'] = true;
61
                    }
62
                    else {
63
                      libraries[library.name][asset.version][file.split(path.sep)[0]] = true;
64
                    }
65
                  });
66
                }
67
              });
68
            }
69
          });
70
          grunt.verbose.ok();
71
72
          // Flatten themes.
73
          for (var library in libraries) {
74
            grunt.verbose.header(library);
75
            if (!libraries.hasOwnProperty(library)) continue;
76
            var versions = Object.keys(libraries[library]);
77
            grunt.verbose.ok('Versions: ' + versions.join(', '));
78
            var themeCount = 0;
79
            for (var version in libraries[library]) {
80
              if (!libraries[library].hasOwnProperty(version)) continue;
81
              var themes = Object.keys(libraries[library][version]).sort();
82
              libraries[library][version] = themes;
83
              if (themes.length > themeCount) {
84
                themeCount = themes.length;
85
              }
86
            }
87
            grunt.verbose.ok(grunt.util.pluralize(themeCount, 'Themes: 1/Themes: ' + themeCount));
88
          }
89
          grunt.verbose.writeln();
90
          grunt.file.write(librariesCache, JSON.stringify(libraries, null, 2));
91
92
          grunt.log.ok('Synced');
93
        }
94
        else {
95
          grunt.verbose.error();
96
          if (error) grunt.verbose.error(error);
97
          grunt.verbose.error('Request URL: ' + pkg.urls.jsdelivr);
98
          grunt.verbose.error('Status Code: ' + response.statusCode);
99
          grunt.verbose.error('Response Headers: ' + JSON.stringify(response.headers, null, 2));
100
          grunt.verbose.error('Response:');
101
          grunt.verbose.error(body);
102
          grunt.fail.fatal('Unable to establish a connection. Run with --verbose to view the response received.');
103
        }
104
        return done(error);
105
      });
106
    });
107
108
    // Run API sync sub-task.
109
    if (!exists || force || expired) {
110
      if (!exists) grunt.verbose.writeln('No libraries cache detected, syncing libraries.');
111
      else if (force) grunt.verbose.writeln('Forced option detected, syncing libraries.');
112
      else if (expired) grunt.verbose.writeln('Libraries cache is over a week old, syncing libraries.');
113
      grunt.task.run(['sync:api']);
114
    }
115
116
    // Register another private sub-task.
117
    grunt.registerTask('sync:libraries', function () {
118
      var bower = require('bower');
119
      var done = this.async();
120
      var inquirer =  require('inquirer');
121
      var queue = require('queue')({concurrency: 1, timeout: 60000});
122
      if (!grunt.file.exists(librariesCache)) {
123
        return grunt.fail.fatal('No libraries detected. Please run `grunt sync --force`.');
124
      }
125
      libraries = grunt.file.readJSON(librariesCache);
126
      var bowerJson = path.join(cwd, 'bower.json');
127
      if (!grunt.file.isDir(librariesPath)) grunt.file.mkdir(librariesPath);
128
129
      // Iterate over libraries.
130
      for (var library in libraries) {
131
        if (!libraries.hasOwnProperty(library)) continue;
132
133
        // Iterate over versions.
134
        for (var version in libraries[library]) {
135
          if (!libraries[library].hasOwnProperty(version)) continue;
136
137
          var endpoint = library + '#' + version;
138
139
          // Check if library is already installed. If so, skip.
140
          var versionPath = path.join(librariesPath, version);
141
          grunt.verbose.write('Checking ' + endpoint + '...');
142
          if (grunt.file.isDir(versionPath) && grunt.file.isDir(versionPath + '/' + library)) {
143
            grunt.verbose.writeln('INSTALLED'.green);
144
            continue;
145
          }
146
147
          grunt.verbose.writeln('MISSING'.red);
148
          grunt.file.mkdir(versionPath);
149
          grunt.file.copy(bowerJson, path.join(versionPath, 'bower.json'));
150
151
          var config = {
152
            cwd: versionPath,
153
            directory: '',
154
            interactive: true,
155
            scripts: {
156
              postinstall: 'rm -rf jquery && rm -rf font-awesome'
157
            }
158
          };
159
160
          // Enqueue bower installations.
161
          (function (endpoint, config) {
162
            queue.push(function (done) {
163
              bower.commands
164
                .install([endpoint], {saveDev: true}, config)
165
                .on('log', function (result) {
166
                  if (result.level === 'action' && result.id !== 'validate' && !result.message.match(/(jquery|font-awesome)/)) {
167
                    grunt.log.writeln(['bower', result.id.cyan, result.message.green].join(' '));
168
                  }
169
                  else if (result.level === 'action') {
170
                    grunt.verbose.writeln(['bower', result.id.cyan, result.message.green].join(' '));
171
                  }
172
                  else {
173
                    grunt.log.debug(['bower', result.id.cyan, result.message.green].join(' '));
174
                  }
175
                })
176
                .on('prompt', function (prompts, callback) {
177
                  inquirer.prompt(prompts, callback);
178
                })
179
                .on('end', function () { done() })
180
              ;
181
            });
182
          })(endpoint, config);
183
        }
184
      }
185
186
      // Start bower queue.
187
      queue.start(function (e) {
188
        return done(e);
189
      });
190
    });
191
192
    // Run private sub-task.
193
    grunt.task.run(['sync:libraries']);
194
  });
195
196
}