Adopt declscope, and align the file boundaries with the units - #24
Merged
Merged
Conversation
ファイル単位のスコープを静的に検査する。設定は declscope 自身が自分に 課しているものと同じで、qualify は ondemand、exported は true。 既存の違反 170 件は baseline に記録した。新しい違反だけが報告される。 baseline は編集せず再生成するもので、直した分は再生成時に消える。 版は 0.2.0 に固定する。
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #24 +/- ##
=======================================
Coverage 82.90% 82.90%
=======================================
Files 35 38 +3
Lines 1685 1685
=======================================
Hits 1397 1397
Misses 288 288
🚀 New features to boost your workflow:
|
e2e の boundary 違反 5 件(setupTestDB / loadConfig / createHandler / createMutationHandler / decodeJSON)はすべて common_test.go 発で、全テスト ファイルから使われる意図的な共有部品。ファイル全体が共有ヘルパ置き場なので、 宣言ごとではなくファイルレベルの //declscope:package 1 つで宣言した。 e2e はテスト専用名前空間しか持たないため qualify は発動せず、これで declscope ./e2e/ は 0 件(naming の追加違反が出ないことも実測済み)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
パッケージ内の宣言はすべて app.go にあり(drivers_*.go はビルドタグ用の import シム)、commands.App / commands.MakeApp / commands.Version として パッケージ名で読まれる公開 API。接頭辞を付けると commands.AppVersion の ように吃るうえ、Version は goreleaser の ldflags (-X ...commands.Version) が名前で参照するため改名できない。よって qualify 6 件は改名ではなく core 指定で解消した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
db.go(Connect と接続ライフサイクル)はパッケージ名そのものの単位なので core にした。statements.go の qualify 5 件は db.QueryOne / db.Exec のように パッケージ名で読まれる API で、"statements" を名前に含めると db.StatementsQueryOne と吃る。名前空間はファイル名から来るため、宣言は 一切改名せずファイルを凝集単位で分割した: - query.go: QueryOne / QueryMany("query" を自然に含む) - exec.go: Exec / ExecResult - bind.go: BindParams("bind" を自然に含む) 分割後 declscope ./internal/db/ は 0 件、go test も通過を実測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
config.go(Config と Parse)と types.go(config.Query 等の公開語彙)は どちらもパッケージ名で読まれる API で、接頭辞は config.TypesQuery のように 吃るため core にした。errors.go は Parse の検証エラーを整形する私的な 下請けなので core に入れず、次のように直した: - errors.go → error.go に改名。単数形なら findMockSourceError / errorWithPath / collectErrors など大半の宣言が語頭一致(右端自由)で 名前空間を運ぶ。 - 運ばない宣言は自然な語順で改名: formatPath → formatErrorPath、 getParentPath → parentErrorPath、isMockPath → isMockErrorPath、 findTypeValue → findTypeValueInErrors、isNumeric → isErrorPathIndex (数値判定の実態は「エラーパス中の配列インデックスか」)など。 - objectSources / arraySources は Mock の排他ソースフィールドを鏡写しに した YAML キー表なので types.go の Mock 隣へ移し、キー表と分かる名前 (objectSourceKeys / isObjectSourceKey 等) にした。error.go からの利用は 判定関数 2 つの //declscope:package で共有を明示。 - config.go からの唯一の入口 formatValidationError も //declscope:package で明示。 core 率は 2/3 ファイル。declscope ./internal/config/ 0 件・テスト通過を実測 (キー表側の directive は surplus 報告が出たため判定関数側だけに絞った)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
qualify 18 件 + boundary 4 件の大半は「Transformer 1 型を transformer.go (コンパイル側)と apply.go(実行側)が分担している」ことに由来する。 両者はパッケージ名の由来である単位そのものなので、両ファイルを core に した。これで CompilePre / PreTransformResult 等の公開 API は無接頭辞の まま、Transformer.program / helpers フィールドの越境も同一名前空間に 収まって消える。 周辺は衛星単位として残した: - timeout.go を新設し JSTimeout / ErrJSTimeout / runWithTimeout を移動。 3 宣言とも "timeout" を自然に含み、watchdog の runWithTimeout は pool と apply の双方から使うため //declscope:package で共有を明示。 - error.go: apply からの入口 parseJSError を //declscope:package で明示、 toHTTPStatus → errorToHTTPStatus に改名。 - global_helpers.go → helpers.go に改名。CompiledHelpers / CompileHelpers が "helpers" を自然に含むため、宣言の改名は不要。 core 率 2/9 ファイル。declscope ./internal/js/ 0 件・テスト通過を実測 (テストファイルが対象ファイルの core 指定に追随することも確認)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
mock.Compile は csv / json / js / filter の各ソース形式ファイルへ振り分ける ディスパッチャで、パッケージ名の単位そのもの。mock.go を core にして Source / Compile / CompileOptions の qualify を解消し(mock.MockCompile と 吃らせない)、Compile が呼ぶ各形式の入口だけを //declscope:package で 明示した: parseCSVOptions / parseCSV(File)WithOptions / compileJS / newJSON / parseJSONString / parseJSONFile / parseJSONL(File) / newJSFilteredSource。 個別の名前も直した: - csv_value.go: parseValue → parseCSVValue(csv.go から使う既定のセル パーサなので共有も明示)、isNumeric → isNumericCSVValue、 parseBool → boolFromCSVValue。いずれも "csvValue" を自然な語順で含む。 - json.go: deepCopy → deepCopyJSON。 - closeQuietly は csv と json の 2 名前空間から使う汎用ユーティリティ なので internal.CloseQuietly として internal パッケージへ昇格した。 - パッケージ doc コメントを csv_value.go から mock.go へ移動。 core 率 1/7 ファイル。declscope 0 件・テスト通過を実測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
executor.go は BaseExecutor を軸にした実行パイプラインでパッケージ名の 単位そのもの。executor.Options / executor.ErrNotFound として読まれる API なので core にして qualify 12 件を解消した。query.go / mutation.go は 既に名前空間を運んでいて無傷。 transform.go は CompileTransforms / CompileMock / CompileTransformOptions というコンパイル入口の集まりなので compile.go に改名し、唯一運ばない Transforms 型を CompiledTransforms に改名した(doc も "holds pre-compiled transforms" でありむしろ正確になる)。 core 率 1/4 ファイル。declscope 0 件・テスト通過を実測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
parser.go は Content-Type を見て form.go / json.go へ振り分ける、 パッケージ名(body parsing)の単位そのもの。core にして body.MaxBodySize / body.Err* / readBody の qualify を解消した。 層をまたぐ入口は //declscope:package で明示: - readBody: 全形式パーサが通るサイズ・charset 検査済みリーダ - parseJSON / parseJSONBytes: Parse からのディスパッチ先 - form.go 側は改名も兼ねる: parseURLEncoded → parseFormURLEncoded、 parseMultipart → parseMultipartForm("form" を自然な語順で含む) parser_test.go の errorReader は core に追随して免除。core 率 1/3。 declscope 0 件・テスト通過を実測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
boundary 22 件の主因は baseHandler 1 型の分担だった: handler.go が汎用 機構を持ち、mutation_handler.go / query_handler.go がそのフィールドを 丸ごと埋めて特殊化する。3 ファイルを //declscope:namespace handler で 1 単位に統合し、フィールド越境をすべて解消した。 - server.go は NewServeMux を持つ組み立て役で core。そこから handler 単位 への入口 4 つ(handlerOptions / createNotFoundHandler / newQueryHandlerWithOptions / newMutationHandlerWithOptions)だけを //declscope:package で明示。 - responder.go は独立単位のまま、handler 側から使う responder 型(と w フィールド)を型への //declscope:package 1 つで共有宣言。 - naming は自然な語順を優先して改名: Executor → HandlerExecutor、ResultProcessor → HandlerResultProcessor、 mutationResultProcessor → mutationHandlerProcessor、 queryResultProcessor → queryHandlerProcessor、 extractPathParams → handlerPathParams、 queryRecord(er) → handledQueryRecord(er)、 marshalOptions → responseMarshalOptions、 validateStatus → validateResponseStatus。 - defaultStatusForPhase / extractNamedParams は baseHandler の判断・処理 そのものなのでメソッド化(レシーバで所属が読めるため naming の対象外)。 - handler/handle(d)、responder/response は語形変化をマッチャが導出できない ため .declscope.yaml の vocabulary に登録した。 core 率 1/5 ファイル。declscope 0 件・テスト通過を実測。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
170 件(boundary 43 / qualify 127)あった違反を構造の修正で 0 件にした ため、baseline は不要になった。最終確認として次を実測: - go build ./... && go test ./... 全通過 - gofmt -l .(go1.27 toolchain の gofmt)が空 - baseline 無しで declscope ./... が exit 0 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012T28FtGHj8psiBJE1btZHR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
declscope holds each declaration to the file that declares it, which is the
privateGo has no word for.No baseline
The first pass recorded 170 violations, 43
boundaryand 127 naming. All of them are gone, and no baseline file is in this PR.Where the boundary entries were
internal/serverbaseHandlerreached from three fileshandlernamespace nowinternal/jsTransformer's compile and apply halvesinternal/mock//declscope:packagee2ecloseQuietlywas used from two namespaces and is nowinternal.CloseQuietly, since it belongs to neither.Files renamed to match what they hold
statements.gobecamequery.go,exec.goandbind.go.transform.gobecamecompile.go, andTransformsbecameCompiledTransforms, which the doc comment already said.errors.gobecameerror.go, because most of its declarations carry the singular.Splitting
statements.gocleared its entries without renaming a single declaration. The file name was the thing that was wrong.Core, and what is left checked
One file per package, except
internal/configwhereconfig.goandtypes.goare both the API anderror.goremains a unit of its own with 16 declarations. No package is entirely core.internal/cli/commandsis the one place where core was the only option:Versionis named by goreleaser's ldflags and cannot be renamed, andcommands.Appis the public entry.Two vocabulary entries
handler: [handle]andresponder: [response]. Both are word-form pairs the matcher cannot derive, which is declscope#64.