Skip to content

Conversation

@jpoehnelt
Copy link
Member

@jpoehnelt jpoehnelt commented Nov 26, 2025

No description provided.

@jpoehnelt jpoehnelt requested a review from a team as a code owner November 26, 2025 17:19
@jpoehnelt jpoehnelt requested a review from sqrrrl November 26, 2025 17:19
@jpoehnelt jpoehnelt changed the title fix/biomejs fix: consistent formatting and numerous lint errors Nov 26, 2025
@jpoehnelt jpoehnelt removed the request for review from sqrrrl November 26, 2025 17:20
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jpoehnelt, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates BiomeJS into the project's workflow for Google Apps Script files, aiming to standardize code style and improve maintainability. The changes encompass the addition of a dedicated script to manage the formatting process and a broad application of these new style rules across the existing codebase. This initiative ensures a more consistent and cleaner code style moving forward.

Highlights

  • BiomeJS Integration: A new TypeScript script (biome-gs.ts) has been introduced to automate the formatting and linting of .gs (Google Apps Script) files using BiomeJS. This script temporarily renames .gs files to .gs.js for processing and then reverts them.
  • Extensive Code Formatting: Numerous .gs files across various directories have undergone significant formatting changes to align with the new BiomeJS style guidelines. This includes consistent use of string literals, object property quoting, and general code style adjustments.
  • Improved Error Handling: The biome-gs.ts script now includes robust error handling and ensures that original .gs files are restored even if BiomeJS encounters issues or the process is interrupted.
  • Documentation Update: The GEMINI.md file has been updated with a new guideline emphasizing that code within snippet tags should be self-contained, particularly for snippets intended for copy-pasting.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a wide range of formatting and linting fixes across numerous files, significantly improving code consistency and adhering to modern JavaScript standards. The changes include converting var to let/const, using arrow functions, and template literals, which is great. I've also noticed fixes for critical issues like duplicate function declarations. I've identified a couple of areas where the changes might have introduced unintended side effects or could be made more robust. My comments below highlight these points for your consideration.

@jpoehnelt
Copy link
Member Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a script for running Biome on .gs files and applies extensive formatting and linting fixes across the entire codebase. The changes improve code consistency and adhere to modern JavaScript standards. My review focuses on ensuring the new script is robust and that the refactoring hasn't introduced any regressions, particularly around error handling. I've identified a few critical issues where error handling was removed and a high-severity issue with an unused variable in advanced/docs.gs. Additionally, I've found some opportunities to improve the new biome-gs.ts script for better performance and robustness.

Comment on lines 140 to 164
function readFirstParagraph(documentId) {
try {
// Get the document using document ID
const document = Docs.Documents.get(documentId, {'includeTabsContent': true});
const firstTab = document.tabs[0];
const bodyElements = firstTab.documentTab.body.content;
for (let i = 0; i < bodyElements.length; i++) {
const structuralElement = bodyElements[i];
// Print the first paragraph text present in document
if (structuralElement.paragraph) {
const paragraphElements = structuralElement.paragraph.elements;
let paragraphText = '';
// Get the document using document ID
const document = Docs.Documents.get(documentId, {
includeTabsContent: true,
});
const firstTab = document.tabs[0];
const bodyElements = firstTab.documentTab.body.content;
for (let i = 0; i < bodyElements.length; i++) {
const structuralElement = bodyElements[i];
// Print the first paragraph text present in document
if (structuralElement.paragraph) {
const paragraphElements = structuralElement.paragraph.elements;
let paragraphText = "";

for (let j = 0; j < paragraphElements.length; j++) {
const paragraphElement = paragraphElements[j];
if (paragraphElement.textRun !== null) {
paragraphText += paragraphElement.textRun.content;
}
for (let j = 0; j < paragraphElements.length; j++) {
const paragraphElement = paragraphElements[j];
if (paragraphElement.textRun !== null) {
paragraphText += paragraphElement.textRun.content;
}
console.log(paragraphText);
return paragraphText;
}
console.log(paragraphText);
return paragraphText;
}
} catch (e) {
// TODO (developer) - Handle exception
console.log('Failed with error %s', e.message);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The try...catch block around the Docs.Documents.get call has been removed. This removes necessary error handling. If the API call fails (e.g., document not found, permissions error), the script will crash. The error handling should be restored to ensure the script is robust and provides meaningful error messages.

function readFirstParagraph(documentId) {
  try {
    // Get the document using document ID
    const document = Docs.Documents.get(documentId, {
      includeTabsContent: true,
    });
    const firstTab = document.tabs[0];
    const bodyElements = firstTab.documentTab.body.content;
    for (let i = 0; i < bodyElements.length; i++) {
      const structuralElement = bodyElements[i];
      // Print the first paragraph text present in document
      if (structuralElement.paragraph) {
        const paragraphElements = structuralElement.paragraph.elements;
        let paragraphText = "";

        for (let j = 0; j < paragraphElements.length; j++) {
          const paragraphElement = paragraphElements[j];
          if (paragraphElement.textRun !== null) {
            paragraphText += paragraphElement.textRun.content;
          }
        }
        console.log(paragraphText);
        return paragraphText;
      }
    }
  } catch (e) {
    // TODO (developer) - Handle exception
    console.log('Failed with error %s', e.message);
  }
}

Comment on lines +24 to +48
async function findGsFiles(
dir: string,
fileList: string[] = [],
): Promise<string[]> {
const files = readdirSync(dir);
for (const file of files) {
const filePath = join(dir, file);
if (
file === "node_modules" ||
file === ".git" ||
file === "dist" ||
file === "target" ||
file === "pkg"
) {
continue;
}
const stat = statSync(filePath);
if (stat.isDirectory()) {
await findGsFiles(filePath, fileList);
} else if (file.endsWith(".gs") && file !== "moment.gs") {
fileList.push(filePath);
}
}
return fileList;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The findGsFiles function uses synchronous file system operations (readdirSync, statSync) within an async function. This mix of synchronous and asynchronous code is inefficient and can block the Node.js event loop, which can be slow for large repositories.

A better approach is to use the promise-based APIs from node:fs/promises and Promise.all to perform directory traversal concurrently. This will significantly improve performance and make the code more robust.

Please also update your imports from node:fs to use readdir from node:fs/promises and remove the now-unused statSync.

async function findGsFiles(dir: string): Promise<string[]> {
  const ignoredDirs = new Set([
    "node_modules",
    ".git",
    "dist",
    "target",
    "pkg",
  ]);
  try {
    const dirents = await readdir(dir, { withFileTypes: true });
    const files = await Promise.all(
      dirents.map(async (dirent) => {
        const fullPath = resolve(dir, dirent.name);
        if (ignoredDirs.has(dirent.name)) {
          return [];
        }
        if (dirent.isDirectory()) {
          return findGsFiles(fullPath);
        }
        if (dirent.isFile() && dirent.name.endsWith(".gs") && dirent.name !== "moment.gs") {
          return [fullPath];
        }
        return [];
      }),
    );
    return files.flat();
  } catch (error) {
    // Ignore errors for directories that can't be read (e.g. permissions)
    console.error(`Could not read directory ${dir}:`, error);
    return [];
  }
}

@jpoehnelt jpoehnelt merged commit 748a7fb into main Nov 26, 2025
14 of 36 checks passed
@jpoehnelt jpoehnelt deleted the fix/biomejs branch November 26, 2025 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant