Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ permissions:

jobs:
generate:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.head_ref || github.ref_name }}
fetch-depth: 0

- name: Setup pnpm
uses: pnpm/action-setup@v6
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
> <sup>**All of [simpleicons](https://simpleicons.org) catalog in your hands**</sup>

<!-- SKILL_ICONS_START icons="javascript,python,typescript,openjdk,dotnet,cplusplus,c,php,swift,kotlin,ruby,go,rust,scala,r,html5,css,sass,tailwindcss,react,angular,vuedotjs,svelte,nextdotjs,nuxt,nodedotjs,express,django,flask,spring,laravel,rubyonrails,postgresql,mysql,mongodb,redis,sqlite,docker,kubernetes,git,github,gitlab,linux,ubuntu,debian,archlinux,vscodium,intellijidea,neovim,vim,webpack,vite,babel,eslint,prettier,npm,yarn,pnpm,bun,deno" -->

![][SKILL_ICONS_0]

<!-- SKILL_ICONS_END -->

[SKILL_ICONS_0]: assets/svgs/javascript..deno.svg
[SKILL_ICONS_0]: assets/svgs/javascript..deno-f11be47.svg
5 changes: 5 additions & 0 deletions assets/svgs/.skill-icons.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"generatedFiles": [
"assets/svgs/javascript..deno-f11be47.svg"
]
}
163 changes: 83 additions & 80 deletions out/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion out/index.cjs.map

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/core/gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export async function generateSvgFile({
outPath: string;
}) {
const snapToPx = (value: number) => Math.round(value);

const filename = parseSlug(slugs);
if (!filename) return null;

const dir = path.join(process.cwd(), outPath);

if (dir) {
await fs.rm(dir, { recursive: true, force: true });
await fs.mkdir(dir, { recursive: true });
}
await fs.mkdir(dir, { recursive: true });

const siIcons = slugs.map(i => getIcon(i));
const iconSize = snapToPx(size * 0.8);
Expand Down
9 changes: 8 additions & 1 deletion src/core/run.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { commitChanges } from '@/utils/commit.js';
import { cleanup, commitChanges, generateManifest } from '@/utils/commit.js';
import {
getListFromReadme,
readReadme,
Expand Down Expand Up @@ -34,6 +34,8 @@ export async function run() {
const readme = await readReadme(filename);
const list = getListFromReadme(readme, tag);

await cleanup(outPath);

const svgs = await Promise.all(
Object.entries(list).map(([, l]) =>
generateSvgFile({
Expand All @@ -45,6 +47,11 @@ export async function run() {
),
);

await generateManifest(
outPath,
svgs.filter((svg): svg is string => Boolean(svg)),
);

const updatedReadme = updateReadmeWithReferences(readme, tag, svgs, list);
const hasChanged = readme !== updatedReadme;

Expand Down
64 changes: 61 additions & 3 deletions src/utils/commit.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,61 @@
import * as exec from '@actions/exec';
import fs from 'node:fs/promises';
import path from 'node:path';

const MANIFEST_FILENAME = '.skill-icons.json';

async function loadGeneratedFiles(outPath: string) {
const rootDir = process.env.GITHUB_WORKSPACE || process.cwd();
const manifestPath = path.resolve(rootDir, outPath, MANIFEST_FILENAME);

try {
const rawManifest = await fs.readFile(manifestPath, 'utf-8');
const parsedManifest = JSON.parse(rawManifest);
return Array.isArray(parsedManifest.generatedFiles)
? parsedManifest.generatedFiles
: [];
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return [];
}

throw error;
}
}

export async function cleanup(outPath: string) {
const rootDir = process.env.GITHUB_WORKSPACE || process.cwd();
const outDirPath = path.resolve(rootDir, outPath);
const generatedFiles = await loadGeneratedFiles(outPath);

for (const filePath of generatedFiles) {
const absoluteFilePath = path.resolve(rootDir, filePath);
const isInsideOutPath = absoluteFilePath.startsWith(outDirPath + path.sep);

if (!isInsideOutPath) {
continue;
}

await fs.rm(absoluteFilePath, { force: true });
}
}

export async function generateManifest(
outPath: string,
generatedFiles: string[],
) {
const rootDir = process.env.GITHUB_WORKSPACE || process.cwd();
const manifestPath = path.resolve(rootDir, outPath, MANIFEST_FILENAME);
const outDirPath = path.dirname(manifestPath);
const manifest = { generatedFiles: Array.from(new Set(generatedFiles)) };

await fs.mkdir(outDirPath, { recursive: true });
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
}

export async function commitChanges(
filename: string,
path: string,
outPath: string,
gcmsg: string,
) {
try {
Expand All @@ -19,8 +72,13 @@ export async function commitChanges(
'github-actions[bot]@users.noreply.github.com',
]);

await exec.exec('git', ['add', filename]);
await exec.exec('git', ['add', path]);
const generatedFiles = await loadGeneratedFiles(outPath);
const manifestPath = path.join(outPath, MANIFEST_FILENAME);
const filesToStage = [filename, manifestPath, ...generatedFiles];

for (const filePath of filesToStage) {
await exec.exec('git', ['add', '-A', '--', filePath]);
}

const { exitCode } = await exec.getExecOutput('git', [
'diff',
Expand Down
14 changes: 9 additions & 5 deletions src/utils/parser.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
export function parseSlug(slugs: string[]): string {
const now = Date.now();
import { createHash } from 'node:crypto';

if (!slugs.length) return `i..${now}.svg`;
if (slugs.length === 1) return `${slugs[0]}.svg`;
function getSlugHash(slugs: string[]) {
return createHash('sha1').update(slugs.join(',')).digest('hex').slice(0, 7);
}

export function parseSlug(slugs: string[]): string | null {
if (!slugs.length) return null;
if (slugs.length === 1) return `${slugs[0]}-${getSlugHash(slugs)}.svg`;

const first = slugs[0];
const last = slugs.at(-1);

return `${first}..${last}.svg`;
return `${first}..${last}-${getSlugHash(slugs)}.svg`;
}
12 changes: 8 additions & 4 deletions src/utils/readme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function getListFromReadme(readmeContent: string, tag: string) {
export function updateReadmeWithReferences(
readmeContent: string,
tag: string,
svgPaths: string[],
svgPaths: Array<string | null>,
list: Array<{ name: string; items: string[] }>,
) {
const blockRegex = createRegex(tag);
Expand All @@ -63,17 +63,21 @@ export function updateReadmeWithReferences(
let updatedContent = readmeContent.replace(blockRegex, () => {
const group = list[idx];
const refKey = `${tag}_${idx}`;
const imagePath = svgPaths[idx] || '';
const imagePath = svgPaths[idx];

references.push(`[${refKey}]: ${imagePath}`);
if (imagePath) {
references.push(`[${refKey}]: ${imagePath}`);
}

const itemsAttr = group?.items?.length
? ` icons="${group.items.join(',')}"`
: '';

idx++;

return `<!-- ${tag}_START${itemsAttr} -->\n![][${refKey}]\n<!-- ${tag}_END -->`;
return `<!-- ${tag}_START${itemsAttr} -->\n${
imagePath ? `\n![][${refKey}]\n` : ''
}\n<!-- ${tag}_END -->`;
});

const refRegex = createRefRegex(tag);
Expand Down