Skip to content

Commit

Permalink
ci: make biome lint happy
Browse files Browse the repository at this point in the history
  • Loading branch information
liby committed Aug 14, 2024
1 parent 7b8130e commit c540ead
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 112 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Check

on:
push:
branches: [main]
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- name: Run Biome
run: biome ci .
2 changes: 2 additions & 0 deletions .github/workflows/update-gist.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: "Update Gist"

on:
push:
branches: [main]
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
Expand Down
20 changes: 13 additions & 7 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
"organizeImports": {
"enabled": true
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"ignore": [
"bun.lockb",
"node_modules"
],
"ignore": ["**/bun.lockb", "**/node_modules"],
"attributePosition": "auto",
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80,
"lineEnding": "lf",
"semicolons": "always"
"lineEnding": "lf"
},
"javascript": {
"formatter": {
Expand All @@ -22,5 +22,11 @@
"formatter": {
"trailingCommas": "none"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}
}
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
"start": "bun src/index.ts"
},
"devDependencies": {
"@biomejs/biome": "1.8.3",
"@octokit/types": "^13.5.0",
"@types/bun": "latest",
"typescript": "^5.0.0"
},
"dependencies": {
"@octokit/request": "^9.1.3"
}
}
}
10 changes: 5 additions & 5 deletions src/github-api-client.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { request } from "@octokit/request";
import { request } from '@octokit/request';

const { GH_TOKEN } = process.env;

