UNPKG

4.22 kBJavaScriptView Raw
1/*
2 * grunt-include-replace
3 * https://github.com/alanshaw/grunt-include-replace
4 *
5 * Copyright (c) 2013 Alan Shaw
6 * Licensed under the MIT license.
7 */
8
9module.exports = function(grunt) {
10
11 "use strict";
12
13 var _ = grunt.util._;
14
15 var path = require('path');
16 var fs = require('fs');
17
18 grunt.registerMultiTask('includereplace', 'Include files and replace variables', function() {
19
20 var options = this.options({
21 prefix: '@@',
22 suffix: '',
23 globals: {}
24 });
25
26 // Variables available in ALL files
27 var globalVars = options.globals;
28
29 // Names of our variables
30 var globalVarNames = Object.keys(globalVars);
31
32 globalVarNames.forEach(function(globalVarName) {
33 if(_.isString(globalVars[globalVarName])) {
34 globalVars[globalVarName] = globalVars[globalVarName];
35 } else {
36 globalVars[globalVarName] = JSON.stringify(globalVars[globalVarName]);
37 }
38 });
39
40 grunt.log.debug('Globals', globalVars);
41
42 // Cached variable regular expressions
43 var globalVarRegExps = {};
44
45 function replace(contents, localVars) {
46
47 localVars = localVars || {};
48
49 var varNames = Object.keys(localVars);
50 var varRegExps = {};
51
52 // Replace local vars
53 varNames.forEach(function(varName) {
54
55 // Process lo-dash templates (for strings) in global variables and JSON.stringify the rest
56 if(_.isString(localVars[varName])) {
57 localVars[varName] = grunt.template.process(localVars[varName]);
58 } else {
59 localVars[varName] = JSON.stringify(localVars[varName]);
60 }
61
62 varRegExps[varName] = varRegExps[varName] || new RegExp(options.prefix + varName + options.suffix, 'g');
63
64 contents = contents.replace(varRegExps[varName], localVars[varName]);
65 });
66
67 // Replace global variables
68 globalVarNames.forEach(function(globalVarName) {
69
70 globalVarRegExps[globalVarName] = globalVarRegExps[globalVarName] || new RegExp(options.prefix + globalVarName + options.suffix, 'g');
71
72 contents = contents.replace(globalVarRegExps[globalVarName], globalVars[globalVarName]);
73 });
74
75 return contents;
76 }
77
78 var includeRegExp = new RegExp(options.prefix + 'include\\(\\s*["\'](.*?)["\'](,\\s*({[\\s\\S]*?})){0,1}\\s*\\)' + options.suffix);
79
80 function include(contents, workingDir) {
81
82 var matches = includeRegExp.exec(contents);
83
84 while(matches) {
85
86 var match = matches[0];
87 var includePath = matches[1];
88 var localVars = matches[3] ? JSON.parse(matches[3]) : {};
89
90 if(!grunt.file.isPathAbsolute(includePath)) {
91 includePath = path.resolve(workingDir + path.sep + includePath);
92 } else {
93 includePath = path.resolve(includePath);
94 }
95
96 grunt.log.debug('Including', includePath);
97 grunt.log.debug('Locals', localVars);
98
99 var includeContents = grunt.file.read(includePath);
100
101 // Make replacements
102 includeContents = replace(includeContents, localVars);
103
104 // Process includes
105 includeContents = include(includeContents, path.dirname(includePath));
106
107 contents = contents.replace(match, includeContents);
108
109 matches = includeRegExp.exec(contents);
110 }
111
112 return contents;
113 }
114
115 this.files.forEach(function(srcDest) {
116
117 srcDest.orig.src.forEach(function(origSrc) {
118
119 grunt.log.debug('Processing glob ' + origSrc);
120
121 // Get the base dir, which we want to omit from our destination path
122 var baseDir = path.dirname(origSrc);
123
124 while(_(baseDir).endsWith('**'))
125 baseDir = path.dirname(baseDir);
126
127 grunt.log.debug('Base dir ' + baseDir);
128
129 grunt.file.expand(origSrc).forEach(function(src) {
130
131 if(!grunt.file.isFile(src)) return;
132
133 grunt.log.debug('Processing ' + src);
134
135 // Read file
136 var contents = grunt.file.read(src);
137
138 // Make replacements
139 contents = replace(contents);
140
141 // Process includes
142 contents = include(contents, path.dirname(src));
143
144 grunt.log.debug(contents);
145
146 var dest = path.normalize(srcDest.dest + path.sep + src.replace(baseDir, ''));
147
148 grunt.log.debug('Saving to', dest);
149
150 grunt.file.write(dest, contents);
151
152 grunt.log.ok('Processed ' + src);
153 });
154 });
155 });
156 });
157};