sleeveforarm
Version:
Making Azure Easy
252 lines • 10.3 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const child_process = require("child_process");
const fs = require("fs-extra");
const jsonCycle = require("json-cycle");
const Path = require("path");
const util_1 = require("util");
const Winston = require("winston");
const CommonUtilities = require("./common-utilities");
const Resource = require("./resource");
const childProcessExec = util_1.promisify(child_process.exec);
var azCommandOutputs;
(function (azCommandOutputs) {
azCommandOutputs[azCommandOutputs["json"] = 0] = "json";
azCommandOutputs[azCommandOutputs["string"] = 1] = "string";
})(azCommandOutputs = exports.azCommandOutputs || (exports.azCommandOutputs = {}));
function exec(command, cwd) {
return __awaiter(this, void 0, void 0, function* () {
try {
Winston.debug(`exec about to run command ${command} in cwd ${cwd}`);
const result = yield childProcessExec(command, { cwd });
Winston.debug("exec ran with command %s in directory %s and got \
output %j", command, cwd, jsonCycle.decycle(result));
return result;
}
catch (err) {
Winston.debug("exec ran with command %s in directory %s and \
failed with error %j\n\
stdout %s\nstderr %s\n", command, cwd, err, err.stdout, err.stderr);
throw err;
}
});
}
exports.exec = exec;
function runExecFailOnStderr(command, skipLog = false) {
return __awaiter(this, void 0, void 0, function* () {
try {
Winston.debug(`runExecFailOnStderr about to run command ${command}`);
const commandResult = yield childProcessExec(command);
if (commandResult.stderr) {
throw new Error(commandResult.stderr);
}
if (!skipLog) {
Winston.debug("Exec Command: %s with stdout: %s", command, commandResult.stdout);
}
return commandResult.stdout;
}
catch (err) {
if (!skipLog) {
Winston.error("Exec Command: %s failed with commandResult %j", command, err);
}
throw new Error(util_1.format("Command %s failed with error %j\n\
stdout %s\nstderr %s", command, err, err.stdout, err.stderr));
}
});
}
exports.runExecFailOnStderr = runExecFailOnStderr;
function executeAzCommand(command, output) {
return __awaiter(this, void 0, void 0, function* () {
Winston.debug(`About to exec command ${command}`);
const stdout = yield runExecFailOnStderr(command, true);
switch (output) {
case azCommandOutputs.json: {
let jsonOut = {};
if (stdout) {
jsonOut = JSON.parse(stdout);
}
Winston.debug("Exec command %s with output %j", command, jsonOut);
return jsonOut;
}
case azCommandOutputs.string: {
Winston.debug("Exec command %s with output %s", command, stdout);
return stdout;
}
default: {
throw new Error("Unsupported output type: " + output);
}
}
});
}
function runAzCommand(command, output = azCommandOutputs.json, retriesAfterFailure = 60) {
return __awaiter(this, void 0, void 0, function* () {
return yield retryAfterFailure(() => __awaiter(this, void 0, void 0, function* () {
return yield executeAzCommand(command, output);
}), retriesAfterFailure);
});
}
exports.runAzCommand = runAzCommand;
function azAppServiceListLocations() {
return __awaiter(this, void 0, void 0, function* () {
return yield module.exports.runAzCommand("az appservice list-locations");
});
}
exports.azAppServiceListLocations = azAppServiceListLocations;
function addPasswordToGitURL(gitURL, password) {
// Insert password with ":" at the front before the first '@' character
const indexOfAt = gitURL.indexOf("@");
return gitURL.slice(0, indexOfAt) + ":" + password +
gitURL.slice(indexOfAt);
}
exports.addPasswordToGitURL = addPasswordToGitURL;
function npmSetup(path) {
return __awaiter(this, void 0, void 0, function* () {
yield CommonUtilities
.exec("npm link sleeveforarm", path);
yield CommonUtilities
.exec("npm install", path);
});
}
exports.npmSetup = npmSetup;
function executeOnSleeveResources(parentPath, processFunction) {
return __awaiter(this, void 0, void 0, function* () {
const directoryContents = yield fs.readdir(parentPath);
const promisesToWaitFor = [];
for (const childFileName of directoryContents) {
const candidatePath = Path.join(parentPath, childFileName);
const isDirectory = (yield fs.stat(candidatePath)).isDirectory;
const sleevePath = Path.join(candidatePath, "sleeve.js");
if (isDirectory && (yield fs.pathExists(sleevePath))) {
promisesToWaitFor.push(processFunction(candidatePath));
}
}
return Promise.all(promisesToWaitFor);
});
}
exports.executeOnSleeveResources = executeOnSleeveResources;
/**
* Javascript doesn't know what interfaces are so when one imports
* an interface in Typescript this does not produce any code in Javascript.
* But typescript still happily lets one specify (foo instance of I) where I
* is the interface. But that check won't work. So we have to do a duck
* typing check instead.
*/
function isIGlobalDefault(object) {
return object.isGlobalDefault !== undefined;
}
exports.isIGlobalDefault = isIGlobalDefault;
function isIStorageResource(object) {
return object.isStorageResource !== undefined;
}
exports.isIStorageResource = isIStorageResource;
function isIInfrastructure(object) {
return object
.initialize !== undefined;
}
exports.isIInfrastructure = isIInfrastructure;
function isResource(object) {
return object instanceof Resource.Resource;
}
exports.isResource = isResource;
function findGlobalDefaultResourceByType(resources, resourceType) {
const resourceFound = resources.find((resource) => {
return resource instanceof resourceType &&
isIGlobalDefault(resource);
});
if (resourceFound === undefined) {
throw new Error(`ResourceType ${resourceType} not found in \
${resources}`);
}
return resourceFound;
}
exports.findGlobalDefaultResourceByType = findGlobalDefaultResourceByType;
function findInfraResourcesByInterface(resources, interfaceCheck) {
const passingResource = [];
for (const resource of resources) {
if (interfaceCheck(resource) && isResource(resource)
&& isIInfrastructure(resource)) {
passingResource.push(resource);
}
}
return passingResource;
}
exports.findInfraResourcesByInterface = findInfraResourcesByInterface;
exports.scratchDirectoryName = ".sleeve";
function localScratchDirectory(targetDirectoryPath) {
return Path.join(targetDirectoryPath, exports.scratchDirectoryName);
}
exports.localScratchDirectory = localScratchDirectory;
function wait(millisecondsToWait) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, millisecondsToWait);
});
});
}
exports.wait = wait;
function retryAfterFailure(command, counter) {
return __awaiter(this, void 0, void 0, function* () {
try {
return yield command();
}
catch (err) {
if (counter === 0) {
throw err;
}
Winston.debug(`In retryAfterFailure with command ${command} at counter \
${counter} and got error ${err}`);
yield wait(1000);
return yield retryAfterFailure(command, --counter);
}
});
}
exports.retryAfterFailure = retryAfterFailure;
/**
* I keep running into bizarre situations where instanceof
* just doesn't work. I checked the Javascript and I have
* no idea what's going on. But really simple checks like
* an object that says it is of type foo will return
* false to "obj instanceof foo". So I have to use this
* check instead. Note that this is NOT a substitute for
* instanceof since I don't check inheritance.
*/
function isClass(obj, classObj) {
return Object.getPrototypeOf(obj).constructor.name === classObj.name;
}
exports.isClass = isClass;
function validateResource(resourceName, length) {
return ((resourceName.length <= length) &&
(RegExp("^[a-zA-Z][a-zA-Z0-9]+$").test(resourceName)));
}
exports.validateResource = validateResource;
/**
* Walks up the directory hierarchy look for the root of a GIT
* project.
* @param startDir The path to start the directory walk in
*/
function findGitRootDir(startDir) {
return __awaiter(this, void 0, void 0, function* () {
let currentDir = startDir;
while (true) {
if ((yield fs.pathExists(currentDir)) === false) {
throw new Error("This isn't a git project");
}
if (yield fs.pathExists(Path.join(currentDir, ".git"))) {
return currentDir;
}
currentDir = Path.normalize(Path.join(currentDir, ".."));
}
});
}
exports.findGitRootDir = findGitRootDir;
//# sourceMappingURL=common-utilities.js.map