Skip to content

Commit a44b4ab

Browse files
tshemsedinovbohdanbulakh
authored andcommitted
Unify skills and roles loader
PR-URL: HowProgrammingWorks#140
1 parent 914fe0d commit a44b4ab

File tree

1 file changed

+46
-65
lines changed

1 file changed

+46
-65
lines changed

.github/src/skills.js

Lines changed: 46 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const caption = concolor('b,white');
1010
const fatal = concolor('b,white/red');
1111
const fixup = concolor('b,black/yellow');
1212

13-
const TITLE = caption`Software engineering self assessment`;
13+
const TITLE = 'Software engineering self assessment';
1414
const PARSING_TIMEOUT = 1000;
1515
const EXECUTION_TIMEOUT = 5000;
1616

@@ -29,27 +29,27 @@ let exitCode = 0;
2929
const wrongFormat = (msg, file) => {
3030
exitCode = 1;
3131
console.log(fatal` Wrong file format: ${msg} `);
32-
console.log(`File: ${file}`);
32+
console.log(fatal` File: ${file} `);
3333
};
3434

3535
const warnFixup = (msg, file) => {
3636
console.log(fixup` Fixup file format: ${msg} `);
37-
console.log(`File: ${file}`);
37+
console.log(fixup` File: ${file} `);
3838
};
3939

4040
const codeBlock = (code) => '```\n' + code + '\n```';
4141

42-
const loadFile = async (file) => {
43-
const fileName = path.join(PATH, file);
44-
const data = await fs.readFile(fileName, 'utf8');
42+
const loadFile = async (filePath) => {
43+
const fileName = path.basename(filePath);
44+
const data = await fs.readFile(filePath, 'utf8');
4545
if (data.includes('\r')) {
46-
warnFixup('expected LF linebreaks, not CRLF or CR', file);
46+
warnFixup('expected LF linebreaks, not CRLF or CR', fileName);
4747
}
4848
if (!data.startsWith('## ')) {
49-
wrongFormat('no markdown «## Heading»', file);
49+
wrongFormat('no markdown «## Heading»', fileName);
5050
}
5151
if (!data.endsWith('\n')) {
52-
warnFixup('no newline at the end of file', file);
52+
warnFixup('no newline at the end of file', fileName);
5353
}
5454
return data;
5555
};
@@ -115,13 +115,14 @@ const formatSkill = (line) => {
115115
return { skill, level };
116116
};
117117

118-
const getSkills = (data, file) => {
118+
const getSkills = (data, file, options) => {
119119
const lines = data.split('\n');
120120
if (lines.at(-1).trim() === '') lines.pop();
121121
let section = '';
122122
let empty = 0;
123+
const sections = {};
124+
const skills = new Set();
123125
const out = [];
124-
const skills = [];
125126
for (const [i, s] of lines.entries()) {
126127
const line = s.trim();
127128
if (line === '') {
@@ -141,6 +142,7 @@ const getSkills = (data, file) => {
141142
if (s.startsWith('-')) {
142143
out.push(line);
143144
section = line.slice(1).trim();
145+
sections[section] = {};
144146
continue;
145147
}
146148
if (s.startsWith(' -')) {
@@ -149,93 +151,72 @@ const getSkills = (data, file) => {
149151
const msg = 'not matching level and emoji';
150152
wrongFormat(`${msg} «${line}» at line ${i + 1}`, file);
151153
out.push(`${s} 👉 Warning: ${msg}`);
152-
skills.push(skill);
154+
skills.add(skill);
153155
continue;
154156
}
155-
if (skills.includes(skill)) {
157+
if (skills.has(skill) && options.unique) {
156158
warnFixup(`removed duplicate skill «${skill}» at line ${i + 1}`, file);
157159
} else {
158-
out.push(` - ${skill}${level ? ': ' + level : ''}`);
159-
skills.push(skill);
160+
if (level) {
161+
out.push(` - ${skill}: ${level}`);
162+
sections[section][skill] = level;
163+
} else {
164+
out.push(` - ${skill}`);
165+
sections[section][skill] = '';
166+
}
167+
skills.add(skill);
160168
}
161169
continue;
162170
}
163171
wrongFormat(`unkonw structure at line ${i + 1}`, file);
164172
}
165173
const output = out.join('\n') + '\n';
166174
if (data !== output) {
167-
const fileName = path.join(PATH, file);
168-
fs.writeFile(fileName, output).catch(() => {});
169-
console.log(`Fixup: ${data.length} -> ${output.length} saved: ${file}`);
175+
fs.writeFile(file, output).catch(() => {});
176+
const fileName = file.slice(PATH.length);
177+
console.log(`Fixup: ${data.length} -> ${output.length} saved: ${fileName}`);
170178
}
171-
return skills;
179+
return { sections, skills };
172180
};
173181

174-
const getRoles = (data, file) => {
175-
const lines = data.split('\n');
176-
if (lines.at(-1).trim() === '') lines.pop();
177-
let section = '';
178-
const roles = {};
179-
for (const [i, s] of lines.entries()) {
180-
const line = s.trim();
181-
if (s.startsWith('-')) {
182-
section = line.slice(1).trim();
183-
roles[section] = [];
184-
continue;
185-
}
186-
if (s.startsWith(' -')) {
187-
const skill = line.slice(1).trim();
188-
roles[section].push(skill);
189-
}
190-
}
191-
return roles;
192-
};
193-
194-
const analise = async (section) => {
195-
console.log(caption`Skills: ${section}`);
196-
const file = `Skills/${section}.md`;
182+
const analise = async (dir, unit, options) => {
183+
console.log(caption`Unit: ${unit}`);
184+
const file = `${dir}/${unit}.md`;
197185
const md = await loadFile(file);
198-
const skills = getSkills(md, file);
199-
console.log(`Count: ${skills.length}\n`);
200-
return skills;
201-
};
202-
203-
const match = async (role) => {
204-
console.log(caption`Roles: ${role}`);
205-
const file = `.github/src/Roles/${role}.md`;
206-
const md = await loadFile(file);
207-
const roles = getRoles(md, file);
208-
console.log(`Count: ${Object.keys(roles).length}\n`);
209-
return roles;
186+
const data = getSkills(md, file, options);
187+
const { sections, skills } = data;
188+
const count = Object.keys(sections).length;
189+
console.log(`Sections: ${count}, Skills: ${skills.size}\n`);
190+
return data;
210191
};
211192

212-
const loadDir = async (dir, mapper) => {
193+
const loadDir = async (place, options = {}) => {
194+
const dir = path.join(PATH, place);
213195
const files = await fs.readdir(dir);
214-
const sections = files
196+
const units = files
215197
.filter((file) => file.endsWith('.md'))
216198
.map((file) => file.substring(0, file.length - '.md'.length));
217199
const collection = {};
218-
for (const section of sections) {
219-
collection[section] = await mapper(section);
200+
for (const unit of units) {
201+
collection[unit] = await analise(dir, unit, options);
220202
}
221203
return collection;
222204
};
223205

224206
(async () => {
225-
console.log(TITLE);
207+
console.log(caption`${TITLE}`);
226208
console.log('Auto Checker\n');
227209

228-
const skills = await loadDir(`${PATH}/Skills/`, analise);
229-
const roles = await loadDir(`${PATH}/.github/src/Roles/`, match);
210+
const skills = await loadDir('Skills', { unique: true });
211+
const roles = await loadDir('.github/src/Roles');
230212

231213
const badgeCode = codeBlock(BADGE);
232-
233214
const report = `## ${TITLE}\n\n${BADGE}\n\n${badgeCode}\n`;
234215
await fs.writeFile(`${PATH}/Profile/REPORT.md`, report);
235216

236-
const readme = await loadFile('.github/src/Templates/README.md');
237-
const newReadme = readme.replace('$BADGE', BADGE);
238-
await fs.writeFile(`${PATH}/README.md`, newReadme);
217+
const template = await loadFile(`${PATH}/.github/src/Templates/README.md`);
218+
const readme = template.replace('$BADGE', BADGE);
219+
await fs.writeFile(`${PATH}/README.md`, readme);
239220

240221
console.log('');
241222
process.exit(exitCode);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy