Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/cli/src/helpers/core/post-installation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,8 @@ function displayGoInstructions(config: ProjectConfig & { depsInstalled: boolean
if (goLogging && goLogging !== "none") {
const loggingNames: Record<string, string> = {
zap: "Zap",
zerolog: "Zerolog",
slog: "slog",
};
output += `${pc.cyan("•")} Logging: ${loggingNames[goLogging] || goLogging}\n`;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export const router = os.router({
goOrm: GoOrmSchema.optional().describe("Go ORM/database (gorm, sqlc)"),
goApi: GoApiSchema.optional().describe("Go API layer (grpc-go)"),
goCli: GoCliSchema.optional().describe("Go CLI tools (cobra, bubbletea)"),
goLogging: GoLoggingSchema.optional().describe("Go logging (zap)"),
goLogging: GoLoggingSchema.optional().describe("Go logging (zap, zerolog, slog)"),
// AI documentation files
aiDocs: z
.array(AiDocsSchema)
Expand Down
10 changes: 10 additions & 0 deletions apps/cli/src/prompts/go-ecosystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ export async function getGoLoggingChoice(goLogging?: GoLogging) {
label: "Zap",
hint: "Blazing fast, structured, leveled logging in Go",
},
{
value: "zerolog" as const,
label: "Zerolog",
hint: "Zero-allocation JSON logger, fastest in benchmarks",
},
{
value: "slog" as const,
label: "slog",
hint: "Go 1.21+ stdlib structured logging (no external dependency)",
},
{
value: "none" as const,
label: "None",
Expand Down
154 changes: 154 additions & 0 deletions apps/cli/test/__snapshots__/template-snapshots.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12879,6 +12879,36 @@ exports[`Template Snapshots - Go Ecosystem Go File Structure Snapshots file stru
]
`;

exports[`Template Snapshots - Go Ecosystem Go File Structure Snapshots file structure: gin-gorm-zerolog 1`] = `
[
".env.example",
"CLAUDE.md",
"README.md",
"cmd/server/main.go",
"go.mod",
"internal/database/database.go",
"internal/handlers/handlers.go",
"internal/models/models.go",
]
`;

exports[`Template Snapshots - Go Ecosystem Go File Structure Snapshots file structure: echo-sqlc-slog 1`] = `
[
".env.example",
"CLAUDE.md",
"README.md",
"cmd/server/main.go",
"go.mod",
"internal/database/database.go",
"internal/handlers/handlers.go",
"internal/models/models.go",
"sql/queries/posts.sql",
"sql/queries/users.sql",
"sql/schema/001_schema.sql",
"sqlc.yaml",
]
`;

exports[`Template Snapshots - Go Ecosystem Go Key File Content Snapshots key files: gin-gorm-zap 1`] = `
{
"fileCount": 9,
Expand Down Expand Up @@ -13173,6 +13203,130 @@ LOG_LEVEL=debug
}
`;

exports[`Template Snapshots - Go Ecosystem Go Key File Content Snapshots key files: gin-gorm-zerolog 1`] = `
{
"fileCount": 9,
"files": [
{
"content":
"# Application settings
HOST=0.0.0.0
PORT=8080

# Database settings (if using GORM or sqlc)
DATABASE_URL=postgres://user:password@localhost:5432/dbname?sslmode=disable

# gRPC settings (if using gRPC)
GRPC_PORT=50051

# Logging level
LOG_LEVEL=debug
"
,
"path": ".env.example",
},
{
"content": "[exists]",
"path": "CLAUDE.md",
},
{
"content": "[exists]",
"path": "cmd/server/main.go",
},
{
"content": "[exists]",
"path": "go.mod",
},
{
"content": "[exists]",
"path": "internal/database/database.go",
},
{
"content": "[exists]",
"path": "internal/handlers/handlers.go",
},
{
"content": "[exists]",
"path": "internal/models/models.go",
},
{
"content": "[exists]",
"path": "README.md",
},
],
}
`;

exports[`Template Snapshots - Go Ecosystem Go Key File Content Snapshots key files: echo-sqlc-slog 1`] = `
{
"fileCount": 13,
"files": [
{
"content":
"# Application settings
HOST=0.0.0.0
PORT=8080

# Database settings (if using GORM or sqlc)
DATABASE_URL=postgres://user:password@localhost:5432/dbname?sslmode=disable

# gRPC settings (if using gRPC)
GRPC_PORT=50051

# Logging level
LOG_LEVEL=debug
"
,
"path": ".env.example",
},
{
"content": "[exists]",
"path": "CLAUDE.md",
},
{
"content": "[exists]",
"path": "cmd/server/main.go",
},
{
"content": "[exists]",
"path": "go.mod",
},
{
"content": "[exists]",
"path": "internal/database/database.go",
},
{
"content": "[exists]",
"path": "internal/handlers/handlers.go",
},
{
"content": "[exists]",
"path": "internal/models/models.go",
},
{
"content": "[exists]",
"path": "README.md",
},
{
"content": "[exists]",
"path": "sql/queries/posts.sql",
},
{
"content": "[exists]",
"path": "sql/queries/users.sql",
},
{
"content": "[exists]",
"path": "sql/schema/001_schema.sql",
},
{
"content": "[exists]",
"path": "sqlc.yaml",
},
],
}
`;

exports[`Template Snapshots - Python Ecosystem Python File Structure Snapshots file structure: fastapi-sqlalchemy-celery 1`] = `
[
".env.example",
Expand Down
91 changes: 91 additions & 0 deletions apps/cli/test/go-language.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ describe("Go Language Support", () => {

it("should have go logging options", () => {
expect(GO_LOGGINGS).toContain("zap");
expect(GO_LOGGINGS).toContain("zerolog");
expect(GO_LOGGINGS).toContain("slog");
expect(GO_LOGGINGS).toContain("none");
});
});
Expand Down Expand Up @@ -1258,6 +1260,95 @@ describe("Go Language Support", () => {
});
});

describe("Zerolog Logging Integration", () => {
it("should include Zerolog dependencies when selected", async () => {
const result = await createVirtual({
projectName: "go-zerolog-project",
ecosystem: "go",
goWebFramework: "gin",
goOrm: "none",
goApi: "none",
goCli: "none",
goLogging: "zerolog",
});

expect(result.success).toBe(true);
const root = result.tree!.root;

const goModContent = getFileContent(root, "go.mod");
expect(goModContent).toBeDefined();
expect(goModContent).toContain("github.com/rs/zerolog");
});

it("should include Zerolog logger initialization in main.go", async () => {
const result = await createVirtual({
projectName: "go-zerolog-main-check",
ecosystem: "go",
goWebFramework: "gin",
goOrm: "none",
goApi: "none",
goCli: "none",
goLogging: "zerolog",
});

expect(result.success).toBe(true);
const root = result.tree!.root;

const mainContent = getFileContent(root, "cmd/server/main.go");
expect(mainContent).toBeDefined();
expect(mainContent).toContain("github.com/rs/zerolog");
expect(mainContent).toContain("var logger zerolog.Logger");
expect(mainContent).toContain("func initLogger()");
expect(mainContent).toContain("logger.Info()");
});
});

describe("slog Logging Integration", () => {
it("should NOT include external slog dependencies in go.mod", async () => {
const result = await createVirtual({
projectName: "go-stdlib-log-project",
ecosystem: "go",
goWebFramework: "gin",
goOrm: "none",
goApi: "none",
goCli: "none",
goLogging: "slog",
});

expect(result.success).toBe(true);
const root = result.tree!.root;

const goModContent = getFileContent(root, "go.mod");
expect(goModContent).toBeDefined();
// slog is stdlib - should not appear in require block
const requireBlock = goModContent!.split("require (")[1]?.split(")")[0] ?? "";
expect(requireBlock).not.toContain("slog");
});

it("should include slog logger initialization in main.go", async () => {
const result = await createVirtual({
projectName: "go-slog-main-check",
ecosystem: "go",
goWebFramework: "gin",
goOrm: "none",
goApi: "none",
goCli: "none",
goLogging: "slog",
});

expect(result.success).toBe(true);
const root = result.tree!.root;

const mainContent = getFileContent(root, "cmd/server/main.go");
expect(mainContent).toBeDefined();
expect(mainContent).toContain("\"log/slog\"");
expect(mainContent).toContain("var logger *slog.Logger");
expect(mainContent).toContain("func initLogger()");
expect(mainContent).toContain("slog.SetDefault(logger)");
expect(mainContent).toContain("logger.Info(");
});
});

describe("Combined Integration Scenarios", () => {
it("should generate full-stack Go project with Gin + GORM + Zap", async () => {
const result = await createVirtual({
Expand Down
22 changes: 22 additions & 0 deletions apps/cli/test/template-snapshots.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,28 @@ describe("Template Snapshots - Go Ecosystem", () => {
goLogging: "none" as const,
},
},
{
name: "gin-gorm-zerolog",
config: {
ecosystem: "go" as const,
goWebFramework: "gin" as const,
goOrm: "gorm" as const,
goApi: "none" as const,
goCli: "none" as const,
goLogging: "zerolog" as const,
},
},
{
name: "echo-sqlc-slog",
config: {
ecosystem: "go" as const,
goWebFramework: "echo" as const,
goOrm: "sqlc" as const,
goApi: "none" as const,
goCli: "none" as const,
goLogging: "slog" as const,
},
},
];

describe("Go File Structure Snapshots", () => {
Expand Down
16 changes: 16 additions & 0 deletions apps/web/src/lib/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,22 @@ export const TECH_OPTIONS: Record<
color: "from-yellow-500 to-amber-600",
default: true,
},
{
id: "zerolog",
name: "Zerolog",
description: "Zero-allocation JSON logger, fastest in benchmarks",
icon: "",
color: "from-blue-500 to-indigo-600",
default: false,
},
{
id: "slog",
name: "slog",
description: "Go 1.21+ stdlib structured logging, no external dependency",
icon: "",
color: "from-cyan-500 to-teal-600",
default: false,
},
{
id: "none",
name: "No Logging Library",
Expand Down
8 changes: 8 additions & 0 deletions apps/web/src/lib/tech-resource-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,14 @@ const BASE_LINKS: LinkMap = {
docsUrl: "https://pkg.go.dev/go.uber.org/zap",
githubUrl: "https://github.com/uber-go/zap",
},
zerolog: {
docsUrl: "https://pkg.go.dev/github.com/rs/zerolog",
githubUrl: "https://github.com/rs/zerolog",
},
slog: {
docsUrl: "https://pkg.go.dev/log/slog",
githubUrl: "https://github.com/golang/go",
},
};

const CATEGORY_LINKS: LinkMap = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,10 @@ function generateGoReadmeContent(config: ProjectConfig): string {
// Logging
if (goLogging === "zap") {
features.push("- **Zap** - Blazing fast, structured logging");
} else if (goLogging === "zerolog") {
features.push("- **Zerolog** - Zero-allocation JSON logger");
} else if (goLogging === "slog") {
features.push("- **slog** - Go stdlib structured logging");
}

if (auth === "go-better-auth") {
Expand Down
Loading
Loading