Skip to content

Conversation

@hemanta212
Copy link
Contributor

@hemanta212 hemanta212 commented Jan 12, 2026

Overview

Run scaf generate from project root to discover and generate code for all packages.

What Changed

Core Features

  • Multi-package discovery: Walks project tree using gocodewalker (respects .gitignore)
  • File merging: Multiple .scaf files in same directory merge into single scaf.go/scaf_test.go
  • Same-package imports: Detected and skipped during merge (functions already available)
  • Config discovery: Walks up from cwd to find .scaf.yaml, schema resolved relative to config

Architecture (Layer Separation)

Layer Change
module/merge.go MergePackageFiles() - import dedup, duplicate fn detection
language/go/package.go InferPackageName() via go/build.ImportDir ladder
language/language.go Added InferPackageName to Language interface
cmd/scaf/generate.go Orchestration only, no direct golang import
cmd/scaf/config.go Extracted loadConfigWithDir for shared use
analysis/rules.go Same-package-import warning rule for LSP

Key Deviations from Original Plan

  1. Language interface extended: Added InferPackageName(dir) to Language interface so cmd doesn't couple to language/go
  2. Keyword detection: Uses go/token.Lookup().IsKeyword() instead of hardcoded map
  3. Config shared: Both generate and test commands use same config discovery (walks up from cwd)
  4. generate vs test semantics: generate merges files (Go package constraint), test uses module resolution (runtime imports)

Package Name Inference (Go)

// 1. go/build.ImportDir (respects build tags)
// 2. parser.PackageClauseOnly on any .go file  
// 3. SanitizePackageName(folder) + keyword warning

Testing

cd example/repro-multi-package
scaf generate  # discovers internal/users/*.scaf, merges, generates

@rlch
Copy link
Owner

rlch commented Jan 12, 2026

LGTM

@hemanta212 hemanta212 force-pushed the feat/multi-package-support branch from b22cf17 to a4bf1c6 Compare January 13, 2026 09:15
hemanta212 and others added 6 commits January 13, 2026 15:01
- example/repro-multi-package/: demonstrates file overwrite and same-package import issues
- .plans/multi-package-support.prd: detailed implementation with pseudocode and file citations

Refs: T-019b9974-f6d1-72b9-878a-58d488781789
Amp-Thread-ID: https://ampcode.com/threads/T-019bb083-728f-70ce-9a30-5cdd1c2a1409
Co-authored-by: Amp <amp@ampcode.com>
- Add module/merge.go with MergePackageFiles() for merging same-dir .scaf files
  - Import deduplication by resolved path
  - Same-package import detection with warnings
  - Duplicate function detection with errors
  - Setup/teardown conflict detection

- Add language/go/package.go with InferPackageName() using stdlib ladder
  - go/build.ImportDir (respects build tags)
  - parser.ParseFile with PackageClauseOnly (catches hidden files)
  - SanitizePackageName fallback (folder name)

- Refactor cmd/scaf/generate.go for go-generate style flow
  - Config discovery walks up from cwd to find .scaf.yaml
  - Schema loaded relative to config location
  - Uses gocodewalker for fast .gitignore-aware directory traversal
  - Groups .scaf files by directory, merges each package
- Add same-package-import rule to analysis/rules.go for LSP diagnostics
- Extract loadConfigWithDir to cmd/scaf/config.go for shared use
- Update test.go to use shared config discovery (walks up from cwd)
- Consolidate MergePackageFiles API to use ParsedFile struct
- Fix same-package imports to be skipped entirely (not just warned)
- Remove redundant MergePackageFilesWithPaths wrapper

Amp-Thread-ID: https://ampcode.com/threads/T-019bb66a-8528-772c-9c6a-8d6ece466737
Co-authored-by: Amp <amp@ampcode.com>
@hemanta212 hemanta212 force-pushed the feat/multi-package-support branch from a4bf1c6 to a217b7d Compare January 13, 2026 09:16
@hemanta212 hemanta212 force-pushed the feat/multi-package-support branch from a217b7d to 3abdbe6 Compare January 13, 2026 09:19
- Add InferPackageName to Language interface
- Add PackageName and AdapterName to GenerateContext
- Move Go-specific logic (binding lookup, package inference) into GoLanguage.Generate()
- Remove direct golang import from cmd/scaf/generate.go
- Use go/token.Lookup for keyword detection instead of hardcoded map
- Add warning when folder name is a Go keyword (e.g., func -> funcpkg)
- Clean up comments and remove gocodewalker references from docs
@hemanta212 hemanta212 force-pushed the feat/multi-package-support branch from d478c98 to 6123de3 Compare January 13, 2026 10:14
Setup and teardown clauses are only used by 'scaf test' for runtime
execution against a real database. The 'scaf generate' command only
uses Functions (-> scaf.go) and Scopes (-> scaf_test.go mocks).

Erroring on conflicting setup/teardown was blocking valid multi-file
packages where each file has its own test fixtures.
Same-package imports (e.g., import "./fixtures") are valid for
'scaf test' runtime resolution but redundant for 'scaf generate'.
Removed the warning as it was noisy and implied user error when
the scaf file was correctly written for testing.
@hemanta212 hemanta212 marked this pull request as ready for review January 13, 2026 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants