225 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			30 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 cleanTagsOriginal = exports.cleanTagsArrayFunction(sortableArrayArg, sortedArray);
 | |
|     var sorterFunctionCounter = 0;
 | |
|     var sorterFunction = function () {
 | |
|         sortableArrayArg.forEach(function (dockerfileArg) {
 | |
|             var cleanTags = exports.cleanTagsArrayFunction(sortableArrayArg, sortedArray);
 | |
|             if (cleanTags.indexOf(dockerfileArg.baseImage) == -1 && sortedArray.indexOf(dockerfileArg) == -1) {
 | |
|                 sortedArray.push(dockerfileArg);
 | |
|             }
 | |
|             ;
 | |
|             if (cleanTagsOriginal.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(NpmciEnv.buildStage);
 | |
|     });
 | |
|     done.resolve(sortedArrayArg);
 | |
|     return done.promise;
 | |
| };
 | |
| exports.pullDockerfileImages = function (sortableArrayArg, registryArg) {
 | |
|     if (registryArg === void 0) { registryArg = "registry.gitlab.com"; }
 | |
|     var done = plugins.q.defer();
 | |
|     sortableArrayArg.forEach(function (dockerfileArg) {
 | |
|         dockerfileArg.pull(registryArg);
 | |
|     });
 | |
|     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;
 | |
| };
 | |
| 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 = this.cleanTag;
 | |
|         this.testTag = exports.dockerTag("registry.gitlab.com", this.repo, this.version, "test");
 | |
|         this.releaseTag = exports.dockerTag(NpmciEnv.dockerRegistry, this.repo, this.version);
 | |
|         this.containerName = "dockerfile-" + this.version;
 | |
|         if (options.filePath && options.read) {
 | |
|             this.content = plugins.smartfile.fs.toStringSync(plugins.path.resolve(options.filePath));
 | |
|         }
 | |
|         ;
 | |
|         this.baseImage = exports.dockerBaseImage(this.content);
 | |
|         this.localBaseImageDependent = false;
 | |
|     }
 | |
|     ;
 | |
|     Dockerfile.prototype.build = function () {
 | |
|         var done = plugins.q.defer();
 | |
|         plugins.beautylog.info("now building Dockerfile for " + this.cleanTag);
 | |
|         npmci_bash_1.bashBare("docker build -t " + this.buildTag + " -f " + this.filePath + " .");
 | |
|         NpmciEnv.dockerFilesBuilt.push(this);
 | |
|         done.resolve();
 | |
|         return done.promise;
 | |
|     };
 | |
|     ;
 | |
|     Dockerfile.prototype.push = function (stageArg) {
 | |
|         var done = plugins.q.defer();
 | |
|         var pushTag;
 | |
|         switch (stageArg) {
 | |
|             case "release":
 | |
|                 pushTag = this.releaseTag;
 | |
|                 break;
 | |
|             case "test":
 | |
|             default:
 | |
|                 pushTag = this.testTag;
 | |
|                 break;
 | |
|         }
 | |
|         npmci_bash_1.bashBare("docker tag " + this.buildTag + " " + pushTag);
 | |
|         npmci_bash_1.bashBare("docker push " + pushTag);
 | |
|         done.resolve();
 | |
|         return done.promise;
 | |
|     };
 | |
|     Dockerfile.prototype.pull = function (registryArg) {
 | |
|         var pullTag = this.testTag;
 | |
|         npmci_bash_1.bashBare("docker pull " + pullTag);
 | |
|         npmci_bash_1.bashBare("docker tag " + pullTag + " " + this.buildTag);
 | |
|     };
 | |
|     ;
 | |
|     Dockerfile.prototype.test = function () {
 | |
|         var testFile = plugins.path.join(paths.NpmciTestDir, "test_" + this.version + ".sh");
 | |
|         var testFileExists = plugins.smartfile.fs.fileExistsSync(testFile);
 | |
|         if (testFileExists) {
 | |
|             npmci_bash_1.bashBare("docker run --name npmci_test_container " + this.buildTag + " mkdir /npmci_test");
 | |
|             npmci_bash_1.bashBare("docker cp " + testFile + " npmci_test_container:/npmci_test/test.sh");
 | |
|             npmci_bash_1.bashBare("docker commit npmci_test_container npmci_test_image");
 | |
|             npmci_bash_1.bashBare("docker run npmci_test_image sh /npmci_test/test.sh");
 | |
|             npmci_bash_1.bashBare("docker rm npmci_test_container");
 | |
|             npmci_bash_1.bashBare("docker rmi --force npmci_test_image");
 | |
|         }
 | |
|         else {
 | |
|             plugins.beautylog.warn("skipping tests for " + this.cleanTag + " because no testfile was found!");
 | |
|         }
 | |
|     };
 | |
|     ;
 | |
|     Dockerfile.prototype.getId = function () {
 | |
|         var containerId = npmci_bash_1.bashBare("docker inspect --type=image --format=\"{{.Id}}\" " + this.buildTag);
 | |
|         return containerId;
 | |
|     };
 | |
|     ;
 | |
|     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 (registryArg, repoArg, versionArg, suffixArg) {
 | |
|     var tagString;
 | |
|     var registry = registryArg;
 | |
|     var repo = repoArg;
 | |
|     var version = versionArg;
 | |
|     if (suffixArg) {
 | |
|         version = versionArg + "_" + suffixArg;
 | |
|     }
 | |
|     ;
 | |
|     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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SSxTQUFnQixDQUFDO0lBQ3JCLElBQUksUUFBUSxHQUFHLFdBQVcsQ0FBQztJQUMzQixJQUFJLElBQUksR0FBRyxPQUFPLENBQUM7SUFDbkIsSUFBSSxPQUFPLEdBQUcsVUFBVSxDQUFDO0lBQ3pCLEVBQUUsQ0FBQSxDQUFDLFNBQVMsQ0FBQyxDQUFBLENBQUM7UUFDVixPQUFPLEdBQUcsVUFBVSxHQUFHLEdBQUcsR0FBRyxTQUFTLENBQUM7SUFDM0MsQ0FBQztJQUFBLENBQUM7SUFDRixTQUFTLEdBQUcsUUFBUSxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLE9BQU8sQ0FBQztJQUNsRCxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ3JCLENBQUMsQ0FBQztBQUVTLDhCQUFzQixHQUFHLFVBQVMsa0JBQStCLEVBQUMsZ0JBQTZCO0lBQ3RHLElBQUksY0FBYyxHQUFZLEVBQUUsQ0FBQztJQUNqQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsVUFBUyxhQUFhO1FBQzdDLEVBQUUsQ0FBQSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUM7WUFDOUMsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEQsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQztBQUMxQixDQUFDLENBQUEiLCJmaWxlIjoibnBtY2kuYnVpbGQuZG9ja2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGx1Z2lucyBmcm9tIFwiLi9ucG1jaS5wbHVnaW5zXCI7XG5pbXBvcnQgKiBhcyBwYXRocyBmcm9tIFwiLi9ucG1jaS5wYXRoc1wiO1xuaW1wb3J0ICogYXMgTnBtY2lFbnYgZnJvbSBcIi4vbnBtY2kuZW52XCI7XG5pbXBvcnQge2Jhc2hCYXJlfSBmcm9tIFwiLi9ucG1jaS5iYXNoXCI7XG5cbmV4cG9ydCBsZXQgYnVpbGQgPSBmdW5jdGlvbigpe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgcmVhZERvY2tlcmZpbGVzKClcbiAgICAgICAgLnRoZW4oc29ydERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbihtYXBEb2NrZXJmaWxlcylcbiAgICAgICAgLnRoZW4oYnVpbGREb2NrZXJmaWxlcylcbiAgICAgICAgLnRoZW4ocHVzaERvY2tlcmZpbGVzKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBkb25lLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbn1cblxuZXhwb3J0IGxldCByZWFkRG9ja2VyZmlsZXMgPSBmdW5jdGlvbigpe1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgbGV0IHJlYWREb2NrZXJmaWxlc0FycmF5OkRvY2tlcmZpbGVbXSA9IFtdXG4gICAgcGx1Z2lucy5ndWxwLnNyYyhcIi4vRG9ja2VyZmlsZSpcIilcbiAgICAgICAgLnBpcGUocGx1Z2lucy50aHJvdWdoMi5vYmooZnVuY3Rpb24oZmlsZSxlbmMsY2Ipe1xuICAgICAgICAgICAgbGV0IG15RG9ja2VyZmlsZSA9IG5ldyBEb2NrZXJmaWxlKHtcbiAgICAgICAgICAgICAgICBmaWxlUGF0aDpmaWxlLnBhdGgsXG4gICAgICAgICAgICAgICAgcmVhZDp0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlYWREb2NrZXJmaWxlc0FycmF5LnB1c2gobXlEb2NrZXJmaWxlKTtcbiAgICAgICAgICAgIGNiKG51bGwsZmlsZSk7XG4gICAgICAgICB9LGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgZG9uZS5yZXNvbHZlKHJlYWREb2NrZXJmaWxlc0FycmF5KTtcbiAgICAgICAgIH0pKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHNvcnREb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKHNvcnRhYmxlQXJyYXlBcmc6RG9ja2VyZmlsZVtdKXtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIGxldCBzb3J0ZWRBcnJheTpEb2NrZXJmaWxlW10gPSBbXTtcbiAgICBsZXQgY2xlYW5UYWdzT3JpZ2luYWwgPSBjbGVhblRhZ3NBcnJheUZ1bmN0aW9uKHNvcnRhYmxlQXJyYXlBcmcsc29ydGVkQXJyYXkpO1xuICAgIGxldCBzb3J0ZXJGdW5jdGlvbkNvdW50ZXI6bnVtYmVyID0gMDtcbiAgICBsZXQgc29ydGVyRnVuY3Rpb24gPSBmdW5jdGlvbigpe1xuICAgICAgICBzb3J0YWJsZUFycmF5QXJnLmZvckVhY2goKGRvY2tlcmZpbGVBcmcpPT57XG4gICAgICAgICAgICBsZXQgY2xlYW5UYWdzID0gY2xlYW5UYWdzQXJyYXlGdW5jdGlvbihzb3J0YWJsZUFycmF5QXJnLHNvcnRlZEFycmF5KTtcbiAgICAgICAgICAgIGlmKGNsZWFuVGFncy5pbmRleE9mKGRvY2tlcmZpbGVBcmcuYmFzZUltYWdlKSA9PSAtMSAmJiBzb3J0ZWRBcnJheS5pbmRleE9mKGRvY2tlcmZpbGVBcmcpID09IC0xKXtcbiAgICAgICAgICAgICAgICBzb3J0ZWRBcnJheS5wdXNoKGRvY2tlcmZpbGVBcmcpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmKGNsZWFuVGFnc09yaWdpbmFsLmluZGV4T2YoZG9ja2VyZmlsZUFyZy5iYXNlSW1hZ2UpICE9IC0xKXtcbiAgICAgICAgICAgICAgICBkb2NrZXJmaWxlQXJnLmxvY2FsQmFzZUltYWdlRGVwZW5kZW50ID0gdHJ1ZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZihzb3J0YWJsZUFycmF5QXJnLmxlbmd0aCA9PSBzb3J0ZWRBcnJheS5sZW5ndGgpe1xuICAgICAgICAgICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5KTtcbiAgICAgICAgfSBlbHNlIGlmIChzb3J0ZXJGdW5jdGlvbkNvdW50ZXIgPCAxMCkge1xuICAgICAgICAgICAgc29ydGVyRnVuY3Rpb25Db3VudGVyKys7XG4gICAgICAgICAgICBzb3J0ZXJGdW5jdGlvbigpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBzb3J0ZXJGdW5jdGlvbigpO1xuICAgIHJldHVybiBkb25lLnByb21pc2U7XG59O1xuXG5leHBvcnQgbGV0IG1hcERvY2tlcmZpbGVzID0gZnVuY3Rpb24oc29ydGVkQXJyYXk6RG9ja2VyZmlsZVtdKXtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIHNvcnRlZEFycmF5LmZvckVhY2goKGRvY2tlcmZpbGVBcmcpID0+IHtcbiAgICAgICAgaWYoZG9ja2VyZmlsZUFyZy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCl7XG4gICAgICAgICAgICBzb3J0ZWRBcnJheS5mb3JFYWNoKChkb2NrZmlsZTI6RG9ja2VyZmlsZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmKGRvY2tmaWxlMi5jbGVhblRhZyA9PSBkb2NrZXJmaWxlQXJnLmJhc2VJbWFnZSl7XG4gICAgICAgICAgICAgICAgICAgIGRvY2tlcmZpbGVBcmcubG9jYWxCYXNlRG9ja2VyZmlsZSA9IGRvY2tmaWxlMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgIH0pO1xuICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheSk7XG4gICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbn1cblxuZXhwb3J0IGxldCBidWlsZERvY2tlcmZpbGVzID0gKHNvcnRlZEFycmF5QXJnOkRvY2tlcmZpbGVbXSkgPT4ge1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgc29ydGVkQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgZG9ja2VyZmlsZUFyZy5idWlsZCgpO1xuICAgIH0pXG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHB1c2hEb2NrZXJmaWxlcyA9IGZ1bmN0aW9uKHNvcnRlZEFycmF5QXJnOkRvY2tlcmZpbGVbXSl7XG4gICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICBzb3J0ZWRBcnJheUFyZy5mb3JFYWNoKGZ1bmN0aW9uKGRvY2tlcmZpbGVBcmcpe1xuICAgICAgICBkb2NrZXJmaWxlQXJnLnB1c2goTnBtY2lFbnYuYnVpbGRTdGFnZSk7XG4gICAgfSk7XG4gICAgZG9uZS5yZXNvbHZlKHNvcnRlZEFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHB1bGxEb2NrZXJmaWxlSW1hZ2VzID0gKHNvcnRhYmxlQXJyYXlBcmc6RG9ja2VyZmlsZVtdLHJlZ2lzdHJ5QXJnID0gXCJyZWdpc3RyeS5naXRsYWIuY29tXCIpID0+IHtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIHNvcnRhYmxlQXJyYXlBcmcuZm9yRWFjaCgoZG9ja2VyZmlsZUFyZykgPT4ge1xuICAgICAgICBkb2NrZXJmaWxlQXJnLnB1bGwocmVnaXN0cnlBcmcpO1xuICAgIH0pO1xuICAgIGRvbmUucmVzb2x2ZShzb3J0YWJsZUFycmF5QXJnKTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufVxuXG5leHBvcnQgbGV0IHRlc3REb2NrZXJmaWxlcyA9IChzb3J0ZWRBcnJheUFyZzpEb2NrZXJmaWxlW10pID0+IHtcbiAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgIHNvcnRlZEFycmF5QXJnLmZvckVhY2goZnVuY3Rpb24oZG9ja2VyZmlsZUFyZyl7XG4gICAgICAgIGRvY2tlcmZpbGVBcmcudGVzdCgpO1xuICAgIH0pO1xuICAgIGRvbmUucmVzb2x2ZShzb3J0ZWRBcnJheUFyZyk7XG4gICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbn07XG5cbmV4cG9ydCBjbGFzcyBEb2NrZXJmaWxlIHtcbiAgICBmaWxlUGF0aDpzdHJpbmc7XG4gICAgcmVwbzpzdHJpbmc7XG4gICAgdmVyc2lvbjpzdHJpbmc7XG4gICAgY2xlYW5UYWc6c3RyaW5nO1xuICAgIGJ1aWxkVGFnOnN0cmluZztcbiAgICB0ZXN0VGFnOnN0cmluZztcbiAgICByZWxlYXNlVGFnOnN0cmluZztcbiAgICBjb250YWluZXJOYW1lOnN0cmluZ1xuICAgIGNvbnRlbnQ6c3RyaW5nO1xuICAgIGJhc2VJbWFnZTpzdHJpbmc7XG4gICAgbG9jYWxCYXNlSW1hZ2VEZXBlbmRlbnQ6Ym9vbGVhbjtcbiAgICBsb2NhbEJhc2VEb2NrZXJmaWxlOkRvY2tlcmZpbGU7XG4gICAgY29uc3RydWN0b3Iob3B0aW9uczp7ZmlsZVBhdGg/OnN0cmluZyxmaWxlQ29udGVudHM/OnN0cmluZ3xCdWZmZXIscmVhZD86Ym9vbGVhbn0pe1xuICAgICAgICB0aGlzLmZpbGVQYXRoID0gb3B0aW9ucy5maWxlUGF0aDtcbiAgICAgICAgdGhpcy5yZXBvID0gTnBtY2lFbnYucmVwby51c2VyICsgXCIvXCIgKyBOcG1jaUVudi5yZXBvLnJlcG87XG4gICAgICAgIHRoaXMudmVyc2lvbiA9IGRvY2tlckZpbGVWZXJzaW9uKHBsdWdpbnMucGF0aC5wYXJzZShvcHRpb25zLmZpbGVQYXRoKS5iYXNlKTtcbiAgICAgICAgdGhpcy5jbGVhblRhZyA9IHRoaXMucmVwbyArIFwiOlwiICsgdGhpcy52ZXJzaW9uO1xuICAgICAgICB0aGlzLmJ1aWxkVGFnID0gdGhpcy5jbGVhblRhZztcbiAgICAgICAgdGhpcy50ZXN0VGFnID0gZG9ja2VyVGFnKFwicmVnaXN0cnkuZ2l0bGFiLmNvbVwiLHRoaXMucmVwbyx0aGlzLnZlcnNpb24sXCJ0ZXN0XCIpO1xuICAgICAgICB0aGlzLnJlbGVhc2VUYWcgPSBkb2NrZXJUYWcoTnBtY2lFbnYuZG9ja2VyUmVnaXN0cnksdGhpcy5yZXBvLHRoaXMudmVyc2lvbik7XG4gICAgICAgIHRoaXMuY29udGFpbmVyTmFtZSA9IFwiZG9ja2VyZmlsZS1cIiArIHRoaXMudmVyc2lvbjtcbiAgICAgICAgaWYob3B0aW9ucy5maWxlUGF0aCAmJiBvcHRpb25zLnJlYWQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZW50ID0gcGx1Z2lucy5zbWFydGZpbGUuZnMudG9TdHJpbmdTeW5jKHBsdWdpbnMucGF0aC5yZXNvbHZlKG9wdGlvbnMuZmlsZVBhdGgpKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5iYXNlSW1hZ2UgPSBkb2NrZXJCYXNlSW1hZ2UodGhpcy5jb250ZW50KTtcbiAgICAgICAgdGhpcy5sb2NhbEJhc2VJbWFnZURlcGVuZGVudCA9IGZhbHNlO1xuICAgIH07XG4gICAgYnVpbGQoKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgcGx1Z2lucy5iZWF1dHlsb2cuaW5mbyhcIm5vdyBidWlsZGluZyBEb2NrZXJmaWxlIGZvciBcIiArIHRoaXMuY2xlYW5UYWcpO1xuICAgICAgICBiYXNoQmFyZShcImRvY2tlciBidWlsZCAtdCBcIiArIHRoaXMuYnVpbGRUYWcgKyBcIiAtZiBcIiArIHRoaXMuZmlsZVBhdGggKyBcIiAuXCIpO1xuICAgICAgICBOcG1jaUVudi5kb2NrZXJGaWxlc0J1aWx0LnB1c2godGhpcyk7XG4gICAgICAgIGRvbmUucmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xuICAgIH07XG4gICAgcHVzaChzdGFnZUFyZyl7XG4gICAgICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgICAgIGxldCBwdXNoVGFnO1xuICAgICAgICBzd2l0Y2ggKHN0YWdlQXJnKXtcbiAgICAgICAgICAgIGNhc2UgXCJyZWxlYXNlXCI6XG4gICAgICAgICAgICAgICAgcHVzaFRhZyA9IHRoaXMucmVsZWFzZVRhZztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJ0ZXN0XCI6XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHB1c2hUYWcgPSB0aGlzLnRlc3RUYWc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgdGFnIFwiICsgdGhpcy5idWlsZFRhZyArIFwiIFwiICsgcHVzaFRhZyk7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHB1c2ggXCIgKyBwdXNoVGFnKTtcbiAgICAgICAgZG9uZS5yZXNvbHZlKCk7XG4gICAgICAgIHJldHVybiBkb25lLnByb21pc2U7XG4gICAgfVxuICAgIHB1bGwocmVnaXN0cnlBcmc6c3RyaW5nKXtcbiAgICAgICAgbGV0IHB1bGxUYWcgPSB0aGlzLnRlc3RUYWc7XG4gICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHB1bGwgXCIgKyBwdWxsVGFnKTtcbiAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgdGFnIFwiICsgcHVsbFRhZyArIFwiIFwiICsgdGhpcy5idWlsZFRhZyk7XG4gICAgfTtcbiAgICB0ZXN0KCl7XG4gICAgICAgIGxldCB0ZXN0RmlsZTpzdHJpbmcgPSBwbHVnaW5zLnBhdGguam9pbihwYXRocy5OcG1jaVRlc3REaXIsXCJ0ZXN0X1wiICsgdGhpcy52ZXJzaW9uICsgXCIuc2hcIik7XG4gICAgICAgIGxldCB0ZXN0RmlsZUV4aXN0czpib29sZWFuID0gcGx1Z2lucy5zbWFydGZpbGUuZnMuZmlsZUV4aXN0c1N5bmModGVzdEZpbGUpO1xuICAgICAgICBpZih0ZXN0RmlsZUV4aXN0cyl7XG4gICAgICAgICAgICBiYXNoQmFyZShcImRvY2tlciBydW4gLS1uYW1lIG5wbWNpX3Rlc3RfY29udGFpbmVyIFwiICsgdGhpcy5idWlsZFRhZyArIFwiIG1rZGlyIC9ucG1jaV90ZXN0XCIpO1xuICAgICAgICAgICAgYmFzaEJhcmUoXCJkb2NrZXIgY3AgXCIgKyB0ZXN0RmlsZSArIFwiIG5wbWNpX3Rlc3RfY29udGFpbmVyOi9ucG1jaV90ZXN0L3Rlc3Quc2hcIik7XG4gICAgICAgICAgICBiYXNoQmFyZShcImRvY2tlciBjb21taXQgbnBtY2lfdGVzdF9jb250YWluZXIgbnBtY2lfdGVzdF9pbWFnZVwiKTtcbiAgICAgICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHJ1biBucG1jaV90ZXN0X2ltYWdlIHNoIC9ucG1jaV90ZXN0L3Rlc3Quc2hcIik7XG4gICAgICAgICAgICBiYXNoQmFyZShcImRvY2tlciBybSBucG1jaV90ZXN0X2NvbnRhaW5lclwiKTtcbiAgICAgICAgICAgIGJhc2hCYXJlKFwiZG9ja2VyIHJtaSAtLWZvcmNlIG5wbWNpX3Rlc3RfaW1hZ2VcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwbHVnaW5zLmJlYXV0eWxvZy53YXJuKFwic2tpcHBpbmcgdGVzdHMgZm9yIFwiICsgdGhpcy5jbGVhblRhZyArIFwiIGJlY2F1c2Ugbm8gdGVzdGZpbGUgd2FzIGZvdW5kIVwiKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgZ2V0SWQoKXtcbiAgICAgICAgbGV0IGNvbnRhaW5lcklkID0gYmFzaEJhcmUoXCJkb2NrZXIgaW5zcGVjdCAtLXR5cGU9aW1hZ2UgLS1mb3JtYXQ9XFxcInt7LklkfX1cXFwiIFwiICsgdGhpcy5idWlsZFRhZyk7XG4gICAgICAgIHJldHVybiBjb250YWluZXJJZDtcbiAgICB9O1xufVxuXG5leHBvcnQgbGV0IGRvY2tlckZpbGVWZXJzaW9uID0gZnVuY3Rpb24oZG9ja2VyZmlsZU5hbWVBcmc6c3RyaW5nKTpzdHJpbmd7XG4gICAgbGV0IHZlcnNpb25TdHJpbmc6c3RyaW5nO1xuICAgIGxldCB2ZXJzaW9uUmVnZXggPSAvRG9ja2VyZmlsZV8oW2EtekEtWjAtOVxcLl0qKSQvO1xuICAgIGxldCByZWdleFJlc3VsdEFycmF5ID0gdmVyc2lvblJlZ2V4LmV4ZWMoZG9ja2VyZmlsZU5hbWVBcmcpO1xuICAgIGlmKHJlZ2V4UmVzdWx0QXJyYXkgJiYgcmVnZXhSZXN1bHRBcnJheS5sZW5ndGggPT0gMil7XG4gICAgICAgIHZlcnNpb25TdHJpbmcgPSByZWdleFJlc3VsdEFycmF5WzFdOyAgICAgICAgXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmVyc2lvblN0cmluZyA9IFwibGF0ZXN0XCI7XG4gICAgfVxuICAgIHJldHVybiB2ZXJzaW9uU3RyaW5nO1xufVxuXG5leHBvcnQgbGV0IGRvY2tlckJhc2VJbWFnZSA9IGZ1bmN0aW9uKGRvY2tlcmZpbGVDb250ZW50QXJnOnN0cmluZyl7XG4gICAgbGV0IGJhc2VJbWFnZVJlZ2V4ID0gL0ZST01cXHMoW2EtekEtejAtOVxcL1xcLVxcOl0qKVxcbj8vXG4gICAgbGV0IHJlZ2V4UmVzdWx0QXJyYXkgPSBiYXNlSW1hZ2VSZWdleC5leGVjKGRvY2tlcmZpbGVDb250ZW50QXJnKVxuICAgIHJldHVybiByZWdleFJlc3VsdEFycmF5WzFdO1xufVxuXG5leHBvcnQgbGV0IGRvY2tlclRhZyA9IGZ1bmN0aW9uKHJlZ2lzdHJ5QXJnOnN0cmluZyxyZXBvQXJnOnN0cmluZyx2ZXJzaW9uQXJnOnN0cmluZyxzdWZmaXhBcmc/OnN0cmluZyk6c3RyaW5ne1xuICAgIGxldCB0YWdTdHJpbmc6c3RyaW5nO1xuICAgIGxldCByZWdpc3RyeSA9IHJlZ2lzdHJ5QXJnO1xuICAgIGxldCByZXBvID0gcmVwb0FyZztcbiAgICBsZXQgdmVyc2lvbiA9IHZlcnNpb25Bcmc7XG4gICAgaWYoc3VmZml4QXJnKXtcbiAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25BcmcgKyBcIl9cIiArIHN1ZmZpeEFyZztcbiAgICB9O1xuICAgIHRhZ1N0cmluZyA9IHJlZ2lzdHJ5ICsgXCIvXCIgKyByZXBvICsgXCI6XCIgKyB2ZXJzaW9uO1xuICAgIHJldHVybiB0YWdTdHJpbmc7XG59O1xuXG5leHBvcnQgbGV0IGNsZWFuVGFnc0FycmF5RnVuY3Rpb24gPSBmdW5jdGlvbihkb2NrZXJmaWxlQXJyYXlBcmc6RG9ja2VyZmlsZVtdLHRyYWNraW5nQXJyYXlBcmc6RG9ja2VyZmlsZVtdKTpzdHJpbmdbXXtcbiAgICBsZXQgY2xlYW5UYWdzQXJyYXk6c3RyaW5nW10gPSBbXTtcbiAgICBkb2NrZXJmaWxlQXJyYXlBcmcuZm9yRWFjaChmdW5jdGlvbihkb2NrZXJmaWxlQXJnKXtcbiAgICAgICAgaWYodHJhY2tpbmdBcnJheUFyZy5pbmRleE9mKGRvY2tlcmZpbGVBcmcpID09IC0xKXtcbiAgICAgICAgICAgIGNsZWFuVGFnc0FycmF5LnB1c2goZG9ja2VyZmlsZUFyZy5jbGVhblRhZyk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY2xlYW5UYWdzQXJyYXk7XG59Il19
 |