guardian-framework 0.1.0
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/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +12958 -0
- package/dist/exports.js +12765 -0
- package/package.json +61 -0
- package/templates/languages/go-patterns.md +411 -0
- package/templates/languages/java-patterns.md +545 -0
- package/templates/languages/python-patterns.md +312 -0
- package/templates/languages/rust-patterns.md +232 -0
- package/templates/languages/typescript-patterns.md +313 -0
- package/templates/pi/INDEX.md +437 -0
- package/templates/pi/agent/AGENTS.md +166 -0
- package/templates/pi/agents/architecture-coordinator.md +40 -0
- package/templates/pi/agents/architecture-validator.md +36 -0
- package/templates/pi/agents/bootstrap-implementer.md +37 -0
- package/templates/pi/agents/issue-factory.md +31 -0
- package/templates/pi/agents/operations-validator.md +32 -0
- package/templates/pi/agents/security-validator.md +33 -0
- package/templates/pi/architecture/CHANGELOG.md +78 -0
- package/templates/pi/architecture/decisions/ADR-template.md +76 -0
- package/templates/pi/architecture/diagrams/system-overview.md +159 -0
- package/templates/pi/architecture/modules/module-template.md +152 -0
- package/templates/pi/context/checklists.md +91 -0
- package/templates/pi/context/domain-workflow.md +180 -0
- package/templates/pi/context/output-formats.md +135 -0
- package/templates/pi/context/patterns-base.md +47 -0
- package/templates/pi/context/patterns.md +38 -0
- package/templates/pi/context/project.md +88 -0
- package/templates/pi/domain/exploration.md +93 -0
- package/templates/pi/domain/ubiquitous-language.md +24 -0
- package/templates/pi/extensions/architect-lib/generators.ts +528 -0
- package/templates/pi/extensions/architect-lib/helpers.ts +344 -0
- package/templates/pi/extensions/architect-lib/types.ts +117 -0
- package/templates/pi/extensions/architect.ts +1425 -0
- package/templates/pi/extensions/ask-user-question.ts +579 -0
- package/templates/pi/extensions/bash-guard.ts +556 -0
- package/templates/pi/extensions/config-reload.ts +115 -0
- package/templates/pi/extensions/coordinator.ts +304 -0
- package/templates/pi/extensions/curator.ts +543 -0
- package/templates/pi/extensions/domain-explorer.ts +990 -0
- package/templates/pi/extensions/filechanges.ts +656 -0
- package/templates/pi/extensions/goal-loop.ts +717 -0
- package/templates/pi/extensions/hooks.ts +452 -0
- package/templates/pi/extensions/kanban.ts +547 -0
- package/templates/pi/extensions/pipeline.ts +1246 -0
- package/templates/pi/extensions/plan-mode.ts +209 -0
- package/templates/pi/extensions/project-scaffolder.ts +284 -0
- package/templates/pi/extensions/read-only-mode.ts +192 -0
- package/templates/pi/extensions/redaction.ts +128 -0
- package/templates/pi/extensions/session-persistence.ts +174 -0
- package/templates/pi/extensions/slash-commands.ts +229 -0
- package/templates/pi/extensions/snippets.ts +201 -0
- package/templates/pi/extensions/validation-runner.ts +100 -0
- package/templates/pi/github/agents/architecture-coordinator.agent.md +27 -0
- package/templates/pi/github/agents/architecture-validator.agent.md +20 -0
- package/templates/pi/github/agents/bootstrap-implementer.agent.md +20 -0
- package/templates/pi/github/agents/epic-planner.agent.md +70 -0
- package/templates/pi/github/agents/issue-factory.agent.md +20 -0
- package/templates/pi/github/agents/operations-validator.agent.md +20 -0
- package/templates/pi/github/agents/security-validator.agent.md +20 -0
- package/templates/pi/github/copilot/settings.json +16 -0
- package/templates/pi/github/copilot-instructions.md +155 -0
- package/templates/pi/github/instructions/architecture.instructions.md +71 -0
- package/templates/pi/github/instructions/validation.instructions.md +69 -0
- package/templates/pi/github/workflows/01-planning-workflow.md +75 -0
- package/templates/pi/github/workflows/02-issue-generation-workflow.md +69 -0
- package/templates/pi/github/workflows/03-implementation-workflow.md +80 -0
- package/templates/pi/github/workflows/04-validation-workflow.md +68 -0
- package/templates/pi/preflight_report.json +99 -0
- package/templates/pi/prompts/blueprint-update.md +262 -0
- package/templates/pi/prompts/blueprint-validate.md +218 -0
- package/templates/pi/prompts/bug-fix.md +50 -0
- package/templates/pi/prompts/ci-blueprint.md +131 -0
- package/templates/pi/prompts/context-refresh.md +258 -0
- package/templates/pi/prompts/epic-plan.md +356 -0
- package/templates/pi/prompts/epic-template.md +186 -0
- package/templates/pi/prompts/feature-development.md +131 -0
- package/templates/pi/prompts/git-issues.md +243 -0
- package/templates/pi/prompts/hotfix.md +71 -0
- package/templates/pi/prompts/issue-closeout.md +342 -0
- package/templates/pi/prompts/issue-draft.md +218 -0
- package/templates/pi/prompts/issue-implementation-series.md +173 -0
- package/templates/pi/prompts/issue-merge.md +372 -0
- package/templates/pi/prompts/issue-template-set.md +392 -0
- package/templates/pi/prompts/issue-template.md +207 -0
- package/templates/pi/prompts/pattern-extract.md +269 -0
- package/templates/pi/prompts/plan-to-issues.md +430 -0
- package/templates/pi/prompts/refactoring.md +82 -0
- package/templates/pi/prompts/scope-analyzer.md +254 -0
- package/templates/pi/prompts/sync-check.md +230 -0
- package/templates/pi/scripts/categorize-issues.sh +171 -0
- package/templates/pi/scripts/ci/check_architecture_conformance.sh +748 -0
- package/templates/pi/scripts/ci/check_planning_packet.py +228 -0
- package/templates/pi/scripts/ci/run_hardening_stages.sh +264 -0
- package/templates/pi/scripts/ci/run_preflight.sh +649 -0
- package/templates/pi/scripts/ci/run_stage.sh +193 -0
- package/templates/pi/scripts/ci/stage_docs_policy.sh +82 -0
- package/templates/pi/scripts/ci/stage_integration.sh +3 -0
- package/templates/pi/scripts/ci/stage_lint.sh +130 -0
- package/templates/pi/scripts/ci/stage_migration_verify.sh +3 -0
- package/templates/pi/scripts/ci/stage_package_build.sh +3 -0
- package/templates/pi/scripts/ci/stage_release_readiness.sh +3 -0
- package/templates/pi/scripts/ci/stage_remaining.sh +242 -0
- package/templates/pi/scripts/ci/stage_security.sh +3 -0
- package/templates/pi/scripts/ci/stage_static_analysis.sh +114 -0
- package/templates/pi/scripts/ci/stage_unit.sh +119 -0
- package/templates/pi/scripts/ci/validate_agent_output.py +181 -0
- package/templates/pi/scripts/ci/validate_agent_output.sh +243 -0
- package/templates/pi/scripts/create-feature-branch.sh +136 -0
- package/templates/pi/scripts/create-mr.sh +117 -0
- package/templates/pi/scripts/fetch-issues.sh +131 -0
- package/templates/pi/scripts/generate-architecture.sh +161 -0
- package/templates/pi/scripts/git/close-epic.sh +69 -0
- package/templates/pi/scripts/git/close-issue.sh +35 -0
- package/templates/pi/scripts/git/create-tracking-issue.sh +174 -0
- package/templates/pi/scripts/git/link-issue-to-epic.sh +51 -0
- package/templates/pi/scripts/git/update-tracking-issue.sh +66 -0
- package/templates/pi/scripts/languages/go/validate-architecture.sh +139 -0
- package/templates/pi/scripts/languages/go/validate-canonical.sh +129 -0
- package/templates/pi/scripts/languages/go/validate-ci.sh +132 -0
- package/templates/pi/scripts/languages/go/validate-integration.sh +156 -0
- package/templates/pi/scripts/languages/go/validate-operations.sh +146 -0
- package/templates/pi/scripts/languages/go/validate-security.sh +135 -0
- package/templates/pi/scripts/languages/go/validate-tests.sh +125 -0
- package/templates/pi/scripts/languages/java/validate-annotations.sh +185 -0
- package/templates/pi/scripts/languages/java/validate-architecture.sh +159 -0
- package/templates/pi/scripts/languages/java/validate-canonical.sh +114 -0
- package/templates/pi/scripts/languages/java/validate-ci.sh +269 -0
- package/templates/pi/scripts/languages/java/validate-integration.sh +149 -0
- package/templates/pi/scripts/languages/java/validate-operations.sh +142 -0
- package/templates/pi/scripts/languages/java/validate-security.sh +174 -0
- package/templates/pi/scripts/languages/java/validate-spring-architecture.sh +227 -0
- package/templates/pi/scripts/languages/java/validate-tests.sh +159 -0
- package/templates/pi/scripts/languages/python/validate-architecture.sh +99 -0
- package/templates/pi/scripts/languages/python/validate-canonical.sh +124 -0
- package/templates/pi/scripts/languages/python/validate-ci.sh +130 -0
- package/templates/pi/scripts/languages/python/validate-integration.sh +119 -0
- package/templates/pi/scripts/languages/python/validate-operations.sh +107 -0
- package/templates/pi/scripts/languages/python/validate-security.sh +68 -0
- package/templates/pi/scripts/languages/python/validate-tests.sh +102 -0
- package/templates/pi/scripts/languages/rust/validate-architecture.sh +188 -0
- package/templates/pi/scripts/languages/rust/validate-canonical.sh +146 -0
- package/templates/pi/scripts/languages/rust/validate-ci.sh +147 -0
- package/templates/pi/scripts/languages/rust/validate-integration.sh +149 -0
- package/templates/pi/scripts/languages/rust/validate-operations.sh +154 -0
- package/templates/pi/scripts/languages/rust/validate-security.sh +153 -0
- package/templates/pi/scripts/languages/rust/validate-tests.sh +150 -0
- package/templates/pi/scripts/languages/typescript/validate-architecture.sh +157 -0
- package/templates/pi/scripts/languages/typescript/validate-canonical.sh +135 -0
- package/templates/pi/scripts/languages/typescript/validate-ci.sh +244 -0
- package/templates/pi/scripts/languages/typescript/validate-integration.sh +166 -0
- package/templates/pi/scripts/languages/typescript/validate-operations.sh +162 -0
- package/templates/pi/scripts/languages/typescript/validate-security.sh +169 -0
- package/templates/pi/scripts/languages/typescript/validate-tests.sh +158 -0
- package/templates/pi/scripts/merge-mr.sh +95 -0
- package/templates/pi/scripts/mr-validation.sh +228 -0
- package/templates/pi/scripts/validate-architecture-readiness.sh +153 -0
- package/templates/pi/scripts/validate-architecture.sh +22 -0
- package/templates/pi/scripts/validate-canonical.sh +22 -0
- package/templates/pi/scripts/validate-ci.sh +37 -0
- package/templates/pi/scripts/validate-integration.sh +22 -0
- package/templates/pi/scripts/validate-operations.sh +22 -0
- package/templates/pi/scripts/validate-security.sh +22 -0
- package/templates/pi/scripts/validate-tests.sh +22 -0
- package/templates/pi/scripts/validate-ubiquitous-language.sh +291 -0
- package/templates/pi/scripts/validation-cache.sh +139 -0
- package/templates/pi/skills/agents/architecture-coordinator.md +178 -0
- package/templates/pi/skills/agents/architecture-generator.md +79 -0
- package/templates/pi/skills/agents/architecture-validator.md +74 -0
- package/templates/pi/skills/agents/ci-mr-validator.md +46 -0
- package/templates/pi/skills/agents/code-developer.md +76 -0
- package/templates/pi/skills/agents/commit.md +46 -0
- package/templates/pi/skills/agents/curator.md +71 -0
- package/templates/pi/skills/agents/debug.md +59 -0
- package/templates/pi/skills/agents/documentation-maintainer.md +36 -0
- package/templates/pi/skills/agents/goal-loop.md +125 -0
- package/templates/pi/skills/agents/hooks.md +122 -0
- package/templates/pi/skills/agents/integration-validator.md +35 -0
- package/templates/pi/skills/agents/issue-creator.md +75 -0
- package/templates/pi/skills/agents/issue-factory.md +143 -0
- package/templates/pi/skills/agents/kanban.md +85 -0
- package/templates/pi/skills/agents/land.md +59 -0
- package/templates/pi/skills/agents/operations-validator.md +43 -0
- package/templates/pi/skills/agents/pipeline.md +113 -0
- package/templates/pi/skills/agents/plan-mode.md +77 -0
- package/templates/pi/skills/agents/pull.md +40 -0
- package/templates/pi/skills/agents/push.md +41 -0
- package/templates/pi/skills/agents/security-validator.md +85 -0
- package/templates/pi/skills/agents/session-persistence.md +119 -0
- package/templates/pi/skills/agents/slash-commands.md +117 -0
- package/templates/pi/skills/agents/snippets.md +99 -0
- package/templates/pi/skills/agents/subagent-registry.md +78 -0
- package/templates/pi/skills/agents/test-validator.md +42 -0
- package/templates/pi/skills/validators/architecture-validator.md +43 -0
- package/templates/pi/skills/validators/ci-validator.md +27 -0
- package/templates/pi/skills/validators/context-compaction.md +73 -0
- package/templates/pi/skills/validators/integration-validator.md +38 -0
- package/templates/pi/skills/validators/model-registry.md +96 -0
- package/templates/pi/skills/validators/operations-validator.md +34 -0
- package/templates/pi/skills/validators/security-guards.md +72 -0
- package/templates/pi/skills/validators/security-validator.md +41 -0
- package/templates/pi/skills/validators/system-prompt-tiers.md +69 -0
- package/templates/pi/skills/validators/test-validator.md +33 -0
- package/templates/pi/types.ts +62 -0
- package/templates/pi/validators/README.md +93 -0
- package/templates/pi/validators/default.toml +209 -0
- package/templates/pi/validators/spring.toml +142 -0
- package/templates/pi/workpad.md +53 -0
- package/templates/project/java/Dockerfile +14 -0
- package/templates/project/java/README.md +40 -0
- package/templates/project/java/pom.xml +132 -0
- package/templates/project/typescript/Dockerfile +15 -0
- package/templates/project/typescript/README.md +29 -0
- package/templates/project/typescript/package.json +23 -0
- package/templates/project/typescript/tsconfig.json +21 -0
- package/templates/workflow.md +123 -0
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "guardian-framework",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Token-optimized agentic framework scaffolder with pi-first architecture",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/exports.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/exports.js",
|
|
10
|
+
"types": "./dist/exports.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"types": "dist/exports.d.ts",
|
|
14
|
+
"bin": {
|
|
15
|
+
"guardian-framework": "./dist/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": ["dist/", "templates/"],
|
|
18
|
+
"engines": {
|
|
19
|
+
"bun": ">=1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "bun build ./src/exports.ts --outfile ./dist/exports.js --target node --format esm && bun build ./src/cli.ts --outfile ./dist/cli.js --target bun --format esm",
|
|
23
|
+
"build:types": "tsc --emitDeclarationOnly --outDir dist || true",
|
|
24
|
+
"prepublishOnly": "bun run build && bun test",
|
|
25
|
+
"test": "bun test",
|
|
26
|
+
"lint": "biome check src tests",
|
|
27
|
+
"format": "biome format . --write",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"dev": "bun run src/cli.ts"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/arman-jalili/guardian-framework"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/arman-jalili/guardian-framework#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/arman-jalili/guardian-framework/issues"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@clack/prompts": "^0.7.0",
|
|
41
|
+
"yaml": "^2.9.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@biomejs/biome": "^1.9.0",
|
|
45
|
+
"@types/bun": "latest",
|
|
46
|
+
"typescript": "^5.0.0"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"cli",
|
|
50
|
+
"agentic",
|
|
51
|
+
"framework",
|
|
52
|
+
"ai",
|
|
53
|
+
"scaffold",
|
|
54
|
+
"pi-first",
|
|
55
|
+
"token-optimized",
|
|
56
|
+
"claude-code",
|
|
57
|
+
"github-copilot"
|
|
58
|
+
],
|
|
59
|
+
"author": "Arman Wolkensteiner-Jalili",
|
|
60
|
+
"license": "MIT"
|
|
61
|
+
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Go Code Patterns
|
|
2
|
+
|
|
3
|
+
> **Purpose:** Reusable Go patterns for Guardian projects.
|
|
4
|
+
> **Generic:** Adapt for your framework (standard library, third-party).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Error Handling
|
|
9
|
+
|
|
10
|
+
```go
|
|
11
|
+
// Custom error types
|
|
12
|
+
type ValidationError struct {
|
|
13
|
+
Field string
|
|
14
|
+
Message string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func (e *ValidationError) Error() string {
|
|
18
|
+
return fmt.Sprintf("validation error on field %s: %s", e.Field, e.Message)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ConfigError struct {
|
|
22
|
+
Reason string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func (e *ConfigError) Error() string {
|
|
26
|
+
return fmt.Sprintf("config error: %s", e.Reason)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Wrapped errors
|
|
30
|
+
func readFile(path string) ([]byte, error) {
|
|
31
|
+
data, err := os.ReadFile(path)
|
|
32
|
+
if err != nil {
|
|
33
|
+
return nil, fmt.Errorf("read file %s: %w", path, err)
|
|
34
|
+
}
|
|
35
|
+
return data, nil
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Error checking
|
|
39
|
+
func process(input string) error {
|
|
40
|
+
result, err := parse(input)
|
|
41
|
+
if err != nil {
|
|
42
|
+
return fmt.Errorf("parse failed: %w", err)
|
|
43
|
+
}
|
|
44
|
+
return nil
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Tracing / Logging
|
|
51
|
+
|
|
52
|
+
```go
|
|
53
|
+
import (
|
|
54
|
+
"log/slog"
|
|
55
|
+
"context"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// Structured logging
|
|
59
|
+
var logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
|
60
|
+
|
|
61
|
+
func processRequest(ctx context.Context, userID string, requestID string) {
|
|
62
|
+
logger.InfoContext(ctx, "Processing request",
|
|
63
|
+
slog.String("user_id", userID),
|
|
64
|
+
slog.String("request_id", requestID),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
result, err := doWork(ctx)
|
|
68
|
+
if err != nil {
|
|
69
|
+
logger.ErrorContext(ctx, "Request failed",
|
|
70
|
+
slog.String("error", err.Error()),
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
logger.InfoContext(ctx, "Request complete",
|
|
76
|
+
slog.Any("result", result),
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Context-aware logging
|
|
81
|
+
func withContext(ctx context.Context) {
|
|
82
|
+
// Add request ID to context
|
|
83
|
+
ctx = context.WithValue(ctx, "request_id", "abc123")
|
|
84
|
+
logger.InfoContext(ctx, "With context")
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Cancellation / Cleanup
|
|
91
|
+
|
|
92
|
+
```go
|
|
93
|
+
import (
|
|
94
|
+
"context"
|
|
95
|
+
"time"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
// Context cancellation
|
|
99
|
+
func longRunningTask(ctx context.Context) error {
|
|
100
|
+
for {
|
|
101
|
+
// Check cancellation
|
|
102
|
+
select {
|
|
103
|
+
case <-ctx.Done():
|
|
104
|
+
log.Println("Task cancelled, cleaning up")
|
|
105
|
+
return ctx.Err()
|
|
106
|
+
default:
|
|
107
|
+
// Do work
|
|
108
|
+
if err := doWork(); err != nil {
|
|
109
|
+
return err
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Sleep with cancellation awareness
|
|
114
|
+
select {
|
|
115
|
+
case <-time.After(1 * time.Second):
|
|
116
|
+
case <-ctx.Done():
|
|
117
|
+
return ctx.Err()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Context with timeout
|
|
123
|
+
func fetchWithTimeout(url string) (*Response, error) {
|
|
124
|
+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
125
|
+
defer cancel()
|
|
126
|
+
|
|
127
|
+
return fetch(ctx, url)
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Atomic Writes
|
|
134
|
+
|
|
135
|
+
```go
|
|
136
|
+
import (
|
|
137
|
+
"os"
|
|
138
|
+
"path/filepath"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
// Write-rename pattern
|
|
142
|
+
func atomicWrite(path string, content []byte) error {
|
|
143
|
+
dir := filepath.Dir(path)
|
|
144
|
+
tempPath := filepath.Join(dir, filepath.Base(path)+".tmp")
|
|
145
|
+
|
|
146
|
+
// Write to temp file
|
|
147
|
+
if err := os.WriteFile(tempPath, content, 0644); err != nil {
|
|
148
|
+
return err
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Atomic rename
|
|
152
|
+
if err := os.Rename(tempPath, path); err != nil {
|
|
153
|
+
os.Remove(tempPath) // Cleanup on failure
|
|
154
|
+
return err
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return nil
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Concurrent Patterns
|
|
164
|
+
|
|
165
|
+
```go
|
|
166
|
+
import (
|
|
167
|
+
"sync"
|
|
168
|
+
"context"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
// WaitGroup for parallel tasks
|
|
172
|
+
func parallelTasks() error {
|
|
173
|
+
var wg sync.WaitGroup
|
|
174
|
+
var err error
|
|
175
|
+
var mu sync.Mutex
|
|
176
|
+
|
|
177
|
+
for i := 0; i < 3; i++ {
|
|
178
|
+
wg.Add(1)
|
|
179
|
+
go func(id int) {
|
|
180
|
+
defer wg.Done()
|
|
181
|
+
if e := task(id); e != nil {
|
|
182
|
+
mu.Lock()
|
|
183
|
+
if err == nil {
|
|
184
|
+
err = e
|
|
185
|
+
}
|
|
186
|
+
mu.Unlock()
|
|
187
|
+
}
|
|
188
|
+
}(i)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
wg.Wait()
|
|
192
|
+
return err
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Semaphore for concurrent limit
|
|
196
|
+
func concurrentLimit(tasks []Task, limit int) error {
|
|
197
|
+
sem := make(chan struct{}, limit)
|
|
198
|
+
var wg sync.WaitGroup
|
|
199
|
+
|
|
200
|
+
for _, task := range tasks {
|
|
201
|
+
wg.Add(1)
|
|
202
|
+
go func(t Task) {
|
|
203
|
+
defer wg.Done()
|
|
204
|
+
sem <- struct{}{} // Acquire
|
|
205
|
+
defer func() { <-sem }() // Release
|
|
206
|
+
|
|
207
|
+
return t.Execute()
|
|
208
|
+
}(task)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
wg.Wait()
|
|
212
|
+
return nil
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Mutex for shared state
|
|
216
|
+
type Cache struct {
|
|
217
|
+
mu sync.RWMutex
|
|
218
|
+
data map[string]string
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
func (c *Cache) Get(key string) (string, bool) {
|
|
222
|
+
c.mu.RLock()
|
|
223
|
+
defer c.mu.RUnlock()
|
|
224
|
+
val, ok := c.data[key]
|
|
225
|
+
return val, ok
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
func (c *Cache) Set(key, value string) {
|
|
229
|
+
c.mu.Lock()
|
|
230
|
+
defer c.mu.Unlock()
|
|
231
|
+
c.data[key] = value
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Testing
|
|
238
|
+
|
|
239
|
+
```go
|
|
240
|
+
// Standard testing
|
|
241
|
+
func TestParse(t *testing.T) {
|
|
242
|
+
result, err := parse("input")
|
|
243
|
+
if err != nil {
|
|
244
|
+
t.Fatalf("parse failed: %v", err)
|
|
245
|
+
}
|
|
246
|
+
if !result.OK {
|
|
247
|
+
t.Errorf("expected OK, got false")
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Table-driven tests
|
|
252
|
+
func TestValidation(t *testing.T) {
|
|
253
|
+
tests := []struct {
|
|
254
|
+
name string
|
|
255
|
+
input string
|
|
256
|
+
wantErr bool
|
|
257
|
+
}{
|
|
258
|
+
{"valid", "valid input", false},
|
|
259
|
+
{"empty", "", true},
|
|
260
|
+
{"invalid", "bad data", true},
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
for _, tt := range tests {
|
|
264
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
265
|
+
err := validate(tt.input)
|
|
266
|
+
if tt.wantErr && err == nil {
|
|
267
|
+
t.Errorf("expected error, got nil")
|
|
268
|
+
}
|
|
269
|
+
if !tt.wantErr && err != nil {
|
|
270
|
+
t.Errorf("unexpected error: %v", err)
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Mocking interfaces
|
|
277
|
+
type Fetcher interface {
|
|
278
|
+
Fetch(url string) (*Response, error)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
type MockFetcher struct {
|
|
282
|
+
Response *Response
|
|
283
|
+
Error error
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
func (m *MockFetcher) Fetch(url string) (*Response, error) {
|
|
287
|
+
return m.Response, m.Error
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
func TestWithMock(t *testing.T) {
|
|
291
|
+
mock := &MockFetcher{Response: &Response{Data: "mock"}}
|
|
292
|
+
result := useFetcher(mock)
|
|
293
|
+
// ...
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Anti-Patterns (NEVER DO)
|
|
300
|
+
|
|
301
|
+
```go
|
|
302
|
+
// ❌ Ignoring errors
|
|
303
|
+
data, _ := os.ReadFile("file") // BAD
|
|
304
|
+
|
|
305
|
+
// ✅ Always handle errors
|
|
306
|
+
data, err := os.ReadFile("file")
|
|
307
|
+
if err != nil {
|
|
308
|
+
return fmt.Errorf("read file: %w", err)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ❌ Panic for errors
|
|
312
|
+
func bad() {
|
|
313
|
+
if err != nil {
|
|
314
|
+
panic(err) // BAD
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ✅ Return errors
|
|
319
|
+
func good() error {
|
|
320
|
+
if err != nil {
|
|
321
|
+
return fmt.Errorf("operation failed: %w", err)
|
|
322
|
+
}
|
|
323
|
+
return nil
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ❌ Global mutable state
|
|
327
|
+
var config = map[string]string{} // BAD
|
|
328
|
+
|
|
329
|
+
// ✅ Encapsulated state
|
|
330
|
+
type Config struct {
|
|
331
|
+
data map[string]string
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
func NewConfig() *Config {
|
|
335
|
+
return &Config{data: make(map[string]string)}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ❌ Goroutine leaks
|
|
339
|
+
func bad() {
|
|
340
|
+
go func() {
|
|
341
|
+
for {
|
|
342
|
+
doWork() // BAD - never stops
|
|
343
|
+
}
|
|
344
|
+
}()
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ✅ Cancellable goroutine
|
|
348
|
+
func good(ctx context.Context) {
|
|
349
|
+
go func() {
|
|
350
|
+
for {
|
|
351
|
+
select {
|
|
352
|
+
case <-ctx.Done():
|
|
353
|
+
return
|
|
354
|
+
default:
|
|
355
|
+
doWork()
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}()
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Build Commands
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Build
|
|
368
|
+
go build ./...
|
|
369
|
+
|
|
370
|
+
# Build binary
|
|
371
|
+
go build -o bin/app ./cmd/app
|
|
372
|
+
|
|
373
|
+
# Test
|
|
374
|
+
go test ./...
|
|
375
|
+
|
|
376
|
+
# Test with coverage
|
|
377
|
+
go test -cover ./...
|
|
378
|
+
|
|
379
|
+
# Test verbose
|
|
380
|
+
go test -v ./...
|
|
381
|
+
|
|
382
|
+
# Lint
|
|
383
|
+
golangci-lint run
|
|
384
|
+
|
|
385
|
+
# Format
|
|
386
|
+
go fmt ./...
|
|
387
|
+
|
|
388
|
+
# Vet
|
|
389
|
+
go vet ./...
|
|
390
|
+
|
|
391
|
+
# Security audit (gosec)
|
|
392
|
+
gosec ./...
|
|
393
|
+
|
|
394
|
+
# Mod tidy
|
|
395
|
+
go mod tidy
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Dependencies
|
|
401
|
+
|
|
402
|
+
```go
|
|
403
|
+
// go.mod
|
|
404
|
+
module github.com/your/project
|
|
405
|
+
|
|
406
|
+
go 1.21
|
|
407
|
+
|
|
408
|
+
require (
|
|
409
|
+
// Standard patterns - no heavy dependencies
|
|
410
|
+
)
|
|
411
|
+
```
|