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