251 lines
33 KiB
JavaScript
251 lines
33 KiB
JavaScript
"use strict";
|
|
var plugins = require("./npmci.plugins");
|
|
var paths = require("./npmci.paths");
|
|
var NpmciEnv = require("./npmci.env");
|
|
var npmci_bash_1 = require("./npmci.bash");
|
|
exports.build = function () {
|
|
var done = plugins.q.defer();
|
|
exports.readDockerfiles()
|
|
.then(exports.sortDockerfiles)
|
|
.then(exports.mapDockerfiles)
|
|
.then(exports.buildDockerfiles)
|
|
.then(exports.pushDockerfiles)
|
|
.then(function () {
|
|
done.resolve();
|
|
});
|
|
return done.promise;
|
|
};
|
|
exports.readDockerfiles = function () {
|
|
var done = plugins.q.defer();
|
|
var readDockerfilesArray = [];
|
|
plugins.gulp.src("./Dockerfile*")
|
|
.pipe(plugins.through2.obj(function (file, enc, cb) {
|
|
var myDockerfile = new Dockerfile({
|
|
filePath: file.path,
|
|
read: true
|
|
});
|
|
readDockerfilesArray.push(myDockerfile);
|
|
cb(null, file);
|
|
}, function () {
|
|
done.resolve(readDockerfilesArray);
|
|
}));
|
|
return done.promise;
|
|
};
|
|
exports.sortDockerfiles = function (sortableArrayArg) {
|
|
var done = plugins.q.defer();
|
|
var sortedArray = [];
|
|
var trackingArray = [];
|
|
var sorterFunctionCounter = 0;
|
|
var sorterFunction = function () {
|
|
sortableArrayArg.forEach(function (dockerfileArg) {
|
|
var cleanTags = exports.cleanTagsArrayFunction(sortableArrayArg, trackingArray);
|
|
if (cleanTags.indexOf(dockerfileArg.baseImage) == -1 && trackingArray.indexOf(dockerfileArg) == -1) {
|
|
sortedArray.push(dockerfileArg);
|
|
trackingArray.push(dockerfileArg);
|
|
}
|
|
else if (cleanTags.indexOf(dockerfileArg.baseImage) != -1) {
|
|
dockerfileArg.localBaseImageDependent = true;
|
|
}
|
|
;
|
|
});
|
|
if (sortableArrayArg.length == sortedArray.length) {
|
|
done.resolve(sortedArray);
|
|
}
|
|
else if (sorterFunctionCounter < 10) {
|
|
sorterFunctionCounter++;
|
|
sorterFunction();
|
|
}
|
|
;
|
|
};
|
|
sorterFunction();
|
|
return done.promise;
|
|
};
|
|
exports.mapDockerfiles = function (sortedArray) {
|
|
var done = plugins.q.defer();
|
|
sortedArray.forEach(function (dockerfileArg) {
|
|
if (dockerfileArg.localBaseImageDependent) {
|
|
sortedArray.forEach(function (dockfile2) {
|
|
if (dockfile2.cleanTag == dockerfileArg.baseImage) {
|
|
dockerfileArg.localBaseDockerfile = dockfile2;
|
|
}
|
|
});
|
|
}
|
|
;
|
|
});
|
|
done.resolve(sortedArray);
|
|
return done.promise;
|
|
};
|
|
exports.buildDockerfiles = function (sortedArrayArg) {
|
|
var done = plugins.q.defer();
|
|
sortedArrayArg.forEach(function (dockerfileArg) {
|
|
dockerfileArg.build();
|
|
});
|
|
done.resolve(sortedArrayArg);
|
|
return done.promise;
|
|
};
|
|
exports.pushDockerfiles = function (sortedArrayArg) {
|
|
var done = plugins.q.defer();
|
|
sortedArrayArg.forEach(function (dockerfileArg) {
|
|
dockerfileArg.push();
|
|
});
|
|
done.resolve(sortedArrayArg);
|
|
return done.promise;
|
|
};
|
|
exports.pullDockerfileImages = function (sortableArrayArg) {
|
|
var done = plugins.q.defer();
|
|
sortableArrayArg.forEach(function (dockerfileArg) {
|
|
dockerfileArg.pull();
|
|
});
|
|
done.resolve(sortableArrayArg);
|
|
return done.promise;
|
|
};
|
|
exports.testDockerfiles = function (sortedArrayArg) {
|
|
var done = plugins.q.defer();
|
|
sortedArrayArg.forEach(function (dockerfileArg) {
|
|
dockerfileArg.test();
|
|
});
|
|
done.resolve(sortedArrayArg);
|
|
return done.promise;
|
|
};
|
|
exports.releaseDockerfiles = function (sortedArrayArg) {
|
|
var done = plugins.q.defer();
|
|
sortedArrayArg.forEach(function (dockerfileArg) {
|
|
dockerfileArg.release();
|
|
});
|
|
done.resolve(sortedArrayArg);
|
|
return done.promise;
|
|
};
|
|
var Dockerfile = (function () {
|
|
function Dockerfile(options) {
|
|
this.filePath = options.filePath;
|
|
this.repo = NpmciEnv.repo.user + "/" + NpmciEnv.repo.repo;
|
|
this.version = exports.dockerFileVersion(plugins.path.parse(options.filePath).base);
|
|
this.cleanTag = this.repo + ":" + this.version;
|
|
this.buildTag = exports.dockerTag(this.repo, this.version, "build");
|
|
this.releaseTag = exports.dockerTag(this.repo, this.version, "release");
|
|
this.containerName = "dockerfile-" + this.version;
|
|
if (options.filePath && options.read) {
|
|
this.content = plugins.smartfile.local.toStringSync(plugins.path.resolve(options.filePath));
|
|
}
|
|
;
|
|
this.baseImage = exports.dockerBaseImage(this.content);
|
|
this.localBaseImageDependent = false;
|
|
}
|
|
;
|
|
Dockerfile.prototype.build = function () {
|
|
var done = plugins.q.defer();
|
|
this.patchContents();
|
|
npmci_bash_1.bashBare("docker build -t " + this.buildTag + " -f " + this.filePath + " .");
|
|
NpmciEnv.dockerFilesBuilt.push(this);
|
|
this.restoreContents();
|
|
done.resolve();
|
|
return done.promise;
|
|
};
|
|
;
|
|
Dockerfile.prototype.push = function () {
|
|
var done = plugins.q.defer();
|
|
if (this.buildTag) {
|
|
npmci_bash_1.bashBare("docker push " + this.buildTag);
|
|
}
|
|
else {
|
|
plugins.beautylog.error("Dockerfile hasn't been built yet!");
|
|
}
|
|
done.resolve();
|
|
return done.promise;
|
|
};
|
|
Dockerfile.prototype.pull = function () {
|
|
npmci_bash_1.bashBare("docker pull " + this.buildTag);
|
|
};
|
|
;
|
|
Dockerfile.prototype.test = function () {
|
|
var testExists = plugins.smartfile.checks.fileExistsSync(plugins.path.join(paths.NpmciProjectDir, ("./test/test_" + this.version + ".sh")));
|
|
if (testExists) {
|
|
npmci_bash_1.bashBare("docker run -v " +
|
|
plugins.path.join(paths.NpmciProjectDir, "./test") + ":/test/ " +
|
|
"--name " + this.containerName + " /test/" + "test_" + this.version + ".sh");
|
|
}
|
|
else {
|
|
plugins.beautylog.warn("skipping tests for " + this.cleanTag + " because no testfile was found!");
|
|
}
|
|
};
|
|
;
|
|
Dockerfile.prototype.release = function () {
|
|
npmci_bash_1.bashBare("docker tag " + this.getId() + " " + this.releaseTag);
|
|
npmci_bash_1.bashBare("docker push " + this.releaseTag);
|
|
};
|
|
Dockerfile.prototype.getId = function () {
|
|
var containerId = npmci_bash_1.bashBare("docker inspect --format=\"{{.Id}}\" " + this.buildTag);
|
|
return containerId;
|
|
};
|
|
;
|
|
Dockerfile.prototype.patchContents = function () {
|
|
var done = plugins.q.defer();
|
|
if (this.localBaseImageDependent == true) {
|
|
this.patchedContent = this.content.replace(/FROM\s[a-zA-Z0-9\/\-\:]*/, 'FROM ' + this.localBaseDockerfile.buildTag);
|
|
plugins.smartfile.memory.toFsSync(this.patchedContent, {
|
|
fileName: plugins.path.parse(this.filePath).name,
|
|
filePath: plugins.path.parse(this.filePath).dir
|
|
});
|
|
}
|
|
done.resolve();
|
|
return done.promise;
|
|
};
|
|
;
|
|
Dockerfile.prototype.restoreContents = function () {
|
|
var done = plugins.q.defer();
|
|
if (this.localBaseImageDependent == true) {
|
|
plugins.smartfile.memory.toFsSync(this.content, {
|
|
fileName: plugins.path.parse(this.filePath).name,
|
|
filePath: plugins.path.parse(this.filePath).dir
|
|
});
|
|
}
|
|
done.resolve();
|
|
return done.promise;
|
|
};
|
|
;
|
|
return Dockerfile;
|
|
}());
|
|
exports.Dockerfile = Dockerfile;
|
|
exports.dockerFileVersion = function (dockerfileNameArg) {
|
|
var versionString;
|
|
var versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/;
|
|
var regexResultArray = versionRegex.exec(dockerfileNameArg);
|
|
if (regexResultArray && regexResultArray.length == 2) {
|
|
versionString = regexResultArray[1];
|
|
}
|
|
else {
|
|
versionString = "latest";
|
|
}
|
|
return versionString;
|
|
};
|
|
exports.dockerBaseImage = function (dockerfileContentArg) {
|
|
var baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/;
|
|
var regexResultArray = baseImageRegex.exec(dockerfileContentArg);
|
|
return regexResultArray[1];
|
|
};
|
|
exports.dockerTag = function (repoArg, versionArg, stageArg) {
|
|
var tagString;
|
|
var registry = NpmciEnv.dockerRegistry;
|
|
if (stageArg == "build" || stageArg == "test") {
|
|
registry = "registry.gitlab.com";
|
|
}
|
|
var repo = repoArg;
|
|
var version = versionArg;
|
|
if (NpmciEnv.buildStage == "build" || NpmciEnv.buildStage == "test") {
|
|
version = version + "_test";
|
|
}
|
|
tagString = registry + "/" + repo + ":" + version;
|
|
return tagString;
|
|
};
|
|
exports.cleanTagsArrayFunction = function (dockerfileArrayArg, trackingArrayArg) {
|
|
var cleanTagsArray = [];
|
|
dockerfileArrayArg.forEach(function (dockerfileArg) {
|
|
if (trackingArrayArg.indexOf(dockerfileArg) == -1) {
|
|
cleanTagsArray.push(dockerfileArg.cleanTag);
|
|
}
|
|
});
|
|
return cleanTagsArray;
|
|
};
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf8;base64,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dCI6WyJpbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gXCIuL25wbWNpLnBsdWdpbnNcIjtcbmltcG9ydCAqIGFzIHBhdGhzIGZyb20gXCIuL25wbWNpLnBhdGhzXCI7XG5pbXBvcnQgKiBhcyBOcG1jaUVudiBmcm9tIFwiLi9ucG1jaS5lbnZcIjtcbmltcG9ydCB7YmFzaEJhcmV9IGZyb20gXCIuL25wbWNpLmJhc2hcIjtcblxuZXhwb3J0IGxldCBidWlsZCA9IGZ1bmN0aW9uKCl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICByZWFkRG9ja2VyZmlsZXMoKVxuICAgICAgICAudGhlbihzb3J0RG9ja2VyZmlsZXMpXG4gICAgICAgIC50aGVuKG1hcERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbihidWlsZERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbihwdXNoRG9ja2VyZmlsZXMpXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGRvbmUucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHJlYWREb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKCl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBsZXQgcmVhZERvY2tlcmZpbGVzQXJyYXk6RG9ja2VyZmlsZVtdID0gW11cbiAgICBwbHVnaW5zLmd1bHAuc3JjKFwiLi9Eb2NrZXJmaWxlKlwiKVxuICAgICAgICAucGlwZShwbHVnaW5zLnRocm91Z2gyLm9iaihmdW5jdGlvbihmaWxlLGVuYyxjYil7XG4gICAgICAgICAgICBsZXQgbXlEb2NrZXJmaWxlID0gbmV3IERvY2tlcmZpbGUoe1xuICAgICAgICAgICAgICAgIGZpbGVQYXRoOmZpbGUucGF0aCxcbiAgICAgICAgICAgICAgICByZWFkOnRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhZERvY2tlcmZpbGVzQXJyYXkucHVzaChteURvY2tlcmZpbGUpO1xuICAgICAgICAgICAgY2IobnVsbCxmaWxlKTtcbiAgICAgICAgIH0sZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICBkb25lLnJlc29sdmUocmVhZERvY2tlcmZpbGVzQXJyYXkpO1xuICAgICAgICAgfSkpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgc29ydERvY2tlcmZpbGVzID0gZnVuY3Rpb24oc29ydGFibGVBcnJheUFyZzpEb2NrZXJmaWxlW10pe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgbGV0IHNvcnRlZEFycmF5OkRvY2tlcmZpbGVbXSA9IFtdOyBcbiAgICBsZXQgdHJhY2tpbmdBcnJheTpEb2NrZXJmaWxlW10gPSBbXTtcbiAgICBsZXQgc29ydGVyRnVuY3Rpb25Db3VudGVyOm51bWJlciA9IDA7XG4gICAgbGV0IHNvcnRlckZ1bmN0aW9uID0gZnVuY3Rpb24oKXtcbiAgICAgICAgc29ydGFibGVBcnJheUFyZy5mb3JFYWNoKChkb2NrZXJmaWxlQXJnKT0+e1xuICAgICAgICAgICAgbGV0IGNsZWFuVGFncyA9IGNsZWFuVGFnc0FycmF5RnVuY3Rpb24oc29ydGFibGVBcnJheUFyZyx0cmFja2luZ0FycmF5KTtcbiAgICAgICAgICAgIGlmKGNsZWFuVGFncy5pbmRleE9mKGRvY2tlcmZpbGVBcmcuYmFzZUltYWdlKSA9PSAtMSAmJiB0cmFja2luZ0FycmF5LmluZGV4T2YoZG9ja2VyZmlsZUFyZykgPT0gLTEpe1xuICAgICAgICAgICAgICAgIHNvcnRlZEFycmF5LnB1c2goZG9ja2VyZmlsZUFyZyk7XG4gICAgICAgICAgICAgICAgdHJhY2tpbmdBcnJheS5wdXNoKGRvY2tlcmZpbGVBcmcpO1xuICAgICAgICAgICAgfSBlbHNlIGlmKGNsZWFuVGFncy5pbmRleE9mKGRvY2tlcmZpbGVBcmcuYmFzZUltYWdlKSAhPSAtMSl7XG4gICAgICAgICAgICAgICAgZG9ja2VyZmlsZUFyZy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9IHRydWU7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYoc29ydGFibGVBcnJheUFyZy5sZW5ndGggPT0gc29ydGVkQXJyYXkubGVuZ3RoKXtcbiAgICAgICAgICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ydGVyRnVuY3Rpb25Db3VudGVyIDwgMTApIHtcbiAgICAgICAgICAgIHNvcnRlckZ1bmN0aW9uQ291bnRlcisrO1xuICAgICAgICAgICAgc29ydGVyRnVuY3Rpb24oKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgc29ydGVyRnVuY3Rpb24oKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxuZXhwb3J0IGxldCBtYXBEb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKHNvcnRlZEFycmF5OkRvY2tlcmZpbGVbXSl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBzb3J0ZWRBcnJheS5mb3JFYWNoKChkb2NrZXJmaWxlQXJnKSA9PiB7XG4gICAgICAgIGlmKGRvY2tlcmZpbGVBcmcubG9jYWxCYXNlSW1hZ2VEZXBlbmRlbnQpe1xuICAgICAgICAgICAgc29ydGVkQXJyYXkuZm9yRWFjaCgoZG9ja2ZpbGUyOkRvY2tlcmZpbGUpID0+IHtcbiAgICAgICAgICAgICAgICBpZihkb2NrZmlsZTIuY2xlYW5UYWcgPT0gZG9ja2VyZmlsZUFyZy5iYXNlSW1hZ2Upe1xuICAgICAgICAgICAgICAgICAgICBkb2NrZXJmaWxlQXJnLmxvY2FsQmFzZURvY2tlcmZpbGUgPSBkb2NrZmlsZTI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICB9KTtcbiAgICBkb25lLnJlc29sdmUoc29ydGVkQXJyYXkpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgYnVpbGREb2NrZXJmaWxlcyA9IChzb3J0ZWRBcnJheUFyZzpEb2NrZXJmaWxlW10pID0+IHtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIHNvcnRlZEFycmF5QXJnLmZvckVhY2goZnVuY3Rpb24oZG9ja2VyZmlsZUFyZyl7XG4gICAgICAgIGRvY2tlcmZpbGVBcmcuYnVpbGQoKTtcbiAgICB9KVxuICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheUFyZyk7XG4gICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbn1cblxuZXhwb3J0IGxldCBwdXNoRG9ja2VyZmlsZXMgPSBmdW5jdGlvbihzb3J0ZWRBcnJheUFyZzpEb2NrZXJmaWxlW10pe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5wdXNoKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHB1bGxEb2NrZXJmaWxlSW1hZ2VzID0gKHNvcnRhYmxlQXJyYXlBcmc6RG9ja2VyZmlsZVtdKSA9PiB7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBzb3J0YWJsZUFycmF5QXJnLmZvckVhY2goKGRvY2tlcmZpbGVBcmcpID0+IHtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5wdWxsKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRhYmxlQXJyYXlBcmcpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59XG5cbmV4cG9ydCBsZXQgdGVzdERvY2tlcmZpbGVzID0gKHNvcnRlZEFycmF5QXJnOkRvY2tlcmZpbGVbXSkgPT4ge1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy50ZXN0KCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxuZXhwb3J0IGxldCByZWxlYXNlRG9ja2VyZmlsZXMgPSAoc29ydGVkQXJyYXlBcmc6RG9ja2VyZmlsZVtdKSA9PiB7XG4gICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5yZWxlYXNlKCk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgY2xhc3MgRG9ja2VyZmlsZSB7XG4gICAgZmlsZVBhdGg6c3RyaW5nO1xuICAgIHJlcG86c3RyaW5nO1xuICAgIHZlcnNpb246c3RyaW5nO1xuICAgIGNsZWFuVGFnOnN0cmluZztcbiAgICBidWlsZFRhZzpzdHJpbmc7XG4gICAgcmVsZWFzZVRhZzpzdHJpbmc7XG4gICAgY29udGFpbmVyTmFtZTpzdHJpbmdcbiAgICBjb250ZW50OnN0cmluZztcbiAgICBwYXRjaGVkQ29udGVudDpzdHJpbmc7XG4gICAgYmFzZUltYWdlOnN0cmluZztcbiAgICBsb2NhbEJhc2VJbWFnZURlcGVuZGVudDpib29sZWFuO1xuICAgIGxvY2FsQmFzZURvY2tlcmZpbGU6RG9ja2VyZmlsZTtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOntmaWxlUGF0aD86c3RyaW5nLGZpbGVDb250ZW50cz86c3RyaW5nfEJ1ZmZlcixyZWFkPzpib29sZWFufSl7XG4gICAgICAgIHRoaXMuZmlsZVBhdGggPSBvcHRpb25zLmZpbGVQYXRoO1xuICAgICAgICB0aGlzLnJlcG8gPSBOcG1jaUVudi5yZXBvLnVzZXIgKyBcIi9cIiArIE5wbWNpRW52LnJlcG8ucmVwbztcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gZG9ja2VyRmlsZVZlcnNpb24ocGx1Z2lucy5wYXRoLnBhcnNlKG9wdGlvbnMuZmlsZVBhdGgpLmJhc2UpO1xuICAgICAgICB0aGlzLmNsZWFuVGFnID0gdGhpcy5yZXBvICsgXCI6XCIgKyB0aGlzLnZlcnNpb247XG4gICAgICAgIHRoaXMuYnVpbGRUYWcgPSBkb2NrZXJUYWcodGhpcy5yZXBvLHRoaXMudmVyc2lvbixcImJ1aWxkXCIpO1xuICAgICAgICB0aGlzLnJlbGVhc2VUYWcgPSBkb2NrZXJUYWcodGhpcy5yZXBvLHRoaXMudmVyc2lvbixcInJlbGVhc2VcIik7XG4gICAgICAgIHRoaXMuY29udGFpbmVyTmFtZSA9IFwiZG9ja2VyZmlsZS1cIiArIHRoaXMudmVyc2lvbjtcbiAgICAgICAgaWYob3B0aW9ucy5maWxlUGF0aCAmJiBvcHRpb25zLnJlYWQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZW50ID0gcGx1Z2lucy5zbWFydGZpbGUubG9jYWwudG9TdHJpbmdTeW5jKHBsdWdpbnMucGF0aC5yZXNvbHZlKG9wdGlvbnMuZmlsZVBhdGgpKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5iYXNlSW1hZ2UgPSBkb2NrZXJCYXNlSW1hZ2UodGhpcy5jb250ZW50KTtcbiAgICAgICAgdGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9IGZhbHNlO1xuICAgIH07XG4gICAgYnVpbGQoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgdGhpcy5wYXRjaENvbnRlbnRzKCk7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIGJ1aWxkIC10IFwiICsgdGhpcy5idWlsZFRhZyArIFwiIC1mIFwiICsgdGhpcy5maWxlUGF0aCArIFwiIC5cIik7XG4gICAgICAgIE5wbWNpRW52LmRvY2tlckZpbGVzQnVpbHQucHVzaCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZXN0b3JlQ29udGVudHMoKTtcbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbiAgICBwdXNoKCl7XG4gICAgICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgICAgIGlmKHRoaXMuYnVpbGRUYWcpe1xuICAgICAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVzaCBcIiArIHRoaXMuYnVpbGRUYWcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGx1Z2lucy5iZWF1dHlsb2cuZXJyb3IoXCJEb2NrZXJmaWxlIGhhc24ndCBiZWVuIGJ1aWx0IHlldCFcIik7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfVxuICAgIHB1bGwoKXtcbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVsbCBcIiArIHRoaXMuYnVpbGRUYWcpO1xuICAgIH07XG4gICAgdGVzdCgpe1xuICAgICAgICBsZXQgdGVzdEV4aXN0cyA9IHBsdWdpbnMuc21hcnRmaWxlLmNoZWNrcy5maWxlRXhpc3RzU3luYyhcbiAgICAgICAgICAgIHBsdWdpbnMucGF0aC5qb2luKHBhdGhzLk5wbWNpUHJvamVjdERpciwoXCIuL3Rlc3QvdGVzdF9cIiArIHRoaXMudmVyc2lvbiArIFwiLnNoXCIpKVxuICAgICAgICApO1xuICAgICAgICBpZih0ZXN0RXhpc3RzKXtcbiAgICAgICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHJ1biAtdiBcIiArIFxuICAgICAgICAgICAgICAgIHBsdWdpbnMucGF0aC5qb2luKHBhdGhzLk5wbWNpUHJvamVjdERpcixcIi4vdGVzdFwiKSArIFwiOi90ZXN0LyBcIiArXG4gICAgICAgICAgICAgICAgXCItLW5hbWUgXCIgKyB0aGlzLmNvbnRhaW5lck5hbWUgKyBcIiAvdGVzdC9cIiArIFwidGVzdF9cIiArIHRoaXMudmVyc2lvbiAgKyBcIi5zaFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBsdWdpbnMuYmVhdXR5bG9nLndhcm4oXCJza2lwcGluZyB0ZXN0cyBmb3IgXCIgKyB0aGlzLmNsZWFuVGFnICsgXCIgYmVjYXVzZSBubyB0ZXN0ZmlsZSB3YXMgZm91bmQhXCIpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZWxlYXNlKCl7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHRhZyBcIiArIHRoaXMuZ2V0SWQoKSArIFwiIFwiICsgdGhpcy5yZWxlYXNlVGFnKTtcbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgcHVzaCBcIiArIHRoaXMucmVsZWFzZVRhZyk7XG4gICAgfVxuICAgIGdldElkKCl7XG4gICAgICAgIGxldCBjb250YWluZXJJZCA9IGJhc2hCYXJlKFwiZG9ja2VyIGluc3BlY3QgLS1mb3JtYXQ9XFxcInt7LklkfX1cXFwiIFwiICsgdGhpcy5idWlsZFRhZyk7XG4gICAgICAgIHJldHVybiBjb250YWluZXJJZDtcbiAgICB9O1xuICAgIHBhdGNoQ29udGVudHMoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgaWYodGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9PSB0cnVlKXtcbiAgICAgICAgICAgIHRoaXMucGF0Y2hlZENvbnRlbnQgPSB0aGlzLmNvbnRlbnQucmVwbGFjZSgvRlJPTVxcc1thLXpBLVowLTlcXC9cXC1cXDpdKi8sICdGUk9NICcgKyB0aGlzLmxvY2FsQmFzZURvY2tlcmZpbGUuYnVpbGRUYWcpO1xuICAgICAgICAgICAgcGx1Z2lucy5zbWFydGZpbGUubWVtb3J5LnRvRnNTeW5jKFxuICAgICAgICAgICAgICAgIHRoaXMucGF0Y2hlZENvbnRlbnQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZTpwbHVnaW5zLnBhdGgucGFyc2UodGhpcy5maWxlUGF0aCkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZVBhdGg6cGx1Z2lucy5wYXRoLnBhcnNlKHRoaXMuZmlsZVBhdGgpLmRpclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbiAgICByZXN0b3JlQ29udGVudHMoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgaWYodGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9PSB0cnVlKXtcbiAgICAgICAgICAgIHBsdWdpbnMuc21hcnRmaWxlLm1lbW9yeS50b0ZzU3luYyhcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZTpwbHVnaW5zLnBhdGgucGFyc2UodGhpcy5maWxlUGF0aCkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZVBhdGg6cGx1Z2lucy5wYXRoLnBhcnNlKHRoaXMuZmlsZVBhdGgpLmRpclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfTtcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJGaWxlVmVyc2lvbiA9IGZ1bmN0aW9uKGRvY2tlcmZpbGVOYW1lQXJnOnN0cmluZyk6c3RyaW5ne1xuICAgIGxldCB2ZXJzaW9uU3RyaW5nOnN0cmluZztcbiAgICBsZXQgdmVyc2lvblJlZ2V4ID0gL0RvY2tlcmZpbGVfKFthLXpBLVowLTlcXC5dKikkLztcbiAgICBsZXQgcmVnZXhSZXN1bHRBcnJheSA9IHZlcnNpb25SZWdleC5leGVjKGRvY2tlcmZpbGVOYW1lQXJnKTtcbiAgICBpZihyZWdleFJlc3VsdEFycmF5ICYmIHJlZ2V4UmVzdWx0QXJyYXkubGVuZ3RoID09IDIpe1xuICAgICAgICB2ZXJzaW9uU3RyaW5nID0gcmVnZXhSZXN1bHRBcnJheVsxXTsgICAgICAgIFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHZlcnNpb25TdHJpbmcgPSBcImxhdGVzdFwiO1xuICAgIH1cbiAgICByZXR1cm4gdmVyc2lvblN0cmluZztcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJCYXNlSW1hZ2UgPSBmdW5jdGlvbihkb2NrZXJmaWxlQ29udGVudEFyZzpzdHJpbmcpe1xuICAgIGxldCBiYXNlSW1hZ2VSZWdleCA9IC9GUk9NXFxzKFthLXpBLXowLTlcXC9cXC1cXDpdKilcXG4/L1xuICAgIGxldCByZWdleFJlc3VsdEFycmF5ID0gYmFzZUltYWdlUmVnZXguZXhlYyhkb2NrZXJmaWxlQ29udGVudEFyZylcbiAgICByZXR1cm4gcmVnZXhSZXN1bHRBcnJheVsxXTtcbn1cblxuZXhwb3J0IGxldCBkb2NrZXJUYWcgPSBmdW5jdGlvbihyZXBvQXJnOnN0cmluZyx2ZXJzaW9uQXJnOnN0cmluZyxzdGFnZUFyZzpzdHJpbmcpOnN0cmluZ3tcbiAgICBsZXQgdGFnU3RyaW5nOnN0cmluZztcbiAgICBsZXQgcmVnaXN0cnkgPSBOcG1jaUVudi5kb2NrZXJSZWdpc3RyeTtcbiAgICBpZihzdGFnZUFyZyA9PSBcImJ1aWxkXCIgIHx8IHN0YWdlQXJnID09IFwidGVzdFwiKXtcbiAgICAgICAgcmVnaXN0cnkgPSBcInJlZ2lzdHJ5LmdpdGxhYi5jb21cIjtcbiAgICB9IFxuICAgIGxldCByZXBvID0gcmVwb0FyZztcbiAgICBsZXQgdmVyc2lvbiA9IHZlcnNpb25Bcmc7XG4gICAgaWYoTnBtY2lFbnYuYnVpbGRTdGFnZSA9PSBcImJ1aWxkXCIgfHwgTnBtY2lFbnYuYnVpbGRTdGFnZSA9PSBcInRlc3RcIil7XG4gICAgICAgIHZlcnNpb24gPSB2ZXJzaW9uICsgXCJfdGVzdFwiO1xuICAgIH1cbiAgICB0YWdTdHJpbmcgPSByZWdpc3RyeSArIFwiL1wiICsgcmVwbyArIFwiOlwiICsgdmVyc2lvbjtcbiAgICByZXR1cm4gdGFnU3RyaW5nO1xufTtcblxuZXhwb3J0IGxldCBjbGVhblRhZ3NBcnJheUZ1bmN0aW9uID0gZnVuY3Rpb24oZG9ja2VyZmlsZUFycmF5QXJnOkRvY2tlcmZpbGVbXSx0cmFja2luZ0FycmF5QXJnOkRvY2tlcmZpbGVbXSk6c3RyaW5nW117XG4gICAgbGV0IGNsZWFuVGFnc0FycmF5OnN0cmluZ1tdID0gW107XG4gICAgZG9ja2VyZmlsZUFycmF5QXJnLmZvckVhY2goZnVuY3Rpb24oZG9ja2VyZmlsZUFyZyl7XG4gICAgICAgIGlmKHRyYWNraW5nQXJyYXlBcmcuaW5kZXhPZihkb2NrZXJmaWxlQXJnKSA9PSAtMSl7XG4gICAgICAgICAgICBjbGVhblRhZ3NBcnJheS5wdXNoKGRvY2tlcmZpbGVBcmcuY2xlYW5UYWcpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNsZWFuVGFnc0FycmF5O1xufSJdfQ==
|