Skip to content

Conversation

@YuevUwU
Copy link
Contributor

@YuevUwU YuevUwU commented Sep 5, 2025

Before

本PR旨在替代以下手動流程:

  1. 放社團照片在 img/club/xxx.jpg
  2. git push
  3. github action 轉換為 webp (且縮放到x1000) 放到converted/img/club/xxx.jpg
  4. git pull
  5. converted/img/club/*.jpg 手動移到 converted/club/*.jpg
  6. github action 重新建立 club.txt

After

  • 現在 converted/img/club 將被忽略
  • 現在僅需將社團照片放進 img/club,就會轉換為WebP丟到converted/club

已知問題

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 5, 2025

Walkthrough

Adds a GitHub Actions step that copies converted club images from converted/img/club to converted/club (skipping existing) then clears the source; updates list-img.js to exclude the club directory when enumerating image folders. No public APIs changed.

Changes

Cohort / File(s) Summary
Workflow: copy then cleanup converted club images
.github/workflows/list-img.yml
Adds a post-WebP conversion step that checks converted/img/club for files, ensures converted/club exists (mkdir -p), copies files with cp -rv --update=none (skipping existing), and then clears the source with rm -rf converted/img/club/*. Does not change other workflow control flow.
Script: exclude 'club' from listing
list-img.js
Introduces excludeDirs = ['club'] and filters directory enumeration so readFilesInFolder returns only directories not in excludeDirs, excluding club when generating images.json. No API signature changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor GH as GitHub Actions
  participant WF as list-img.yml
  participant FS as File System

  GH->>WF: Run workflow
  WF->>FS: Convert images to WebP (existing)
  note over WF,FS: New guarded copy+cleanup step
  WF->>FS: test for files in converted/img/club (compgen / conditional)
  alt files exist
    WF->>FS: mkdir -p converted/club
    WF->>FS: cp -rv --update=none converted/img/club/* -> converted/club/
    WF->>FS: rm -rf converted/img/club/*
  end
  WF-->>GH: Continue remaining steps (unchanged)
Loading
sequenceDiagram
  autonumber
  participant CLI as list-img.js
  participant FS as File System
  participant OUT as images.json

  CLI->>FS: Read subfolders under images root
  FS-->>CLI: Folder list
  CLI->>CLI: Filter folders (excludeDirs = ['club'])
  CLI->>FS: Read images in remaining folders
  CLI->>OUT: Write images.json
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hop and I copy with careful paws,
Club pictures leap past file-system laws.
One burrow kept off the numbered list,
I tidy and move and then desist.
A carrot cheer — the job's done, applause. 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
.github/workflows/list-img.yml (1)

48-51: Confirm data-retention intent for duplicates.

This logic deletes same-named files from converted/img/club if they already exist in converted/club. If you intend to keep the newer duplicates for manual review instead of discarding them, switch to rsync -a --ignore-existing without the final rm. Otherwise, current behavior permanently drops those files.

list-img.js (2)

7-8: Use a Set for O(1) exclusion checks.

Minor improvement and clearer intent.

-const excludeDirs = ['club']; 
+const excludeDirs = new Set(['club']);

12-12: Align predicate with Set-based exclusion (and keep behavior identical).

-    return fs.statSync(itemPath).isDirectory() && !excludeDirs.includes(item);
+    return fs.statSync(itemPath).isDirectory() && !excludeDirs.has(item);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 14f4895 and 412ca66.

📒 Files selected for processing (2)
  • .github/workflows/list-img.yml (1 hunks)
  • list-img.js (1 hunks)

@YuevUwU
Copy link
Contributor Author

YuevUwU commented Sep 5, 2025

@coderabbitai help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 5, 2025

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@YuevUwU
Copy link
Contributor Author

YuevUwU commented Sep 5, 2025

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 5, 2025

✅ Actions performed

Full review triggered.

YuevUwU and others added 6 commits September 6, 2025 05:48
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…n error code 1

I don't want to ignore other error (by adding `|| true`)
If there are no better solution, I still want to use cp
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
.github/workflows/list-img.yml (1)

48-54: Non-portable cp flag will fail; switch to mv -n with guard

cp --update=none isn’t supported on ubuntu-latest and will break the job. Use a guarded mv -n and only clean leftovers if any.

Apply this diff:

             - name: 移動已轉換的社團圖片到 converted/club (已存在者除外)
               run: |
                   mkdir -p converted/club
                   if [ -d converted/img/club ] && compgen -G "converted/img/club/*" > /dev/null; then
-                    cp -rv --update=none converted/img/club/* converted/club/
-                    rm -rf converted/img/club/*
+                    mv -vn converted/img/club/* converted/club/
+                    rm -rf converted/img/club/* || true
                   fi

Alternative: rsync for idempotent copy + cleanup (also portable):

mkdir -p converted/club
if [ -d converted/img/club ] && compgen -G "converted/img/club/*" > /dev/null; then
  rsync -a --ignore-existing converted/img/club/ converted/club/
  find converted/img/club -type f -delete
  find converted/img/club -type d -empty -delete
fi
🧹 Nitpick comments (1)
list-img.js (1)

7-13: Use a Set for exclusions; consider Dirent and sorting for determinism

  • Swap array includes for a Set to avoid linear scans.
  • Optional: use withFileTypes to avoid extra stat calls and sort folders/files to keep images.json stable across runs.

Apply this minimal diff:

-const excludeDirs = ['club']; 
+const excludeDirs = new Set(['club']); 

-    return fs.statSync(itemPath).isDirectory() && !excludeDirs.includes(item);
+    return fs.statSync(itemPath).isDirectory() && !excludeDirs.has(item);

Optional outside this range (deterministic output):

// sort folders
const imageFolders = readFilesInFolder(imgFolder).sort();

// later, sort files per folder
const images = fs.readdirSync(folderPath).sort();

Optional alternative (fewer syscalls):

function readFilesInFolder(folderPath) {
  return fs.readdirSync(folderPath, { withFileTypes: true })
    .filter(d => d.isDirectory() && !excludeDirs.has(d.name))
    .map(d => d.name);
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 14f4895 and af14250.

📒 Files selected for processing (2)
  • .github/workflows/list-img.yml (1 hunks)
  • list-img.js (1 hunks)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
list-img.js (4)

7-7: Make exclusions configurable and O(1) lookup

Use an env-driven Set so CI or local runs can tweak excluded dirs without code changes; also normalize case.

-const excludeDirs = ['club']; 
+const excludeDirSet = new Set(
+  (process.env.EXCLUDE_DIRS || 'club')
+    .split(',')
+    .map(s => s.trim().toLowerCase())
+    .filter(Boolean)
+);

9-13: Avoid per-entry statSync; use withFileTypes + stable ordering

This removes extra syscalls and ensures deterministic folder order. Adjust for the Set from above.

-function readFilesInFolder(folderPath) {
-  return fs.readdirSync(folderPath).filter(item => {
-    const itemPath = path.join(folderPath, item);
-    return fs.statSync(itemPath).isDirectory() && !excludeDirs.includes(item);
-  });
-}
+function readFilesInFolder(folderPath) {
+  return fs
+    .readdirSync(folderPath, { withFileTypes: true })
+    .filter(d => d.isDirectory() && !excludeDirSet.has(d.name.toLowerCase()))
+    .map(d => d.name)
+    .sort();
+}

20-24: Filter to image files and sort for deterministic images.json

Prevents subfolders/hidden files from leaking into the JSON and stabilizes diff noise.

-  imageFolders.forEach(folder => {
-    const folderPath = path.join(imgFolder, folder);
-    const images = fs.readdirSync(folderPath);
-    imageJson[folder] = images;
-  });
+  const exts = /\.(?:avif|webp|png|jpe?g|gif)$/i;
+  imageFolders.forEach(folder => {
+    const folderPath = path.join(imgFolder, folder);
+    const dirents = fs.readdirSync(folderPath, { withFileTypes: true });
+    const images = dirents
+      .filter(d => d.isFile() && exts.test(d.name))
+      .map(d => d.name)
+      .sort();
+    imageJson[folder] = images;
+  });

26-28: Atomic write to avoid partial files

Write to a temp file then rename.

-  const jsonString = JSON.stringify(imageJson, null, 2);
-  fs.writeFileSync(jsonFilePath, jsonString);
+  const jsonString = JSON.stringify(imageJson, null, 2);
+  const tmpPath = `${jsonFilePath}.tmp`;
+  fs.writeFileSync(tmpPath, jsonString);
+  fs.renameSync(tmpPath, jsonFilePath);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between af14250 and e543436.

📒 Files selected for processing (2)
  • .github/workflows/list-img.yml (1 hunks)
  • list-img.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/list-img.yml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant