1 | "use strict";
|
2 |
|
3 | var grunt = require('grunt');
|
4 | var path = require('path');
|
5 | var plugin;
|
6 |
|
7 |
|
8 | module.exports = function () {
|
9 | plugin.initialisePlugin();
|
10 | };
|
11 |
|
12 |
|
13 | plugin = {
|
14 | initialisePlugin: function () {
|
15 | this.registerTasks();
|
16 | this.registerHelpers();
|
17 | },
|
18 |
|
19 | registerTasks: function () {
|
20 | this.registerTextReplaceTask();
|
21 | },
|
22 |
|
23 | registerHelpers: function () {
|
24 | this.registerReplaceHelper();
|
25 | this.registerTextReplaceHelper();
|
26 | this.registerTextReplaceMultipleHelper();
|
27 | this.registerTextReplaceFileHelper();
|
28 | this.registerTextReplaceFileMultipleHelper();
|
29 | },
|
30 |
|
31 | registerTextReplaceTask: function () {
|
32 | grunt.registerMultiTask('replace',
|
33 | 'General purpose text replacement for grunt. Allows you to replace ' +
|
34 | 'text in files using strings, regexs or functions.',
|
35 | this.replaceTask);
|
36 | },
|
37 |
|
38 | replaceTask: function () {
|
39 | grunt.helper('replace', {
|
40 | src: this.data.src,
|
41 | dest: this.data.dest,
|
42 | overwrite: this.data.overwrite,
|
43 | replacements: this.data.replacements
|
44 | });
|
45 | },
|
46 |
|
47 | registerReplaceHelper: function () {
|
48 | grunt.registerHelper('replace',
|
49 | this.replaceHelper);
|
50 | },
|
51 |
|
52 | registerTextReplaceHelper: function () {
|
53 | grunt.registerHelper('text-replace',
|
54 | this.textReplaceHelper);
|
55 | },
|
56 |
|
57 | registerTextReplaceMultipleHelper: function () {
|
58 | grunt.registerHelper('text-replace-multiple',
|
59 | this.textReplaceMultipleHelper);
|
60 | },
|
61 |
|
62 | registerTextReplaceFileHelper: function () {
|
63 | grunt.registerHelper('text-replace-file',
|
64 | this.textReplaceFileHelper);
|
65 | },
|
66 |
|
67 | registerTextReplaceFileMultipleHelper: function () {
|
68 | grunt.registerHelper('text-replace-file-multiple',
|
69 | this.textReplaceFileMultipleHelper);
|
70 | },
|
71 |
|
72 | textReplaceHelper: function (fullText, from, to) {
|
73 | var regex = plugin.convertPatternToRegex(from);
|
74 | var expandedReplacement = plugin.expandReplacement(to);
|
75 | return fullText.replace(regex, expandedReplacement);
|
76 | },
|
77 |
|
78 | textReplaceMultipleHelper: function (fullText, allReplacements) {
|
79 | return allReplacements.reduce(function (fullText, replacement) {
|
80 | return grunt.helper('text-replace',
|
81 | fullText, replacement.from, replacement.to);
|
82 | }, fullText);
|
83 | },
|
84 |
|
85 | textReplaceFileHelper: function (pathToSource, dest, replacements) {
|
86 | var pathToDestination = plugin.getPathToDestination(pathToSource, dest);
|
87 | grunt.file.copy(pathToSource, pathToDestination, {
|
88 | process: function (fullText) {
|
89 | return grunt.helper('text-replace-multiple', fullText, replacements);
|
90 | }
|
91 | });
|
92 | },
|
93 |
|
94 | getPathToDestination: function (pathToSource, dest) {
|
95 | var isDestinationDirectory = (/\/$/).test(dest);
|
96 | var fileName = path.basename(pathToSource);
|
97 | var pathToDestination;
|
98 | if (typeof dest === 'undefined') {
|
99 | pathToDestination = pathToSource;
|
100 | } else {
|
101 | pathToDestination = dest + (isDestinationDirectory ? fileName : '');
|
102 | }
|
103 | return pathToDestination;
|
104 | },
|
105 |
|
106 | textReplaceFileMultipleHelper: function (src, dest, replacements) {
|
107 | var sourceFiles = grunt.file.expandFiles(src);
|
108 | sourceFiles.forEach(function (pathToSource) {
|
109 | grunt.helper('text-replace-file', pathToSource, dest, replacements);
|
110 | });
|
111 | },
|
112 |
|
113 | replaceHelper: function (settings) {
|
114 | var src = grunt.file.expandFiles(settings.src || []);
|
115 | var dest = settings.dest;
|
116 | var overwrite = settings.overwrite;
|
117 | var replacements = settings.replacements;
|
118 | var isDestinationDirectory = (/\/$/).test(dest);
|
119 | var initialWarnCount = grunt.fail.warncount;
|
120 |
|
121 | if (typeof dest === 'undefined' &&
|
122 | typeof src === 'undefined' &&
|
123 | typeof replacements === 'undefined') {
|
124 | grunt.warn(plugin.errorMessages.noTargetsDefined);
|
125 | } else if (src.length === 0) {
|
126 | grunt.warn(plugin.errorMessages.noSourceFiles);
|
127 | } else if (typeof dest === 'undefined' && overwrite !== true) {
|
128 | grunt.warn(plugin.errorMessages.noDestination);
|
129 | } else if (typeof replacements === 'undefined') {
|
130 | grunt.warn(plugin.errorMessages.noReplacements);
|
131 | } else if (typeof dest !== 'undefined' && overwrite === true) {
|
132 | grunt.warn(plugin.errorMessages.overwriteFailure);
|
133 | } else if (isDestinationDirectory === false && src.length > 1) {
|
134 | grunt.warn(plugin.errorMessages.multipleSourceSingleDestination);
|
135 | } else if (grunt.fail.warncount - initialWarnCount === 0) {
|
136 | grunt.helper('text-replace-file-multiple', src, dest, replacements);
|
137 | }
|
138 | },
|
139 |
|
140 | errorMessages: {
|
141 | noTargetsDefined: "No targets were found. Remember to wrap functionality " +
|
142 | "within a target.",
|
143 | noSourceFiles: "No source files found",
|
144 | noDestination: "Destination is not defined! If you want to overwrite " +
|
145 | "files, then make sure to set overwrite: true. If you don't wish to " +
|
146 | "overwrite, then make sure to set a destination",
|
147 | noReplacements: "No replacements were found.",
|
148 | overwriteFailure: "Overwrite is to true, but a destination has also " +
|
149 | "been defined. If you want to overwrite files, remove the destination. " +
|
150 | "If you want to send files to a destination, then ensure overwrite is " +
|
151 | "not set to true",
|
152 | multipleSourceSingleDestination: "Cannot write multiple files to same " +
|
153 | "file. If you wish to export to a directory, make sure there is a " +
|
154 | "trailing slash on the destination. If you wish to write to a single " +
|
155 | "file, make sure there is only one source file"
|
156 | },
|
157 |
|
158 | convertPatternToRegex: function (pattern) {
|
159 | var regexCharacters = '\\[](){}^$-.*+?|,/';
|
160 | if (typeof pattern === 'string') {
|
161 | regexCharacters.split('').forEach(function (character) {
|
162 | var characterAsRegex = new RegExp('(\\' + character + ')', 'g');
|
163 | pattern = pattern.replace(characterAsRegex, '\\$1');
|
164 | });
|
165 | pattern = new RegExp(pattern, 'g');
|
166 | }
|
167 | return pattern;
|
168 | },
|
169 |
|
170 | expandReplacement: function (replacement) {
|
171 | if (typeof replacement === 'function') {
|
172 | return this.expandFunctionReplacement(replacement);
|
173 | } else if (typeof replacement === 'string') {
|
174 | return this.expandStringReplacement(replacement);
|
175 | }
|
176 | },
|
177 |
|
178 | expandFunctionReplacement: function (replacement) {
|
179 | return function () {
|
180 | var matchedSubstring = arguments[0];
|
181 | var index = arguments[arguments.length - 2];
|
182 | var fullText = arguments[arguments.length - 1];
|
183 | var regexMatches = Array.prototype.slice.call(arguments, 1,
|
184 | arguments.length - 2);
|
185 | var returnValue = replacement(matchedSubstring, index, fullText,
|
186 | regexMatches);
|
187 | return (typeof returnValue === 'string') ?
|
188 | grunt.template.process(returnValue) : returnValue;
|
189 | };
|
190 | },
|
191 |
|
192 | expandStringReplacement: function (replacement) {
|
193 | return grunt.template.process(replacement);
|
194 | }
|
195 | };
|
196 |
|
197 |
|
198 |
|