buildkite-graph
Advanced tools
Comparing version
import 'reflect-metadata'; | ||
import { PotentialStep } from './index'; | ||
export interface BaseStep { | ||
@@ -7,4 +8,11 @@ } | ||
export declare abstract class Step implements BaseStep { | ||
readonly dependencies: Set<Step>; | ||
dependsOn(...steps: Step[]): this; | ||
readonly dependencies: Set<PotentialStep>; | ||
/** | ||
* This marks the given step or conditional as a dependency to the current | ||
* step. | ||
* In case the dependency is a conditional, then that conditional will | ||
* always be added to the graph (e.g. the value of the accept function of that | ||
* conditional will be trumped by the fact that the current step depends on it) | ||
*/ | ||
dependsOn(...steps: PotentialStep[]): this; | ||
always: boolean; | ||
@@ -11,0 +19,0 @@ alwaysExecute(): this; |
@@ -53,2 +53,9 @@ "use strict"; | ||
} | ||
/** | ||
* This marks the given step or conditional as a dependency to the current | ||
* step. | ||
* In case the dependency is a conditional, then that conditional will | ||
* always be added to the graph (e.g. the value of the accept function of that | ||
* conditional will be trumped by the fact that the current step depends on it) | ||
*/ | ||
Step.prototype.dependsOn = function () { | ||
@@ -55,0 +62,0 @@ var steps = []; |
@@ -1,5 +0,5 @@ | ||
import { Step, Pipeline } from '.'; | ||
import { Step } from '.'; | ||
export declare type Generator<T> = () => T; | ||
export declare type ThingOrGenerator<T> = T | Generator<T>; | ||
export declare abstract class Conditional<T extends Step | Pipeline> { | ||
export declare abstract class Conditional<T extends Step> { | ||
private readonly guarded; | ||
@@ -6,0 +6,0 @@ constructor(guarded: ThingOrGenerator<T>); |
@@ -22,3 +22,3 @@ import 'reflect-metadata'; | ||
}; | ||
export declare type PotentialStep = Pipeline | Step | Conditional<Pipeline | Step>; | ||
export declare type PotentialStep = Step | Conditional<Step>; | ||
export declare class Pipeline { | ||
@@ -31,3 +31,3 @@ readonly name: string; | ||
slug(): string; | ||
private readonly _steps; | ||
private _steps; | ||
} |
@@ -8,22 +8,2 @@ "use strict"; | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
@@ -49,3 +29,3 @@ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
var wait_1 = require("./steps/wait"); | ||
var stortedWithBlocks_1 = require("./stortedWithBlocks"); | ||
var sortedWithBlocks_1 = require("./sortedWithBlocks"); | ||
var base_1 = require("./base"); | ||
@@ -83,3 +63,3 @@ exports.Step = base_1.Step; | ||
Pipeline.prototype.add = function () { | ||
var _a; | ||
var _this = this; | ||
var step = []; | ||
@@ -89,3 +69,8 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
} | ||
(_a = this.steps).push.apply(_a, __spread(step)); | ||
step.forEach(function (s) { | ||
if (_this.steps.includes(s)) { | ||
throw new Error('Can not add the same step more than once'); | ||
} | ||
_this.steps.push(s); | ||
}); | ||
return this; | ||
@@ -100,47 +85,43 @@ }; | ||
}; | ||
Object.defineProperty(Pipeline.prototype, "_steps", { | ||
get: function () { | ||
var e_1, _a; | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
var stepsWithBlocks = stortedWithBlocks_1.stortedWithBlocks(this); | ||
// TODO: when step.always = true, | ||
// then previous step needs a wait step with continueOnFailure: true | ||
// if step after does not have .always = true a wait step needs to be | ||
// inserted. | ||
// See: https://buildkite.com/docs/pipelines/wait-step#continuing-on-failure | ||
var steps = []; | ||
var lastWait = undefined; | ||
try { | ||
for (var stepsWithBlocks_1 = __values(stepsWithBlocks), stepsWithBlocks_1_1 = stepsWithBlocks_1.next(); !stepsWithBlocks_1_1.done; stepsWithBlocks_1_1 = stepsWithBlocks_1.next()) { | ||
var s = stepsWithBlocks_1_1.value; | ||
if (s === null) { | ||
lastWait = new wait_1.WaitStep(); | ||
steps.push(lastWait); | ||
} | ||
else { | ||
if (lastWait) { | ||
if (s.always && !lastWait.continueOnFailure) { | ||
lastWait.continueOnFailure = true; | ||
} | ||
else if (lastWait.continueOnFailure && !s.always) { | ||
lastWait = new wait_1.WaitStep(); | ||
steps.push(lastWait); | ||
} | ||
Pipeline.prototype._steps = function () { | ||
var e_1, _a; | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
var stepsWithBlocks = sortedWithBlocks_1.sortedWithBlocks(this); | ||
// TODO: when step.always = true, | ||
// then previous step needs a wait step with continueOnFailure: true | ||
// if step after does not have .always = true a wait step needs to be | ||
// inserted. | ||
// See: https://buildkite.com/docs/pipelines/wait-step#continuing-on-failure | ||
var steps = []; | ||
var lastWait = undefined; | ||
try { | ||
for (var stepsWithBlocks_1 = __values(stepsWithBlocks), stepsWithBlocks_1_1 = stepsWithBlocks_1.next(); !stepsWithBlocks_1_1.done; stepsWithBlocks_1_1 = stepsWithBlocks_1.next()) { | ||
var s = stepsWithBlocks_1_1.value; | ||
if (s === null) { | ||
lastWait = new wait_1.WaitStep(); | ||
steps.push(lastWait); | ||
} | ||
else { | ||
if (lastWait) { | ||
if (s.always && !lastWait.continueOnFailure) { | ||
lastWait.continueOnFailure = true; | ||
} | ||
steps.push(s); | ||
else if (lastWait.continueOnFailure && !s.always) { | ||
lastWait = new wait_1.WaitStep(); | ||
steps.push(lastWait); | ||
} | ||
} | ||
steps.push(s); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (stepsWithBlocks_1_1 && !stepsWithBlocks_1_1.done && (_a = stepsWithBlocks_1.return)) _a.call(stepsWithBlocks_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (stepsWithBlocks_1_1 && !stepsWithBlocks_1_1.done && (_a = stepsWithBlocks_1.return)) _a.call(stepsWithBlocks_1); | ||
} | ||
return steps; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return steps; | ||
}; | ||
__decorate([ | ||
@@ -147,0 +128,0 @@ class_transformer_1.Expose(), |
@@ -23,3 +23,3 @@ "use strict"; | ||
var __1 = require("../"); | ||
var stortedWithBlocks_1 = require("../stortedWithBlocks"); | ||
var sortedWithBlocks_1 = require("../sortedWithBlocks"); | ||
var DotSerializer = /** @class */ (function () { | ||
@@ -30,3 +30,3 @@ function DotSerializer() { | ||
var e_1, _a, e_2, _b; | ||
var allSteps = stortedWithBlocks_1.stortedWithBlocks(e); | ||
var allSteps = sortedWithBlocks_1.sortedWithBlocks(e); | ||
if (allSteps.length > 0) { | ||
@@ -33,0 +33,0 @@ allSteps.unshift(null); |
@@ -10,5 +10,5 @@ "use strict"; | ||
JsonSerializer.prototype.serialize = function (e) { | ||
var serialized = class_transformer_1.serialize(e); | ||
// Workaround to get rid of undefined values | ||
var json = JSON.parse(JSON.stringify(class_transformer_1.classToPlain(e))); | ||
return this.stringify ? JSON.stringify(json) : json; | ||
return this.stringify ? serialized : JSON.parse(serialized); | ||
}; | ||
@@ -15,0 +15,0 @@ return JsonSerializer; |
import { Step } from './base'; | ||
import { Pipeline } from './index'; | ||
export declare function sortedSteps(e: Pipeline): Step[]; | ||
import { Conditional } from './conditional'; | ||
export declare function sortedSteps(e: Pipeline, cache: Map<Conditional<Step>, Step>): Step[]; |
@@ -19,5 +19,6 @@ "use strict"; | ||
var unwrapSteps_1 = require("./unwrapSteps"); | ||
function sortedSteps(e) { | ||
var conditional_1 = require("./conditional"); | ||
function sortedSteps(e, cache) { | ||
var e_1, _a; | ||
var steps = unwrapSteps_1.unwrapSteps(e.steps); | ||
var steps = unwrapSteps_1.unwrapSteps(e.steps, cache); | ||
var sortOp = new topological_sort_1.default(new Map(steps.map(function (step) { return [step, step]; }))); | ||
@@ -28,3 +29,24 @@ for (var i = 0; i < steps.length; i++) { | ||
for (var _b = (e_1 = void 0, __values(step.dependencies)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var dependency = _c.value; | ||
var potentialDependency = _c.value; | ||
// when we depend on a conditional the acceptor of the conditional doesn't matter | ||
// we need to always get it and add it to the graph | ||
var dependency = void 0; | ||
if (potentialDependency instanceof conditional_1.Conditional) { | ||
if (cache.has(potentialDependency)) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
dependency = cache.get(potentialDependency); | ||
} | ||
else { | ||
// in the case we have to unwrap the conditional we store it for later use | ||
// otherwise the getter will be called many times, returning a new object each | ||
// time which means evenm though multiple steps might depend on the same conditionals | ||
// we would add a new step each time. Also, generating a step can be potentially expemnsive | ||
// so we want to do this only once | ||
dependency = potentialDependency.get(); | ||
cache.set(potentialDependency, dependency); | ||
} | ||
} | ||
else { | ||
dependency = potentialDependency; | ||
} | ||
if (steps.indexOf(dependency) === -1) { | ||
@@ -31,0 +53,0 @@ // a dependency has not been added to the graph explicitly, |
@@ -1,3 +0,3 @@ | ||
import { PotentialStep } from '.'; | ||
import { Step } from './base'; | ||
export declare function unwrapSteps(steps: PotentialStep[]): Step[]; | ||
import { PotentialStep, Step } from './index'; | ||
import { Conditional } from './conditional'; | ||
export declare function unwrapSteps(steps: PotentialStep[], cache: Map<Conditional<Step>, Step>): Step[]; |
@@ -13,26 +13,5 @@ "use strict"; | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var _1 = require("."); | ||
var conditional_1 = require("./conditional"); | ||
function unwrapSteps(steps) { | ||
function unwrapSteps(steps, cache) { | ||
var e_1, _a; | ||
@@ -43,14 +22,14 @@ var ret = []; | ||
var s = steps_1_1.value; | ||
if (s instanceof _1.Pipeline) { | ||
ret.push.apply(ret, __spread(unwrapSteps(s.steps))); | ||
} | ||
else if (s instanceof conditional_1.Conditional) { | ||
if (s instanceof conditional_1.Conditional) { | ||
if (s.accept()) { | ||
var cond = s.get(); | ||
if (cond instanceof _1.Pipeline) { | ||
ret.push.apply(ret, __spread(unwrapSteps(cond.steps))); | ||
var cond = void 0; | ||
if (cache.has(s)) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
cond = cache.get(s); | ||
} | ||
else { | ||
ret.push(cond); | ||
cond = s.get(); | ||
cache.set(s, cond); | ||
} | ||
ret.push(cond); | ||
} | ||
@@ -57,0 +36,0 @@ } |
{ | ||
"name": "buildkite-graph", | ||
"version": "2.2.0", | ||
"version": "3.0.0", | ||
"main": "dist/index.js", | ||
@@ -16,9 +16,9 @@ "typings": "dist/index.d.ts", | ||
"@types/js-yaml": "^3.12.1", | ||
"@types/node": "^12.7.2", | ||
"@typescript-eslint/eslint-plugin": "^2.0.0", | ||
"@typescript-eslint/parser": "^2.0.0", | ||
"@types/node": "^12.7.11", | ||
"@typescript-eslint/eslint-plugin": "^2.3.3", | ||
"@typescript-eslint/parser": "^2.3.3", | ||
"cz-conventional-changelog": "3.0.2", | ||
"eslint": "^6.2.2", | ||
"eslint-config-prettier": "^6.1.0", | ||
"husky": "^3.0.4", | ||
"eslint": "^6.5.1", | ||
"eslint-config-prettier": "^6.4.0", | ||
"husky": "^3.0.8", | ||
"jest": "^24.9.0", | ||
@@ -29,5 +29,5 @@ "prettier": "^1.18.2", | ||
"semantic-release": "^15.13.24", | ||
"ts-jest": "^24.0.2", | ||
"ts-node": "^8.3.0", | ||
"typescript": "^3.6.2" | ||
"ts-jest": "^24.1.0", | ||
"ts-node": "^8.4.1", | ||
"typescript": "^3.6.3" | ||
}, | ||
@@ -34,0 +34,0 @@ "scripts": { |
79855
1.41%1826
0.22%