azure-pipelines-tasks-webdeployment-common 4.227.0 → 4.230.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/msdeployutility.js +94 -1
- package/package.json +2 -1
- package/packageUtility.js +1 -9
- package/ziputility.d.ts +1 -0
- package/ziputility.js +27 -1
package/msdeployutility.js
CHANGED
|
@@ -82,7 +82,7 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
|
|
|
82
82
|
msDeployCmdArgs += ' -skip:Directory=App_Data';
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
additionalArguments = additionalArguments ? additionalArguments : ' ';
|
|
85
|
+
additionalArguments = additionalArguments ? escapeQuotes(additionalArguments) : ' ';
|
|
86
86
|
msDeployCmdArgs += ' ' + additionalArguments;
|
|
87
87
|
if (!(removeAdditionalFilesFlag && useWebDeploy)) {
|
|
88
88
|
msDeployCmdArgs += " -enableRule:DoNotDeleteRule";
|
|
@@ -97,6 +97,99 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
|
|
|
97
97
|
return msDeployCmdArgs;
|
|
98
98
|
}
|
|
99
99
|
exports.getMSDeployCmdArgs = getMSDeployCmdArgs;
|
|
100
|
+
/**
|
|
101
|
+
* Escapes quotes in a string to ensure proper command-line parsing.
|
|
102
|
+
* @param {string} additionalArguments - The string to format.
|
|
103
|
+
* @returns {string} The formatted string with escaped quotes.
|
|
104
|
+
*/
|
|
105
|
+
function escapeQuotes(additionalArguments) {
|
|
106
|
+
const parsedArgs = parseAdditionalArguments(additionalArguments);
|
|
107
|
+
const separator = ",";
|
|
108
|
+
const formattedArgs = parsedArgs.map(function (arg) {
|
|
109
|
+
let formattedArg = '';
|
|
110
|
+
let equalsSignEncountered = false;
|
|
111
|
+
for (let i = 0; i < arg.length; i++) {
|
|
112
|
+
const char = arg.charAt(i);
|
|
113
|
+
if (char == separator && equalsSignEncountered) {
|
|
114
|
+
equalsSignEncountered = false;
|
|
115
|
+
arg = arg.replace(formattedArg, escapeArg(formattedArg));
|
|
116
|
+
formattedArg = '';
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (equalsSignEncountered) {
|
|
120
|
+
formattedArg += char;
|
|
121
|
+
}
|
|
122
|
+
if (char == '=') {
|
|
123
|
+
equalsSignEncountered = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
;
|
|
127
|
+
if (formattedArg.length > 0) {
|
|
128
|
+
arg = arg.replace(formattedArg, escapeArg(formattedArg));
|
|
129
|
+
}
|
|
130
|
+
return arg;
|
|
131
|
+
});
|
|
132
|
+
return formattedArgs.join(' ');
|
|
133
|
+
}
|
|
134
|
+
exports.escapeQuotes = escapeQuotes;
|
|
135
|
+
/**
|
|
136
|
+
* Escapes special characters in a string to ensure proper command-line parsing.
|
|
137
|
+
* @param {string} arg - The string to format.
|
|
138
|
+
* @returns {string} The formatted string with escaped characters.
|
|
139
|
+
*/
|
|
140
|
+
function escapeArg(arg) {
|
|
141
|
+
var escapedChars = new RegExp(/[\\\^\.\*\?\-\&\|\(\)\<\>\t\n\r\f]/);
|
|
142
|
+
// If the argument starts with dowble quote and ends with double quote, the replace it with escaped double quotes
|
|
143
|
+
if (arg.startsWith('"') && arg.endsWith('"')) {
|
|
144
|
+
return '"\\' + arg.slice(0, arg.length - 1) + '\\""';
|
|
145
|
+
}
|
|
146
|
+
// If the argument starts with single quote and ends with single quote, then replace it with escaped double qoutes
|
|
147
|
+
if (arg.startsWith("'") && arg.endsWith("'")) {
|
|
148
|
+
return '"\\"' + arg.slice(1, arg.length - 1) + '\\""';
|
|
149
|
+
}
|
|
150
|
+
if (escapedChars.test(arg)) {
|
|
151
|
+
return '"\\"' + arg + '\\""';
|
|
152
|
+
}
|
|
153
|
+
return arg;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Parses additional arguments for the msdeploy command-line utility.
|
|
157
|
+
* @param {string} additionalArguments - The additional arguments to parse.
|
|
158
|
+
* @returns {string[]} An array of parsed arguments.
|
|
159
|
+
*/
|
|
160
|
+
function parseAdditionalArguments(additionalArguments) {
|
|
161
|
+
var parsedArgs = [];
|
|
162
|
+
var isInsideQuotes = false;
|
|
163
|
+
for (let i = 0; i < additionalArguments.length; i++) {
|
|
164
|
+
var arg = '';
|
|
165
|
+
var qouteSymbol = '';
|
|
166
|
+
let char = additionalArguments.charAt(i);
|
|
167
|
+
// command parse start
|
|
168
|
+
if (char === '-') {
|
|
169
|
+
while (i < additionalArguments.length) {
|
|
170
|
+
char = additionalArguments.charAt(i);
|
|
171
|
+
const prevSym = additionalArguments.charAt(i - 1);
|
|
172
|
+
// If we reach space and we are not inside quotes, then it is the end of the argument
|
|
173
|
+
if (char === ' ' && !isInsideQuotes)
|
|
174
|
+
break;
|
|
175
|
+
// If we reach unescaped comma and we inside qoutes we assume that it is the end of quoted line
|
|
176
|
+
if (isInsideQuotes && char === qouteSymbol && prevSym !== '\\') {
|
|
177
|
+
isInsideQuotes = false;
|
|
178
|
+
qouteSymbol = '';
|
|
179
|
+
// If we reach unescaped comma and we are not inside qoutes we assume that it is the beggining of quoted line
|
|
180
|
+
}
|
|
181
|
+
else if (!isInsideQuotes && (char === '"' || char === "'") && prevSym !== '\\') {
|
|
182
|
+
isInsideQuotes = !isInsideQuotes;
|
|
183
|
+
qouteSymbol = char;
|
|
184
|
+
}
|
|
185
|
+
arg += char;
|
|
186
|
+
i += 1;
|
|
187
|
+
}
|
|
188
|
+
parsedArgs.push(arg);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return parsedArgs;
|
|
192
|
+
}
|
|
100
193
|
function getWebDeployArgumentsString(webDeployArguments, publishingProfile) {
|
|
101
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
102
195
|
return getMSDeployCmdArgs(webDeployArguments.package.getPath(), webDeployArguments.appName, publishingProfile, webDeployArguments.removeAdditionalFilesFlag, webDeployArguments.excludeFilesFromAppDataFlag, webDeployArguments.takeAppOfflineFlag, webDeployArguments.virtualApplication, webDeployArguments.setParametersFile, webDeployArguments.additionalArguments, yield webDeployArguments.package.isMSBuildPackage(), webDeployArguments.package.isFolder(), webDeployArguments.useWebDeploy);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azure-pipelines-tasks-webdeployment-common",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.230.0",
|
|
4
4
|
"description": "Common Lib for MSDeploy Utility",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"azure-pipelines-task-lib": "^4.2.0",
|
|
24
24
|
"decompress-zip": "^0.3.3",
|
|
25
25
|
"ltx": "2.8.0",
|
|
26
|
+
"node-stream-zip": "^1.15.0",
|
|
26
27
|
"q": "1.4.1",
|
|
27
28
|
"winreg": "1.2.2",
|
|
28
29
|
"xml2js": "0.6.2"
|
package/packageUtility.js
CHANGED
|
@@ -74,15 +74,7 @@ class Package {
|
|
|
74
74
|
isMSBuildPackage() {
|
|
75
75
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
76
|
if (this._isMSBuildPackage == undefined) {
|
|
77
|
-
this._isMSBuildPackage =
|
|
78
|
-
if (this.getPackageType() != PackageType.folder) {
|
|
79
|
-
var pacakgeComponent = yield zipUtility.getArchivedEntries(this._path);
|
|
80
|
-
if (((pacakgeComponent["entries"].indexOf("parameters.xml") > -1) || (pacakgeComponent["entries"].indexOf("Parameters.xml") > -1)) &&
|
|
81
|
-
((pacakgeComponent["entries"].indexOf("systemInfo.xml") > -1) || (pacakgeComponent["entries"].indexOf("systeminfo.xml") > -1)
|
|
82
|
-
|| (pacakgeComponent["entries"].indexOf("SystemInfo.xml") > -1))) {
|
|
83
|
-
this._isMSBuildPackage = true;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
77
|
+
this._isMSBuildPackage = this.getPackageType() != PackageType.folder && (yield zipUtility.checkIfFilesExistsInZip(this._path, ["parameters.xml", "systeminfo.xml"]));
|
|
86
78
|
tl.debug("Is the package an msdeploy package : " + this._isMSBuildPackage);
|
|
87
79
|
}
|
|
88
80
|
return this._isMSBuildPackage;
|
package/ziputility.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export declare function archiveFolder(folderPath: any, targetPath: any, zipName:
|
|
|
4
4
|
* Returns array of files present in archived package
|
|
5
5
|
*/
|
|
6
6
|
export declare function getArchivedEntries(archivedPackage: string): Promise<any>;
|
|
7
|
+
export declare function checkIfFilesExistsInZip(archivedPackage: string, files: string[]): any;
|
package/ziputility.js
CHANGED
|
@@ -9,11 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.getArchivedEntries = exports.archiveFolder = exports.unzip = void 0;
|
|
12
|
+
exports.checkIfFilesExistsInZip = exports.getArchivedEntries = exports.archiveFolder = exports.unzip = void 0;
|
|
13
13
|
const tl = require("azure-pipelines-task-lib/task");
|
|
14
14
|
const path = require("path");
|
|
15
15
|
const Q = require("q");
|
|
16
16
|
const fs = require("fs");
|
|
17
|
+
const StreamZip = require("node-stream-zip");
|
|
17
18
|
var DecompressZip = require('decompress-zip');
|
|
18
19
|
var archiver = require('archiver');
|
|
19
20
|
const deleteDir = (path) => tl.exist(path) && tl.rmRF(path);
|
|
@@ -155,3 +156,28 @@ function getArchivedEntries(archivedPackage) {
|
|
|
155
156
|
});
|
|
156
157
|
}
|
|
157
158
|
exports.getArchivedEntries = getArchivedEntries;
|
|
159
|
+
function checkIfFilesExistsInZip(archivedPackage, files) {
|
|
160
|
+
let deferred = Q.defer();
|
|
161
|
+
for (let i = 0; i < files.length; i++) {
|
|
162
|
+
files[i] = files[i].toLowerCase();
|
|
163
|
+
}
|
|
164
|
+
const zip = new StreamZip({
|
|
165
|
+
file: archivedPackage,
|
|
166
|
+
storeEntries: true
|
|
167
|
+
});
|
|
168
|
+
zip.on('ready', () => {
|
|
169
|
+
let fileCount = 0;
|
|
170
|
+
for (let entry in zip.entries()) {
|
|
171
|
+
if (files.indexOf(entry.toLowerCase()) != -1) {
|
|
172
|
+
fileCount += 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
zip.close();
|
|
176
|
+
deferred.resolve(fileCount == files.length);
|
|
177
|
+
});
|
|
178
|
+
zip.on('error', error => {
|
|
179
|
+
deferred.reject(error);
|
|
180
|
+
});
|
|
181
|
+
return deferred.promise;
|
|
182
|
+
}
|
|
183
|
+
exports.checkIfFilesExistsInZip = checkIfFilesExistsInZip;
|