export const githubRequest = request.defaults({
baseUrl: "https://api.github.com",
baseUrl: 'https://api.github.com',
headers: {
"content-type": "application/json",
"user-agent": "octokit-request.js/9.1.3 bun/1.1.6",
accept: "application/vnd.github.v3+json",
'content-type': 'application/json',
'user-agent': 'octokit-request.js/9.1.3 bun/1.1.6',
accept: 'application/vnd.github.v3+json',
authorization: `bearer ${GH_TOKEN}`,
},
per_page: 100,
Expand Down
107 changes: 61 additions & 46 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,66 @@
import { githubRequest } from "./github-api-client";
import { createLanguageStats } from "./language-stats";
import { runLinguist, type FileData } from "./linguist-analyzer";
import type { GetCommitContentsResponse } from "./types/commit";
import type { CommonEvent, PushEvent } from "./types/event";
import { githubRequest } from './github-api-client';
import { createLanguageStats } from './language-stats';
import { type FileData, runLinguist } from './linguist-analyzer';
import type { GetCommitContentsResponse } from './types/commit';
import type { PushEvent } from './types/event';

const { GH_TOKEN, GIST_ID, USERNAME, DAYS } = process.env;

const validateEnv = (): void => {
if (!GH_TOKEN) throw new Error("GH_TOKEN is not provided.");
if (!GIST_ID) throw new Error("GIST_ID is not provided.");
if (!USERNAME) throw new Error("USERNAME is not provided.");
if (!GH_TOKEN) throw new Error('GH_TOKEN is not provided.');
if (!GIST_ID) throw new Error('GIST_ID is not provided.');
if (!USERNAME) throw new Error('USERNAME is not provided.');
};

const fetchCommits = async (
username: string,
fromDate: Date
username: string | null,
fromDate: Date,
): Promise<GetCommitContentsResponse[]> => {
if (username === null) {
throw new Error('USERNAME is not provided.');
}

const maxEvents = 300;
const perPage = 100;
const pages = Math.ceil(maxEvents / perPage);
const commits: GetCommitContentsResponse[] = [];

for (let page = 0; page < pages; page++) {
const events = await githubRequest("GET /users/{username}/events", {
const events = await githubRequest('GET /users/{username}/events', {
username,
per_page: perPage,
page,
})
});
const pushEvents = events.data.filter(
(event): event is PushEvent => event.type === "PushEvent" && event.actor.login === username
(event): event is PushEvent =>
event.type === 'PushEvent' && event.actor.login === username,
);

const recentPushEvents = pushEvents.filter(
({ created_at }) => new Date(created_at) > fromDate
({ created_at }) => new Date(created_at) > fromDate,
);
console.log(`${recentPushEvents.length} events fetched.`);

const newCommits = await Promise.allSettled(
recentPushEvents.flatMap(({ repo, payload }) =>
payload.commits
.filter((commit) => commit.distinct === true)
.map((commit) => githubRequest("GET /repos/{owner}/{repo}/commits/{ref}", {
owner: repo.name.split("/")[0],
repo: repo.name.split("/")[1],
ref: commit.sha,
}))
)
.map((commit) =>
githubRequest('GET /repos/{owner}/{repo}/commits/{ref}', {
owner: repo.name.split('/')[0],
repo: repo.name.split('/')[1],
ref: commit.sha,
}),
),
),
);

commits.push(
...newCommits
.filter((result) => result.status === "fulfilled")
.filter((result) => result.status === 'fulfilled')
.map((result) => {
return result.value.data
})
return result.value.data;
}),
);

if (recentPushEvents.length < pushEvents.length) {
Expand All @@ -65,46 +72,47 @@ const fetchCommits = async (
};

const processCommits = (commits: GetCommitContentsResponse[]): FileData[] => {

const result = commits
.filter((commit) => commit.parents.length <= 1)
.flatMap((commit) =>
commit.files?.map(({ filename, additions, deletions, changes, status, patch }) => ({
path: filename,
additions,
deletions,
changes,
status,
patch,
}))
commit.files?.map(
({ filename, additions, deletions, changes, status, patch }) => ({
path: filename,
additions,
deletions,
changes,
status,
patch,
}),
),
)
.filter((fileData) => fileData !== undefined);

return result;
};

const updateGist = async (gistId: string, content: string) => {
const gist = await githubRequest("GET /gists/{gist_id}", {
const gist = await githubRequest('GET /gists/{gist_id}', {
gist_id: gistId,
});
const filename = Object.keys(gist.data.files!)[0];
await githubRequest("PATCH /gists/{gist_id}", {
const filename = Object.keys(gist.data.files ?? {})[0];
await githubRequest('PATCH /gists/{gist_id}', {
gist_id: gistId,
files: {
[filename]: {
filename: `Bryan’s Recent Coding Languages`,
filename: 'Bryan’s Recent Coding Languages',
content,
},
},
});
console.log(`Update succeeded.`);
console.log('Update succeeded.');
};

const main = async () => {
try {
validateEnv();

const username = USERNAME!;
const username = USERNAME ?? null;
const days = Math.max(1, Math.min(30, Number(DAYS || 14)));
const fromDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);

Expand All @@ -113,21 +121,28 @@ const main = async () => {

const commits = await fetchCommits(username, fromDate);
console.log(`${commits.length} commits fetched.`);
console.log(`\n`);
console.log('\n');

const files = processCommits(commits);
const langs = await runLinguist(files);
console.log("\nLanguage statistics:");
langs.forEach((lang) =>
console.log(`${lang.name}: ${lang.count} files, ${lang.additions + lang.deletions} changes`)
);
console.log('\nLanguage statistics:');
for (const lang of langs) {
console.log(
`${lang.name}: ${lang.count} files, ${lang.additions + lang.deletions} changes`,
);
}

const content = createLanguageStats(langs);
console.log("\nGenerated content:");
console.log('\nGenerated content:');
console.log(content);
console.log(`\n`);
console.log('\n');

if (GIST_ID) {
await updateGist(GIST_ID, content);
} else {
throw new Error('GIST_ID is not provided.');
}

await updateGist(GIST_ID!, content);
} catch (e) {
console.error(e);
process.exitCode = 1;
Expand Down
12 changes: 7 additions & 5 deletions src/language-stats.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ProcessedLanguageStats } from "./linguist-analyzer";
import type { ProcessedLanguageStats } from './linguist-analyzer';

const UNITS = [
{ symbol: 'E', value: 1e18 },
Expand All @@ -24,7 +24,7 @@ const formatNumber = (num: number): string => {
};

const generateBarChart = (percent: number, size: number): string => {
const symbols = "░▏▎▍▌▋▊▉█";
const symbols = '░▏▎▍▌▋▊▉█';
const fractionComplete = Math.floor((size * 8 * percent) / 100);
const fullBars = Math.floor(fractionComplete / 8);

Expand All @@ -40,7 +40,9 @@ const generateBarChart = (percent: number, size: number): string => {
);
};

export const createLanguageStats = (languages: ProcessedLanguageStats[]): string => {
export const createLanguageStats = (
languages: ProcessedLanguageStats[],
): string => {
return languages
.map(({ name, percent, additions, deletions }) => {
const truncatedName = truncateString(name, 10).padEnd(10);
Expand All @@ -50,9 +52,9 @@ export const createLanguageStats = (languages: ProcessedLanguageStats[]): string
const formatChanges = `${formattedAdditions} /${formattedDeletions}`;

const bar = generateBarChart(percent, 18);
const percentageString = percent.toFixed(2).padStart(5) + '%';
const percentageString = `${percent.toFixed(2).padStart(5)}%`;

return `${truncatedName} ${formatChanges} ${bar} ${percentageString}`;
})
.join('\n');
};
};
Loading

0 comments on commit c540ead

Please sign in to comment.