Skip to content

Commit 748a7fb

Browse files
authored
fix: consistent formatting and numerous lint errors (#600)
1 parent 7187fe3 commit 748a7fb

File tree

193 files changed

+5677
-4521
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

193 files changed

+5677
-4521
lines changed

.github/scripts/biome-gs.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { exec } from "node:child_process";
18+
import { readdirSync, renameSync, statSync } from "node:fs";
19+
import { join, resolve } from "node:path";
20+
import { promisify } from "node:util";
21+
22+
const execAsync = promisify(exec);
23+
24+
async function findGsFiles(
25+
dir: string,
26+
fileList: string[] = [],
27+
): Promise<string[]> {
28+
const files = readdirSync(dir);
29+
for (const file of files) {
30+
const filePath = join(dir, file);
31+
if (
32+
file === "node_modules" ||
33+
file === ".git" ||
34+
file === "dist" ||
35+
file === "target" ||
36+
file === "pkg"
37+
) {
38+
continue;
39+
}
40+
const stat = statSync(filePath);
41+
if (stat.isDirectory()) {
42+
await findGsFiles(filePath, fileList);
43+
} else if (file.endsWith(".gs") && file !== "moment.gs") {
44+
fileList.push(filePath);
45+
}
46+
}
47+
return fileList;
48+
}
49+
50+
async function main() {
51+
const command = process.argv[2]; // 'lint' or 'format'
52+
if (command !== "lint" && command !== "format") {
53+
console.error("Usage: tsx biome-gs.ts [lint|format]");
54+
process.exit(1);
55+
}
56+
57+
const rootDir = resolve(".");
58+
const gsFiles = await findGsFiles(rootDir);
59+
const renamedFiles: { oldPath: string; newPath: string }[] = [];
60+
61+
const restoreFiles = () => {
62+
for (const { oldPath, newPath } of renamedFiles) {
63+
try {
64+
renameSync(newPath, oldPath);
65+
} catch (e) {
66+
console.error(`Failed to restore ${newPath} to ${oldPath}:`, e);
67+
}
68+
}
69+
renamedFiles.length = 0;
70+
};
71+
72+
process.on("SIGINT", () => {
73+
restoreFiles();
74+
process.exit(1);
75+
});
76+
process.on("SIGTERM", () => {
77+
restoreFiles();
78+
process.exit(1);
79+
});
80+
process.on("exit", restoreFiles);
81+
82+
try {
83+
// 1. Rename .gs to .gs.js
84+
for (const gsFile of gsFiles) {
85+
const jsFile = `${gsFile}.js`;
86+
renameSync(gsFile, jsFile);
87+
renamedFiles.push({ oldPath: gsFile, newPath: jsFile });
88+
}
89+
90+
// 2. Run Biome
91+
const biomeArgs = command === "format" ? "check --write ." : "check .";
92+
console.log(`Running biome ${biomeArgs}...`);
93+
try {
94+
const { stdout, stderr } = await execAsync(
95+
`pnpm exec biome ${biomeArgs}`,
96+
{ cwd: rootDir },
97+
);
98+
if (stdout) console.log(stdout.replace(/\.gs\.js/g, ".gs"));
99+
if (stderr) console.error(stderr.replace(/\.gs\.js/g, ".gs"));
100+
} catch (e: unknown) {
101+
const err = e as { stdout?: string; stderr?: string };
102+
if (err.stdout) console.log(err.stdout.replace(/\.gs\.js/g, ".gs"));
103+
if (err.stderr) console.error(err.stderr.replace(/\.gs\.js/g, ".gs"));
104+
// Don't exit yet, we need to restore files
105+
}
106+
} catch (err) {
107+
console.error("An error occurred:", err);
108+
} finally {
109+
restoreFiles();
110+
// Remove listeners to avoid double-running or issues on exit
111+
process.removeAllListeners("exit");
112+
process.removeAllListeners("SIGINT");
113+
process.removeAllListeners("SIGTERM");
114+
}
115+
}
116+
117+
main().catch((err) => {
118+
console.error(err);
119+
process.exit(1);
120+
});

GEMINI.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ This guide outlines best practices for developing Google Apps Script projects, f
66

77
* For new sample directories, ensure the top-level folder is included in the [`test.yaml`](.github/workflows/test.yaml) GitHub workflow's matrix configuration.
88
* Do not move or delete snippet tags: `[END apps_script_... ]` or `[END apps_script_... ]`.
9-
9+
* Keep code within snippet tags self-contained. Avoid depending on helper functions defined outside the snippet tags if the snippet is intended to be copied and pasted.
10+
* Avoid function name collisions (e.g., multiple `onOpen` or `main` functions) by placing separate samples in their own directories or files. Do not append suffixes like `_2`, `_3` to function names. For variables, replace collisions with a more descriptive name.
1011

1112
## Tools
1213

adminSDK/directory/quickstart.gs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,27 @@
2020
*/
2121
function listUsers() {
2222
const optionalArgs = {
23-
customer: 'my_customer',
23+
customer: "my_customer",
2424
maxResults: 10,
25-
orderBy: 'email'
25+
orderBy: "email",
2626
};
2727
if (!AdminDirectory || !AdminDirectory.Users) {
28-
throw new Error('Enable the AdminDirectory Advanced Service.');
28+
throw new Error("Enable the AdminDirectory Advanced Service.");
2929
}
3030
const response = AdminDirectory.Users.list(optionalArgs);
3131
const users = response.users;
3232
if (!users || users.length === 0) {
33-
console.log('No users found.');
33+
console.log("No users found.");
3434
return;
3535
}
3636
// Print the list of user's full name and email
37-
console.log('Users:');
37+
console.log("Users:");
3838
for (const user of users) {
3939
if (user.primaryEmail) {
4040
if (user.name?.fullName) {
41-
console.log('%s (%s)', user.primaryEmail, user.name.fullName);
41+
console.log("%s (%s)", user.primaryEmail, user.name.fullName);
4242
} else {
43-
console.log('%s', user.primaryEmail);
43+
console.log("%s", user.primaryEmail);
4444
}
4545
}
4646
}

adminSDK/reports/quickstart.gs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,38 @@
1919
* @see https://developers.google.com/admin-sdk/reports/reference/rest/v1/activities/list
2020
*/
2121
function listLogins() {
22-
const userKey = 'all';
23-
const applicationName = 'login';
22+
const userKey = "all";
23+
const applicationName = "login";
2424
const optionalArgs = {
25-
maxResults: 10
25+
maxResults: 10,
2626
};
2727
if (!AdminReports || !AdminReports.Activities) {
28-
throw new Error('Enable the AdminReports Advanced Service.');
28+
throw new Error("Enable the AdminReports Advanced Service.");
2929
}
3030
const response = AdminReports.Activities.list(
31-
userKey, applicationName, optionalArgs);
31+
userKey,
32+
applicationName,
33+
optionalArgs,
34+
);
3235
const activities = response.items;
3336
if (!activities || activities.length === 0) {
34-
console.log('No logins found.');
37+
console.log("No logins found.");
3538
return;
3639
}
3740
// Print login events
38-
console.log('Logins:');
41+
console.log("Logins:");
3942
for (const activity of activities) {
40-
if (activity.id?.time && activity.actor?.email && activity.events?.[0]?.name) {
41-
console.log('%s: %s (%s)', activity.id.time, activity.actor.email,
42-
activity.events[0].name);
43+
if (
44+
activity.id?.time &&
45+
activity.actor?.email &&
46+
activity.events?.[0]?.name
47+
) {
48+
console.log(
49+
"%s: %s (%s)",
50+
activity.id.time,
51+
activity.actor.email,
52+
activity.events[0].name,
53+
);
4354
}
4455
}
4556
}

adminSDK/reseller/quickstart.gs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,29 @@
2020
*/
2121
function listSubscriptions() {
2222
const optionalArgs = {
23-
maxResults: 10
23+
maxResults: 10,
2424
};
2525
if (!AdminReseller || !AdminReseller.Subscriptions) {
26-
throw new Error('Enable the AdminReseller Advanced Service.');
26+
throw new Error("Enable the AdminReseller Advanced Service.");
2727
}
2828
const response = AdminReseller.Subscriptions.list(optionalArgs);
2929
const subscriptions = response.subscriptions;
3030
if (!subscriptions || subscriptions.length === 0) {
31-
console.log('No subscriptions found.');
31+
console.log("No subscriptions found.");
3232
return;
3333
}
34-
console.log('Subscriptions:');
34+
console.log("Subscriptions:");
3535
for (const subscription of subscriptions) {
3636
if (subscription.customerId && subscription.skuId) {
3737
if (subscription.plan?.planName) {
38-
console.log('%s (%s, %s)', subscription.customerId, subscription.skuId,
39-
subscription.plan.planName);
38+
console.log(
39+
"%s (%s, %s)",
40+
subscription.customerId,
41+
subscription.skuId,
42+
subscription.plan.planName,
43+
);
4044
} else {
41-
console.log('%s (%s)', subscription.customerId, subscription.skuId);
45+
console.log("%s (%s)", subscription.customerId, subscription.skuId);
4246
}
4347
}
4448
}

0 commit comments

Comments
 (0)