@ngxtm/devkit 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +59 -13
- package/cli/rules.js +248 -0
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Cobra CLI
|
|
3
|
+
description: Modern CLI framework used by kubectl, docker, and more.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [golang, cobra, cli, command]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['cmd/**/*.go', '**/root.go']
|
|
8
|
+
keywords: [cobra, Command, RunE, Flags, PersistentFlags]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Cobra CLI Standards
|
|
12
|
+
|
|
13
|
+
## Basic Setup
|
|
14
|
+
|
|
15
|
+
```go
|
|
16
|
+
// cmd/root.go
|
|
17
|
+
package cmd
|
|
18
|
+
|
|
19
|
+
import (
|
|
20
|
+
"os"
|
|
21
|
+
"github.com/spf13/cobra"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
var rootCmd = &cobra.Command{
|
|
25
|
+
Use: "myapp",
|
|
26
|
+
Short: "A brief description",
|
|
27
|
+
Long: `A longer description...`,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func Execute() {
|
|
31
|
+
if err := rootCmd.Execute(); err != nil {
|
|
32
|
+
os.Exit(1)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
func init() {
|
|
37
|
+
rootCmd.PersistentFlags().StringP("config", "c", "", "config file")
|
|
38
|
+
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "verbose output")
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```go
|
|
43
|
+
// main.go
|
|
44
|
+
package main
|
|
45
|
+
|
|
46
|
+
import "myapp/cmd"
|
|
47
|
+
|
|
48
|
+
func main() {
|
|
49
|
+
cmd.Execute()
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Subcommands
|
|
54
|
+
|
|
55
|
+
```go
|
|
56
|
+
// cmd/serve.go
|
|
57
|
+
var serveCmd = &cobra.Command{
|
|
58
|
+
Use: "serve",
|
|
59
|
+
Short: "Start the server",
|
|
60
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
61
|
+
port, _ := cmd.Flags().GetInt("port")
|
|
62
|
+
return startServer(port)
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func init() {
|
|
67
|
+
rootCmd.AddCommand(serveCmd)
|
|
68
|
+
serveCmd.Flags().IntP("port", "p", 8080, "server port")
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// cmd/db.go - nested commands
|
|
72
|
+
var dbCmd = &cobra.Command{
|
|
73
|
+
Use: "db",
|
|
74
|
+
Short: "Database operations",
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var dbMigrateCmd = &cobra.Command{
|
|
78
|
+
Use: "migrate",
|
|
79
|
+
Short: "Run migrations",
|
|
80
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
81
|
+
return runMigrations()
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func init() {
|
|
86
|
+
rootCmd.AddCommand(dbCmd)
|
|
87
|
+
dbCmd.AddCommand(dbMigrateCmd)
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Flags
|
|
92
|
+
|
|
93
|
+
```go
|
|
94
|
+
var cfgFile string
|
|
95
|
+
var verbose bool
|
|
96
|
+
|
|
97
|
+
func init() {
|
|
98
|
+
// Persistent flags (inherited by subcommands)
|
|
99
|
+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
|
|
100
|
+
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose")
|
|
101
|
+
|
|
102
|
+
// Local flags (only for this command)
|
|
103
|
+
serveCmd.Flags().IntP("port", "p", 8080, "port number")
|
|
104
|
+
serveCmd.Flags().StringSlice("hosts", []string{}, "allowed hosts")
|
|
105
|
+
|
|
106
|
+
// Required flags
|
|
107
|
+
serveCmd.MarkFlagRequired("port")
|
|
108
|
+
|
|
109
|
+
// Flag groups
|
|
110
|
+
serveCmd.MarkFlagsRequiredTogether("cert", "key")
|
|
111
|
+
serveCmd.MarkFlagsMutuallyExclusive("json", "yaml")
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Arguments
|
|
116
|
+
|
|
117
|
+
```go
|
|
118
|
+
var echoCmd = &cobra.Command{
|
|
119
|
+
Use: "echo [message]",
|
|
120
|
+
Short: "Echo a message",
|
|
121
|
+
Args: cobra.ExactArgs(1), // Require exactly 1 arg
|
|
122
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
123
|
+
fmt.Println(args[0])
|
|
124
|
+
return nil
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Argument validators
|
|
129
|
+
cobra.NoArgs // No arguments allowed
|
|
130
|
+
cobra.ExactArgs(n) // Exactly n arguments
|
|
131
|
+
cobra.MinimumNArgs(n) // At least n arguments
|
|
132
|
+
cobra.MaximumNArgs(n) // At most n arguments
|
|
133
|
+
cobra.RangeArgs(m, n) // Between m and n arguments
|
|
134
|
+
|
|
135
|
+
// Custom validation
|
|
136
|
+
Args: func(cmd *cobra.Command, args []string) error {
|
|
137
|
+
if len(args) < 1 {
|
|
138
|
+
return errors.New("requires at least one argument")
|
|
139
|
+
}
|
|
140
|
+
return nil
|
|
141
|
+
},
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Viper Integration
|
|
145
|
+
|
|
146
|
+
```go
|
|
147
|
+
import (
|
|
148
|
+
"github.com/spf13/cobra"
|
|
149
|
+
"github.com/spf13/viper"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
func init() {
|
|
153
|
+
cobra.OnInitialize(initConfig)
|
|
154
|
+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
|
|
155
|
+
|
|
156
|
+
// Bind flags to viper
|
|
157
|
+
rootCmd.PersistentFlags().String("database-url", "", "database URL")
|
|
158
|
+
viper.BindPFlag("database.url", rootCmd.PersistentFlags().Lookup("database-url"))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
func initConfig() {
|
|
162
|
+
if cfgFile != "" {
|
|
163
|
+
viper.SetConfigFile(cfgFile)
|
|
164
|
+
} else {
|
|
165
|
+
viper.SetConfigName("config")
|
|
166
|
+
viper.SetConfigType("yaml")
|
|
167
|
+
viper.AddConfigPath(".")
|
|
168
|
+
viper.AddConfigPath("$HOME/.myapp")
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
viper.AutomaticEnv()
|
|
172
|
+
viper.ReadInConfig()
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Pre/Post Hooks
|
|
177
|
+
|
|
178
|
+
```go
|
|
179
|
+
var rootCmd = &cobra.Command{
|
|
180
|
+
Use: "myapp",
|
|
181
|
+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
|
182
|
+
// Runs before any command
|
|
183
|
+
return initLogger()
|
|
184
|
+
},
|
|
185
|
+
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
|
186
|
+
// Runs after any command
|
|
187
|
+
return cleanup()
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
var serveCmd = &cobra.Command{
|
|
192
|
+
Use: "serve",
|
|
193
|
+
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
194
|
+
// Runs before this command only
|
|
195
|
+
return validateConfig()
|
|
196
|
+
},
|
|
197
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
198
|
+
return serve()
|
|
199
|
+
},
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Shell Completions
|
|
204
|
+
|
|
205
|
+
```go
|
|
206
|
+
// Auto-generated completions
|
|
207
|
+
rootCmd.GenBashCompletionFile("completions/myapp.bash")
|
|
208
|
+
rootCmd.GenZshCompletionFile("completions/myapp.zsh")
|
|
209
|
+
rootCmd.GenFishCompletionFile("completions/myapp.fish")
|
|
210
|
+
|
|
211
|
+
// Custom completions
|
|
212
|
+
var userCmd = &cobra.Command{
|
|
213
|
+
Use: "user [username]",
|
|
214
|
+
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
215
|
+
users := fetchUsernames()
|
|
216
|
+
return users, cobra.ShellCompDirectiveNoFileComp
|
|
217
|
+
},
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Best Practices
|
|
222
|
+
|
|
223
|
+
1. **Structure**: One file per command in `cmd/` directory
|
|
224
|
+
2. **Errors**: Use `RunE` and return errors, don't `os.Exit`
|
|
225
|
+
3. **Flags**: Use persistent flags for shared options
|
|
226
|
+
4. **Viper**: Integrate for config file support
|
|
227
|
+
5. **Help**: Write clear Use, Short, and Long descriptions
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Cobra CLI References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Command Patterns**](command-patterns.md) - Commands, flags, subcommands
|
|
6
|
+
|
|
7
|
+
## Quick Checks
|
|
8
|
+
|
|
9
|
+
- [ ] Root command for main entry
|
|
10
|
+
- [ ] Subcommands for features
|
|
11
|
+
- [ ] Persistent flags for global options
|
|
12
|
+
- [ ] PreRun/PostRun hooks
|
|
13
|
+
- [ ] Automatic help generation
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Cobra Command Patterns
|
|
2
|
+
|
|
3
|
+
## Basic Structure
|
|
4
|
+
|
|
5
|
+
```go
|
|
6
|
+
package cmd
|
|
7
|
+
|
|
8
|
+
import (
|
|
9
|
+
"fmt"
|
|
10
|
+
"os"
|
|
11
|
+
"github.com/spf13/cobra"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
var rootCmd = &cobra.Command{
|
|
15
|
+
Use: "myapp",
|
|
16
|
+
Short: "A brief description of your application",
|
|
17
|
+
Long: `A longer description that spans multiple lines
|
|
18
|
+
and likely contains examples and usage of using your application.`,
|
|
19
|
+
Run: func(cmd *cobra.Command, args []string) {
|
|
20
|
+
// Root command logic (or show help)
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
func Execute() {
|
|
25
|
+
if err := rootCmd.Execute(); err != nil {
|
|
26
|
+
fmt.Fprintln(os.Stderr, err)
|
|
27
|
+
os.Exit(1)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func init() {
|
|
32
|
+
// Initialize flags and configuration
|
|
33
|
+
cobra.OnInitialize(initConfig)
|
|
34
|
+
|
|
35
|
+
// Persistent flags (available to this command and all subcommands)
|
|
36
|
+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
|
|
37
|
+
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
|
|
38
|
+
|
|
39
|
+
// Local flags (only for this command)
|
|
40
|
+
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Subcommands
|
|
45
|
+
|
|
46
|
+
```go
|
|
47
|
+
package cmd
|
|
48
|
+
|
|
49
|
+
import (
|
|
50
|
+
"fmt"
|
|
51
|
+
"github.com/spf13/cobra"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
var createCmd = &cobra.Command{
|
|
55
|
+
Use: "create [name]",
|
|
56
|
+
Short: "Create a new resource",
|
|
57
|
+
Long: `Create a new resource with the specified name.`,
|
|
58
|
+
Args: cobra.ExactArgs(1), // Require exactly 1 argument
|
|
59
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
60
|
+
name := args[0]
|
|
61
|
+
|
|
62
|
+
// Get flag values
|
|
63
|
+
dryRun, _ := cmd.Flags().GetBool("dry-run")
|
|
64
|
+
template, _ := cmd.Flags().GetString("template")
|
|
65
|
+
|
|
66
|
+
if dryRun {
|
|
67
|
+
fmt.Printf("Would create: %s\n", name)
|
|
68
|
+
return nil
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return createResource(name, template)
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
func init() {
|
|
76
|
+
rootCmd.AddCommand(createCmd)
|
|
77
|
+
|
|
78
|
+
createCmd.Flags().BoolP("dry-run", "n", false, "Dry run mode")
|
|
79
|
+
createCmd.Flags().StringP("template", "t", "default", "Template to use")
|
|
80
|
+
createCmd.MarkFlagRequired("template")
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Argument Validation
|
|
85
|
+
|
|
86
|
+
```go
|
|
87
|
+
var cmd = &cobra.Command{
|
|
88
|
+
Use: "process [file...]",
|
|
89
|
+
Short: "Process files",
|
|
90
|
+
// Argument validators
|
|
91
|
+
Args: cobra.MinimumNArgs(1), // At least 1
|
|
92
|
+
// Args: cobra.MaximumNArgs(3), // At most 3
|
|
93
|
+
// Args: cobra.ExactArgs(2), // Exactly 2
|
|
94
|
+
// Args: cobra.RangeArgs(1, 3), // 1 to 3
|
|
95
|
+
// Args: cobra.NoArgs, // None allowed
|
|
96
|
+
|
|
97
|
+
// Custom validator
|
|
98
|
+
Args: func(cmd *cobra.Command, args []string) error {
|
|
99
|
+
for _, arg := range args {
|
|
100
|
+
if !isValidFile(arg) {
|
|
101
|
+
return fmt.Errorf("invalid file: %s", arg)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return nil
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
108
|
+
for _, file := range args {
|
|
109
|
+
if err := processFile(file); err != nil {
|
|
110
|
+
return err
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return nil
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Flag Types
|
|
119
|
+
|
|
120
|
+
```go
|
|
121
|
+
var (
|
|
122
|
+
stringFlag string
|
|
123
|
+
intFlag int
|
|
124
|
+
boolFlag bool
|
|
125
|
+
stringSlice []string
|
|
126
|
+
stringToString map[string]string
|
|
127
|
+
durationFlag time.Duration
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
func init() {
|
|
131
|
+
// String
|
|
132
|
+
cmd.Flags().StringVarP(&stringFlag, "name", "n", "default", "Description")
|
|
133
|
+
|
|
134
|
+
// Int
|
|
135
|
+
cmd.Flags().IntVarP(&intFlag, "count", "c", 10, "Number of items")
|
|
136
|
+
|
|
137
|
+
// Bool
|
|
138
|
+
cmd.Flags().BoolVarP(&boolFlag, "verbose", "v", false, "Enable verbose")
|
|
139
|
+
|
|
140
|
+
// String slice (can be specified multiple times)
|
|
141
|
+
cmd.Flags().StringSliceVarP(&stringSlice, "tag", "t", nil, "Tags")
|
|
142
|
+
|
|
143
|
+
// String to string map
|
|
144
|
+
cmd.Flags().StringToStringVar(&stringToString, "label", nil, "Labels (key=value)")
|
|
145
|
+
|
|
146
|
+
// Duration
|
|
147
|
+
cmd.Flags().DurationVar(&durationFlag, "timeout", 30*time.Second, "Timeout")
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Hooks
|
|
152
|
+
|
|
153
|
+
```go
|
|
154
|
+
var cmd = &cobra.Command{
|
|
155
|
+
Use: "deploy",
|
|
156
|
+
|
|
157
|
+
// Runs before Run
|
|
158
|
+
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
159
|
+
return validateConfig()
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Main execution
|
|
163
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
164
|
+
return deploy()
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// Runs after Run (even if Run errors)
|
|
168
|
+
PostRunE: func(cmd *cobra.Command, args []string) error {
|
|
169
|
+
return cleanup()
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// Persistent versions run for all child commands too
|
|
173
|
+
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
174
|
+
initLogging()
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Nested Commands
|
|
180
|
+
|
|
181
|
+
```go
|
|
182
|
+
// rootCmd → userCmd → createUserCmd
|
|
183
|
+
var userCmd = &cobra.Command{
|
|
184
|
+
Use: "user",
|
|
185
|
+
Short: "User management",
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var createUserCmd = &cobra.Command{
|
|
189
|
+
Use: "create [name]",
|
|
190
|
+
Short: "Create a user",
|
|
191
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
192
|
+
return createUser(args[0])
|
|
193
|
+
},
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var listUserCmd = &cobra.Command{
|
|
197
|
+
Use: "list",
|
|
198
|
+
Short: "List users",
|
|
199
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
200
|
+
return listUsers()
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
func init() {
|
|
205
|
+
rootCmd.AddCommand(userCmd)
|
|
206
|
+
userCmd.AddCommand(createUserCmd)
|
|
207
|
+
userCmd.AddCommand(listUserCmd)
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Completions
|
|
212
|
+
|
|
213
|
+
```go
|
|
214
|
+
var cmd = &cobra.Command{
|
|
215
|
+
Use: "set-env [environment]",
|
|
216
|
+
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
217
|
+
return []string{"dev", "staging", "production"}, cobra.ShellCompDirectiveNoFileComp
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Generate completions
|
|
222
|
+
// myapp completion bash > /etc/bash_completion.d/myapp
|
|
223
|
+
// myapp completion zsh > "${fpath[1]}/_myapp"
|
|
224
|
+
```
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Go Core
|
|
3
|
+
description: Go language fundamentals, concurrency, error handling, and project patterns.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [golang, core, language]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['go.mod', '**/*.go']
|
|
8
|
+
keywords: [func, package, import, goroutine, chan]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Go Core Standards
|
|
12
|
+
|
|
13
|
+
## Goroutines & Channels
|
|
14
|
+
|
|
15
|
+
```go
|
|
16
|
+
// Spawn goroutine
|
|
17
|
+
go func() {
|
|
18
|
+
result := process(data)
|
|
19
|
+
resultChan <- result
|
|
20
|
+
}()
|
|
21
|
+
|
|
22
|
+
// Unbuffered channel (synchronous)
|
|
23
|
+
ch := make(chan int)
|
|
24
|
+
|
|
25
|
+
// Buffered channel
|
|
26
|
+
ch := make(chan int, 100)
|
|
27
|
+
|
|
28
|
+
// Send and receive
|
|
29
|
+
ch <- value // Send
|
|
30
|
+
value := <-ch // Receive
|
|
31
|
+
|
|
32
|
+
// Select for multiplexing
|
|
33
|
+
select {
|
|
34
|
+
case msg := <-msgChan:
|
|
35
|
+
handle(msg)
|
|
36
|
+
case <-time.After(5 * time.Second):
|
|
37
|
+
return errors.New("timeout")
|
|
38
|
+
case <-ctx.Done():
|
|
39
|
+
return ctx.Err()
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Patterns**:
|
|
44
|
+
- Worker pools with buffered channels
|
|
45
|
+
- Fan-out/fan-in for parallel processing
|
|
46
|
+
- Done channel for cancellation
|
|
47
|
+
|
|
48
|
+
## Error Handling
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// Return errors, don't panic
|
|
52
|
+
func fetchUser(id int) (*User, error) {
|
|
53
|
+
user, err := db.FindUser(id)
|
|
54
|
+
if err != nil {
|
|
55
|
+
return nil, fmt.Errorf("fetch user %d: %w", id, err)
|
|
56
|
+
}
|
|
57
|
+
return user, nil
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Error wrapping (Go 1.13+)
|
|
61
|
+
if errors.Is(err, sql.ErrNoRows) {
|
|
62
|
+
return nil, ErrNotFound
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Type assertion for custom errors
|
|
66
|
+
var apiErr *APIError
|
|
67
|
+
if errors.As(err, &apiErr) {
|
|
68
|
+
log.Printf("API error: %d", apiErr.Code)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Sentinel errors
|
|
72
|
+
var ErrNotFound = errors.New("not found")
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Rules**:
|
|
76
|
+
- Always check errors immediately
|
|
77
|
+
- Wrap with context: `fmt.Errorf("operation: %w", err)`
|
|
78
|
+
- Use `errors.Is` and `errors.As` for comparison
|
|
79
|
+
- **Never**: `panic` for recoverable errors
|
|
80
|
+
|
|
81
|
+
## Interfaces
|
|
82
|
+
|
|
83
|
+
```go
|
|
84
|
+
// Small interfaces
|
|
85
|
+
type Reader interface {
|
|
86
|
+
Read(p []byte) (n int, err error)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
type Writer interface {
|
|
90
|
+
Write(p []byte) (n int, err error)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Composition
|
|
94
|
+
type ReadWriter interface {
|
|
95
|
+
Reader
|
|
96
|
+
Writer
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Accept interfaces, return structs
|
|
100
|
+
func ProcessData(r Reader) (*Result, error) {
|
|
101
|
+
data, err := io.ReadAll(r)
|
|
102
|
+
// ...
|
|
103
|
+
return &Result{}, nil
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Best Practices**:
|
|
108
|
+
- Define interfaces where used, not where implemented
|
|
109
|
+
- Keep interfaces small (1-3 methods)
|
|
110
|
+
- Use `interface{}` sparingly; prefer generics (Go 1.18+)
|
|
111
|
+
|
|
112
|
+
## Context
|
|
113
|
+
|
|
114
|
+
```go
|
|
115
|
+
// Pass context as first parameter
|
|
116
|
+
func fetchData(ctx context.Context, id int) (*Data, error) {
|
|
117
|
+
// Respect cancellation
|
|
118
|
+
select {
|
|
119
|
+
case <-ctx.Done():
|
|
120
|
+
return nil, ctx.Err()
|
|
121
|
+
default:
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Use context with HTTP requests
|
|
125
|
+
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
|
|
126
|
+
return client.Do(req)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Add timeout
|
|
130
|
+
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
131
|
+
defer cancel()
|
|
132
|
+
|
|
133
|
+
// Add values (use sparingly)
|
|
134
|
+
ctx = context.WithValue(ctx, requestIDKey, reqID)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Rules**:
|
|
138
|
+
- Never store context in structs
|
|
139
|
+
- Always call cancel function (use defer)
|
|
140
|
+
- Use for cancellation, deadlines, request-scoped values only
|
|
141
|
+
|
|
142
|
+
## Project Structure
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
project/
|
|
146
|
+
├── cmd/
|
|
147
|
+
│ └── myapp/
|
|
148
|
+
│ └── main.go # Entry point
|
|
149
|
+
├── internal/ # Private packages
|
|
150
|
+
│ ├── handler/
|
|
151
|
+
│ ├── service/
|
|
152
|
+
│ └── repository/
|
|
153
|
+
├── pkg/ # Public packages
|
|
154
|
+
├── api/ # API definitions (proto, OpenAPI)
|
|
155
|
+
├── configs/
|
|
156
|
+
├── go.mod
|
|
157
|
+
└── go.sum
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Conventions**:
|
|
161
|
+
- `internal/` prevents external imports
|
|
162
|
+
- `cmd/` for multiple entry points
|
|
163
|
+
- Flat structure for small projects
|
|
164
|
+
|
|
165
|
+
## Testing
|
|
166
|
+
|
|
167
|
+
```go
|
|
168
|
+
// Table-driven tests
|
|
169
|
+
func TestAdd(t *testing.T) {
|
|
170
|
+
tests := []struct {
|
|
171
|
+
name string
|
|
172
|
+
a, b int
|
|
173
|
+
expected int
|
|
174
|
+
}{
|
|
175
|
+
{"positive", 1, 2, 3},
|
|
176
|
+
{"negative", -1, -1, -2},
|
|
177
|
+
{"zero", 0, 0, 0},
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for _, tt := range tests {
|
|
181
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
182
|
+
result := Add(tt.a, tt.b)
|
|
183
|
+
if result != tt.expected {
|
|
184
|
+
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Parallel tests
|
|
191
|
+
func TestParallel(t *testing.T) {
|
|
192
|
+
t.Parallel()
|
|
193
|
+
// ...
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Benchmarks
|
|
197
|
+
func BenchmarkProcess(b *testing.B) {
|
|
198
|
+
for i := 0; i < b.N; i++ {
|
|
199
|
+
Process(data)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Performance
|
|
205
|
+
|
|
206
|
+
1. **Preallocate slices**: `make([]T, 0, expectedLen)`
|
|
207
|
+
2. **Avoid allocations**: Reuse buffers, use `sync.Pool`
|
|
208
|
+
3. **Profile first**: `go tool pprof` before optimizing
|
|
209
|
+
4. **Escape analysis**: `go build -gcflags='-m'` to check heap escapes
|
|
210
|
+
5. **String building**: Use `strings.Builder` not `+` concatenation
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Go Core References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Error Handling**](error-handling.md) - Error wrapping, custom errors, sentinel errors
|
|
6
|
+
- [**Concurrency Patterns**](concurrency-patterns.md) - Goroutines, channels, sync primitives
|
|
7
|
+
|
|
8
|
+
## Quick Checks
|
|
9
|
+
|
|
10
|
+
- [ ] Always handle errors explicitly
|
|
11
|
+
- [ ] Use `fmt.Errorf` with `%w` for wrapping
|
|
12
|
+
- [ ] Context for cancellation and timeouts
|
|
13
|
+
- [ ] Prefer channels for communication, mutexes for state
|
|
14
|
+
- [ ] Use `defer` for cleanup
|