Commit 2b08e18

Anton Golub <antongolub@antongolub.com>
2024-12-04 19:41:13
feat: log $ outputs (#89)
* feat: log $ outputs * refactor: separate logger
1 parent f4d7f66
src/task/comments/discussion-comments.ts
@@ -25,7 +25,7 @@ export default task({
         data.discussionComments.push(comment)
         batchReactions(comment.reactionsTotal.totalCount, comment.id)
       }
-      console.log(
+      octokit.log.info(
         `| discussion comments ${data.discussionComments.length}/${resp.user.repositoryDiscussionComments.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/comments/issue-comments.ts
@@ -23,7 +23,7 @@ export default task({
         batchReactions(comment.reactionsTotal.totalCount, comment.id)
       }
 
-      console.log(
+      octokit.log.info(
         `| issue comments ${data.issueComments.length}/${resp.user.issueComments.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/commits/commits-batch.ts
@@ -10,7 +10,7 @@ export default task({
       author: data.user.id,
     })
 
-    console.log(
+    octokit.log.info(
       `| commits batch ${resp.nodes.length} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
     )
 
src/task/commits/commits.ts
@@ -27,7 +27,7 @@ export default task({
         repo.commits.push(commit)
       }
 
-      console.log(
+      octokit.log.info(
         `| commits ${repo?.owner.login}/${repo?.name} ${repo.commits.length}/${resp.node.defaultBranchRef.target.history.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/issue-timeline/issue-timeline-batch.ts
@@ -9,7 +9,7 @@ export default task({
       ids,
     })
 
-    console.log(
+    octokit.log.info(
       `| issue timeline batch ${resp.nodes.length} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
     )
     for (const node of resp.nodes) {
src/task/issue-timeline/issue-timeline.ts
@@ -19,7 +19,7 @@ export default task({
         throw new Error('Failed to load issue timeline')
       }
 
-      console.log(
+      octokit.log.info(
         `| timeline ${resp.node.timelineItems.nodes.length}/${resp.node.timelineItems.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
       for (const event of resp.node.timelineItems.nodes) {
src/task/issues/issues.ts
@@ -19,7 +19,7 @@ export default task({
         throw new Error('Failed to load issues')
       }
 
-      console.log(
+      octokit.log.info(
         `| issues ${data.issues.length + resp.user.issues.nodes.length}/${
           resp.user.issues.totalCount
         } (cost: ${resp.rateLimit?.cost}, remaining: ${
src/task/pulls/pulls.ts
@@ -18,7 +18,7 @@ export default task({
         throw new Error('Failed to load pull requests')
       }
 
-      console.log(
+      octokit.log.info(
         `| pull requests ${
           data.pulls.length + resp.user.pullRequests.nodes.length
         }/${resp.user.pullRequests.totalCount} (cost: ${
src/task/reactions/reactions-batch.ts
@@ -9,7 +9,7 @@ export default task({
       ids,
     })
 
-    console.log(
+    octokit.log.info(
       `| reactions batch ${nodes.length} (cost: ${rateLimit?.cost}, remaining: ${rateLimit?.remaining})`,
     )
     for (const node of nodes) {
src/task/reactions/reactions-discussion-comments.ts
@@ -25,7 +25,7 @@ export default task({
         discussionComment.reactions.push(reaction)
       }
 
-      console.log(
+      octokit.log.info(
         `| discussion comment reactions ${discussionComment.reactions.length}/${resp.node.reactions.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/reactions/reactions-issue-comments.ts
@@ -25,7 +25,7 @@ export default task({
         issueComment.reactions.push(reaction)
       }
 
-      console.log(
+      octokit.log.info(
         `| issue comment reactions ${issueComment.reactions.length}/${resp.node.reactions.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/reactions/reactions-issue.ts
@@ -25,7 +25,7 @@ export default task({
         issue.reactions.push(reaction)
       }
 
-      console.log(
+      octokit.log.info(
         `| issue reactions ${data.issueComments.length}/${resp.node.reactions.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/reactions/reactions-pull.ts
@@ -25,7 +25,7 @@ export default task({
         pull.reactions.push(reaction)
       }
 
-      console.log(
+      octokit.log.info(
         `| pull reactions ${data.issueComments.length}/${resp.node.reactions.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/repos/repos.ts
@@ -25,14 +25,14 @@ export default task({
         const commitCount =
           repo.defaultBranchRef?.target?.history.totalCount ?? 0
         if (commitCount >= 10_000) {
-          console.error(
+          octokit.log.error(
             `Too many commits for ${repo.owner.login}/${repo.name}: ${commitCount} commits; My-Badges will skip repos with more than 10k commits.`,
           )
         } else {
           batchCommits(commitCount, repo.id)
         }
       }
-      console.log(
+      octokit.log.info(
         `| repos ${data.repos.length}/${resp.user.repositories.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/task/stars/stars.ts
@@ -18,7 +18,7 @@ export default task({
       for (const repo of resp.user.starredRepositories.nodes) {
         data.starredRepositories.push(repo)
       }
-      console.log(
+      octokit.log.info(
         `| stars ${data.starredRepositories.length}/${resp.user.starredRepositories.totalCount} (cost: ${resp.rateLimit?.cost}, remaining: ${resp.rateLimit?.remaining})`,
       )
     }
src/context.ts
@@ -44,7 +44,7 @@ export function createCtx(
     boolean: ['dryrun', 'compact'],
     alias: {
       'dry-run': 'dryrun',
-    }
+    },
   })
   const {
     cwd: _cwd = CWD,
src/log.ts
@@ -0,0 +1,1 @@
+export const log = console
src/main.test.ts
@@ -1,11 +1,12 @@
 import { describe, it } from 'vitest'
 import { main } from './main.js'
 import os from 'node:os'
+import { log } from './log.js'
 
 const temp = `${os.tmpdir()}/${Math.random().toString(36).slice(2)}`
 
 describe.skip('main', () => {
-  console.log('temp', temp)
+  log.info('temp', temp)
   it(
     'generates badges by repo name',
     async () => {
src/main.ts
@@ -9,13 +9,14 @@ import { updateReadme } from './update-readme.js'
 import { processTasks } from './process-tasks.js'
 import { Data } from './data.js'
 import { createCtx } from './context.js'
+import { log } from './log.js'
 import url from 'node:url'
 
 isMain() &&
   main()
     .then(() => process.exit(0))
     .catch((err) => {
-      console.error(err)
+      log.error(err)
       process.exit(1)
     })
 
@@ -50,7 +51,7 @@ export async function main(
     ctx.badgesCompact,
   )
 
-  console.log(JSON.stringify(userBadges, null, 2))
+  log.info(JSON.stringify(userBadges, null, 2))
 
   if (repo.ready) {
     updateBadges(userBadges, ctx.badgesDir, ctx.badgesDatafile)
src/process-tasks.ts
@@ -7,6 +7,7 @@ import allTasks from './task/index.js'
 import { type Context } from './context.js'
 import { createBatcher } from './batch.js'
 import { getOctokit } from './utils.js'
+import { log } from './log.js'
 
 const MAX_ATTEMPTS = 3
 
@@ -87,7 +88,7 @@ export async function processTasks(
   while (todo.length > 0) {
     const { taskName, params, attempts } = todo.shift()!
     if (taskSkipSet.has(taskName)) {
-      console.log(`Skipping task ${taskName}`)
+      log.info(`Skipping task ${taskName}`)
       continue
     }
 
@@ -101,7 +102,7 @@ export async function processTasks(
     }
     const { batch, flush } = createBatcher(next)
 
-    console.log(
+    log.info(
       `==> Running task ${taskName}`,
       new URLSearchParams(params).toString(),
       attempts > 0 ? `(attempt: ${attempts + 1})` : '',
@@ -115,24 +116,24 @@ export async function processTasks(
       }
 
       if (attempts >= MAX_ATTEMPTS || !retry) {
-        console.error(
+        log.error(
           `!!! Failed to run task ${taskName}`,
           new URLSearchParams(params).toString(),
           `after ${attempts} attempts`,
         )
-        console.error(e)
+        log.error(e)
       } else {
-        console.error(
+        log.error(
           `!!! Failed to run task ${taskName}`,
           new URLSearchParams(params).toString(),
           `retrying`,
           `(will try ${MAX_ATTEMPTS - attempts} more times)`,
         )
-        console.error(e)
+        log.error(e)
         todo.push({ taskName, params, attempts: attempts + 1 })
       }
     }
-    console.log(`<== Finished ${taskName} (${todo.length} tasks left)`)
+    log.info(`<== Finished ${taskName} (${todo.length} tasks left)`)
 
     flush()
 
src/repo.ts
@@ -3,6 +3,7 @@ import path from 'node:path'
 import { Badge } from './badges.js'
 import { $ as _$ } from './utils.js'
 import { Context } from './context.js'
+import { log } from './log.js'
 
 export function getRepo({
   gitDir,
@@ -20,6 +21,14 @@ export function getRepo({
   const basicAuth = ghToken ? `${ghRepoOwner}:${ghToken}@` : ''
   const gitUrl = `https://${basicAuth}github.com/${ghRepoOwner}/${ghRepoName}.git`
   const $ = _$({
+    on: {
+      stdout(data) {
+        log.info(data.toString())
+      },
+      stderr(e) {
+        log.error(e.toString())
+      },
+    },
     cwd,
     sync: true,
   })
@@ -29,11 +38,11 @@ export function getRepo({
     },
     pull() {
       if (dryrun) return
+      log.info('Fetching from git...')
       if (fs.existsSync(path.resolve(cwd, '.git'))) {
         $`git pull`
         return
       }
-
       $`git clone --depth=1 ${gitUrl} .`
       $`git config user.name ${gitName}`
       $`git config user.email ${gitEmail}`
@@ -41,6 +50,7 @@ export function getRepo({
     },
     push() {
       if (!ready) return
+      log.info('Pushing to git...')
       $`git add .`
       $`git status`
       $`git commit -m 'Update badges'`
src/update-badges.ts
@@ -2,12 +2,14 @@ import fs from 'node:fs'
 import path from 'node:path'
 import { Badge } from './badges.js'
 import { quoteAttr } from './utils.js'
+import { log } from './log.js'
 
 export function updateBadges(
   badges: Badge[],
   badgesDir: string,
   badgesDatafile: string,
 ) {
+  log.info('Generating badges...')
   fs.mkdirSync(badgesDir, { recursive: true })
   fs.writeFileSync(badgesDatafile, JSON.stringify(badges, null, 2))
 
src/update-readme.test.ts
@@ -41,8 +41,6 @@ describe('generateReadme()', () => {
 
     const contents = generateReadme(readme, badges, 64)
 
-    console.log('contents', contents)
-
     expect(contents).toEqual(
       `<!-- my-badges start -->
 <a href="my-badges/a-commit.md"><img src="" alt="test" title="test" width="64"></a>
src/update-readme.ts
@@ -2,6 +2,7 @@ import fs from 'node:fs'
 import path from 'node:path'
 import { Badge } from './badges.js'
 import { quoteAttr } from './utils.js'
+import { log } from './log.js'
 
 const START_MARK = '<!-- my-badges start -->'
 const END_MARK = '<!-- my-badges end -->'
@@ -33,9 +34,10 @@ export function generateReadme(
   badges: Badge[],
   size: number | string = BADGE_SIZE,
 ) {
+  log.info('Updating README.md...')
+
   const start = content.indexOf(START_MARK)
   const end = content.indexOf(END_MARK)
-  console.log('start', start, 'end', end)
   if ((start === -1 && end !== -1) || (start !== -1 && end === -1))
     throw new Error(
       'Invalid README.md: both or none of the marks should be present',
src/utils.ts
@@ -5,6 +5,7 @@ import { PullRequest } from './task/pulls/pulls.graphql.js'
 import { Issue } from './task/issues/issues.graphql.js'
 import { retry } from '@octokit/plugin-retry'
 import { throttling } from '@octokit/plugin-throttling'
+import { log } from './log.js'
 
 export { $, type TShellSync } from 'zurk'
 
@@ -13,7 +14,7 @@ const MyOctokit = Octokit.plugin(retry, throttling)
 export function getOctokit(token: string) {
   return new MyOctokit({
     auth: token,
-    log: console,
+    log,
     throttle: {
       onRateLimit: (retryAfter, options: any, octokit, retryCount) => {
         octokit.log.warn(