@ioffice/tc-builder
Advanced tools
Comparing version 3.0.0 to 3.1.0-beta.1903141815
@@ -1,2 +0,3 @@ | ||
import { Environment, IO, Git, Github } from '../services'; | ||
import { Environment, Git, Github, IO } from '../services'; | ||
import { IReleaseInfo } from '../types'; | ||
/** | ||
@@ -21,2 +22,7 @@ * ### AbstractBuilder | ||
/** | ||
* Gets called whenever we want to create a release. The implementation should define the | ||
* operations that need to be done to help the user create a release of the library. | ||
*/ | ||
abstract releaseSetup(param: IReleaseInfo): Promise<void>; | ||
/** | ||
* Gets called right before the `publish` method. This is the place where we | ||
@@ -77,2 +83,16 @@ * can rearrange the files in the appropriate directories. | ||
protected createPreRelease(): Promise<string>; | ||
/** | ||
* Setup the release process. It calls the `releaseSetup` method specified in the derived | ||
* builders. An `IReleaseInfo` object will be passed into the method so that we may be able | ||
* to modify files related to the release. For NPM builds for instance we care about modifying: | ||
* | ||
* - package.json changes the version | ||
* - README.md needs to be replaced all occurrences of the old version for the new one. | ||
* - CHANGELOG.md needs to set up the links | ||
* | ||
* After this is done we will be in the `release` branch. It is our responsibility to make | ||
* sure that the setup was done correctly and finish writing any remaining information to | ||
* continue with the release process. | ||
*/ | ||
protected runReleaseSetup(): Promise<string>; | ||
private runBuilder; | ||
@@ -79,0 +99,0 @@ protected handleMasterBranch(): Promise<void>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
const tslib_1 = require("tslib"); | ||
const semver = require("semver"); | ||
const services_1 = require("../services"); | ||
const Util_1 = require("../Util"); | ||
/** | ||
* This module provides the `AbstractBuilder` class. It provides a flow to handle merges to | ||
* the master branch as well a pull requests. | ||
*/ /** */ | ||
var Util_1 = require("../Util"); | ||
var services_1 = require("../services"); | ||
/** | ||
* ### AbstractBuilder | ||
@@ -16,6 +13,6 @@ * | ||
*/ | ||
var AbstractBuilder = /** @class */ (function () { | ||
function AbstractBuilder(env, io, git, github) { | ||
class AbstractBuilder { | ||
constructor(env, io, git, github) { | ||
this.step = ''; | ||
var provider = services_1.Provider.getInstance(); | ||
const provider = services_1.Provider.getInstance(); | ||
this.env = env || provider.env; | ||
@@ -30,27 +27,21 @@ this.io = io || provider.io; | ||
*/ | ||
AbstractBuilder.prototype.run = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 5, , 6]); | ||
if (!this.env.isPreRelease) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.runStep('preRelease', 'creating pre-release', this.createPreRelease)]; | ||
case 1: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 2: return [4 /*yield*/, this.runStep('TC-Builder', 'running tc-builder', this.runBuilder)]; | ||
case 3: | ||
_a.sent(); | ||
_a.label = 4; | ||
case 4: return [3 /*break*/, 6]; | ||
case 5: | ||
err_1 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_1)]; | ||
case 6: return [2 /*return*/, 0]; | ||
run() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
if (this.env.isPreRelease) { | ||
yield this.runStep('preRelease', 'creating pre-release', this.createPreRelease); | ||
} | ||
}); | ||
else if (this.env.isReleaseSetup) { | ||
yield this.runStep('releaseSetup', 'running release-setup', this.runReleaseSetup); | ||
} | ||
else { | ||
yield this.runStep('TC-Builder', 'running tc-builder', this.runBuilder); | ||
} | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
return 0; | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -70,217 +61,199 @@ * Create a standard pre-release of the current state of the project. This command | ||
*/ | ||
AbstractBuilder.prototype.createPreRelease = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var files, list, err_2, branch, err_3, failure, version, err_4, err_5; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, Util_1.util.getModifiedFiles()]; | ||
case 1: | ||
files = _a.sent(); | ||
if (files.length > 0) { | ||
list = "\n " + files.join('\n '); | ||
return [2 /*return*/, this.io.failure("Commit the following files before preReleasing:" + list)]; | ||
} | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
err_2 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Unable to obtain modified files: " + err_2)]; | ||
case 3: | ||
_a.trys.push([3, 6, , 7]); | ||
return [4 /*yield*/, this.git.getBranch()]; | ||
case 4: | ||
branch = _a.sent(); | ||
return [4 /*yield*/, this.git.switchBranch('__build', true)]; | ||
case 5: | ||
_a.sent(); | ||
return [3 /*break*/, 7]; | ||
case 6: | ||
err_3 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_3)]; | ||
case 7: | ||
failure = ''; | ||
version = ''; | ||
_a.label = 8; | ||
case 8: | ||
_a.trys.push([8, 11, , 12]); | ||
return [4 /*yield*/, this.runStep('beforePublish', 'running beforePublish', this.beforePublish)]; | ||
case 9: | ||
_a.sent(); | ||
return [4 /*yield*/, this.runStep('publish', '', this.publish)]; | ||
case 10: | ||
version = _a.sent(); | ||
return [3 /*break*/, 12]; | ||
case 11: | ||
err_4 = _a.sent(); | ||
failure = err_4; | ||
return [3 /*break*/, 12]; | ||
case 12: | ||
_a.trys.push([12, 14, , 15]); | ||
return [4 /*yield*/, this.git.switchAndDelete(branch, '__build')]; | ||
case 13: | ||
_a.sent(); | ||
return [3 /*break*/, 15]; | ||
case 14: | ||
err_5 = _a.sent(); | ||
this.io.warn(err_5); | ||
return [3 /*break*/, 15]; | ||
case 15: | ||
if (failure) { | ||
return [2 /*return*/, this.io.failure(failure)]; | ||
} | ||
return [2 /*return*/, this.io.success(version, version ? "Pre-released version " + version : '')]; | ||
createPreRelease() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const files = yield Util_1.util.getModifiedFiles(); | ||
if (files.length > 0) { | ||
const list = `\n ${files.join('\n ')}`; | ||
return this.io.failure(`Commit the following files before preReleasing:${list}`); | ||
} | ||
}); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Unable to obtain modified files: ${err}`); | ||
} | ||
let branch; | ||
try { | ||
branch = yield this.git.getBranch(); | ||
yield this.git.switchBranch('__build', true); | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
let failure = ''; | ||
let version = ''; | ||
try { | ||
yield this.runStep('beforePublish', 'running beforePublish', this.beforePublish); | ||
version = yield this.runStep('publish', '', this.publish); | ||
} | ||
catch (err) { | ||
failure = err; | ||
} | ||
try { | ||
yield this.git.switchAndDelete(branch, '__build'); | ||
} | ||
catch (err) { | ||
this.io.warn(err); | ||
} | ||
if (failure) { | ||
return this.io.failure(failure); | ||
} | ||
return this.io.success(version, version ? `Pre-released version ${version}` : ''); | ||
}); | ||
}; | ||
AbstractBuilder.prototype.runBuilder = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var target, err_6; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 7, , 8]); | ||
return [4 /*yield*/, this.runStep('test', 'running tests', this.test)]; | ||
case 1: | ||
_a.sent(); | ||
if (this.env.ci === services_1.CI.NONE) { | ||
this.io.log('Not a CI environment.'); | ||
return [2 /*return*/]; | ||
} | ||
target = this.env.targetBranch; | ||
if (!this.env.pullRequestBranch) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, this.handlePullRequest()]; | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 3: | ||
if (!(target === 'master' || target === 'refs/heads/master')) return [3 /*break*/, 5]; | ||
return [4 /*yield*/, this.handleMasterBranch()]; | ||
case 4: | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 5: | ||
this.io.log("Nothing else to do on '" + target + "' branch."); | ||
_a.label = 6; | ||
case 6: return [3 /*break*/, 8]; | ||
case 7: | ||
err_6 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_6)]; | ||
case 8: return [2 /*return*/]; | ||
} | ||
/** | ||
* Setup the release process. It calls the `releaseSetup` method specified in the derived | ||
* builders. An `IReleaseInfo` object will be passed into the method so that we may be able | ||
* to modify files related to the release. For NPM builds for instance we care about modifying: | ||
* | ||
* - package.json changes the version | ||
* - README.md needs to be replaced all occurrences of the old version for the new one. | ||
* - CHANGELOG.md needs to set up the links | ||
* | ||
* After this is done we will be in the `release` branch. It is our responsibility to make | ||
* sure that the setup was done correctly and finish writing any remaining information to | ||
* continue with the release process. | ||
*/ | ||
runReleaseSetup() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const currentBranch = yield this.git.getBranch(); | ||
if (currentBranch !== 'master') { | ||
return this.io.failure('releaseSetup may only run on the master branch'); | ||
} | ||
}); | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
try { | ||
// TODO: lets make sure everything is pushed. For now I'm doing the basic check for files | ||
const files = yield Util_1.util.getModifiedFiles(); | ||
if (files.length > 0) { | ||
return this.io.failure(`releaseSetup requires everything to be committed and pushed`); | ||
} | ||
} | ||
catch (err) { | ||
return this.io.failure(`Unable to obtain modified files: ${err}`); | ||
} | ||
const currentVersion = this.env.packageVersion; | ||
let newVersion = ''; | ||
if (!currentVersion) { | ||
return this.io.failure(`Unable to obtain the current package version`); | ||
} | ||
if (!semver.parse(currentVersion)) { | ||
return this.io.failure(`Current version is not parsable: ${currentVersion}`); | ||
} | ||
try { | ||
newVersion = yield this.io.promptForNewVersion(currentVersion); | ||
yield this.git.switchBranch('release', true); | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
let failure = ''; | ||
try { | ||
yield this.runStep('releaseSetup', 'running releaseSetup', this.releaseSetup, { | ||
currentVersion, | ||
newVersion, | ||
}); | ||
} | ||
catch (err) { | ||
failure = err; | ||
} | ||
if (failure) { | ||
return this.io.failure(failure); | ||
} | ||
return this.io.success(newVersion, newVersion ? `setup for version ${newVersion} complete` : ''); | ||
}); | ||
}; | ||
AbstractBuilder.prototype.handleMasterBranch = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var version, err_7, err_8, msg; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.io.log('New changes on master branch.'); | ||
if (!this.env.isRelease) return [3 /*break*/, 9]; | ||
version = ''; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 4, , 5]); | ||
return [4 /*yield*/, this.runStep('beforePublish', 'running beforePublish', this.beforePublish)]; | ||
case 2: | ||
_a.sent(); | ||
return [4 /*yield*/, this.runStep('publish', '', this.publish)]; | ||
case 3: | ||
version = _a.sent(); | ||
this.io.log("Released version " + version); | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
err_7 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_7)]; | ||
case 5: | ||
_a.trys.push([5, 7, , 8]); | ||
return [4 /*yield*/, this.runStep('afterPublish', 'running afterPublish', this.afterPublish)]; | ||
case 6: | ||
_a.sent(); | ||
return [3 /*break*/, 8]; | ||
case 7: | ||
err_8 = _a.sent(); | ||
this.io.warn(err_8); | ||
return [3 /*break*/, 8]; | ||
case 8: return [3 /*break*/, 10]; | ||
case 9: | ||
msg = JSON.stringify(this.env.commitMessage); | ||
this.io.log("Nothing to release. Last commit message: " + msg); | ||
_a.label = 10; | ||
case 10: return [2 /*return*/, Promise.resolve()]; | ||
} | ||
runBuilder() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.runStep('test', 'running tests', this.test); | ||
if (this.env.ci === services_1.CI.NONE) { | ||
this.io.log('Not a CI environment.'); | ||
return; | ||
} | ||
}); | ||
const target = this.env.targetBranch; | ||
if (this.env.pullRequestBranch) { | ||
yield this.handlePullRequest(); | ||
} | ||
else if (target === 'master' || target === 'refs/heads/master') { | ||
yield this.handleMasterBranch(); | ||
} | ||
else { | ||
this.io.log(`Nothing else to do on '${target}' branch.`); | ||
} | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
}); | ||
}; | ||
AbstractBuilder.prototype.handlePullRequest = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_9, err_10; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.io.log('Handling pull request'); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 7, , 8]); | ||
return [4 /*yield*/, this.runStep('beforeVerifyPullRequest', 'running beforeVerifyPullRequest', this.beforeVerifyPullRequest)]; | ||
case 2: | ||
_a.sent(); | ||
if (!(this.env.pullRequestBranch === 'release')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, this.runStep('verifyRelease', 'verifying release', this.verifyRelease)]; | ||
case 3: | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 4: return [4 /*yield*/, this.runStep('verifyNonRelease', 'verifying non-release', this.verifyNonRelease)]; | ||
case 5: | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: return [3 /*break*/, 8]; | ||
case 7: | ||
err_9 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_9)]; | ||
case 8: | ||
_a.trys.push([8, 10, , 11]); | ||
return [4 /*yield*/, this.runStep('afterVerifyPullRequest', 'running afterVerifyPullRequest', this.afterVerifyPullRequest)]; | ||
case 9: | ||
_a.sent(); | ||
return [3 /*break*/, 11]; | ||
case 10: | ||
err_10 = _a.sent(); | ||
this.io.warn(err_10); | ||
return [3 /*break*/, 11]; | ||
case 11: return [2 /*return*/, Promise.resolve()]; | ||
} | ||
handleMasterBranch() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
this.io.log('New changes on master branch.'); | ||
if (this.env.isRelease) { | ||
let version = ''; | ||
try { | ||
yield this.runStep('beforePublish', 'running beforePublish', this.beforePublish); | ||
version = yield this.runStep('publish', '', this.publish); | ||
this.io.log(`Released version ${version}`); | ||
} | ||
}); | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
try { | ||
yield this.runStep('afterPublish', 'running afterPublish', this.afterPublish); | ||
} | ||
catch (err) { | ||
this.io.warn(err); | ||
} | ||
} | ||
else { | ||
const msg = JSON.stringify(this.env.commitMessage); | ||
this.io.log(`Nothing to release. Last commit message: ${msg}`); | ||
} | ||
return Promise.resolve(); | ||
}); | ||
}; | ||
AbstractBuilder.prototype.runStep = function (name, desc, fn) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var result, err_11; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.step = name; | ||
this.io.openBlock(this.step, desc); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, fn.call(this)]; | ||
case 2: | ||
result = _a.sent(); | ||
this.io.closeBlock(this.step); | ||
return [2 /*return*/, result]; | ||
case 3: | ||
err_11 = _a.sent(); | ||
this.io.closeBlock(this.step); | ||
return [2 /*return*/, Promise.reject(err_11)]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
handlePullRequest() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
this.io.log('Handling pull request'); | ||
try { | ||
yield this.runStep('beforeVerifyPullRequest', 'running beforeVerifyPullRequest', this.beforeVerifyPullRequest); | ||
if (this.env.pullRequestBranch === 'release') { | ||
yield this.runStep('verifyRelease', 'verifying release', this.verifyRelease); | ||
} | ||
}); | ||
else { | ||
yield this.runStep('verifyNonRelease', 'verifying non-release', this.verifyNonRelease); | ||
} | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
try { | ||
yield this.runStep('afterVerifyPullRequest', 'running afterVerifyPullRequest', this.afterVerifyPullRequest); | ||
} | ||
catch (err) { | ||
this.io.warn(err); | ||
} | ||
return Promise.resolve(); | ||
}); | ||
}; | ||
return AbstractBuilder; | ||
}()); | ||
} | ||
runStep(name, desc, fn, arg) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
this.step = name; | ||
this.io.openBlock(this.step, desc); | ||
try { | ||
const result = yield fn.call(this, arg); | ||
this.io.closeBlock(this.step); | ||
return result; | ||
} | ||
catch (err) { | ||
this.io.closeBlock(this.step); | ||
throw err; | ||
} | ||
}); | ||
} | ||
} | ||
exports.AbstractBuilder = AbstractBuilder; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var AbstractBuilder_1 = require("./AbstractBuilder"); | ||
const tslib_1 = require("tslib"); | ||
const AbstractBuilder_1 = require("./AbstractBuilder"); | ||
exports.AbstractBuilder = AbstractBuilder_1.AbstractBuilder; | ||
var NPMBuilder_1 = require("./NPMBuilder"); | ||
const NPMBuilder_1 = require("./NPMBuilder"); | ||
exports.NPMBuilder = NPMBuilder_1.NPMBuilder; | ||
@@ -12,41 +12,29 @@ /** | ||
*/ | ||
function runBuilder(Builder, dumpMessages) { | ||
if (dumpMessages === void 0) { dumpMessages = true; } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var builder, err_1, m; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
builder = new Builder(); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, builder.run()]; | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
m = typeof err_1 === 'string' ? err_1 : err_1.message; | ||
builder.io.log(err_1); | ||
builder.io.error("Failure in the `" + builder.step + "` step: " + m); | ||
if (dumpMessages) { | ||
builder.io.dumpMessages(); | ||
} | ||
return [2 /*return*/, { builder: builder, code: 1 }]; | ||
case 4: | ||
try { | ||
if (dumpMessages) { | ||
builder.io.dumpMessages(); | ||
} | ||
} | ||
catch (err) { | ||
builder.io.log("Unable to dump messages: " + err); | ||
} | ||
builder.io.log('Process is done.'); | ||
return [2 /*return*/, { builder: builder, code: 0 }]; | ||
function runBuilder(Builder, dumpMessages = true) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const builder = new Builder(); | ||
try { | ||
yield builder.run(); | ||
} | ||
catch (err) { | ||
const m = typeof err === 'string' ? err : err.message; | ||
builder.io.log(err); | ||
builder.io.error(`Failure in the \`${builder.step}\` step: ${m}`); | ||
if (dumpMessages) { | ||
builder.io.dumpMessages(); | ||
} | ||
}); | ||
return { builder, code: 1 }; | ||
} | ||
try { | ||
if (dumpMessages) { | ||
builder.io.dumpMessages(); | ||
} | ||
} | ||
catch (err) { | ||
builder.io.log(`Unable to dump messages: ${err}`); | ||
} | ||
builder.io.log('Process is done.'); | ||
return { builder, code: 0 }; | ||
}); | ||
} | ||
exports.runBuilder = runBuilder; |
@@ -0,1 +1,2 @@ | ||
import { IReleaseInfo } from '../types'; | ||
import { AbstractBuilder } from './AbstractBuilder'; | ||
@@ -19,3 +20,34 @@ declare class NPMBuilder extends AbstractBuilder { | ||
private verifyChangeLog; | ||
/** | ||
* The release setup requires 3 things to happen: | ||
* | ||
* - update package.json | ||
* - update README.md | ||
* - update CHANGELOG.md | ||
*/ | ||
releaseSetup({ currentVersion, newVersion }: IReleaseInfo): Promise<void>; | ||
/** | ||
* Obtain a link to the comparison between two tags/hashes. | ||
*/ | ||
private githubCompareLink; | ||
/** | ||
* The CHANGELOG setup is a bit more complicated. We need to make sure that every version has | ||
* an entry and that each entry is a link to the comparison of the repo. | ||
* | ||
* @param content The content of the CHANGELOG.md file. | ||
* @param newVersion The new version we are releasing. | ||
* @param firstCommit The very first commit hash of the repo. | ||
*/ | ||
private updateChangeLog; | ||
/** | ||
* Currently the README files in iOffice project contain links to the documentation and these | ||
* links point to specific versions. For this reason we must update the links so that any instance | ||
* that points to the current version will now point to the new one. | ||
* | ||
* @param content The content of the README file. | ||
* @param currentVersion The current version of the package. | ||
* @param newVersion The new version we are releasing. | ||
*/ | ||
private updateREADME; | ||
} | ||
export { NPMBuilder, }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var Mocha = require("mocha"); | ||
var fs = require("fs"); | ||
var moment = require("moment"); | ||
var semver = require("semver"); | ||
var Util_1 = require("../Util"); | ||
var services_1 = require("../services"); | ||
var AbstractBuilder_1 = require("./AbstractBuilder"); | ||
var NPMBuilder = /** @class */ (function (_super) { | ||
tslib_1.__extends(NPMBuilder, _super); | ||
function NPMBuilder() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
NPMBuilder.prototype.test = function () { | ||
var _this = this; | ||
return new Promise(function (fulfill, reject) { | ||
var mocha = new Mocha(); | ||
if (_this.env.ci === services_1.CI.TRAVIS) { | ||
const tslib_1 = require("tslib"); | ||
const fs = require("fs"); | ||
const Mocha = require("mocha"); | ||
const moment = require("moment"); | ||
const semver = require("semver"); | ||
const services_1 = require("../services"); | ||
const Util_1 = require("../Util"); | ||
const AbstractBuilder_1 = require("./AbstractBuilder"); | ||
class NPMBuilder extends AbstractBuilder_1.AbstractBuilder { | ||
test() { | ||
return new Promise((fulfill, reject) => { | ||
const mocha = new Mocha(); | ||
if (this.env.ci === services_1.CI.TRAVIS) { | ||
mocha.useColors(true); | ||
} | ||
mocha.addFile('build/test/index.js'); | ||
mocha.run(function (failures) { | ||
mocha.run((failures) => { | ||
if (failures > 0) { | ||
var verb = failures === 1 ? 'is' : 'are'; | ||
var amount = failures === 1 ? '' : 's'; | ||
reject("There " + verb + " " + failures + " test" + amount + " failing"); | ||
const verb = failures === 1 ? 'is' : 'are'; | ||
const amount = failures === 1 ? '' : 's'; | ||
reject(`There ${verb} ${failures} test${amount} failing`); | ||
} | ||
else { | ||
_this.io.log('Testing passed'); | ||
this.io.log('Testing passed'); | ||
fulfill(); | ||
@@ -36,4 +31,4 @@ } | ||
}); | ||
}; | ||
NPMBuilder.prototype.beforePublish = function () { | ||
} | ||
beforePublish() { | ||
try { | ||
@@ -44,133 +39,85 @@ Util_1.util.move('build/main/', '.'); | ||
catch (err) { | ||
return this.io.failure("Failed moving 'build/main/' to root directory:\n" + err.toString()); | ||
return this.io.failure(`Failed moving 'build/main/' to root directory:\n${err.toString()}`); | ||
} | ||
}; | ||
NPMBuilder.prototype.publish = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var tag, finalVersion, err_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
tag = this.env.isPreRelease ? ' --tag next' : ''; | ||
finalVersion = this.env.packageVersion; | ||
if (this.env.isPreRelease) { | ||
finalVersion = this.env.packageVersion + "-beta." + moment().format('YYMMDDHHmm'); | ||
Util_1.util.changePackageVersion(finalVersion); | ||
} | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, Util_1.util.execCmd("npm publish" + tag, true)]; | ||
case 2: | ||
_a.sent(); | ||
return [2 /*return*/, finalVersion]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("npm publish failed")]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
publish() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const tag = this.env.isPreRelease ? ' --tag next' : ''; | ||
let finalVersion = this.env.packageVersion; | ||
if (this.env.isPreRelease) { | ||
finalVersion = `${this.env.packageVersion}-beta.${moment().format('YYMMDDHHmm')}`; | ||
Util_1.util.changePackageVersion(finalVersion); | ||
} | ||
try { | ||
yield Util_1.util.execCmd(`npm publish${tag}`, true); | ||
return finalVersion; | ||
} | ||
catch (err) { | ||
return this.io.failure(`npm publish failed`); | ||
} | ||
}); | ||
}; | ||
NPMBuilder.prototype.afterPublish = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_2; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, this.github.createRelease()]; | ||
case 1: | ||
_a.sent(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
err_2 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_2)]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
afterPublish() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.github.createRelease(); | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
}); | ||
}; | ||
NPMBuilder.prototype.beforeVerifyPullRequest = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
return tslib_1.__generator(this, function (_a) { | ||
return [2 /*return*/]; | ||
}); | ||
} | ||
beforeVerifyPullRequest() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
}); | ||
}; | ||
NPMBuilder.prototype.verifyRelease = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var npmVersion, err_3, changeLogData, changeLogErr; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
npmVersion = ''; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, Util_1.util.execCmd("npm show " + this.env.packageName + " version")]; | ||
case 2: | ||
npmVersion = (_a.sent()).trim(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_3 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("failed to obtain npm version: " + err_3)]; | ||
case 4: | ||
if (!semver.gt(this.env.packageVersion, npmVersion)) { | ||
return [2 /*return*/, this.io.failure("Package version needs to be > " + npmVersion)]; | ||
} | ||
try { | ||
changeLogData = fs.readFileSync('./CHANGELOG.md'); | ||
changeLogErr = this.verifyChangeLog(changeLogData.toString()); | ||
if (changeLogErr) { | ||
return [2 /*return*/, this.io.failure(changeLogErr)]; | ||
} | ||
} | ||
catch (err) { | ||
this.io.warn("Unable to read `CHANGELOG.md`: " + err.toString()); | ||
return [2 /*return*/]; | ||
} | ||
this.io.log('Ready to merge the release branch.'); | ||
return [2 /*return*/]; | ||
} | ||
verifyRelease() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
let npmVersion = ''; | ||
try { | ||
npmVersion = (yield Util_1.util.execCmd(`npm show ${this.env.packageName} version`)).trim(); | ||
} | ||
catch (err) { | ||
return this.io.failure(`failed to obtain npm version: ${err}`); | ||
} | ||
if (!semver.gt(this.env.packageVersion, npmVersion)) { | ||
return this.io.failure(`Package version needs to be > ${npmVersion}`); | ||
} | ||
try { | ||
const changeLogData = fs.readFileSync('./CHANGELOG.md'); | ||
const changeLogErr = this.verifyChangeLog(changeLogData.toString()); | ||
if (changeLogErr) { | ||
return this.io.failure(changeLogErr); | ||
} | ||
}); | ||
} | ||
catch (err) { | ||
this.io.warn(`Unable to read \`CHANGELOG.md\`: ${err.toString()}`); | ||
return; | ||
} | ||
this.io.log('Ready to merge the release branch.'); | ||
}); | ||
}; | ||
NPMBuilder.prototype.verifyNonRelease = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var npmVersion, err_4; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
npmVersion = ''; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, Util_1.util.execCmd("npm show " + this.env.packageName + " version")]; | ||
case 2: | ||
npmVersion = (_a.sent()).trim(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_4 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("failed to obtain npm version: " + err_4)]; | ||
case 4: | ||
if (npmVersion.includes('beta')) { | ||
this.io.log('Package has not yet been released, it is in beta mode'); | ||
} | ||
else if (semver.gt(this.env.packageVersion, npmVersion)) { | ||
return [2 /*return*/, this.io.failure('You may only modify the package version on the \`release\` branch.')]; | ||
} | ||
else { | ||
this.io.log('Everything looks good ...'); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
verifyNonRelease() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
let npmVersion = ''; | ||
try { | ||
npmVersion = (yield Util_1.util.execCmd(`npm show ${this.env.packageName} version`)).trim(); | ||
} | ||
catch (err) { | ||
return this.io.failure(`failed to obtain npm version: ${err}`); | ||
} | ||
if (npmVersion.includes('beta')) { | ||
this.io.log('Package has not yet been released, it is in beta mode'); | ||
} | ||
else if (semver.gt(this.env.packageVersion, npmVersion)) { | ||
return this.io.failure('You may only modify the package version on the \`release\` branch.'); | ||
} | ||
else { | ||
this.io.log('Everything looks good ...'); | ||
} | ||
}); | ||
}; | ||
NPMBuilder.prototype.afterVerifyPullRequest = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { | ||
return [2 /*return*/]; | ||
}); }); | ||
}; | ||
} | ||
afterVerifyPullRequest() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { }); | ||
} | ||
/** | ||
@@ -183,14 +130,102 @@ * Given the contents of a changelog file it returns a message explaining what it needs to be | ||
*/ | ||
NPMBuilder.prototype.verifyChangeLog = function (content) { | ||
var version = this.env.packageVersion; | ||
if (!content.includes("\n## [" + version + "] - ")) { | ||
return "Missing entry in `CHANGELOG.md` for the current release version " + version; | ||
verifyChangeLog(content) { | ||
const version = this.env.packageVersion; | ||
if (!content.includes(`\n## [${version}] - `)) { | ||
return `Missing entry in \`CHANGELOG.md\` for the current release version ${version}`; | ||
} | ||
if (!content.includes("\n[" + version + "]: ")) { | ||
return "Missing link definition in `CHANGELOG.md` for the comparison with the last release"; | ||
if (!content.includes(`\n[${version}]: `)) { | ||
return `Missing link definition in \`CHANGELOG.md\` for the comparison with the last release`; | ||
} | ||
return ''; | ||
}; | ||
return NPMBuilder; | ||
}(AbstractBuilder_1.AbstractBuilder)); | ||
} | ||
/** | ||
* The release setup requires 3 things to happen: | ||
* | ||
* - update package.json | ||
* - update README.md | ||
* - update CHANGELOG.md | ||
*/ | ||
releaseSetup({ currentVersion, newVersion }) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
// package.json | ||
Util_1.util.changePackageVersion(newVersion); | ||
// CHANGELOG.md | ||
const changelogFile = './CHANGELOG.md'; | ||
try { | ||
const firstCommit = yield this.git.getFirstCommit(); | ||
const changeLogData = fs.readFileSync(changelogFile); | ||
const newData = this.updateChangeLog(changeLogData.toString(), newVersion, firstCommit); | ||
fs.writeFileSync(changelogFile, newData); | ||
} | ||
catch (err) { | ||
this.io.warn(`Unable to update '${changelogFile}': ${err.toString()}`); | ||
return; | ||
} | ||
// README.md | ||
const readmeFile = './README.md'; | ||
try { | ||
const readmeData = fs.readFileSync(readmeFile); | ||
const newData = this.updateREADME(readmeData.toString(), currentVersion, newVersion); | ||
fs.writeFileSync(readmeFile, newData); | ||
} | ||
catch (err) { | ||
this.io.warn(`Unable to update '${readmeFile}': ${err.toString()}`); | ||
return; | ||
} | ||
const unreleased = this.githubCompareLink(currentVersion, 'HEAD'); | ||
this.io.log(`See ${unreleased} to create the CHANGELOG summary.`); | ||
}); | ||
} | ||
/** | ||
* Obtain a link to the comparison between two tags/hashes. | ||
*/ | ||
githubCompareLink(prev, next) { | ||
const owner = this.env.owner; | ||
const repo = this.env.repo; | ||
return `https://github.com/${owner}/${repo}/compare/${prev}...${next}`; | ||
} | ||
/** | ||
* The CHANGELOG setup is a bit more complicated. We need to make sure that every version has | ||
* an entry and that each entry is a link to the comparison of the repo. | ||
* | ||
* @param content The content of the CHANGELOG.md file. | ||
* @param newVersion The new version we are releasing. | ||
* @param firstCommit The very first commit hash of the repo. | ||
*/ | ||
updateChangeLog(content, newVersion, firstCommit) { | ||
const [header, main] = content.split('## [Unreleased]'); | ||
const [entries] = main.split('[Unreleased]:'); | ||
const lines = entries.split('\n'); | ||
const versions = lines | ||
.filter(x => x.startsWith('## [')) | ||
.map(line => (line.match(/## \[(.*)]/) || [])[1]) | ||
.filter(x => x); | ||
versions.unshift(newVersion); | ||
versions.push(firstCommit); | ||
const links = [`[Unreleased]: ${this.githubCompareLink(newVersion, 'HEAD')}`]; | ||
for (let i = 0; i < versions.length - 1; i++) { | ||
links.push(`[${versions[i]}]: ${this.githubCompareLink(versions[i + 1], versions[i])}`); | ||
} | ||
return [ | ||
header, | ||
'## [Unreleased]\n\n', | ||
`## [${newVersion}] - ${moment().format('LL')}\n\n`, | ||
entries, | ||
links.join('\n'), | ||
'\n', | ||
].join(''); | ||
} | ||
/** | ||
* Currently the README files in iOffice project contain links to the documentation and these | ||
* links point to specific versions. For this reason we must update the links so that any instance | ||
* that points to the current version will now point to the new one. | ||
* | ||
* @param content The content of the README file. | ||
* @param currentVersion The current version of the package. | ||
* @param newVersion The new version we are releasing. | ||
*/ | ||
updateREADME(content, currentVersion, newVersion) { | ||
return content.split(currentVersion).join(newVersion); | ||
} | ||
} | ||
exports.NPMBuilder = NPMBuilder; |
@@ -1,3 +0,3 @@ | ||
import { TypedObject, ExitCode, IProjectResults, IProjectStatus, IFileMessages } from './Interfaces'; | ||
import * as ts from 'typescript'; | ||
import { ExitCode, IFileMessages, IProjectResults, IProjectStatus, TypedObject } from './Interfaces'; | ||
declare function compile(program: ts.Program, tsOptions: ts.CompilerOptions, tsLintConfigPath?: string, verbose?: boolean): TypedObject<IFileMessages>; | ||
@@ -4,0 +4,0 @@ declare function compileProject(tsConfigPath: string, tsLintConfigPath?: string, verbose?: boolean): IProjectResults; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Interfaces_1 = require("./Interfaces"); | ||
var fs = require("fs"); | ||
var ts = require("typescript"); | ||
var Lint = require("tslint"); | ||
var pth = require("path"); | ||
var ProgressBar = require("progress"); | ||
var services_1 = require("../services"); | ||
var Formatter_1 = require("./Formatter"); | ||
const fs = require("fs"); | ||
const pth = require("path"); | ||
const ProgressBar = require("progress"); | ||
const Lint = require("tslint"); | ||
const ts = require("typescript"); | ||
const services_1 = require("../services"); | ||
const Formatter_1 = require("./Formatter"); | ||
const Interfaces_1 = require("./Interfaces"); | ||
function cout(msg, verbose) { | ||
if (verbose) { | ||
process.stdout.write(msg + "\n"); | ||
process.stdout.write(`${msg}\n`); | ||
} | ||
} | ||
function getDiagnosticCategory(category) { | ||
var _a; | ||
var map = (_a = {}, | ||
_a[ts.DiagnosticCategory.Error] = 'error', | ||
_a[ts.DiagnosticCategory.Warning] = 'warning', | ||
_a[ts.DiagnosticCategory.Message] = 'warning', | ||
_a); | ||
const map = { | ||
[ts.DiagnosticCategory.Error]: 'error', | ||
[ts.DiagnosticCategory.Warning]: 'warning', | ||
[ts.DiagnosticCategory.Message]: 'warning', | ||
}; | ||
return map[category]; | ||
} | ||
function compile(program, tsOptions, tsLintConfigPath, verbose) { | ||
var results = {}; | ||
var outDirectory = tsOptions.outDir || '.'; | ||
var emitResult = program.emit(); | ||
var preDiagnostics = ts.getPreEmitDiagnostics(program); | ||
var allDiagnostics = preDiagnostics.concat(emitResult.diagnostics); | ||
var emittedFiles = program.getSourceFiles() | ||
.filter(function (x) { return !x.fileName.includes('node_modules'); }); | ||
var options = { | ||
const results = {}; | ||
const outDirectory = tsOptions.outDir || '.'; | ||
const emitResult = program.emit(); | ||
const preDiagnostics = ts.getPreEmitDiagnostics(program); | ||
const allDiagnostics = preDiagnostics.concat(emitResult.diagnostics); | ||
const emittedFiles = program.getSourceFiles() | ||
.filter(x => !x.fileName.includes('node_modules')); | ||
const options = { | ||
fix: false, | ||
formatter: 'json', | ||
}; | ||
var bar; | ||
let bar; | ||
if (verbose) { | ||
bar = new ProgressBar(" linting: :bar :percent :etas", { | ||
bar = new ProgressBar(` linting: :bar :percent :etas`, { | ||
complete: '█', | ||
@@ -46,3 +45,3 @@ incomplete: '░', | ||
} | ||
emittedFiles.forEach(function (file) { | ||
emittedFiles.forEach((file) => { | ||
if (verbose) { | ||
@@ -54,7 +53,7 @@ bar.tick(); | ||
} | ||
var fileName = file.fileName; | ||
const fileName = file.fileName; | ||
if (!results[fileName]) { | ||
results[fileName] = { | ||
fileName: fileName, | ||
outDirectory: outDirectory, | ||
fileName, | ||
outDirectory, | ||
absPath: pth.resolve(file.fileName), | ||
@@ -65,11 +64,11 @@ messages: [], | ||
if (tsLintConfigPath) { | ||
var linter = new Lint.Linter(options, program); | ||
var configFile = Lint.Configuration.loadConfigurationFromPath(tsLintConfigPath); | ||
const linter = new Lint.Linter(options, program); | ||
const configFile = Lint.Configuration.loadConfigurationFromPath(tsLintConfigPath); | ||
linter.lint(fileName, '', configFile); | ||
var lintResults = linter.getResult(); | ||
var failures = JSON.parse(lintResults.output); | ||
var fileMessages_1 = results[fileName]; | ||
failures.forEach(function (failure) { | ||
var _a = failure.startPosition, line = _a.line, character = _a.character; | ||
fileMessages_1.messages.push({ | ||
const lintResults = linter.getResult(); | ||
const failures = JSON.parse(lintResults.output); | ||
const fileMessages = results[fileName]; | ||
failures.forEach((failure) => { | ||
const { line, character } = failure.startPosition; | ||
fileMessages.messages.push({ | ||
message: failure.failure, | ||
@@ -84,16 +83,16 @@ line: line + 1, | ||
}); | ||
fileMessages_1.messages.sort(function (a, b) { return a.line - b.line; }); | ||
fileMessages.messages.sort((a, b) => a.line - b.line); | ||
} | ||
}); | ||
allDiagnostics.forEach(function (diagnostic) { | ||
var file = diagnostic.file; | ||
allDiagnostics.forEach((diagnostic) => { | ||
const file = diagnostic.file; | ||
if (!file || !file.fileName || !diagnostic.start) { | ||
return; | ||
} | ||
var fileMessages = results[file.fileName]; | ||
var pos = file.getLineAndCharacterOfPosition(diagnostic.start); | ||
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, ''); | ||
const fileMessages = results[file.fileName]; | ||
const pos = file.getLineAndCharacterOfPosition(diagnostic.start); | ||
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, ''); | ||
if (fileMessages) { | ||
fileMessages.messages.push({ | ||
message: message, | ||
message, | ||
line: pos.line + 1, | ||
@@ -104,5 +103,5 @@ character: pos.character + 1, | ||
category: getDiagnosticCategory(diagnostic.category), | ||
type: "TS" + diagnostic.code, | ||
type: `TS${diagnostic.code}`, | ||
}); | ||
fileMessages.messages.sort(function (a, b) { return a.line - b.line; }); | ||
fileMessages.messages.sort((a, b) => a.line - b.line); | ||
} | ||
@@ -114,35 +113,35 @@ }); | ||
function compileProject(tsConfigPath, tsLintConfigPath, verbose) { | ||
var project = ts.readConfigFile(tsConfigPath, ts.sys.readFile); | ||
const project = ts.readConfigFile(tsConfigPath, ts.sys.readFile); | ||
if (project.error) { | ||
throw new Error(ts.formatDiagnostics([project.error], { | ||
getCanonicalFileName: function (f) { return f; }, | ||
getCanonicalFileName: (f) => f, | ||
getCurrentDirectory: process.cwd, | ||
getNewLine: function () { return "\n"; }, | ||
getNewLine: () => "\n", | ||
})); | ||
} | ||
var parseConfigHost = { | ||
const parseConfigHost = { | ||
fileExists: fs.existsSync, | ||
readDirectory: ts.sys.readDirectory, | ||
readFile: function (file) { return fs.readFileSync(file, "utf8"); }, | ||
readFile: (file) => fs.readFileSync(file, "utf8"), | ||
useCaseSensitiveFileNames: true, | ||
}; | ||
var parsed = ts.parseJsonConfigFileContent(project.config, parseConfigHost, pth.resolve(process.cwd()), {}); | ||
const parsed = ts.parseJsonConfigFileContent(project.config, parseConfigHost, pth.resolve(process.cwd()), {}); | ||
if (parsed.errors !== undefined) { | ||
// ignore warnings and 'TS18003: No inputs were found in config file ...' | ||
var errors = parsed.errors.filter(function (d) { return d.category === ts.DiagnosticCategory.Error && d.code !== 18003; }); | ||
const errors = parsed.errors.filter((d) => d.category === ts.DiagnosticCategory.Error && d.code !== 18003); | ||
if (errors.length !== 0) { | ||
throw new Error(ts.formatDiagnostics(errors, { | ||
getCanonicalFileName: function (f) { return f; }, | ||
getCanonicalFileName: (f) => f, | ||
getCurrentDirectory: process.cwd, | ||
getNewLine: function () { return "\n"; }, | ||
getNewLine: () => "\n", | ||
})); | ||
} | ||
} | ||
cout("Creating program", verbose); | ||
parsed.fileNames.forEach(function (x) { return cout(" - " + x, verbose); }); | ||
var host = ts.createCompilerHost(parsed.options, true); | ||
var program = ts.createProgram(parsed.fileNames, parsed.options, host); | ||
var results = compile(program, project.config.compilerOptions || {}, tsLintConfigPath, verbose); | ||
var output = { | ||
results: results, | ||
cout(`Creating program`, verbose); | ||
parsed.fileNames.forEach(x => cout(` - ${x}`, verbose)); | ||
const host = ts.createCompilerHost(parsed.options, true); | ||
const program = ts.createProgram(parsed.fileNames, parsed.options, host); | ||
const results = compile(program, project.config.compilerOptions || {}, tsLintConfigPath, verbose); | ||
const output = { | ||
results, | ||
numMessages: 0, | ||
@@ -153,7 +152,7 @@ numErrors: 0, | ||
}; | ||
Object.keys(results).forEach(function (key) { | ||
var file = results[key]; | ||
Object.keys(results).forEach((key) => { | ||
const file = results[key]; | ||
output.numMessages += file.messages.length; | ||
file.messages.forEach(function (msg) { | ||
var item = output.byMessage[msg.type] = output.byMessage[msg.type] || { | ||
file.messages.forEach((msg) => { | ||
const item = output.byMessage[msg.type] = output.byMessage[msg.type] || { | ||
count: 0, | ||
@@ -189,8 +188,5 @@ references: [], | ||
*/ | ||
function compileCLI(tsconfigPath, tslintPath, verbose, messageMap, ci, dumpMessages) { | ||
if (messageMap === void 0) { messageMap = {}; } | ||
if (ci === void 0) { ci = false; } | ||
if (dumpMessages === void 0) { dumpMessages = true; } | ||
var io = services_1.Provider.getInstance().io; | ||
var projectResults; | ||
function compileCLI(tsconfigPath, tslintPath, verbose, messageMap = {}, ci = false, dumpMessages = true) { | ||
const io = services_1.Provider.getInstance().io; | ||
let projectResults; | ||
try { | ||
@@ -201,3 +197,3 @@ projectResults = compileProject(tsconfigPath, tslintPath, verbose); | ||
io.log(e.stack); | ||
io.error("Failure during project compilation: " + e.message); | ||
io.error(`Failure during project compilation: ${e.message}`); | ||
if (dumpMessages) { | ||
@@ -208,3 +204,3 @@ io.dumpMessages(); | ||
} | ||
var projectStatus = getProjectStatus(projectResults, messageMap); | ||
const projectStatus = getProjectStatus(projectResults, messageMap); | ||
if (projectStatus.status !== Interfaces_1.ExitCode.OK) { | ||
@@ -225,8 +221,8 @@ io.log(Formatter_1.formatProjectResults(projectStatus, projectResults, ci)); | ||
function getProjectStatus(projectResults, messageMap) { | ||
var exceptionsResults = { | ||
const exceptionsResults = { | ||
status: Interfaces_1.ExitCode.OK, | ||
exceptions: {}, | ||
}; | ||
var messageTypes = Object.keys(messageMap); | ||
var failureStatus = { | ||
const messageTypes = Object.keys(messageMap); | ||
const failureStatus = { | ||
needsReadjustment: false, | ||
@@ -238,10 +234,10 @@ errorException: false, | ||
}; | ||
messageTypes.forEach(function (type) { | ||
var message = projectResults.byMessage[type] || { | ||
messageTypes.forEach((type) => { | ||
const message = projectResults.byMessage[type] || { | ||
count: 0, | ||
references: [], | ||
}; | ||
var sample = message.references[0]; | ||
var failed = message.count > messageMap[type]; | ||
var needsReadjustment = message.count < messageMap[type]; | ||
const sample = message.references[0]; | ||
const failed = message.count > messageMap[type]; | ||
const needsReadjustment = message.count < messageMap[type]; | ||
failureStatus.needsReadjustment = failureStatus.needsReadjustment || needsReadjustment; | ||
@@ -260,4 +256,4 @@ if (!sample) { | ||
exceptionsResults.exceptions[type] = { | ||
type: type, | ||
failed: failed, | ||
type, | ||
failed, | ||
found: message.count, | ||
@@ -264,0 +260,0 @@ allowed: messageMap[type], |
@@ -1,2 +0,2 @@ | ||
import { TypedObject, IFileMessages, IProjectStatus, IProjectResults } from './Interfaces'; | ||
import { IFileMessages, IProjectResults, IProjectStatus, TypedObject } from './Interfaces'; | ||
declare function formatResults(results: TypedObject<IFileMessages>): string; | ||
@@ -3,0 +3,0 @@ declare function formatProjectResults(projectStatus: IProjectStatus, projectResults: IProjectResults, ci?: boolean, ciLimit?: number): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Interfaces_1 = require("./Interfaces"); | ||
var colors = require("colors"); | ||
const colors = require("colors"); | ||
const Interfaces_1 = require("./Interfaces"); | ||
function align(msg, alignment, size) { | ||
var repeatNumber = Math.max(size - msg.length, 0); | ||
const repeatNumber = Math.max(size - msg.length, 0); | ||
if (alignment === 'l') { | ||
@@ -13,7 +13,7 @@ return msg + ' '.repeat(repeatNumber); | ||
function breakMsg(msg, size) { | ||
var result = []; | ||
var words = msg.split(' '); | ||
var line = []; | ||
var length = 0; | ||
words.forEach(function (word) { | ||
const result = []; | ||
const words = msg.split(' '); | ||
const line = []; | ||
let length = 0; | ||
words.forEach((word) => { | ||
if (length + word.length <= size) { | ||
@@ -34,5 +34,5 @@ line.push(word); | ||
function _formatResults(buf, messages) { | ||
var colSizes = [0, 0, 0, 0]; | ||
messages.forEach(function (msg) { | ||
msg.forEach(function (item, index) { | ||
const colSizes = [0, 0, 0, 0]; | ||
messages.forEach((msg) => { | ||
msg.forEach((item, index) => { | ||
if (item.length > colSizes[index]) { | ||
@@ -43,3 +43,3 @@ colSizes[index] = Math.min(item.length, 80); | ||
}); | ||
var colorMap = { | ||
const colorMap = { | ||
error: colors.red, | ||
@@ -51,4 +51,4 @@ warning: colors.yellow, | ||
}; | ||
messages.forEach(function (msg) { | ||
var main = breakMsg(msg[3], colSizes[3]); | ||
messages.forEach((msg) => { | ||
const main = breakMsg(msg[3], colSizes[3]); | ||
buf.push(' '); | ||
@@ -69,10 +69,10 @@ buf.push(colorMap[msg[0]](align(msg[1], 'r', colSizes[1]))); | ||
if (main.length > 1) { | ||
var indent_1 = ' '.repeat(5 + colSizes[1] + colSizes[2]); | ||
main.slice(1).forEach(function (line, index) { | ||
var lineMsg = align(line, 'l', colSizes[3]); | ||
const indent = ' '.repeat(5 + colSizes[1] + colSizes[2]); | ||
main.slice(1).forEach((line, index) => { | ||
const lineMsg = align(line, 'l', colSizes[3]); | ||
if (index === main.length - 2) { | ||
buf.push("" + indent_1 + lineMsg.underline); | ||
buf.push(`${indent}${lineMsg.underline}`); | ||
} | ||
else { | ||
buf.push("" + indent_1 + lineMsg); | ||
buf.push(`${indent}${lineMsg}`); | ||
} | ||
@@ -85,16 +85,16 @@ buf.push('\n'); | ||
function formatResults(results) { | ||
var buffer = []; | ||
var fileNames = Object.keys(results).sort(); | ||
fileNames.forEach(function (fileName) { | ||
var obj = results[fileName]; | ||
var numMessages = obj.messages.length; | ||
const buffer = []; | ||
const fileNames = Object.keys(results).sort(); | ||
fileNames.forEach(fileName => { | ||
const obj = results[fileName]; | ||
const numMessages = obj.messages.length; | ||
if (!numMessages) { | ||
return; | ||
} | ||
var foundMessageWord = "MESSAGE" + (numMessages === 1 ? '' : 'S'); | ||
var messageInfo = numMessages + " " + foundMessageWord; | ||
buffer.push("\n" + messageInfo.magenta + " in " + fileName.underline.magenta + ":\n"); | ||
const foundMessageWord = `MESSAGE${numMessages === 1 ? '' : 'S'}`; | ||
const messageInfo = `${numMessages} ${foundMessageWord}`; | ||
buffer.push(`\n${messageInfo.magenta} in ${fileName.underline.magenta}:\n`); | ||
buffer.push('\n'); | ||
var messages = []; | ||
obj.messages.forEach(function (msg) { | ||
const messages = []; | ||
obj.messages.forEach((msg) => { | ||
messages.push([ | ||
@@ -114,4 +114,4 @@ msg.category, | ||
function _formatExceptions(buf, messages) { | ||
var size = 0; | ||
messages.forEach(function (msg) { | ||
let size = 0; | ||
messages.forEach((msg) => { | ||
if (msg[1].length > size) { | ||
@@ -121,5 +121,5 @@ size = msg[1].length; | ||
}); | ||
messages.forEach(function (msg) { | ||
var failed = msg[0]; | ||
var warn = msg[2] < msg[3]; | ||
messages.forEach((msg) => { | ||
const failed = msg[0]; | ||
const warn = msg[2] < msg[3]; | ||
buf.push(' '); | ||
@@ -144,35 +144,34 @@ if (warn) { | ||
if (failed) { | ||
var allowed = msg[3] === -1 ? '' : ", " + msg[3].toString().yellow + " allowed"; | ||
buf.push(msg[2].toString().red + " found" + allowed + "\n"); | ||
const allowed = msg[3] === -1 ? '' : `, ${msg[3].toString().yellow} allowed`; | ||
buf.push(`${msg[2].toString().red} found${allowed}\n`); | ||
} | ||
else if (warn) { | ||
buf.push(msg[2].toString().green + " found, " + msg[3].toString().yellow + " allowed\n"); | ||
buf.push(`${msg[2].toString().green} found, ${msg[3].toString().yellow} allowed\n`); | ||
} | ||
else { | ||
buf.push((msg[2] + " found, " + msg[3] + " allowed\n").gray); | ||
buf.push(`${msg[2]} found, ${msg[3]} allowed\n`.gray); | ||
} | ||
}); | ||
} | ||
function formatCIResults(byMessage, listLimit) { | ||
if (listLimit === void 0) { listLimit = 5; } | ||
var buffer = []; | ||
var msgTypes = Object.keys(byMessage).sort(); | ||
msgTypes.forEach(function (msgType) { | ||
var obj = byMessage[msgType]; | ||
var numMessages = obj.count; | ||
function formatCIResults(byMessage, listLimit = 5) { | ||
const buffer = []; | ||
const msgTypes = Object.keys(byMessage).sort(); | ||
msgTypes.forEach((msgType) => { | ||
const obj = byMessage[msgType]; | ||
const numMessages = obj.count; | ||
if (!numMessages) { | ||
return; | ||
} | ||
var messageInfo = numMessages + " " + msgType; | ||
buffer.push("\n" + messageInfo.magenta + ":\n"); | ||
const messageInfo = `${numMessages} ${msgType}`; | ||
buffer.push(`\n${messageInfo.magenta}:\n`); | ||
buffer.push('\n'); | ||
var fileNames = obj.references.map(function (x) { return x.fileInfo.absPath; }); | ||
var uniqueFileNames = Array.from(new Set(fileNames)); | ||
var totalRefs = Math.min(listLimit, uniqueFileNames.length); | ||
var refs = uniqueFileNames.slice(0, totalRefs); | ||
refs.forEach(function (msg) { | ||
var msgReferences = obj.references.filter(function (x) { return x.fileInfo.absPath === msg; }); | ||
var locations = msgReferences.map(function (x) { return x.message.line.toString().red + ":" + x.message.character; }); | ||
buffer.push(" - " + msg + "\n"); | ||
buffer.push(" " + locations.join(', ') + "\n"); | ||
const fileNames = obj.references.map(x => x.fileInfo.absPath); | ||
const uniqueFileNames = Array.from(new Set(fileNames)); | ||
const totalRefs = Math.min(listLimit, uniqueFileNames.length); | ||
const refs = uniqueFileNames.slice(0, totalRefs); | ||
refs.forEach((msg) => { | ||
const msgReferences = obj.references.filter(x => x.fileInfo.absPath === msg); | ||
const locations = msgReferences.map(x => `${x.message.line.toString().red}:${x.message.character}`); | ||
buffer.push(` - ${msg}\n`); | ||
buffer.push(` ${locations.join(', ')}\n`); | ||
}); | ||
@@ -185,7 +184,5 @@ if (totalRefs < uniqueFileNames.length) { | ||
} | ||
function formatProjectResults(projectStatus, projectResults, ci, ciLimit) { | ||
if (ci === void 0) { ci = false; } | ||
if (ciLimit === void 0) { ciLimit = 10; } | ||
var buffer = []; | ||
var allMessages = ''; | ||
function formatProjectResults(projectStatus, projectResults, ci = false, ciLimit = 10) { | ||
const buffer = []; | ||
let allMessages = ''; | ||
if (!ci || projectResults.numMessages < ciLimit) { | ||
@@ -197,6 +194,9 @@ allMessages = formatResults(projectResults.results); | ||
} | ||
var allTypes = Array.from(new Set(Object.keys(projectResults.byMessage).concat(Object.keys(projectStatus.exceptions)))).sort(); | ||
var messages = []; | ||
allTypes.forEach(function (type) { | ||
var exception = projectStatus.exceptions[type]; | ||
const allTypes = Array.from(new Set([ | ||
...Object.keys(projectResults.byMessage), | ||
...Object.keys(projectStatus.exceptions), | ||
])).sort(); | ||
const messages = []; | ||
allTypes.forEach((type) => { | ||
const exception = projectStatus.exceptions[type]; | ||
if (exception) { | ||
@@ -210,8 +210,8 @@ messages.push([exception.failed, exception.type, exception.found, exception.allowed]); | ||
_formatExceptions(buffer, messages); | ||
var exceptions = messages.length ? 'STATS:'.magenta + "\n\n" + buffer.join('') : ''; | ||
const exceptions = messages.length ? `${'STATS:'.magenta}\n\n${buffer.join('')}` : ''; | ||
buffer.length = 0; | ||
if (projectStatus.status === Interfaces_1.ExitCode.NEEDS_READJUSTMENT) { | ||
return exceptions + "\n\n"; | ||
return `${exceptions}\n\n`; | ||
} | ||
return allMessages + "\n\n" + exceptions + "\n\n"; | ||
return `${allMessages}\n\n${exceptions}\n\n`; | ||
} | ||
@@ -221,23 +221,23 @@ exports.formatProjectResults = formatProjectResults; | ||
if (projectStatus.status === Interfaces_1.ExitCode.NEEDS_READJUSTMENT) { | ||
return "Number of allowed messages need to be lowered in `package.json`"; | ||
return `Number of allowed messages need to be lowered in \`package.json\``; | ||
} | ||
var formatItem = function (itemName, itemCount) { | ||
var amount = itemCount === 1 ? '' : 's'; | ||
return "`" + itemCount + "` _" + itemName + amount + "_"; | ||
const formatItem = (itemName, itemCount) => { | ||
const amount = itemCount === 1 ? '' : 's'; | ||
return `\`${itemCount}\` _${itemName}${amount}_`; | ||
}; | ||
var results = projectResults.results; | ||
var numFiles = Object.keys(results) | ||
.filter(function (fileName) { | ||
var obj = results[fileName]; | ||
const results = projectResults.results; | ||
const numFiles = Object.keys(results) | ||
.filter((fileName) => { | ||
const obj = results[fileName]; | ||
return obj.messages.length > 0; | ||
}).length; | ||
var errors = projectResults.numErrors; | ||
var warnings = projectResults.numWarnings; | ||
var stats = []; | ||
const errors = projectResults.numErrors; | ||
const warnings = projectResults.numWarnings; | ||
const stats = []; | ||
if (errors) | ||
stats.push("" + formatItem('error', errors)); | ||
stats.push(`${formatItem('error', errors)}`); | ||
if (warnings) | ||
stats.push("" + formatItem('warning', warnings)); | ||
return stats.join(' and ') + " found over the span of " + formatItem('file', numFiles); | ||
stats.push(`${formatItem('warning', warnings)}`); | ||
return `${stats.join(' and ')} found over the span of ${formatItem('file', numFiles)}`; | ||
} | ||
exports.formatFailureMessage = formatFailureMessage; |
@@ -1,4 +0,3 @@ | ||
import { MessageCategory, TypedObject, ExitCode, ITSMessage, IFileInfo, IFileMessages, IMessageInfo, IMessageReference, IProjectResults, IProjectStatus } from './Interfaces'; | ||
import { compile, compileProject, compileCLI, getProjectStatus } from './Compiler'; | ||
import { formatResults, formatProjectResults, formatFailureMessage } from './Formatter'; | ||
export { MessageCategory, TypedObject, ExitCode, ITSMessage, IFileInfo, IFileMessages, IMessageInfo, IMessageReference, IProjectResults, IProjectStatus, compile, compileProject, compileCLI, getProjectStatus, formatResults, formatProjectResults, formatFailureMessage, }; | ||
export * from './Compiler'; | ||
export * from './Formatter'; | ||
export * from './Interfaces'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Interfaces_1 = require("./Interfaces"); | ||
exports.ExitCode = Interfaces_1.ExitCode; | ||
var Compiler_1 = require("./Compiler"); | ||
exports.compile = Compiler_1.compile; | ||
exports.compileProject = Compiler_1.compileProject; | ||
exports.compileCLI = Compiler_1.compileCLI; | ||
exports.getProjectStatus = Compiler_1.getProjectStatus; | ||
var Formatter_1 = require("./Formatter"); | ||
exports.formatResults = Formatter_1.formatResults; | ||
exports.formatProjectResults = Formatter_1.formatProjectResults; | ||
exports.formatFailureMessage = Formatter_1.formatFailureMessage; | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./Compiler"), exports); | ||
tslib_1.__exportStar(require("./Formatter"), exports); | ||
tslib_1.__exportStar(require("./Interfaces"), exports); |
@@ -1,6 +0,6 @@ | ||
import { MessageCategory, TypedObject, ExitCode, ITSMessage, IFileInfo, IFileMessages, IMessageInfo, IMessageReference, IProjectResults, IProjectStatus, compile, compileProject, compileCLI, getProjectStatus, formatResults, formatProjectResults, formatFailureMessage } from './compiler'; | ||
import { AbstractBuilder, IBuilder, NPMBuilder, runBuilder } from './builders'; | ||
import { IField, IAction, IAttachment, AbstractSlack, ISlacker, TravisSlack, runSlacker } from './slack'; | ||
import { CI, Environment, IBuilderMessages, IO, Git, Github, Provider } from './services'; | ||
import { util, Util } from './Util'; | ||
import { ExitCode, IFileInfo, IFileMessages, IMessageInfo, IMessageReference, IProjectResults, IProjectStatus, ITSMessage, MessageCategory, TypedObject, compile, compileCLI, compileProject, formatFailureMessage, formatProjectResults, formatResults, getProjectStatus } from './compiler'; | ||
import { CI, Environment, Git, Github, IBuilderMessages, IO, Provider } from './services'; | ||
import { AbstractSlack, IAction, IAttachment, IField, ISlacker, TravisSlack, runSlacker } from './slack'; | ||
import { Util, util } from './Util'; | ||
export { MessageCategory, TypedObject, ExitCode, ITSMessage, IFileInfo, IFileMessages, IMessageInfo, IMessageReference, IProjectResults, IProjectStatus, compile, compileProject, compileCLI, getProjectStatus, formatResults, formatProjectResults, formatFailureMessage, AbstractBuilder, IBuilder, NPMBuilder, runBuilder, IField, IAction, IAttachment, AbstractSlack, ISlacker, TravisSlack, runSlacker, CI, Environment, IBuilderMessages, IO, Git, Github, Provider, util, Util, }; |
34
index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var compiler_1 = require("./compiler"); | ||
const builders_1 = require("./builders"); | ||
exports.AbstractBuilder = builders_1.AbstractBuilder; | ||
exports.NPMBuilder = builders_1.NPMBuilder; | ||
exports.runBuilder = builders_1.runBuilder; | ||
const compiler_1 = require("./compiler"); | ||
exports.ExitCode = compiler_1.ExitCode; | ||
exports.compile = compiler_1.compile; | ||
exports.compileCLI = compiler_1.compileCLI; | ||
exports.compileProject = compiler_1.compileProject; | ||
exports.compileCLI = compiler_1.compileCLI; | ||
exports.formatFailureMessage = compiler_1.formatFailureMessage; | ||
exports.formatProjectResults = compiler_1.formatProjectResults; | ||
exports.formatResults = compiler_1.formatResults; | ||
exports.getProjectStatus = compiler_1.getProjectStatus; | ||
exports.formatResults = compiler_1.formatResults; | ||
exports.formatProjectResults = compiler_1.formatProjectResults; | ||
exports.formatFailureMessage = compiler_1.formatFailureMessage; | ||
var builders_1 = require("./builders"); | ||
exports.AbstractBuilder = builders_1.AbstractBuilder; | ||
exports.NPMBuilder = builders_1.NPMBuilder; | ||
exports.runBuilder = builders_1.runBuilder; | ||
var slack_1 = require("./slack"); | ||
exports.AbstractSlack = slack_1.AbstractSlack; | ||
exports.TravisSlack = slack_1.TravisSlack; | ||
exports.runSlacker = slack_1.runSlacker; | ||
var services_1 = require("./services"); | ||
const services_1 = require("./services"); | ||
exports.CI = services_1.CI; | ||
exports.Environment = services_1.Environment; | ||
exports.IO = services_1.IO; | ||
exports.Git = services_1.Git; | ||
exports.Github = services_1.Github; | ||
exports.IO = services_1.IO; | ||
exports.Provider = services_1.Provider; | ||
var Util_1 = require("./Util"); | ||
const slack_1 = require("./slack"); | ||
exports.AbstractSlack = slack_1.AbstractSlack; | ||
exports.TravisSlack = slack_1.TravisSlack; | ||
exports.runSlacker = slack_1.runSlacker; | ||
const Util_1 = require("./Util"); | ||
exports.Util = Util_1.Util; | ||
exports.util = Util_1.util; | ||
exports.Util = Util_1.Util; |
{ | ||
"name": "@ioffice/tc-builder", | ||
"version": "3.0.0", | ||
"version": "3.1.0-beta.1903141815", | ||
"description": "iOFFICE TeamCity Builder", | ||
"author": "iOffice", | ||
"license": "UNLICENSED", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/iOffice/tc-builder.git" | ||
}, | ||
"engines" : { | ||
"node": ">=8.0.0" | ||
}, | ||
"main": "index.js", | ||
@@ -14,30 +23,26 @@ "typings": "index.d.ts", | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/iOffice/tc-builder.git" | ||
}, | ||
"author": "iOffice", | ||
"license": "UNLICENSED", | ||
"devDependencies": { | ||
"@ioffice/tslint-config-ioffice": "0.4.1", | ||
"@types/chai": "4.1.4", | ||
"@types/mocha": "5.2.3", | ||
"@types/progress": "2.0.1", | ||
"@types/request-promise": "4.1.41", | ||
"@ioffice/tslint-config-ioffice": "0.6.1", | ||
"@types/chai": "4.1.7", | ||
"@types/inquirer": "0.0.44", | ||
"@types/mocha": "5.2.6", | ||
"@types/progress": "2.0.3", | ||
"@types/request-promise": "4.1.42", | ||
"@types/semver": "5.5.0", | ||
"@types/sinon": "5.0.1", | ||
"chai": "4.1.2", | ||
"colors": "1.3.0", | ||
"mocha": "5.2.0", | ||
"moment": "2.22.2", | ||
"progress": "2.0.0", | ||
"request": "2.87.0", | ||
"request-promise": "4.2.2", | ||
"request-promise-core": "1.1.1", | ||
"semver": "5.5.0", | ||
"sinon": "6.0.1", | ||
"tslint": "5.10.0", | ||
"tslint-eslint-rules": "5.3.1", | ||
"typedoc": "0.11.1", | ||
"typescript": "2.9.2" | ||
"@types/sinon": "7.0.10", | ||
"chai": "4.2.0", | ||
"colors": "1.3.3", | ||
"inquirer": "6.2.2", | ||
"mocha": "6.0.2", | ||
"moment": "2.24.0", | ||
"progress": "2.0.3", | ||
"request": "2.88.0", | ||
"request-promise": "4.2.4", | ||
"request-promise-core": "1.1.2", | ||
"semver": "5.6.0", | ||
"sinon": "7.2.7", | ||
"tslint": "5.14.0", | ||
"tslint-eslint-rules": "5.4.0", | ||
"typedoc": "0.14.2", | ||
"typescript": "3.3.3333" | ||
}, | ||
@@ -44,0 +49,0 @@ "publishConfig": { |
@@ -22,2 +22,3 @@ declare enum CI { | ||
readonly slackChannels: string[]; | ||
readonly isReleaseSetup: boolean; | ||
readonly isPreRelease: boolean; | ||
@@ -24,0 +25,0 @@ readonly isRelease: boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Util_1 = require("../Util"); | ||
const Util_1 = require("../Util"); | ||
var CI; | ||
@@ -15,6 +15,6 @@ (function (CI) { | ||
*/ | ||
var Environment = /** @class */ (function () { | ||
function Environment() { | ||
class Environment { | ||
constructor() { | ||
this.releaseRegEx = /^Merge pull request #(\d+) from (.*)\/release(.*)/; | ||
var pEnv = process.env; | ||
const pEnv = process.env; | ||
this.projectName = this.getProjectName(); | ||
@@ -31,6 +31,7 @@ this.configName = this.getConfigName(); | ||
this.slackChannels = this.getSlackChannels(); | ||
this.isReleaseSetup = !!pEnv['RELEASE_SETUP']; | ||
this.isPreRelease = !!pEnv['PRERELEASE']; | ||
this.isRelease = !!this.commitMessage.match(this.releaseRegEx); | ||
var pkg = this.readPackage(); | ||
var repoInfo = this.getRepoInfo(pkg); | ||
const pkg = this.readPackage(); | ||
const repoInfo = this.getRepoInfo(pkg); | ||
this.packageName = pkg.name || ''; | ||
@@ -44,7 +45,7 @@ this.packageVersion = pkg.version || ''; | ||
*/ | ||
Environment.prototype.readPackage = function () { | ||
readPackage() { | ||
return Util_1.util.readJSON('./package.json'); | ||
}; | ||
Environment.prototype.getCIEnvironment = function () { | ||
var pEnv = process.env; | ||
} | ||
getCIEnvironment() { | ||
const pEnv = process.env; | ||
if (pEnv['TEAMCITY']) | ||
@@ -57,44 +58,44 @@ return CI.TEAMCITY; | ||
return CI.NONE; | ||
}; | ||
Environment.prototype.getProjectName = function () { | ||
var pEnv = process.env; | ||
} | ||
getProjectName() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_PROJECT_NAME'] || pEnv['PROJECT_NAME'] || ''; | ||
}; | ||
Environment.prototype.getConfigName = function () { | ||
var pEnv = process.env; | ||
} | ||
getConfigName() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_BUILDCONF_NAME'] || pEnv['CONFIG_NAME'] || ''; | ||
}; | ||
Environment.prototype.getBuildId = function () { | ||
var pEnv = process.env; | ||
} | ||
getBuildId() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_BUILD_ID'] || pEnv['TRAVIS_BUILD_ID'] || ''; | ||
}; | ||
Environment.prototype.getBuildNumber = function () { | ||
var pEnv = process.env; | ||
} | ||
getBuildNumber() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_BUILD_NUMBER'] || pEnv['TRAVIS_BUILD_NUMBER'] || ''; | ||
}; | ||
Environment.prototype.getPullRequestBranch = function () { | ||
var pEnv = process.env; | ||
} | ||
getPullRequestBranch() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_PULL_REQUEST_BRANCH'] || pEnv['TRAVIS_PULL_REQUEST_BRANCH'] || ''; | ||
}; | ||
Environment.prototype.getPullRequestNumber = function () { | ||
var pEnv = process.env; | ||
} | ||
getPullRequestNumber() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_PULL_REQUEST_NUMBER'] || pEnv['TRAVIS_PULL_REQUEST'] || ''; | ||
}; | ||
Environment.prototype.getTargetBranch = function () { | ||
var pEnv = process.env; | ||
} | ||
getTargetBranch() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_TARGET_BRANCH'] || pEnv['TRAVIS_BRANCH'] || ''; | ||
}; | ||
Environment.prototype.getCommitMessage = function () { | ||
var pEnv = process.env; | ||
} | ||
getCommitMessage() { | ||
const pEnv = process.env; | ||
return pEnv['TEAMCITY_COMMIT_MESSAGE'] || pEnv['TRAVIS_COMMIT_MESSAGE'] || ''; | ||
}; | ||
Environment.prototype.getSlackChannels = function () { | ||
var pEnv = process.env; | ||
} | ||
getSlackChannels() { | ||
const pEnv = process.env; | ||
return Object.keys(pEnv) | ||
.filter(function (key) { return key.startsWith('SLACK_CHANNEL_'); }) | ||
.map(function (channel) { return process.env[channel] || ''; }) | ||
.filter(function (x) { return x; }); | ||
}; | ||
Environment.prototype.getRepoInfo = function (pkg) { | ||
var gitUrl = pkg.repository; | ||
.filter(key => key.startsWith('SLACK_CHANNEL_')) | ||
.map(channel => process.env[channel] || '') | ||
.filter(x => x); | ||
} | ||
getRepoInfo(pkg) { | ||
let gitUrl = pkg.repository; | ||
if (gitUrl && typeof gitUrl !== 'string') { | ||
@@ -106,7 +107,6 @@ gitUrl = pkg.repository.url; | ||
} | ||
var _a = gitUrl.match(/(.*)\/(.*)\/(.*)\.git$/), owner = _a[2], repo = _a[3]; | ||
return { owner: owner, repo: repo }; | ||
}; | ||
return Environment; | ||
}()); | ||
const [, , owner, repo] = gitUrl.match(/(.*)\/(.*)\/(.*)\.git$/); | ||
return { owner, repo }; | ||
} | ||
} | ||
exports.Environment = Environment; |
@@ -10,2 +10,6 @@ import { IO } from './IO'; | ||
/** | ||
* Obtain the very first commit for the repo. | ||
*/ | ||
getFirstCommit(): Promise<string>; | ||
/** | ||
* Switch the git branch. | ||
@@ -12,0 +16,0 @@ */ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var Util_1 = require("../Util"); | ||
var Git = /** @class */ (function () { | ||
function Git(io) { | ||
const tslib_1 = require("tslib"); | ||
const Util_1 = require("../Util"); | ||
class Git { | ||
constructor(io) { | ||
this.io = io; | ||
@@ -12,91 +12,70 @@ } | ||
*/ | ||
Git.prototype.getBranch = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var branch, err_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, Util_1.util.exec("git symbolic-ref HEAD | sed 's!refs/heads/!!'")]; | ||
case 1: | ||
branch = _a.sent(); | ||
return [2 /*return*/, this.io.success(branch, "Git branch: " + branch)]; | ||
case 2: | ||
err_1 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Git.getBranch failure: " + err_1)]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
getBranch() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const branch = yield Util_1.util.exec(`git symbolic-ref HEAD | sed 's!refs\/heads\/!!'`); | ||
return this.io.success(branch, `Git branch: ${branch}`); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Git.getBranch failure: ${err}`); | ||
} | ||
}); | ||
}; | ||
} | ||
/** | ||
* Obtain the very first commit for the repo. | ||
*/ | ||
getFirstCommit() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const commit = yield Util_1.util.exec('git rev-list --max-parents=0 HEAD'); | ||
return this.io.success(commit, `First commit: ${commit}`); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Git.getFirstCommit failure: ${err}`); | ||
} | ||
}); | ||
} | ||
/** | ||
* Switch the git branch. | ||
*/ | ||
Git.prototype.switchBranch = function (branch, isNew) { | ||
if (isNew === void 0) { isNew = false; } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var newFlag, output, err_2; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
newFlag = isNew ? ' -b' : ''; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, Util_1.util.exec("git checkout" + newFlag + " " + branch + " -q")]; | ||
case 2: | ||
output = _a.sent(); | ||
return [2 /*return*/, this.io.success(output, "Switched to '" + branch + "' branch")]; | ||
case 3: | ||
err_2 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Git.switchBranch(" + branch + ", " + isNew + ") failure: " + err_2)]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
switchBranch(branch, isNew = false) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const newFlag = isNew ? ' -b' : ''; | ||
try { | ||
const output = yield Util_1.util.exec(`git checkout${newFlag} ${branch} -q`); | ||
return this.io.success(output, `Switched to '${branch}' branch`); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Git.switchBranch(${branch}, ${isNew}) failure: ${err}`); | ||
} | ||
}); | ||
}; | ||
} | ||
/** | ||
* Remove all the changes in the current branch. | ||
*/ | ||
Git.prototype.discardBranchChanges = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var output, err_3; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, Util_1.util.exec('git stash save --keep-index --include-untracked && git stash drop')]; | ||
case 1: | ||
output = _a.sent(); | ||
return [2 /*return*/, this.io.success(output, "Branch changes have been discarded")]; | ||
case 2: | ||
err_3 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Git.discardBranchChanges failure: " + err_3)]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
discardBranchChanges() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const output = yield Util_1.util.exec('git stash save --keep-index --include-untracked && git stash drop'); | ||
return this.io.success(output, `Branch changes have been discarded`); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Git.discardBranchChanges failure: ${err}`); | ||
} | ||
}); | ||
}; | ||
} | ||
/** | ||
* Delete a git branch. | ||
*/ | ||
Git.prototype.deleteBranch = function (branch) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var output, err_4; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, Util_1.util.exec("git branch -D " + branch + " -q")]; | ||
case 1: | ||
output = _a.sent(); | ||
return [2 /*return*/, this.io.success(output, "'" + branch + "' branch has been deleted")]; | ||
case 2: | ||
err_4 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Git.deleteBranch('" + branch + "') failure: " + err_4)]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
deleteBranch(branch) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const output = yield Util_1.util.exec(`git branch -D ${branch} -q`); | ||
return this.io.success(output, `'${branch}' branch has been deleted`); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Git.deleteBranch('${branch}') failure: ${err}`); | ||
} | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -107,29 +86,16 @@ * Provides a safe way of first discarding all the current changes in the branch we wish to | ||
*/ | ||
Git.prototype.switchAndDelete = function (toBranch, fromBranch) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var err_5; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 4, , 5]); | ||
return [4 /*yield*/, this.discardBranchChanges()]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, this.switchBranch(toBranch)]; | ||
case 2: | ||
_a.sent(); | ||
return [4 /*yield*/, this.deleteBranch(fromBranch)]; | ||
case 3: | ||
_a.sent(); | ||
return [2 /*return*/, this.io.success('')]; | ||
case 4: | ||
err_5 = _a.sent(); | ||
return [2 /*return*/, this.io.failure(err_5)]; | ||
case 5: return [2 /*return*/]; | ||
} | ||
}); | ||
switchAndDelete(toBranch, fromBranch) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.discardBranchChanges(); | ||
yield this.switchBranch(toBranch); | ||
yield this.deleteBranch(fromBranch); | ||
return this.io.success(''); | ||
} | ||
catch (err) { | ||
return this.io.failure(err); | ||
} | ||
}); | ||
}; | ||
return Git; | ||
}()); | ||
} | ||
} | ||
exports.Git = Git; |
@@ -0,4 +1,4 @@ | ||
import { RequestPromise } from 'request-promise'; | ||
import { Environment } from './Environment'; | ||
import { IO } from './IO'; | ||
import { RequestPromise } from 'request-promise'; | ||
declare class Github { | ||
@@ -5,0 +5,0 @@ env: Environment; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var http = require("request-promise"); | ||
var Github = /** @class */ (function () { | ||
function Github(env, io) { | ||
const tslib_1 = require("tslib"); | ||
const http = require("request-promise"); | ||
class Github { | ||
constructor(env, io) { | ||
this.env = env; | ||
this.io = io; | ||
this.baseUrl = "https://api.github.com/repos/" + env.owner + "/" + env.repo; | ||
this.baseUrl = `https://api.github.com/repos/${env.owner}/${env.repo}`; | ||
} | ||
Github.prototype.request = function (endpoint, method, body) { | ||
if (method === void 0) { method = 'GET'; } | ||
if (body === void 0) { body = null; } | ||
var options = { | ||
method: method, | ||
uri: this.baseUrl + "/" + endpoint, | ||
request(endpoint, method = 'GET', body = null) { | ||
const options = { | ||
method, | ||
uri: `${this.baseUrl}/${endpoint}`, | ||
qs: { access_token: this.env.githubToken }, | ||
@@ -25,35 +23,25 @@ headers: { 'User-Agent': 'iOffice-TCBuilder' }, | ||
return http(options); | ||
}; | ||
Github.prototype.createRelease = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var version, owner, repo, err_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
version = this.env.packageVersion; | ||
owner = this.env.owner; | ||
repo = this.env.repo; | ||
return [4 /*yield*/, this.request('releases', 'POST', { | ||
'tag_name': version, | ||
'target_commitish': 'master', | ||
name: "Version " + version, | ||
body: "**See [CHANGELOG](https://github.com/" + owner + "/" + repo + "/blob/master/CHANGELOG.md).**", | ||
draft: false, | ||
prerelease: false, | ||
})]; | ||
case 1: | ||
_a.sent(); | ||
this.io.log('Created Github release'); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
err_1 = _a.sent(); | ||
return [2 /*return*/, this.io.failure("Failed to release to GitHub:\n" + err_1.toString())]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
createRelease() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const version = this.env.packageVersion; | ||
const owner = this.env.owner; | ||
const repo = this.env.repo; | ||
yield this.request('releases', 'POST', { | ||
'tag_name': version, | ||
'target_commitish': 'master', | ||
name: `Version ${version}`, | ||
body: `**See [CHANGELOG](https://github.com/${owner}/${repo}/blob/master/CHANGELOG.md).**`, | ||
draft: false, | ||
prerelease: false, | ||
}); | ||
this.io.log('Created Github release'); | ||
} | ||
catch (err) { | ||
return this.io.failure(`Failed to release to GitHub:\n${err.toString()}`); | ||
} | ||
}); | ||
}; | ||
return Github; | ||
}()); | ||
} | ||
} | ||
exports.Github = Github; |
import { CI, Environment } from './Environment'; | ||
import { IBuilderMessages, IO } from './IO'; | ||
import { Git } from './Git'; | ||
import { Github } from './Github'; | ||
import { IBuilderMessages, IO } from './IO'; | ||
declare class Provider { | ||
@@ -6,0 +6,0 @@ private static instance; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Environment_1 = require("./Environment"); | ||
const Environment_1 = require("./Environment"); | ||
exports.CI = Environment_1.CI; | ||
exports.Environment = Environment_1.Environment; | ||
var IO_1 = require("./IO"); | ||
exports.IO = IO_1.IO; | ||
var Git_1 = require("./Git"); | ||
const Git_1 = require("./Git"); | ||
exports.Git = Git_1.Git; | ||
var Github_1 = require("./Github"); | ||
const Github_1 = require("./Github"); | ||
exports.Github = Github_1.Github; | ||
var Provider = /** @class */ (function () { | ||
function Provider() { | ||
const IO_1 = require("./IO"); | ||
exports.IO = IO_1.IO; | ||
class Provider { | ||
constructor() { | ||
this.env = new Environment_1.Environment(); | ||
@@ -19,8 +19,7 @@ this.io = new IO_1.IO(this.env); | ||
} | ||
Provider.getInstance = function () { | ||
static getInstance() { | ||
Provider.instance = Provider.instance || new Provider(); | ||
return Provider.instance; | ||
}; | ||
return Provider; | ||
}()); | ||
} | ||
} | ||
exports.Provider = Provider; |
@@ -41,3 +41,10 @@ import { Environment } from './Environment'; | ||
dumpMessages(): void; | ||
/** | ||
* Prompts the user for the next version provided by the `currentVersion`. The current version is | ||
* assumed to be parsable by `semver`. | ||
* | ||
* @param currentVersion The current version of the package. | ||
*/ | ||
promptForNewVersion(currentVersion: string): Promise<string>; | ||
} | ||
export { IBuilderMessages, IO, }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Environment_1 = require("./Environment"); | ||
var Util_1 = require("../Util"); | ||
var colors = require("colors"); | ||
var IO = /** @class */ (function () { | ||
function IO(env) { | ||
const colors = require("colors"); | ||
const inquirer = require("inquirer"); | ||
const semver = require("semver"); | ||
const Util_1 = require("../Util"); | ||
const Environment_1 = require("./Environment"); | ||
class IO { | ||
constructor(env) { | ||
this.env = env; | ||
} | ||
IO.prototype.log = function (msg) { | ||
log(msg) { | ||
// tslint:disable-next-line | ||
console.log(msg); | ||
}; | ||
} | ||
/** | ||
* Print a message to the console and stores the warning. | ||
*/ | ||
IO.prototype.warn = function (msg) { | ||
warn(msg) { | ||
IO.warnings.push([msg, +(new Date())]); | ||
if (this.env.ci === Environment_1.CI.TEAMCITY) { | ||
this.log("##teamcity[message text='" + this.escapeTC(msg) + "' status='WARNING']"); | ||
this.log(`##teamcity[message text='${this.escapeTC(msg)}' status='WARNING']`); | ||
} | ||
else if (this.env.ci === Environment_1.CI.TRAVIS) { | ||
this.log("##buildWarning: " + msg); | ||
this.log(`##buildWarning: ${msg}`); | ||
} | ||
else { | ||
this.log("WARNING: " + msg); | ||
this.log(`WARNING: ${msg}`); | ||
} | ||
}; | ||
} | ||
/** | ||
* Prints a message to the console and stores the error. | ||
*/ | ||
IO.prototype.error = function (msg) { | ||
error(msg) { | ||
IO.errors.push([msg, +(new Date())]); | ||
if (this.env.ci === Environment_1.CI.TEAMCITY) { | ||
this.log("##teamcity[buildProblem description='" + this.escapeTC(msg) + "']"); | ||
this.log(`##teamcity[buildProblem description='${this.escapeTC(msg)}']`); | ||
} | ||
else if (this.env.ci === Environment_1.CI.TRAVIS) { | ||
this.log("##buildFailure: " + msg); | ||
this.log(`##buildFailure: ${msg}`); | ||
} | ||
else { | ||
this.log("ERROR: " + msg + "\n"); | ||
this.log(`ERROR: ${msg}\n`); | ||
} | ||
}; | ||
} | ||
/** | ||
* To be used to pass a resolved promise down a chain of promises. | ||
*/ | ||
IO.prototype.success = function (value, msg) { | ||
success(value, msg) { | ||
if (msg) | ||
this.log(msg); | ||
return Promise.resolve(value); | ||
}; | ||
} | ||
/** | ||
* To be used to pass a rejected promise down a chain of promises. | ||
*/ | ||
IO.prototype.failure = function (err) { | ||
failure(err) { | ||
if (typeof err === 'string') { | ||
@@ -60,9 +62,9 @@ return Promise.reject(new Error(err)); | ||
return Promise.reject(err); | ||
}; | ||
IO.prototype.openBlock = function (name, desc) { | ||
} | ||
openBlock(name, desc) { | ||
if (this.env.ci === Environment_1.CI.TEAMCITY) { | ||
this.log("##teamcity[blockOpened name='" + name + "' description='" + this.escapeTC(desc) + "']"); | ||
this.log(`##teamcity[blockOpened name='${name}' description='${this.escapeTC(desc)}']`); | ||
} | ||
else if (this.env.ci === Environment_1.CI.TRAVIS) { | ||
this.log("travis_fold:start:" + name); | ||
this.log(`travis_fold:start:${name}`); | ||
if (desc) { | ||
@@ -73,14 +75,14 @@ this.log(colors.yellow(desc)); | ||
else { | ||
var description = desc ? " - " + desc : ''; | ||
this.log("## " + name + description); | ||
const description = desc ? ` - ${desc}` : ''; | ||
this.log(`## ${name}${description}`); | ||
} | ||
}; | ||
IO.prototype.closeBlock = function (name) { | ||
} | ||
closeBlock(name) { | ||
if (this.env.ci === Environment_1.CI.TEAMCITY) { | ||
this.log("##teamcity[blockClosed name='" + name + "']"); | ||
this.log(`##teamcity[blockClosed name='${name}']`); | ||
} | ||
else if (this.env.ci === Environment_1.CI.TRAVIS) { | ||
this.log("travis_fold:end:" + name); | ||
this.log(`travis_fold:end:${name}`); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -90,3 +92,3 @@ * Teamcity requires certain characters to be escaped when we use service messages. See | ||
*/ | ||
IO.prototype.escapeTC = function (msg) { | ||
escapeTC(msg) { | ||
return msg | ||
@@ -98,6 +100,6 @@ .replace(/\|/g, '||') | ||
.replace(/\n/g, '|n'); | ||
}; | ||
IO.prototype.loadMessages = function () { | ||
} | ||
loadMessages() { | ||
return Util_1.util.readJSON('./tcBuilderMessages.json'); | ||
}; | ||
} | ||
/** | ||
@@ -107,13 +109,12 @@ * To be called before the process finishes so that all the error and warning messages may be | ||
*/ | ||
IO.prototype.dumpMessages = function () { | ||
var _a, _b; | ||
var fileName = './tcBuilderMessages.json'; | ||
var data = { | ||
errors: IO.errors.slice(), | ||
warnings: IO.warnings.slice(), | ||
dumpMessages() { | ||
const fileName = './tcBuilderMessages.json'; | ||
const data = { | ||
errors: [...IO.errors], | ||
warnings: [...IO.warnings], | ||
}; | ||
var current = this.loadMessages(); | ||
const current = this.loadMessages(); | ||
if (current) { | ||
(_a = data.errors).push.apply(_a, current.errors); | ||
(_b = data.warnings).push.apply(_b, current.warnings); | ||
data.errors.push(...current.errors); | ||
data.warnings.push(...current.warnings); | ||
} | ||
@@ -126,7 +127,27 @@ if (data.errors.length === 0 && data.warnings.length === 0) { | ||
} | ||
}; | ||
IO.warnings = []; | ||
IO.errors = []; | ||
return IO; | ||
}()); | ||
} | ||
/** | ||
* Prompts the user for the next version provided by the `currentVersion`. The current version is | ||
* assumed to be parsable by `semver`. | ||
* | ||
* @param currentVersion The current version of the package. | ||
*/ | ||
promptForNewVersion(currentVersion) { | ||
const newPatch = semver.parse(currentVersion).inc('patch').version; | ||
const newMinor = semver.parse(currentVersion).inc('minor').version; | ||
const newMajor = semver.parse(currentVersion).inc('major').version; | ||
return new Promise((resolve, reject) => { | ||
inquirer.prompt([ | ||
{ | ||
type: 'list', | ||
name: 'version', | ||
message: `Current version is ${currentVersion}. Choose the next version:`, | ||
choices: [newPatch, newMinor, newMajor], | ||
}, | ||
]).then(answers => resolve(answers['version']), reject); | ||
}); | ||
} | ||
} | ||
IO.warnings = []; | ||
IO.errors = []; | ||
exports.IO = IO; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Util_1 = require("../Util"); | ||
const Util_1 = require("../Util"); | ||
/** | ||
@@ -10,4 +10,4 @@ * Trying to keep this file free of dependencies. Using | ||
function promiseSerial(funcs) { | ||
return funcs.reduce(function (promise, func) { | ||
return promise.then(function (result) { return func().then(Array.prototype.concat.bind(result)); }); | ||
return funcs.reduce((promise, func) => { | ||
return promise.then(result => func().then(Array.prototype.concat.bind(result))); | ||
}, Promise.resolve([])); | ||
@@ -19,8 +19,8 @@ } | ||
function install(pkg, depType, options) { | ||
var _a = options || {}, _b = _a.exact, exact = _b === void 0 ? false : _b, _c = _a.regex, regex = _c === void 0 ? '' : _c, _d = _a.latest, latest = _d === void 0 ? false : _d; | ||
return new Promise(function (resolve, reject) { | ||
var exitNumber = 0; | ||
var deps = pkg[depType]; | ||
var fns = Object.keys(deps) | ||
.filter(function (name) { | ||
const { exact = false, regex = '', latest = false } = options || {}; | ||
return new Promise((resolve, reject) => { | ||
let exitNumber = 0; | ||
const deps = pkg[depType]; | ||
const fns = Object.keys(deps) | ||
.filter((name) => { | ||
if (regex && !name.match(new RegExp(regex, 'i'))) | ||
@@ -30,10 +30,10 @@ return false; | ||
}) | ||
.map(function (name) { | ||
return function () { | ||
var version = latest ? 'latest' : deps[name]; | ||
var eParam = exact ? ' -E' : ''; | ||
var dParam = depType === 'devDependencies' ? ' -D' : ''; | ||
var cmd = "yarn add" + eParam + dParam + " " + name + "@" + version; | ||
process.stdout.write("$ " + cmd + "\n"); | ||
return Util_1.util.execCmd(cmd, true).catch(function () { | ||
.map((name) => { | ||
return () => { | ||
const version = latest ? 'latest' : deps[name]; | ||
const eParam = exact ? ' -E' : ''; | ||
const dParam = depType === 'devDependencies' ? ' -D' : ''; | ||
const cmd = `yarn add${eParam}${dParam} ${name}@${version}`; | ||
process.stdout.write(`$ ${cmd}\n`); | ||
return Util_1.util.execCmd(cmd, true).catch(() => { | ||
exitNumber += 1; | ||
@@ -43,3 +43,3 @@ }); | ||
}); | ||
promiseSerial(fns).then(function () { | ||
promiseSerial(fns).then(() => { | ||
if (exitNumber === 0) { | ||
@@ -46,0 +46,0 @@ resolve(0); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fs = require("fs"); | ||
var path = require("path"); | ||
var Util_1 = require("../Util"); | ||
var services_1 = require("../services"); | ||
var rel = function (x) { return path.resolve(__dirname, x); }; | ||
var log = function (msg) { return process.stdout.write(msg + "\n"); }; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const services_1 = require("../services"); | ||
const Util_1 = require("../Util"); | ||
const rel = (x) => path.resolve(__dirname, x); | ||
const log = (msg) => process.stdout.write(`${msg}\n`); | ||
function safeMkDir(directory) { | ||
@@ -15,16 +15,16 @@ if (!fs.existsSync(directory)) { | ||
function getFileContents(fileName, replacements) { | ||
var contents = fs.readFileSync(rel("./projectFiles/" + fileName + ".tpl")); | ||
const contents = fs.readFileSync(rel(`./projectFiles/${fileName}.tpl`)); | ||
return Util_1.util.replaceStrings(contents.toString(), replacements); | ||
} | ||
function verifySourceDirectory() { | ||
var files = ['src/main/index.ts', 'src/test/index.ts']; | ||
const files = ['src/main/index.ts', 'src/test/index.ts']; | ||
safeMkDir('src'); | ||
safeMkDir('src/main'); | ||
safeMkDir('src/test'); | ||
files.forEach(function (fileName) { | ||
files.forEach((fileName) => { | ||
if (fs.existsSync(fileName)) { | ||
log("[SKIP]: " + fileName); | ||
log(`[SKIP]: ${fileName}`); | ||
} | ||
else { | ||
log("[WRITING]: " + fileName); | ||
log(`[WRITING]: ${fileName}`); | ||
fs.writeFileSync(fileName, '\n'); | ||
@@ -44,11 +44,11 @@ } | ||
function writeFiles(fileList, replacements) { | ||
fileList.forEach(function (item) { | ||
var fileName = Array.isArray(item) ? item[0] : item; | ||
var destFileName = Array.isArray(item) ? item[1] : item; | ||
var contents = getFileContents(fileName, replacements); | ||
fileList.forEach((item) => { | ||
const fileName = Array.isArray(item) ? item[0] : item; | ||
const destFileName = Array.isArray(item) ? item[1] : item; | ||
const contents = getFileContents(fileName, replacements); | ||
if (fs.existsSync(destFileName)) { | ||
log("[SKIP]: " + destFileName); | ||
log(`[SKIP]: ${destFileName}`); | ||
} | ||
else { | ||
log("[WRITING]: " + destFileName); | ||
log(`[WRITING]: ${destFileName}`); | ||
fs.writeFileSync(destFileName, contents); | ||
@@ -59,3 +59,3 @@ } | ||
function setupFiles(replacements, fileName) { | ||
var projectFiles = [ | ||
const projectFiles = [ | ||
'.editorconfig', | ||
@@ -73,4 +73,4 @@ '.gitignore', | ||
if (fileName) { | ||
if (!fs.existsSync(rel("./projectFiles/" + fileName + ".tpl"))) { | ||
log("[ERROR]: invalid file " + fileName); | ||
if (!fs.existsSync(rel(`./projectFiles/${fileName}.tpl`))) { | ||
log(`[ERROR]: invalid file ${fileName}`); | ||
} | ||
@@ -100,4 +100,4 @@ else { | ||
log('[WEBPACK SETUP]'); | ||
var directory = process.argv[process.argv.indexOf('webpack') + 1]; | ||
var skipDeps = process.argv.indexOf('--skip-deps'); | ||
const directory = process.argv[process.argv.indexOf('webpack') + 1]; | ||
const skipDeps = process.argv.indexOf('--skip-deps'); | ||
if (!directory) { | ||
@@ -107,3 +107,3 @@ log('ERROR: usage: tc-builder setup webpack (dirname) [--skip-deps]'); | ||
writeFiles([ | ||
['webpack/webpack.config.ts', directory + "/webpack.config.ts"], | ||
['webpack/webpack.config.ts', `${directory}/webpack.config.ts`], | ||
], replacements); | ||
@@ -113,3 +113,3 @@ if (skipDeps) { | ||
} | ||
var packages = [ | ||
const packages = [ | ||
'@types/webpack', | ||
@@ -130,5 +130,5 @@ 'webpack', | ||
]; | ||
packages.forEach(function (name) { | ||
var cmd = "yarn add -E -D " + name + "@latest"; | ||
process.stdout.write("$ " + cmd + "\n"); | ||
packages.forEach((name) => { | ||
const cmd = `yarn add -E -D ${name}@latest`; | ||
process.stdout.write(`$ ${cmd}\n`); | ||
Util_1.util.execCmd(cmd, true); | ||
@@ -139,4 +139,4 @@ }); | ||
log('[ANGULAR SETUP]'); | ||
var directory = process.argv[process.argv.indexOf('angular') + 1]; | ||
var skipDeps = process.argv.indexOf('--skip-deps'); | ||
const directory = process.argv[process.argv.indexOf('angular') + 1]; | ||
const skipDeps = process.argv.indexOf('--skip-deps'); | ||
if (!directory) { | ||
@@ -146,5 +146,5 @@ log('ERROR: usage: tc-builder setup angular (dirname) [--skip-deps]'); | ||
writeFiles([ | ||
['angular/App.bundle.ts', directory + "/App.bundle.ts"], | ||
['angular/App.component.ts', directory + "/App.component.ts"], | ||
['angular/App.module.ts', directory + "/App.module.ts"], | ||
['angular/App.bundle.ts', `${directory}/App.bundle.ts`], | ||
['angular/App.component.ts', `${directory}/App.component.ts`], | ||
['angular/App.module.ts', `${directory}/App.module.ts`], | ||
], replacements); | ||
@@ -154,3 +154,3 @@ if (skipDeps) { | ||
} | ||
var packages = [ | ||
const packages = [ | ||
'@angular/animations', | ||
@@ -172,5 +172,5 @@ '@angular/common', | ||
]; | ||
packages.forEach(function (name) { | ||
var cmd = "yarn add -E -D " + name + "@latest"; | ||
process.stdout.write("$ " + cmd + "\n"); | ||
packages.forEach((name) => { | ||
const cmd = `yarn add -E -D ${name}@latest`; | ||
process.stdout.write(`$ ${cmd}\n`); | ||
Util_1.util.execCmd(cmd, true); | ||
@@ -180,4 +180,4 @@ }); | ||
function runSetup() { | ||
var env = services_1.Provider.getInstance().env; | ||
var replacements = { | ||
const env = services_1.Provider.getInstance().env; | ||
const replacements = { | ||
packageName: env.packageName, | ||
@@ -188,6 +188,6 @@ repo: env.repo, | ||
}; | ||
var projectPkg = Util_1.util.readJSON('./package.json', '.'); | ||
const projectPkg = Util_1.util.readJSON('./package.json', '.'); | ||
if (projectPkg) { | ||
var fileName_1 = process.argv[process.argv.indexOf('setup') + 1]; | ||
var environments = [ | ||
const fileName = process.argv[process.argv.indexOf('setup') + 1]; | ||
const environments = [ | ||
'teamcity', | ||
@@ -198,5 +198,5 @@ 'travis', | ||
]; | ||
var env_1 = environments.find(function (x) { return x === fileName_1; }); | ||
if (env_1) { | ||
var envMap = { | ||
const env = environments.find(x => x === fileName); | ||
if (env) { | ||
const envMap = { | ||
teamcity: teamcitySetup, | ||
@@ -207,6 +207,6 @@ travis: travisSetup, | ||
}; | ||
envMap[env_1](replacements); | ||
envMap[env](replacements); | ||
} | ||
else if (fileName_1) { | ||
setupFiles(replacements, fileName_1); | ||
else if (fileName) { | ||
setupFiles(replacements, fileName); | ||
} | ||
@@ -213,0 +213,0 @@ else { |
@@ -40,5 +40,5 @@ interface IField { | ||
declare abstract class AbstractSlack { | ||
readonly env: import("src/main/services/Environment").Environment; | ||
readonly io: import("src/main/services/IO").IO; | ||
readonly messages: import("src/main/services/IO").IBuilderMessages | null; | ||
readonly env: import("../services/Environment").Environment; | ||
readonly io: import("../services/IO").IO; | ||
readonly messages: import("../services/IO").IBuilderMessages | null; | ||
abstract getTitle(): string; | ||
@@ -45,0 +45,0 @@ abstract getTitleLink(): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var http = require("request-promise"); | ||
var services_1 = require("../services"); | ||
const tslib_1 = require("tslib"); | ||
const http = require("request-promise"); | ||
const services_1 = require("../services"); | ||
/** | ||
@@ -11,4 +11,4 @@ * Service to send slack messages. For this to work there needs to be environment variables with | ||
*/ | ||
var AbstractSlack = /** @class */ (function () { | ||
function AbstractSlack() { | ||
class AbstractSlack { | ||
constructor() { | ||
this.env = services_1.Provider.getInstance().env; | ||
@@ -18,33 +18,21 @@ this.io = services_1.Provider.getInstance().io; | ||
} | ||
AbstractSlack.prototype.run = function () { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var attachment_1, promises, err_1; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (this.env.slackChannels.length === 0) { | ||
return [2 /*return*/, Promise.reject('No slack channels found.')]; | ||
} | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
attachment_1 = this.createAttachment(); | ||
promises = this.env.slackChannels.map(function (item) { | ||
var _a = item.split('#'), token = _a[0], channel = _a[1]; | ||
return _this.sendMessage(token, channel, attachment_1); | ||
}); | ||
return [4 /*yield*/, Promise.all(promises)]; | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
return [2 /*return*/, Promise.reject(err_1)]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
run() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
if (this.env.slackChannels.length === 0) { | ||
return Promise.reject('No slack channels found.'); | ||
} | ||
try { | ||
const attachment = this.createAttachment(); | ||
const promises = this.env.slackChannels.map((item) => { | ||
const [token, channel] = item.split('#'); | ||
return this.sendMessage(token, channel, attachment); | ||
}); | ||
yield Promise.all(promises); | ||
} | ||
catch (err) { | ||
return Promise.reject(err); | ||
} | ||
}); | ||
}; | ||
AbstractSlack.prototype.getStatus = function () { | ||
} | ||
getStatus() { | ||
if (!this.messages) | ||
@@ -57,4 +45,4 @@ return 'good'; | ||
return 'good'; | ||
}; | ||
AbstractSlack.prototype.getBuildType = function () { | ||
} | ||
getBuildType() { | ||
if (this.env.pullRequestBranch) | ||
@@ -65,7 +53,7 @@ return 'Pull Request'; | ||
return 'Master'; | ||
}; | ||
AbstractSlack.prototype.getBuildBranch = function () { | ||
} | ||
getBuildBranch() { | ||
return this.env.pullRequestBranch || 'master'; | ||
}; | ||
AbstractSlack.prototype.getStatusMessage = function (status) { | ||
} | ||
getStatusMessage(status) { | ||
if (status === 'good') | ||
@@ -76,12 +64,9 @@ return 'passed with flying colors!'; | ||
return 'failed.'; | ||
}; | ||
AbstractSlack.prototype.getFields = function () { | ||
var fields = []; | ||
} | ||
getFields() { | ||
const fields = []; | ||
if (this.messages) { | ||
var listMessages = function (item) { | ||
item.sort(function (a, b) { return a[1] - b[1]; }); | ||
return item.map(function (_a) { | ||
var msg = _a[0]; | ||
return "\u2022 " + msg; | ||
}).join('\n'); | ||
const listMessages = (item) => { | ||
item.sort((a, b) => a[1] - b[1]); | ||
return item.map(([msg]) => `• ${msg}`).join('\n'); | ||
}; | ||
@@ -104,11 +89,11 @@ if (this.messages.errors.length > 0) { | ||
return fields; | ||
}; | ||
AbstractSlack.prototype.getActions = function () { | ||
var env = this.env; | ||
} | ||
getActions() { | ||
const env = this.env; | ||
if (env.pullRequestBranch) { | ||
var num = env.pullRequestNumber; | ||
const num = env.pullRequestNumber; | ||
return [{ | ||
type: 'button', | ||
text: "PR #" + num, | ||
url: "https://github.com/" + env.owner + "/" + env.repo + "/pull/" + num, | ||
text: `PR #${num}`, | ||
url: `https://github.com/${env.owner}/${env.repo}/pull/${num}`, | ||
}]; | ||
@@ -119,4 +104,4 @@ } | ||
type: 'button', | ||
text: env.packageName + "@" + env.packageVersion, | ||
url: "https://github.com/" + env.owner + "/" + env.repo + "/releases/tag/" + env.packageVersion, | ||
text: `${env.packageName}@${env.packageVersion}`, | ||
url: `https://github.com/${env.owner}/${env.repo}/releases/tag/${env.packageVersion}`, | ||
}]; | ||
@@ -127,28 +112,28 @@ } | ||
text: 'Github', | ||
url: "https://github.com/" + env.owner + "/" + env.repo, | ||
url: `https://github.com/${env.owner}/${env.repo}`, | ||
}]; | ||
}; | ||
AbstractSlack.prototype.createAttachment = function () { | ||
var env = this.env; | ||
var status = this.getStatus(); | ||
var statusMessage = this.getStatusMessage(status); | ||
var buildType = this.getBuildType(); | ||
var buildBranch = this.getBuildBranch(); | ||
} | ||
createAttachment() { | ||
const env = this.env; | ||
const status = this.getStatus(); | ||
const statusMessage = this.getStatusMessage(status); | ||
const buildType = this.getBuildType(); | ||
const buildBranch = this.getBuildBranch(); | ||
return { | ||
fallback: status + ": " + env.repo + "/" + buildBranch + " build " + statusMessage, | ||
fallback: `${status}: ${env.repo}/${buildBranch} build ${statusMessage}`, | ||
color: status, | ||
title: this.getTitle(), | ||
title_link: this.getTitleLink(), | ||
text: "The _" + buildType + "_ build for the *" + buildBranch + "* branch " + statusMessage, | ||
text: `The _${buildType}_ build for the *${buildBranch}* branch ${statusMessage}`, | ||
fields: this.getFields(), | ||
actions: this.getActions(), | ||
}; | ||
}; | ||
AbstractSlack.prototype.sendMessage = function (token, channel, attachment) { | ||
var body = { | ||
channel: channel, | ||
} | ||
sendMessage(token, channel, attachment) { | ||
const body = { | ||
channel, | ||
'as_user': true, | ||
'attachments': [attachment], | ||
}; | ||
var options = { | ||
const options = { | ||
method: 'POST', | ||
@@ -159,11 +144,10 @@ uri: 'https://slack.com/api/chat.postMessage', | ||
'Content-Type': 'application/json; charset=utf-8', | ||
'Authorization': "Bearer " + token, | ||
'Authorization': `Bearer ${token}`, | ||
}, | ||
json: true, | ||
body: body, | ||
body, | ||
}; | ||
return http(options); | ||
}; | ||
return AbstractSlack; | ||
}()); | ||
} | ||
} | ||
exports.AbstractSlack = AbstractSlack; |
@@ -1,2 +0,2 @@ | ||
import { IField, IAction, IAttachment, AbstractSlack, ISlacker } from './AbstractSlack'; | ||
import { AbstractSlack, IAction, IAttachment, IField, ISlacker } from './AbstractSlack'; | ||
import { TravisSlack } from './TravisSlack'; | ||
@@ -3,0 +3,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var AbstractSlack_1 = require("./AbstractSlack"); | ||
const tslib_1 = require("tslib"); | ||
const AbstractSlack_1 = require("./AbstractSlack"); | ||
exports.AbstractSlack = AbstractSlack_1.AbstractSlack; | ||
var TravisSlack_1 = require("./TravisSlack"); | ||
const TravisSlack_1 = require("./TravisSlack"); | ||
exports.TravisSlack = TravisSlack_1.TravisSlack; | ||
@@ -13,25 +13,15 @@ /** | ||
function runSlacker(Slacker) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var slack, err_1; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
slack = new Slacker(); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, slack.run()]; | ||
case 2: | ||
_a.sent(); | ||
console['log']('Success'); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_1 = _a.sent(); | ||
console['log'](err_1); | ||
return [2 /*return*/, 1]; | ||
case 4: return [2 /*return*/, 0]; | ||
} | ||
}); | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const slack = new Slacker(); | ||
try { | ||
yield slack.run(); | ||
console['log']('Success'); | ||
} | ||
catch (err) { | ||
console['log'](err); | ||
return 1; | ||
} | ||
return 0; | ||
}); | ||
} | ||
exports.runSlacker = runSlacker; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var AbstractSlack_1 = require("./AbstractSlack"); | ||
var TravisSlack = /** @class */ (function (_super) { | ||
tslib_1.__extends(TravisSlack, _super); | ||
function TravisSlack() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
const AbstractSlack_1 = require("./AbstractSlack"); | ||
class TravisSlack extends AbstractSlack_1.AbstractSlack { | ||
getTitle() { | ||
const env = this.env; | ||
return `${env.repo} [Travis ${this.getBuildType()} Build #${env.buildNumber}]`; | ||
} | ||
TravisSlack.prototype.getTitle = function () { | ||
var env = this.env; | ||
return env.repo + " [Travis " + this.getBuildType() + " Build #" + env.buildNumber + "]"; | ||
}; | ||
TravisSlack.prototype.getTitleLink = function () { | ||
var env = this.env; | ||
return "https://travis-ci.com/" + env.owner + "/" + env.repo + "/builds/" + env.buildId; | ||
}; | ||
return TravisSlack; | ||
}(AbstractSlack_1.AbstractSlack)); | ||
getTitleLink() { | ||
const env = this.env; | ||
return `https://travis-ci.com/${env.owner}/${env.repo}/builds/${env.buildId}`; | ||
} | ||
} | ||
exports.TravisSlack = TravisSlack; |
#!/usr/bin/env node | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var Util_1 = require("./Util"); | ||
var Setup_1 = require("./setup/Setup"); | ||
var compiler_1 = require("./compiler"); | ||
var builders_1 = require("./builders"); | ||
var slack_1 = require("./slack"); | ||
var commands = [ | ||
'setup', | ||
'compile', | ||
'run', | ||
'slack-notify', | ||
]; | ||
var options = [ | ||
'--dev', | ||
'--no-lint', | ||
'--verbose', | ||
'--help', | ||
'-h', | ||
'--version', | ||
'-v', | ||
'--ci', | ||
'--no-msg-dump', | ||
]; | ||
var _a = commands.map(function (x) { return process.argv.indexOf(x) > -1; }), setup = _a[0], compile = _a[1], run = _a[2], slackNotify = _a[3]; | ||
var _b = options.map(function (x) { return process.argv.indexOf(x) > -1; }), dev = _b[0], noLint = _b[1], verbose = _b[2], help = _b[3], h = _b[4], version = _b[5], v = _b[6], ci = _b[7], noMsgDump = _b[8]; | ||
var tcPkg = Util_1.util.readJSON('./package.json', __dirname) || {}; | ||
var tcPkgVersion = tcPkg['version']; | ||
var log = function (msg) { return process.stdout.write(msg + "\n"); }; | ||
var usage = "usage: tc-builder (command) [--options]\n\nThe following commands are supported:\n\n - setup: Installs all the same dependencies as the ones in the tc-builder and creates\n configuration files if they do not exists. This command should be run when starting\n a new project or updating tc-builder.\n\n If there are any new updates to the configuration files and you wish to see them you\n can provide the name of the file right after the command.\n - update-tools: Installs all the latest devDependencies.\n - compile: Looks at the 'tsconfig.json' file to compile the project. By default it will also\n lint the files unless we use the '--no-lint' option.\n - run: Main command to be run in team city. It will make sure to run all the tests and publish\n to npm if necessary.\n - slack-notify: If you have provided the appropiate slack environment variables then this will\n get slack to send a message.\n\nOptions:\n\n --dev: Uses tsconfig.dev.json and tslint.dev.json\n --no-lint: Skip linting.\n --verbose: Print messages of the steps for the 'compile' command.\n --ci: Continous Integration flag, minimizes the output in case there are too many errors.\n --help, -h: Print this message.\n --version, -v: Print the version.\n --no-msg-dump: Skip dumping error and warning messages to './tcBuilderMessages.json'.\n\ntc-builder@" + tcPkgVersion + "\n"; | ||
const tslib_1 = require("tslib"); | ||
const builders_1 = require("./builders"); | ||
const compiler_1 = require("./compiler"); | ||
const Setup_1 = require("./setup/Setup"); | ||
const slack_1 = require("./slack"); | ||
const Util_1 = require("./Util"); | ||
const args = { | ||
commands: { | ||
setup: 'setup', | ||
compile: 'compile', | ||
run: 'run', | ||
'slack-notify': 'slackNotify', | ||
}, | ||
booleans: { | ||
'--verbose': 'verbose', | ||
'--help': 'help', | ||
'-h': 'help', | ||
'--version': 'version', | ||
'-v': 'version', | ||
'--ci': 'ci', | ||
'--no-msg-dump': 'noMsgDump', | ||
'--no-lint': 'noLint', | ||
}, | ||
definitions: { | ||
tsconfigPath: './tsconfig.json', | ||
tslintPath: './tslint.json', | ||
}, | ||
}; | ||
const parsedArgs = Util_1.util.parseArgVector(process.argv.slice(2), args); | ||
const { setup, compile, run, slackNotify, } = parsedArgs.commands; | ||
const { noLint, verbose, help, version, ci, noMsgDump, } = parsedArgs.booleans; | ||
const tcPkg = Util_1.util.readJSON('./package.json', __dirname) || {}; | ||
const tcPkgVersion = tcPkg['version']; | ||
const log = (msg) => process.stdout.write(`${msg}\n`); | ||
const usage = `usage: tc-builder (command) [--options] | ||
The following commands are supported: | ||
- setup: Installs all the same dependencies as the ones in the tc-builder and creates | ||
configuration files if they do not exists. This command should be run when starting | ||
a new project or updating tc-builder. | ||
If there are any new updates to the configuration files and you wish to see them you | ||
can provide the name of the file right after the command. | ||
- compile: Looks at the 'tsconfig.json' file to compile the project. By default it will also | ||
lint the files unless we use the '--no-lint' option. | ||
- run: Main command to be run in team city. It will make sure to run all the tests and publish | ||
to npm if necessary. | ||
- slack-notify: If you have provided the appropriate slack environment variables then this will | ||
get slack to send a message. | ||
Options: | ||
--dev: Uses tsconfig.dev.json and tslint.dev.json | ||
--no-lint: Skip linting. | ||
--verbose: Print messages of the steps for the 'compile' command. | ||
--ci: Continous Integration flag, minimizes the output in case there are too many errors. | ||
--help, -h: Print this message. | ||
--version, -v: Print the version. | ||
--no-msg-dump: Skip dumping error and warning messages to './tcBuilderMessages.json'. | ||
tc-builder@${tcPkgVersion} | ||
`; | ||
function main() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var exitNumber, projectPkg, tcBuilderOptions, messageMap, code; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
exitNumber = 0; | ||
if (!(help || h)) return [3 /*break*/, 1]; | ||
log(usage); | ||
return [3 /*break*/, 9]; | ||
case 1: | ||
if (!(version || v)) return [3 /*break*/, 2]; | ||
log(tcPkgVersion); | ||
return [3 /*break*/, 9]; | ||
case 2: | ||
if (!((+setup) + (+compile) + (+run) + (+slackNotify) !== 1)) return [3 /*break*/, 3]; | ||
log("usage: tc-builder <" + commands.join(' | ') + "> [-h]"); | ||
exitNumber = 1; | ||
return [3 /*break*/, 9]; | ||
case 3: | ||
if (!setup) return [3 /*break*/, 4]; | ||
exitNumber = Setup_1.runSetup(); | ||
return [3 /*break*/, 9]; | ||
case 4: | ||
if (!compile) return [3 /*break*/, 5]; | ||
projectPkg = Util_1.util.readJSON('./package.json', '.'); | ||
tcBuilderOptions = projectPkg ? projectPkg['tcBuilder'] || {} : {}; | ||
messageMap = tcBuilderOptions['allowed'] || {}; | ||
exitNumber = compiler_1.compileCLI(dev ? 'tsconfig.dev.json' : 'tsconfig.json', noLint ? '' : (dev ? './tslint.dev.json' : './tslint.json'), verbose, messageMap, ci, !noMsgDump); | ||
return [3 /*break*/, 9]; | ||
case 5: | ||
if (!run) return [3 /*break*/, 7]; | ||
return [4 /*yield*/, builders_1.runBuilder(builders_1.NPMBuilder, !noMsgDump)]; | ||
case 6: | ||
code = (_a.sent()).code; | ||
exitNumber = code; | ||
return [3 /*break*/, 9]; | ||
case 7: | ||
if (!slackNotify) return [3 /*break*/, 9]; | ||
return [4 /*yield*/, slack_1.runSlacker(slack_1.TravisSlack)]; | ||
case 8: | ||
exitNumber = _a.sent(); | ||
_a.label = 9; | ||
case 9: | ||
process.on('exit', function () { | ||
process.exit(exitNumber); | ||
}); | ||
return [2 /*return*/]; | ||
} | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
let exitNumber = 0; | ||
if (help) { | ||
log(usage); | ||
} | ||
else if (version) { | ||
log(tcPkgVersion); | ||
} | ||
else if ((+setup) + (+compile) + (+run) + (+slackNotify) !== 1) { | ||
log(`usage: tc-builder <${Object.keys(args.commands).join(' | ')}> [-h]`); | ||
exitNumber = 1; | ||
} | ||
else if (setup) { | ||
exitNumber = Setup_1.runSetup(); | ||
} | ||
else if (compile) { | ||
const projectPkg = Util_1.util.readJSON('./package.json', '.'); | ||
const tcBuilderOptions = projectPkg ? projectPkg['tcBuilder'] || {} : {}; | ||
const messageMap = tcBuilderOptions['allowed'] || {}; | ||
exitNumber = compiler_1.compileCLI(parsedArgs.definitions['tsconfigPath'], noLint ? '' : parsedArgs.definitions['tslintPath'], verbose, messageMap, ci, !noMsgDump); | ||
} | ||
else if (run) { | ||
const { code } = yield builders_1.runBuilder(builders_1.NPMBuilder, !noMsgDump); | ||
exitNumber = code; | ||
} | ||
else if (slackNotify) { | ||
exitNumber = yield slack_1.runSlacker(slack_1.TravisSlack); | ||
} | ||
process.on('exit', () => { | ||
process.exit(exitNumber); | ||
}); | ||
@@ -83,0 +99,0 @@ }); |
#!/usr/bin/env node | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Util_1 = require("./Util"); | ||
var Install_1 = require("./setup/Install"); | ||
var tcBuilderPkg = Util_1.util.readJSON('./package.json', __dirname) || {}; | ||
var usage = "usage: tc-install [--options]\n\nOptions:\n\n --help, -h: Print this message.\n --update: Update the set of dependencies to the latest version.\n --prod: Install/Update only the non devDependencies.\n --exact: Do not add the caret character to the start of the version.\n --match: A regex string must follow this option so that we only install/update certain files.\n\ntc-install@" + tcBuilderPkg['version'] + "\n"; | ||
const Install_1 = require("./setup/Install"); | ||
const Util_1 = require("./Util"); | ||
const tcBuilderPkg = Util_1.util.readJSON('./package.json', __dirname) || {}; | ||
const usage = `usage: tc-install [--options] | ||
Options: | ||
--help, -h: Print this message. | ||
--update: Update the set of dependencies to the latest version. | ||
--prod: Install/Update only the non devDependencies. | ||
--exact: Do not add the caret character to the start of the version. | ||
--match: A regex string must follow this option so that we only install/update certain files. | ||
tc-install@${tcBuilderPkg['version']} | ||
`; | ||
function main() { | ||
var exitNumber = 0; | ||
var options = [ | ||
let exitNumber = 0; | ||
const options = [ | ||
'-h', | ||
@@ -18,20 +29,20 @@ '--help', | ||
]; | ||
var _a = options.map(function (x) { return process.argv.indexOf(x) > -1; }), h = _a[0], help = _a[1], update = _a[2], prod = _a[3], exact = _a[4], match = _a[5]; | ||
const [h, help, update, prod, exact, match,] = options.map(x => process.argv.indexOf(x) > -1); | ||
if (h || help) { | ||
process.stdout.write(usage + "\n"); | ||
process.stdout.write(`${usage}\n`); | ||
} | ||
else { | ||
var regex = match ? process.argv[process.argv.indexOf('--match') + 1] : ''; | ||
var depType = prod ? 'dependencies' : 'devDependencies'; | ||
var promise = void 0; | ||
const regex = match ? process.argv[process.argv.indexOf('--match') + 1] : ''; | ||
const depType = prod ? 'dependencies' : 'devDependencies'; | ||
let promise; | ||
if (update) { | ||
var projectPkg = Util_1.util.readJSON('./package.json', '.') || {}; | ||
promise = Install_1.install(projectPkg, depType, { exact: exact, regex: regex, latest: true }); | ||
const projectPkg = Util_1.util.readJSON('./package.json', '.') || {}; | ||
promise = Install_1.install(projectPkg, depType, { exact, regex, latest: true }); | ||
} | ||
else { | ||
promise = Install_1.install(tcBuilderPkg, depType, { exact: exact, regex: regex, latest: false }); | ||
promise = Install_1.install(tcBuilderPkg, depType, { exact, regex, latest: false }); | ||
} | ||
promise.catch(function (numFailed) { return exitNumber = numFailed; }); | ||
promise.catch((numFailed) => exitNumber = numFailed); | ||
} | ||
process.on('exit', function () { | ||
process.on('exit', () => { | ||
process.exit(exitNumber); | ||
@@ -38,0 +49,0 @@ }); |
@@ -0,1 +1,23 @@ | ||
interface IArgV { | ||
commands: { | ||
[key: string]: string; | ||
}; | ||
booleans: { | ||
[key: string]: string; | ||
}; | ||
definitions: { | ||
[key: string]: string; | ||
}; | ||
} | ||
interface IParsedArgV { | ||
commands: { | ||
[key: string]: boolean; | ||
}; | ||
booleans: { | ||
[key: string]: boolean; | ||
}; | ||
definitions: { | ||
[key: string]: string; | ||
}; | ||
} | ||
declare class Util { | ||
@@ -6,2 +28,9 @@ private static instance; | ||
/** | ||
* To be used in command line applications to parse the argument vector provided to the cli. | ||
* | ||
* @param argv process.argv | ||
* @param config | ||
*/ | ||
parseArgVector(argv: string[], config: IArgV): IParsedArgV; | ||
/** | ||
* Update the version property in the file `package.json`. If the `package.json` is in another | ||
@@ -8,0 +37,0 @@ * directory you may override the location by specifying the second parameter. |
155
Util.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fs_1 = require("fs"); | ||
var pth = require("path"); | ||
var child_process_1 = require("child_process"); | ||
var Util = /** @class */ (function () { | ||
function Util() { | ||
} | ||
Util.getInstance = function () { | ||
const child_process_1 = require("child_process"); | ||
const fs_1 = require("fs"); | ||
const pth = require("path"); | ||
class Util { | ||
constructor() { } | ||
static getInstance() { | ||
Util.instance = Util.instance = new Util(); | ||
return Util.instance; | ||
}; | ||
} | ||
/** | ||
* To be used in command line applications to parse the argument vector provided to the cli. | ||
* | ||
* @param argv process.argv | ||
* @param config | ||
*/ | ||
parseArgVector(argv, config) { | ||
const result = { | ||
commands: {}, | ||
booleans: {}, | ||
definitions: Object.assign({}, config.definitions), | ||
}; | ||
argv.forEach((item) => { | ||
if (config.commands[item]) { | ||
result.commands[config.commands[item]] = true; | ||
} | ||
else if (config.booleans[item]) { | ||
result.booleans[config.booleans[item]] = true; | ||
} | ||
else if (item.startsWith('-D')) { | ||
const [name, value] = item.split('='); | ||
const defName = name.slice(2); | ||
if (!(defName in result.definitions)) { | ||
throw (new Error(`${defName} is not a valid -D argument`)); | ||
} | ||
result.definitions[defName] = value; | ||
} | ||
else { | ||
throw (new Error(`${item} is not a valid argument`)); | ||
} | ||
}); | ||
return result; | ||
} | ||
/** | ||
* Update the version property in the file `package.json`. If the `package.json` is in another | ||
* directory you may override the location by specifying the second parameter. | ||
*/ | ||
Util.prototype.changePackageVersion = function (version, filePath) { | ||
if (filePath === void 0) { filePath = './package.json'; } | ||
var contents = fs_1.readFileSync(filePath, 'utf8'); | ||
var lines = contents.split('\n'); | ||
var newLines = lines.map(function (line) { | ||
changePackageVersion(version, filePath = './package.json') { | ||
const contents = fs_1.readFileSync(filePath, 'utf8'); | ||
const lines = contents.split('\n'); | ||
const newLines = lines.map((line) => { | ||
if (line.trim().startsWith('"version"')) { | ||
return " \"version\": \"" + version + "\","; | ||
return ` "version": "${version}",`; | ||
} | ||
@@ -28,3 +59,3 @@ return line; | ||
fs_1.writeFileSync(filePath, newLines.join('\n')); | ||
}; | ||
} | ||
/** | ||
@@ -38,14 +69,13 @@ * Execute a system command such as `pwd`. When setting the `print` argument to true | ||
*/ | ||
Util.prototype.execCmd = function (cmd, print) { | ||
if (print === void 0) { print = false; } | ||
return new Promise(function (fulfill, reject) { | ||
var parts = cmd.split(' '); | ||
var handle = child_process_1.spawn(parts[0], parts.slice(1)); | ||
var buffer = []; | ||
var onData = print ? | ||
function (data) { return process.stdout.write(data.toString()); } : | ||
function (data) { return buffer.push(data.toString()); }; | ||
execCmd(cmd, print = false) { | ||
return new Promise((fulfill, reject) => { | ||
const parts = cmd.split(' '); | ||
const handle = child_process_1.spawn(parts[0], parts.slice(1)); | ||
const buffer = []; | ||
const onData = print ? | ||
(data) => process.stdout.write(data.toString()) : | ||
(data) => buffer.push(data.toString()); | ||
handle.stdout.on('data', onData); | ||
handle.stderr.on('data', onData); | ||
handle.on('exit', function (code) { | ||
handle.on('exit', (code) => { | ||
if (code === 0) { | ||
@@ -59,3 +89,3 @@ fulfill(buffer.join('').trim()); | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -65,5 +95,5 @@ * Execute a system command such as `pwd`. Note that some output may be missing since some | ||
*/ | ||
Util.prototype.exec = function (cmd) { | ||
return new Promise(function (fulfill, reject) { | ||
child_process_1.exec(cmd, function (error, stdout, stderr) { | ||
exec(cmd) { | ||
return new Promise((fulfill, reject) => { | ||
child_process_1.exec(cmd, (error, stdout, stderr) => { | ||
if (error) { | ||
@@ -78,11 +108,11 @@ return reject(error.toString()); | ||
}); | ||
}; | ||
} | ||
/** | ||
* Returns a list of all the files that have not yet been committed. | ||
*/ | ||
Util.prototype.getModifiedFiles = function () { | ||
return this.execCmd('git status -s').then(function (result) { | ||
return result.split('\n').map(function (x) { return x.trim(); }).filter(function (x) { return x; }); | ||
getModifiedFiles() { | ||
return this.execCmd('git status -s').then((result) => { | ||
return result.split('\n').map(x => x.trim()).filter(x => x); | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -93,14 +123,14 @@ * Move files and/or directories recursively. If the `src` parameter ends with `/` then only | ||
*/ | ||
Util.prototype.move = function (src, dest) { | ||
var buf = []; | ||
move(src, dest) { | ||
const buf = []; | ||
_move(src, dest, buf); | ||
return buf; | ||
}; | ||
} | ||
/** | ||
* Read the json contents from a file. Returns null if there is an issue while parsing. | ||
*/ | ||
Util.prototype.readJSON = function (name, path) { | ||
var base = path || process.cwd(); | ||
readJSON(name, path) { | ||
const base = path || process.cwd(); | ||
try { | ||
return JSON.parse(fs_1.readFileSync(base + "/" + name, 'utf8')); | ||
return JSON.parse(fs_1.readFileSync(`${base}/${name}`, 'utf8')); | ||
} | ||
@@ -110,10 +140,10 @@ catch (e) { | ||
} | ||
}; | ||
} | ||
/** | ||
* Write the contents to a file. Returns a boolean indicating if writing was successful. | ||
*/ | ||
Util.prototype.writeJSON = function (contents, name, path) { | ||
var base = path || process.cwd(); | ||
writeJSON(contents, name, path) { | ||
const base = path || process.cwd(); | ||
try { | ||
fs_1.writeFileSync(base + "/" + name, JSON.stringify(contents, null, 2)); | ||
fs_1.writeFileSync(`${base}/${name}`, JSON.stringify(contents, null, 2)); | ||
return true; | ||
@@ -124,3 +154,3 @@ } | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -130,15 +160,14 @@ * Quick and dirty string replacement. The `template` needs to have strings in the form | ||
*/ | ||
Util.prototype.replaceStrings = function (template, properties) { | ||
var result = template; | ||
Object.keys(properties).forEach(function (key) { | ||
var reg = new RegExp("%{" + key + "}", 'g'); | ||
replaceStrings(template, properties) { | ||
let result = template; | ||
Object.keys(properties).forEach((key) => { | ||
const reg = new RegExp(`%{${key}}`, 'g'); | ||
result = result.replace(reg, properties[key]); | ||
}); | ||
return result; | ||
}; | ||
return Util; | ||
}()); | ||
} | ||
} | ||
exports.Util = Util; | ||
function _move(src, dest, buf) { | ||
var stats = fs_1.statSync(src); | ||
const stats = fs_1.statSync(src); | ||
if (stats.isFile()) { | ||
@@ -151,7 +180,7 @@ buf.push(pth.normalize(dest)); | ||
// move directory contents | ||
var files = fs_1.readdirSync(src); | ||
files.forEach(function (file) { | ||
var filePath = pth.normalize(src + "/" + file); | ||
var destPath = pth.normalize(dest + "/" + file); | ||
var fileStats = fs_1.statSync(filePath); | ||
const files = fs_1.readdirSync(src); | ||
files.forEach((file) => { | ||
const filePath = pth.normalize(`${src}/${file}`); | ||
const destPath = pth.normalize(`${dest}/${file}`); | ||
const fileStats = fs_1.statSync(filePath); | ||
if (fileStats.isFile()) { | ||
@@ -166,3 +195,3 @@ buf.push(destPath); | ||
catch (e) { } | ||
_move(filePath + "/", destPath, buf); | ||
_move(`${filePath}/`, destPath, buf); | ||
fs_1.rmdirSync(filePath); | ||
@@ -174,8 +203,8 @@ } | ||
// move whole directory | ||
var dirName = pth.basename(src); | ||
const dirName = pth.basename(src); | ||
try { | ||
fs_1.mkdirSync(pth.normalize(dest + "/" + dirName)); | ||
fs_1.mkdirSync(pth.normalize(`${dest}/${dirName}`)); | ||
} | ||
catch (e) { } | ||
_move(src + "/", pth.normalize(dest + "/" + dirName), buf); | ||
_move(`${src}/`, pth.normalize(`${dest}/${dirName}`), buf); | ||
fs_1.rmdirSync(src); | ||
@@ -185,3 +214,3 @@ } | ||
} | ||
var util = Util.getInstance(); | ||
const util = Util.getInstance(); | ||
exports.util = util; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
64
2887
16
114942
23
2