Skip to content

Commit

Permalink
feat(2492): Update to eslint-config-screwdriver v5 (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyi committed Jul 9, 2021
1 parent 70b392f commit 409ea68
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 343 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ npm-debug.log
.DS_STORE
.*.swp
.nyc_output
package-lock.json
13 changes: 8 additions & 5 deletions lib/getNextJobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const getNextJobs = (workflowGraph, config) => {
// Check if the job is triggerd by chainPR with regexp
const chainPRTrigger = config.trigger.match(PR_JOB_NAME);

workflowGraph.edges.forEach((edge) => {
workflowGraph.edges.forEach(edge => {
// Check if edge src is specific branch commit or pr with regexp
const edgeSrcBranchRegExp = new RegExp('^~(pr|commit|release|tag|subscribe):/(.+)/$');
const edgeSrcBranch = edge.src.match(edgeSrcBranchRegExp);
Expand Down Expand Up @@ -54,10 +54,13 @@ const getNextJobs = (workflowGraph, config) => {
} else {
jobs.add(edge.dest);
}
// chainPRTrigger[1] must be 'PR-$num' if matches regexp
} else if (config.chainPR
&& chainPRTrigger && config.trigger === `${chainPRTrigger[1]}:${edge.src}`
&& !EXTERNAL_TRIGGER_ALL.test(edge.dest)) {
// chainPRTrigger[1] must be 'PR-$num' if matches regexp
} else if (
config.chainPR &&
chainPRTrigger &&
config.trigger === `${chainPRTrigger[1]}:${edge.src}` &&
!EXTERNAL_TRIGGER_ALL.test(edge.dest)
) {
jobs.add(`${chainPRTrigger[1]}:${edge.dest}`);
}
});
Expand Down
9 changes: 5 additions & 4 deletions lib/getSrcForJoin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
function findJobs(workflowGraph, destJobName) {
const jobs = new Set();

workflowGraph.edges.forEach((edge) => {
workflowGraph.edges.forEach(edge => {
if (edge.dest === destJobName && edge.join) {
jobs.add(workflowGraph.nodes.find(node => node.name === edge.src));
}
Expand All @@ -31,10 +31,11 @@ function findPRJobs(workflowGraph, destJobName) {
const jobs = new Set();
const [prPrefix, prJobName] = destJobName.split(':');

workflowGraph.edges.forEach((edge) => {
workflowGraph.edges.forEach(edge => {
if (edge.dest === prJobName && edge.join) {
const findJob = Object.assign({},
workflowGraph.nodes.find(node => node.name === edge.src));
const findJob = {
...workflowGraph.nodes.find(node => node.name === edge.src)
};

// need to add `PR-{PR number}:` prefix when returning
findJob.name = `${prPrefix}:${findJob.name}`;
Expand Down
156 changes: 78 additions & 78 deletions lib/getWorkflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ const hoek = require('@hapi/hoek');
* @param {String} name A Node Name, e.g. foo, ~foo, ~pr, ~commit, ~release, ~tag, ~sd@1234:foo
* @return {String} A filtered node name, e.g. foo, foo, ~pr, ~commit, ~release, ~tag, ~sd@1234:foo
*/
const filterNodeName = name =>
(/^~((pr|commit|release|tag)(?:$|:)|(sd@))/.test(name) ? name : name.replace('~', ''));
const filterNodeName = name => (/^~((pr|commit|release|tag)(?:$|:)|(sd@))/.test(name) ? name : name.replace('~', ''));

/**
* Build external nodes for its downstream jobs, DFS to traverse its children
Expand All @@ -20,13 +19,15 @@ const filterNodeName = name =>
* @return {Promise} List of graph nodes
*/
const buildExternalNodes = async (children, nodes, triggerFactory) => {
await Promise.all(children.map(async (dest) => {
nodes.add(dest.replace('~sd@', 'sd@'));
await Promise.all(
children.map(async dest => {
nodes.add(dest.replace('~sd@', 'sd@'));

const newChildren = await triggerFactory.getDestFromSrc(dest);
const newChildren = await triggerFactory.getDestFromSrc(dest);

await buildExternalNodes(newChildren, nodes, triggerFactory);
}));
await buildExternalNodes(newChildren, nodes, triggerFactory);
})
);
};

/**
Expand All @@ -42,7 +43,7 @@ const calculateNodes = async (jobs, triggerFactory, pipelineId) => {

// for backward compatibility. TODO: remove this block later
if (!triggerFactory) {
Object.keys(jobs).forEach((name) => {
Object.keys(jobs).forEach(name => {
nodes.add(name);
if (Array.isArray(jobs[name].requires)) {
jobs[name].requires.forEach(n => nodes.add(filterNodeName(n)));
Expand All @@ -53,37 +54,37 @@ const calculateNodes = async (jobs, triggerFactory, pipelineId) => {
}

// new implementation. allow external join
await Promise.all(Object.keys(jobs).map(async (jobName) => {
nodes.add(jobName);
await Promise.all(
Object.keys(jobs).map(async jobName => {
nodes.add(jobName);

// upstream nodes
if (Array.isArray(jobs[jobName].requires)) {
jobs[jobName].requires.forEach(n => nodes.add(filterNodeName(n)));
}
// upstream nodes
if (Array.isArray(jobs[jobName].requires)) {
jobs[jobName].requires.forEach(n => nodes.add(filterNodeName(n)));
}

// downstream nodes
const srcName = `sd@${pipelineId}:${jobName}`;
// downstream nodes
const srcName = `sd@${pipelineId}:${jobName}`;

// Calculate which downstream jobs are triggered BY current job
// Only need to take care of external triggers, since internal will be taken care automatically
const externalDownstreamOr = await triggerFactory.getDestFromSrc(`~${srcName}`);
const externalDownstreamAnd = await triggerFactory.getDestFromSrc(srcName);
// Calculate which downstream jobs are triggered BY current job
// Only need to take care of external triggers, since internal will be taken care automatically
const externalDownstreamOr = await triggerFactory.getDestFromSrc(`~${srcName}`);
const externalDownstreamAnd = await triggerFactory.getDestFromSrc(srcName);

externalDownstreamOr.forEach((dest) => {
nodes.add(dest.replace('~sd@', 'sd@'));
});
externalDownstreamOr.forEach(dest => {
nodes.add(dest.replace('~sd@', 'sd@'));
});

await buildExternalNodes(
externalDownstreamAnd, nodes, triggerFactory);
}));
await buildExternalNodes(externalDownstreamAnd, nodes, triggerFactory);
})
);

return [...nodes].map((name) => {
return [...nodes].map(name => {
const m = { name };
const displayName = hoek.reach(
jobs[name],
'annotations>screwdriver.cd/displayName',
{ separator: '>', default: undefined }
);
const displayName = hoek.reach(jobs[name], 'annotations>screwdriver.cd/displayName', {
separator: '>',
default: undefined
});

if (displayName !== undefined) {
m.displayName = displayName;
Expand All @@ -103,13 +104,15 @@ const calculateNodes = async (jobs, triggerFactory, pipelineId) => {
* @return {Promise} List of graph edges { src, dest }
*/
const buildExternalEdges = async (root, children, edges, triggerFactory) => {
await Promise.all(children.map(async (dest) => {
edges.push({ src: root, dest: dest.replace('~sd@', 'sd@') });
await Promise.all(
children.map(async dest => {
edges.push({ src: root, dest: dest.replace('~sd@', 'sd@') });

const newChildren = await triggerFactory.getDestFromSrc(dest);
const newChildren = await triggerFactory.getDestFromSrc(dest);

await buildExternalEdges(dest, newChildren, edges, triggerFactory);
}));
await buildExternalEdges(dest, newChildren, edges, triggerFactory);
})
);
};

/**
Expand All @@ -125,22 +128,20 @@ const calculateEdges = async (jobs, triggerFactory, pipelineId) => {

// for backward compatibility. TODO: remove this block later
if (!triggerFactory) {
Object.keys(jobs).forEach((j) => {
Object.keys(jobs).forEach(j => {
const job = jobs[j];
const dest = j;

if (Array.isArray(job.requires)) {
const specialTriggers = new Set(
job.requires.filter(name => name.charAt(0) === '~'));
const normalTriggers = new Set(
job.requires.filter(name => name.charAt(0) !== '~'));
const specialTriggers = new Set(job.requires.filter(name => name.charAt(0) === '~'));
const normalTriggers = new Set(job.requires.filter(name => name.charAt(0) !== '~'));
const isJoin = normalTriggers.size > 1;

specialTriggers.forEach((src) => {
specialTriggers.forEach(src => {
edges.push({ src: filterNodeName(src), dest });
});

normalTriggers.forEach((src) => {
normalTriggers.forEach(src => {
const obj = { src, dest };

if (isJoin) {
Expand All @@ -156,45 +157,44 @@ const calculateEdges = async (jobs, triggerFactory, pipelineId) => {
}

// new implementation. allow external join
await Promise.all(Object.keys(jobs).map(async (jobName) => {
const job = jobs[jobName];

if (Array.isArray(job.requires)) {
// Calculate which upstream jobs trigger the current job
const upstreamOr = new Set(
job.requires.filter(name => name.charAt(0) === '~'));
const upstreamAnd = new Set(
job.requires.filter(name => name.charAt(0) !== '~'));
const isJoin = upstreamAnd.size > 1;

upstreamOr.forEach((src) => {
edges.push({ src: filterNodeName(src), dest: jobName });
});
upstreamAnd.forEach((src) => {
const obj = { src, dest: jobName };
await Promise.all(
Object.keys(jobs).map(async jobName => {
const job = jobs[jobName];

if (isJoin) {
obj.join = true;
}
edges.push(obj);
});
}
if (Array.isArray(job.requires)) {
// Calculate which upstream jobs trigger the current job
const upstreamOr = new Set(job.requires.filter(name => name.charAt(0) === '~'));
const upstreamAnd = new Set(job.requires.filter(name => name.charAt(0) !== '~'));
const isJoin = upstreamAnd.size > 1;

const srcName = `sd@${pipelineId}:${jobName}`;
upstreamOr.forEach(src => {
edges.push({ src: filterNodeName(src), dest: jobName });
});
upstreamAnd.forEach(src => {
const obj = { src, dest: jobName };

// Calculate which downstream jobs are triggered BY current job
// Only need to take care of external triggers, since internal will be taken care automatically
const externalDownstreamOr = await triggerFactory.getDestFromSrc(`~${srcName}`);
const externalDownstreamAnd = await triggerFactory.getDestFromSrc(srcName);
if (isJoin) {
obj.join = true;
}
edges.push(obj);
});
}

externalDownstreamOr.forEach((dest) => {
edges.push({ src: jobName, dest: dest.replace('~sd@', 'sd@') });
});
const srcName = `sd@${pipelineId}:${jobName}`;

// Calculate which downstream jobs are triggered BY current job
// Only need to take care of external triggers, since internal will be taken care automatically
const externalDownstreamOr = await triggerFactory.getDestFromSrc(`~${srcName}`);
const externalDownstreamAnd = await triggerFactory.getDestFromSrc(srcName);

externalDownstreamOr.forEach(dest => {
edges.push({ src: jobName, dest: dest.replace('~sd@', 'sd@') });
});

// Handle join case
await buildExternalEdges(
jobName, externalDownstreamAnd, edges, triggerFactory);
}));
// Handle join case
await buildExternalEdges(jobName, externalDownstreamAnd, edges, triggerFactory);
})
);

return edges;
};
Expand Down
5 changes: 3 additions & 2 deletions lib/hasCycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ const isCyclic = (workflowGraph, jobName, visitedJobs, path) => {

const triggerList = getNextJobs(workflowGraph, { trigger: jobName, prNum: 1 });

const hasCycle = triggerList.some((name) => {
const hasCycle = triggerList.some(name => {
if (!visitedJobs.has(name)) {
return isCyclic(workflowGraph, name, visitedJobs, path);
} else if (path.includes(name)) {
}
if (path.includes(name)) {
// When a job is visited and is in the current path, then cycle detected
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@
"Tiffany Kyi <tiffanykyi@gmail.com>"
],
"devDependencies": {
"chai": "^4.1.2",
"eslint": "^4.19.1",
"eslint-config-screwdriver": "^3.0.0",
"chai": "^4.3.4",
"eslint": "^7.5.0",
"eslint-config-screwdriver": "^5.0.1",
"mocha": "^8.2.1",
"mocha-multi-reporters": "^1.5.1",
"mocha-sonarqube-reporter": "^1.0.2",
"nyc": "^15.0.0",
"rewire": "^4.0.1",
"sinon": "^7.5.0"
"sinon": "^9.0.0"
},
"dependencies": {
"@hapi/hoek": "^9.1.0",
Expand Down
2 changes: 1 addition & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const assert = require('chai').assert;
const { assert } = require('chai');
const parser = require('../index');

describe('index test', () => {
Expand Down
Loading

0 comments on commit 409ea68

Please sign in to comment.