Skip to content

Commit 71675d7

Browse files
committed
Refactor
1 parent e674d37 commit 71675d7

File tree

4 files changed

+168
-140
lines changed

4 files changed

+168
-140
lines changed

src/globals.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {IKeyValue} from "./index";
2+
3+
export class Globals {
4+
5+
public readonly variables: IKeyValue = {};
6+
public readonly beforeScripts: string[] | null;
7+
public readonly scripts: string[] | null;
8+
public readonly afterScripts: string[] | null;
9+
10+
}

src/index.ts

Lines changed: 81 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import c = require("ansi-colors");
2-
import * as dotProp from "dot-prop";
3-
import fs = require("fs");
4-
import yaml = require("js-yaml");
52
import * as winston from "winston";
63
import yargs = require("yargs");
74
import {Job} from "./job";
5+
import {Parser} from "./parser";
6+
7+
export interface IKeyValue {
8+
[key: string]: string | undefined;
9+
}
810

911
const colorizer = winston.format.colorize();
1012

@@ -19,113 +21,82 @@ const logger: winston.Logger = winston.createLogger({
1921
],
2022
});
2123

22-
const illigalJobName = ["include", "local_configuration", "image", "services", "stages", "pages", "types", "before_script", "default", "after_script", "variables", "cache", "include"];
2324
const argv = yargs.argv;
2425
const cwd = argv.cwd || process.cwd();
2526

26-
// Parse .gitlab-ci.yml
27-
const gitlabCiYmlPath = `${cwd}/.gitlab-ci.yml`;
28-
if (!fs.existsSync(gitlabCiYmlPath)) {
29-
logger.error(`Could not find ${gitlabCiYmlPath}`);
30-
process.exit(1);
31-
}
32-
const gitlabCiContent = fs.readFileSync(gitlabCiYmlPath, "utf8");
33-
const gitlabCiData = yaml.safeLoad(gitlabCiContent);
34-
35-
// Parse .gitlab-local.yml
36-
const gitlabCiLocalYmlPath = `${cwd}/.gitlab-ci.local.yml`;
37-
if (!fs.existsSync(gitlabCiLocalYmlPath)) {
38-
logger.error(`Could not find ${gitlabCiLocalYmlPath}`);
39-
process.exit(1);
40-
}
41-
const gitlabCiLocalContent = fs.readFileSync(gitlabCiLocalYmlPath, "utf8");
42-
const gitlabLocalData = yaml.safeLoad(gitlabCiLocalContent);
43-
44-
const jobs = new Map<string, Job>();
45-
const stages = new Map<string, Job[]>();
46-
47-
export interface IKeyValue {
48-
[key: string]: string | undefined;
49-
}
50-
51-
const globalVariables = dotProp.get<IKeyValue>(gitlabCiData, "variables") || {};
52-
const globalLocalVariables = dotProp.get<IKeyValue>(gitlabLocalData, "variables") || {};
53-
54-
for (const value of gitlabCiData.stages) {
55-
stages.set(value, []);
56-
}
57-
58-
const addToMaps = (key: string, job: Job) => {
59-
const stage = stages.get(job.stage);
60-
if (stage) {
61-
stage.push(job);
62-
} else {
63-
const stagesJoin = Array.from(stages.keys()).join(", ");
64-
console.error(`${c.blueBright(`${job.name}`)} ${c.yellow(`${job.stage}`)} ${c.red(`isn't specified in stages. Must be one of the following`)} ${c.yellow(`${stagesJoin}`)}`);
65-
process.exit(1);
66-
}
67-
68-
jobs.set(key, job);
69-
};
70-
71-
for (const [key, value] of Object.entries(gitlabCiData)) {
72-
if (illigalJobName.includes(key) || key[0] === ".") {
73-
continue;
74-
}
75-
76-
const job = new Job(value, key, cwd, {...globalVariables, ...globalLocalVariables});
77-
addToMaps(key, job);
78-
}
79-
80-
for (const [key, value] of Object.entries(gitlabLocalData || {})) {
81-
if (illigalJobName.includes(key)) {
82-
continue;
83-
}
84-
85-
let job = jobs.get(key);
86-
if (job) {
87-
job.override(value);
88-
} else {
89-
job = new Job(value, key, cwd, {...globalVariables, ...globalLocalVariables});
90-
addToMaps(key, job);
91-
}
92-
}
93-
94-
const runJobs = async () => {
95-
96-
for (const [stageName, jobList] of stages) {
97-
const promises: Array<Promise<any>> = [];
98-
99-
if (jobList.length === 0) {
100-
console.log(`=> ${c.yellow(`${stageName}`)} has no jobs`);
101-
console.log("");
102-
continue;
103-
}
104-
105-
if (jobList.length === 0) {
106-
continue;
107-
}
108-
109-
const jobNames = `${jobList.join(" ")}`;
110-
console.log(`=> ${c.yellow(`${stageName}`)} > ${c.blueBright(`${jobNames}`)} ${c.magentaBright(`starting`)}...`);
111-
for (const job of jobList) {
112-
const jobPromise = job.start();
113-
promises.push(jobPromise);
114-
}
115-
116-
try {
117-
await Promise.all(promises);
118-
console.log("");
119-
} catch (e) {
120-
if (e !== "") { console.error(e); }
121-
process.exit(1);
122-
}
123-
}
124-
};
125-
126-
process.on("uncaughtException", (err) => {
127-
// handle the error safely
128-
console.log(err);
129-
});
130-
131-
runJobs().catch();
27+
const parser = new Parser(cwd, logger);
28+
//
29+
// console.log(gitlabData);
30+
process.exit(0);
31+
32+
// const jobs = new Map<string, Job>();
33+
// const stages = new Map<string, Job[]>();
34+
//
35+
// export interface IKeyValue {
36+
// [key: string]: string | undefined;
37+
// }
38+
//
39+
// for (const value of gitlabCiData.stages) {
40+
// stages.set(value, []);
41+
// }
42+
//
43+
// const addToMaps = (key: string, job: Job) => {
44+
// const stage = stages.get(job.stage);
45+
// if (stage) {
46+
// stage.push(job);
47+
// } else {
48+
// const stagesJoin = Array.from(stages.keys()).join(", ");
49+
// console.error(`${c.blueBright(`${job.name}`)} ${c.yellow(`${job.stage}`)} ${c.red(`isn't specified in stages. Must be one of the following`)} ${c.yellow(`${stagesJoin}`)}`);
50+
// process.exit(1);
51+
// }
52+
//
53+
// jobs.set(key, job);
54+
// };
55+
//
56+
// for (const [key, value] of Object.entries(gitlabCiData)) {
57+
// if (illigalJobName.includes(key) || key[0] === ".") {
58+
// continue;
59+
// }
60+
//
61+
// const job = new Job(value, key, cwd, {...globalVariables, ...globalLocalVariables});
62+
// addToMaps(key, job);
63+
// }
64+
//
65+
// const runJobs = async () => {
66+
//
67+
// for (const [stageName, jobList] of stages) {
68+
// const promises: Array<Promise<any>> = [];
69+
//
70+
// if (jobList.length === 0) {
71+
// console.log(`=> ${c.yellow(`${stageName}`)} has no jobs`);
72+
// console.log("");
73+
// continue;
74+
// }
75+
//
76+
// if (jobList.length === 0) {
77+
// continue;
78+
// }
79+
//
80+
// const jobNames = `${jobList.join(" ")}`;
81+
// console.log(`=> ${c.yellow(`${stageName}`)} > ${c.blueBright(`${jobNames}`)} ${c.magentaBright(`starting`)}...`);
82+
// for (const job of jobList) {
83+
// const jobPromise = job.start();
84+
// promises.push(jobPromise);
85+
// }
86+
//
87+
// try {
88+
// await Promise.all(promises);
89+
// console.log("");
90+
// } catch (e) {
91+
// if (e !== "") { console.error(e); }
92+
// process.exit(1);
93+
// }
94+
// }
95+
// };
96+
//
97+
// process.on("uncaughtException", (err) => {
98+
// // handle the error safely
99+
// console.log(err);
100+
// });
101+
//
102+
// runJobs().catch();

src/job.ts

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,50 @@ import c = require("ansi-colors");
22
import * as dotProp from "dot-prop";
33
import prettyHrtime = require("pretty-hrtime");
44
import * as shelljs from "shelljs";
5+
import {Globals} from "./globals";
56
import {IKeyValue} from "./index";
67

78
const shell = process.env.EXEPATH ? `${process.env.EXEPATH}/bash.exe` : "/bin/bash";
89

910
export class Job {
1011

11-
private static getScriptLikeFromData(jobData: any, keyname: string): string[] {
12+
private static getScriptLikesFromData(jobData: any, keyname: string): string[] | null {
1213
const sc = dotProp.get<string | string[] | undefined>(jobData, keyname);
1314
if (sc) {
1415
let scripts: string[] = [];
1516
scripts = scripts.concat(sc);
1617
return scripts;
1718
}
18-
return [];
19+
return null;
1920
}
2021

2122
public readonly stage: string;
2223
public readonly name: string;
2324

2425
private readonly cwd: any;
2526

26-
private readonly globalVariables: IKeyValue;
27+
private readonly globals: Globals;
2728
private readonly variables: IKeyValue;
28-
private variablesLocal: IKeyValue = {};
2929

30-
private allowFailure: boolean;
31-
private beforeScripts: string[] = [];
32-
private afterScripts: string[] = [];
33-
private scripts: string[] = [];
30+
private readonly allowFailure: boolean;
3431

35-
constructor(jobData: any, name: string, cwd: any, globalVariables: IKeyValue) {
32+
private readonly beforeScripts: string[] = [];
33+
private readonly scripts: string[] = [];
34+
private readonly afterScripts: string[] = [];
35+
36+
constructor(jobData: any, name: string, cwd: any, globals: Globals) {
3637
this.name = name;
3738
this.cwd = cwd;
38-
this.globalVariables = globalVariables;
39-
this.stage = dotProp.get<string>(jobData, "stage") || ".pre";
40-
41-
this.scripts = Job.getScriptLikeFromData(jobData, "script");
42-
this.beforeScripts = Job.getScriptLikeFromData(jobData, "before_script");
43-
this.afterScripts = Job.getScriptLikeFromData(jobData, "after_script");
39+
this.globals = globals;
4440

41+
this.stage = dotProp.get<string>(jobData, "stage") || ".pre";
42+
this.scripts = Job.getScriptLikesFromData(jobData, "script") || globals.scripts || [];
43+
this.beforeScripts = Job.getScriptLikesFromData(jobData, "before_script") || globals.beforeScripts || [];
44+
this.afterScripts = Job.getScriptLikesFromData(jobData, "after_script") || globals.afterScripts || [];
4545
this.allowFailure = dotProp.get<boolean>(jobData, "allow_failure") || false;
4646
this.variables = dotProp.get<IKeyValue>(jobData, "variables") || {};
4747
}
4848

49-
public override(jobData: any): void {
50-
const scripts = Job.getScriptLikeFromData(jobData, "script");
51-
this.scripts = scripts.length > 0 ? scripts : this.scripts;
52-
53-
const beforeScripts = Job.getScriptLikeFromData(jobData, "before_script");
54-
this.beforeScripts = beforeScripts.length > 0 ? beforeScripts : this.beforeScripts;
55-
56-
const afterScripts = Job.getScriptLikeFromData(jobData, "after_script");
57-
this.afterScripts = afterScripts.length > 0 ? afterScripts : this.afterScripts;
58-
59-
this.allowFailure = dotProp.get<boolean>(jobData, "allow_failure") || this.allowFailure;
60-
this.variablesLocal = dotProp.get<IKeyValue>(jobData, "variables") || {};
61-
}
62-
6349
public async start(): Promise<void> {
6450
if (this.scripts.length === 0) {
6551
console.error(`${c.blueBright(`${this.name}`)} ${c.red(`must have script specified`)}`);
@@ -122,7 +108,7 @@ export class Job {
122108
}
123109

124110
private getEnvs(): IKeyValue {
125-
return {...this.globalVariables, ...this.variables, ...this.variablesLocal, ...process.env};
111+
return {...this.globals.variables, ...this.variables, ...process.env};
126112
}
127113

128114
private async exec(script: string): Promise<number> {

src/parser.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as dotProp from "dot-prop";
2+
import fs = require("fs");
3+
import yaml = require("js-yaml");
4+
import * as winston from "winston";
5+
import {IKeyValue} from "./index";
6+
import {Job} from "./job";
7+
8+
export class Parser {
9+
10+
private readonly illigalJobNames = [
11+
"include", "local_configuration", "image", "services",
12+
"stages", "pages", "types", "before_script", "default",
13+
"after_script", "variables", "cache", "include",
14+
];
15+
private readonly gitlabData: any;
16+
17+
constructor(cwd: any, logger: winston.Logger) {
18+
// Parse .gitlab-ci.yml
19+
const gitlabCiYmlPath = `${cwd}/.gitlab-ci.yml`;
20+
if (!fs.existsSync(gitlabCiYmlPath)) {
21+
logger.error(`Could not find ${gitlabCiYmlPath}`);
22+
process.exit(1);
23+
}
24+
const gitlabCiContent = fs.readFileSync(gitlabCiYmlPath, "utf8");
25+
const gitlabCiData = yaml.safeLoad(gitlabCiContent);
26+
const globalVariables = dotProp.get<IKeyValue>(gitlabCiData, "variables") || {};
27+
28+
// Parse .gitlab-local.yml
29+
const gitlabCiLocalYmlPath = `${cwd}/.gitlab-ci.local.yml`;
30+
if (!fs.existsSync(gitlabCiLocalYmlPath)) {
31+
logger.error(`Could not find ${gitlabCiLocalYmlPath}`);
32+
process.exit(1);
33+
}
34+
const gitlabCiLocalContent = fs.readFileSync(gitlabCiLocalYmlPath, "utf8");
35+
const gitlabLocalData = yaml.safeLoad(gitlabCiLocalContent);
36+
const globalLocalVariables = dotProp.get<IKeyValue>(gitlabLocalData, "variables") || {};
37+
38+
const gitlabData = {...gitlabCiData, ...gitlabLocalData};
39+
this.gitlabData.variables = {...globalVariables, ...globalLocalVariables};
40+
41+
console.log(this.gitlabData);
42+
43+
this.jobs = this.createJobs(gitlabData, cwd);
44+
}
45+
46+
private createJobs(gitlabData: any, cwd: any): Job[] {
47+
const variables = gitlabData.variables;
48+
49+
for (const [key, value] of Object.entries(gitlabData)) {
50+
if (this.illigalJobNames.includes(key) || key[0] === ".") {
51+
continue;
52+
}
53+
54+
const job = new Job(value, key, cwd, variables);
55+
addToMaps(key, job);
56+
}
57+
58+
return jobs;
59+
}
60+
61+
}

0 commit comments

Comments
 (0)