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
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ gh auth switch --user OsscJpDevInfra # 異なる場合は切り替え
| 内容 | 読む文書 |
|---|---|
| **コーディング規約(全領域共通)** | [`CODING.md`](root/programs/CODING.md) |
| **設定ファイルの扱い(全領域共通)** | [`Configuration.md`](root/programs/Configuration.md) |
| **設定ファイルの扱い(全領域共通)** | [`CONFIGURATION.md`](root/programs/CONFIGURATION.md) |
| `root/programs/CS/Frameworks/` の分析 | [`Frameworks/ANALYSIS.md`](root/programs/CS/Frameworks/ANALYSIS.md) |
| `root/programs/CS/Samples/` の分析 | [`Samples/ANALYSIS.md`](root/programs/CS/Samples/ANALYSIS.md) |
| `root/programs/CS/Samples4NetCore/` の分析 | [`Samples4NetCore/ANALYSIS.md`](root/programs/CS/Samples4NetCore/ANALYSIS.md) |

**設定ファイルに「仕組み」を書き足したくなったら、[`Configuration.md`](root/programs/Configuration.md)
**設定ファイルに「仕組み」を書き足したくなったら、[`CONFIGURATION.md`](root/programs/CONFIGURATION.md)
に書く。** 設定ファイルは 86 個あり、一部にだけ詳しい説明があると、
**書かれていないファイルを「該当しない」と誤読させる。**
値の隣に書くのは「そのキーが何か」までにする(分担は同書 0 節)。
Expand Down
97 changes: 88 additions & 9 deletions root/programs/0_RunAll.ps1
Original file line number Diff line number Diff line change
@@ -1,29 +1,69 @@
# --- 引数 ---
# Lang : 対象の言語。CS(既定)/ VB / Both。1 と 3 にそのまま渡す。
# Lang : 対象の言語。CS(既定)/ VB / Both。1 と 3 にそのまま渡す。
# IgnoreErrors : 既知のエラーとして合否判定から外す正規表現。1 にだけ渡す。
#
# **既定で ClickOnce の署名エラーを除外する。**(#555)
# WSClientWinCone_sample.csproj は証明書の拇印を直接指定しているため、
# その証明書が無い環境では必ず失敗する(BUILDING.md 4 節)。
# 既定で除外しないと、**「NG が 1 本ある」が常態になり、本物の失敗と見分けが付かない。**
#
# 除外したものは 1_BuildAll.ps1 が件数と内容を別枠で表示するので、黙って消えはしない。
# 除外せずに回したいときは -IgnoreErrors @() を渡す。
[CmdletBinding()]
param(
[ValidateSet("CS", "VB", "Both")]
[string]$Lang = "CS"
[string]$Lang = "CS",
[string[]]$IgnoreErrors = @('error MSB(3482|3325|3321):.*WSClientWinCone_sample\.csproj')
)

# --- 処理部:他のps1ファイルを順次実行 ---
# --- 処理部 ---
# 1 → 2 → 3 を順に実行する。**その前に、設定ファイルの突き合わせを警告として行う**(#553)。
# ※ ダブル クリック起動でもカレント ディレクトリに依存しないよう $PSScriptRoot を使う。
# ※ 順序は固定(RELEASE.md 3 節)。1 のクリーンとアセンブリ配置が 2・3 の前提になる。
#
# UseLang = $true のものにだけ -Lang を渡す。
# 2_RunAllTests.ps1 に渡さないのは、VB 側にテスト プロジェクトが無く(#542)、
# 単体テストが CS の Frameworks\Tests に集約されているため。
#
# UseIgnore = $true のものにだけ -IgnoreErrors を渡す。
# 受け取るのは 1_BuildAll.ps1 だけである(2 と 3 は同名の引数を持たない)。

# まとめの整形。Format-Table は 5.1 で全角の桁を数えないため、自前で揃える。
. (Join-Path $PSScriptRoot "SummaryTable.ps1")

$scripts = @(
@{ Name = "1_BuildAll.ps1"; UseLang = $true }
@{ Name = "2_RunAllTests.ps1"; UseLang = $false }
@{ Name = "3_SmokeTest.ps1"; UseLang = $true }
@{ Name = "1_BuildAll.ps1"; UseLang = $true; UseIgnore = $true }
@{ Name = "2_RunAllTests.ps1"; UseLang = $false; UseIgnore = $false }
@{ Name = "3_SmokeTest.ps1"; UseLang = $true; UseIgnore = $false }
)
$results = @()

# --- 設定ファイルの突き合わせ(警告のみ)---(#553)
#
# **合否には影響させない。** CS / VB の設定の差は、ビルドや疎通とは別の観点である。
# ここで終了コードを汚すと、0_RunAll.ps1 の結果をそのまま合否として読めなくなる(#555)。
#
# 一覧は出さない(25 行が毎回流れると、本来の検証ログが読みにくくなる)。
# **異常があったときだけ「見に行け」と伝える。**
#
# -Lang に関わらず常に行う。比較は本質的に CS ↔ VB であり、片方だけを回すときにも意味がある。
function Test-ConfigSync
{
# **6>$null が要る。** Write-Host はパイプラインに流れないので、
# | Out-Null では一覧を抑止できない(PowerShell 5.0 以降は情報ストリーム)。
& (Join-Path $PSScriptRoot "CompareConfig.ps1") -Check 6>$null | Out-Null
return ($LASTEXITCODE -eq 0)
}

$configOk = Test-ConfigSync
if (-not $configOk)
{
Write-Host ""
Write-Host "【警告】設定ファイルに想定外の差分があります。" -ForegroundColor Yellow
Write-Host " .\CompareConfig.ps1 -Check で内容を確認してください。"
Write-Host ""
}

foreach ($s in $scripts)
{
# -Lang VB では単体テストの対象が無いので飛ばす。
Expand All @@ -36,10 +76,31 @@ foreach ($s in $scripts)
}

$splat = @{}
if ($s.UseLang) { $splat.Lang = $Lang }
if ($s.UseLang) { $splat.Lang = $Lang }
if ($s.UseIgnore) { $splat.IgnoreErrors = $IgnoreErrors }

& (Join-Path $PSScriptRoot $s.Name) @splat
$results += [pscustomobject]@{ スクリプト = $s.Name; 終了コード = $LASTEXITCODE }

# --- bindingRedirect の突き合わせ(警告のみ)---(#556)
#
# **ビルドの直後に行う。** 見るのは「そのプロジェクトが配布するアセンブリ」なので、
# ビルド前だと材料が無く「判定不能」ばかりになる。
# 設定ファイルどうしを比べる CompareConfig.ps1(先頭で実行)とは、そこが違う。
if ($s.Name -eq "1_BuildAll.ps1")
{
# 6>$null で一覧を抑止する(上と同じ理由)。
& (Join-Path $PSScriptRoot "CompareRedirect.ps1") -Check 6>$null | Out-Null
$redirectOk = ($LASTEXITCODE -eq 0)

if (-not $redirectOk)
{
Write-Host ""
Write-Host "【警告】bindingRedirect が、配布されないアセンブリの版を指しています。" -ForegroundColor Yellow
Write-Host " .\CompareRedirect.ps1 -Check で内容を確認してください。"
Write-Host ""
}
}
}

# --- 結果のまとめ ---
Expand All @@ -49,8 +110,10 @@ Write-Host ""
Write-SummaryTable $results
Write-Host ""

# 1_BuildAll.ps1 は既知の署名エラー(MSB3482)で 1 になることがある。
# 終了コードだけで判断せず、エラー一覧の内容を確認すること(RELEASE.md 3 節)。
# **終了コードをそのまま合否として読んでよい。**(#555)
# 既知の署名エラー(MSB3482)は -IgnoreErrors の既定値で除外しているため、
# 1_BuildAll.ps1 が 1 を返したら、それは**別の理由**である。
# 除外した内容は 1_BuildAll.ps1 のサマリに別枠で出るので、そちらも目は通すこと。
#
# 「対象外」は飛ばした印であって失敗ではないので、NG に数えない。
$ng = @($results | Where-Object { $_.終了コード -ne 0 -and $_.終了コード -ne "対象外" })
Expand All @@ -63,5 +126,21 @@ else
Write-Host ("{0} 本が 0 以外で終了しました。上のログを確認してください。" -f $ng.Count) -ForegroundColor Yellow
}

# 警告は、ここにも出す。
# **通しは長い。途中の警告は流れて見落とされる。**
if (-not $configOk)
{
Write-Host ""
Write-Host "【警告】設定ファイルに想定外の差分があります(CompareConfig.ps1 -Check)。" -ForegroundColor Yellow
Write-Host " 合否には数えていません。CONFIGURATION.md 11 節を参照。"
}

if ($null -ne $redirectOk -and -not $redirectOk)
{
Write-Host ""
Write-Host "【警告】bindingRedirect が、配布されないアセンブリの版を指しています" -ForegroundColor Yellow
Write-Host " (CompareRedirect.ps1 -Check)。合否には数えていません。"
}

# --- 画面を残すための処理 ---
Read-Host "`nEnterキーを押すとウィンドウを閉じます"
25 changes: 15 additions & 10 deletions root/programs/1_BuildAll.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ if ([Console]::OutputEncoding.CodePage -ne 65001)
# SkipIfDone : 同じ実行内で同じバッチが既に走っていれば飛ばす(-Lang Both 用)
$stepsCS = @(
# --- net48 : 基盤 ---
@{ Name = "Clean (net48 基盤)"; Bat = "1_DeleteDir.bat"; Clean = $true }
@{ Name = "Clean files (net48 基盤)"; Bat = "1_DeleteFile.bat"; Clean = $true }
@{ Name = "Clean (net48 基盤)"; Bat = "1_DeleteDir.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Clean files (net48 基盤)"; Bat = "1_DeleteFile.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "NuGet (net48)"; Bat = "2_Build_NuGet_net48.bat" }
@{ Name = "Business (net48)"; Bat = "3_Build_Business_net48.bat" }
@{ Name = "Business.RichClient (net48)"; Bat = "3_Build_BusinessRichClient_net48.bat" }

# --- netcore100 : 基盤 ---
@{ Name = "Clean (core 基盤)"; Bat = "1_DeleteDir.bat"; Clean = $true }
@{ Name = "Clean files (core 基盤)"; Bat = "1_DeleteFile.bat"; Clean = $true }
@{ Name = "Clean (core 基盤)"; Bat = "1_DeleteDir.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Clean files (core 基盤)"; Bat = "1_DeleteFile.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "NuGet (netcore100)"; Bat = "2_Build_NuGet_netcore100.bat" }
@{ Name = "Business (netcore100)"; Bat = "3_Build_Business_netcore100.bat" }
@{ Name = "Business.RichClient (core)"; Bat = "3_Build_BusinessRichClient_netcore100.bat" }
Expand All @@ -142,8 +142,8 @@ $stepsCS = @(
@{ Name = "CopyAssemblies"; Bat = "4_Build_CopyAssemblies.bat" }

# --- net48 : ツールとサンプル ---
@{ Name = "Clean (net48 サンプル)"; Bat = "1_DeleteDir.bat"; Clean = $true }
@{ Name = "Clean files (net48 サンプル)"; Bat = "1_DeleteFile.bat"; Clean = $true }
@{ Name = "Clean (net48 サンプル)"; Bat = "1_DeleteDir.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Clean files (net48 サンプル)"; Bat = "1_DeleteFile.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Framework_Tool (net48)"; Bat = "4_Build_Framework_Tool.bat" }
@{ Name = "2CS_sample (net48)"; Bat = "5_Build_2CS_sample.bat" }
@{ Name = "Bat_sample (net48)"; Bat = "5_Build_Bat_sample.bat" }
Expand All @@ -154,8 +154,8 @@ $stepsCS = @(
@{ Name = "WebApp_sample (net48)"; Bat = "10_Build_WebApp_sample.bat" }

# --- netcore100 : ツールとサンプル ---
@{ Name = "Clean (core サンプル)"; Bat = "1_DeleteDir.bat"; Clean = $true }
@{ Name = "Clean files (core サンプル)"; Bat = "1_DeleteFile.bat"; Clean = $true }
@{ Name = "Clean (core サンプル)"; Bat = "1_DeleteDir.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Clean files (core サンプル)"; Bat = "1_DeleteFile.bat"; Clean = $true; SkipIfDone = $true }
@{ Name = "Framework_ToolCore"; Bat = "4_Build_Framework_ToolCore.bat" }
@{ Name = "2CSCore_sample"; Bat = "5_Build_2CSCore_sample.bat" }
@{ Name = "BatCore_sample"; Bat = "5_Build_BatCore_sample.bat" }
Expand Down Expand Up @@ -296,8 +296,13 @@ $allKnown = New-Object System.Collections.Generic.List[string]
$total = [Diagnostics.Stopwatch]::StartNew()

# 実行済みのバッチ("フォルダ\バッチ名")。SkipIfDone の判定に使う。
# ※ 1_DeleteDir.bat のように意図して繰り返すステップがあるため、
#   一律の重複排除はしない。SkipIfDone を付けたものだけを対象にする。
# ※ 一律の重複排除はしない。SkipIfDone を付けたものだけを対象にする。
#
# **Clean は区画ごとに置いてあるが、実際に走るのは最初の 1 回だけ。**(#557)
# 1_DeleteDir.bat は bin を含めてカレント配下から再帰的に消すため、
# 2 回目以降は**直前の区画でビルドした成果物を消してしまう。**
# 通しは元々クリーン ビルドなので、最初の 1 回で足りる。
# 区画の区切りとしての表示は「実行済み」として残す(黙って消さない)。
$executed = @{}

foreach ($s in $steps)
Expand Down
71 changes: 71 additions & 0 deletions root/programs/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -850,3 +850,74 @@ VB の `.vbproj` は `Microsoft.Data.SqlClient` などを `PackageReference` で

**ビルドの成否では気付けない。** 疎通確認(`3_SmokeTest.ps1 -Lang VB`)で初めて分かる。
実際、#533 で「VB の全ビルドが通る」ことを確認した後も、この不具合は残っていた。

---

## 11. 参照とパッケージを洗うとき(#554)

`packages.config` と `<Reference>` は**ビルドの入力**である。
実行時の設定(`app.config` / `appsettings.json`)とは別なので、本書で扱う。

### 「参照が無い=不要」ではない

`packages.config` の id を `csproj` の `<Reference>` と突き合わせると、
**8 プロジェクトで 48 件が「未参照」に見える。うち 44 件は消してはいけない。**

| 種類 | 件数 | csproj に出るか |
|---|---|---|
| **サテライト**(`Xxx.ja`) | 25 | **出なくて正常**。`bin\ja\` に置かれるだけで、参照は本体が持つ |
| **コンテンツ**(bootstrap / jQuery / Modernizr 等) | 19 | **出なくて正常**。`Scripts\` `Content\` に展開されるだけ |
| **アセンブリで、どこからも参照されない** | 4 | 不要 |

判定のしかたは次の通り。

- サテライト : **`.ja` を取った id が、同じ `packages.config` に在るか**
- コンテンツ : **展開物が実在するか**(`Content/bootstrap.css` `Scripts/jquery-*.js` 等)
- **メタ パッケージ**(`Microsoft.AspNet.WebApi` 等)は `packages\<id>.<ver>\` に
`lib` を持たない。**中身が nupkg と EULA だけなら、それはメタである**

### アセンブリ名がソースに出てこなくても、使われている

`<Reference>` 側も同じで、**アセンブリ名で grep しても当たらないが必要**なものがある。

| アセンブリ | 実際は | どこで分かるか |
|---|---|---|
| `System.Web.Http.WebHost` | `GlobalConfiguration` を提供する | `Global.asax.cs` の `GlobalConfiguration.Configuration` |
| `Microsoft.ScriptManager.MSAjax` / `.WebForms` | `<asp:ScriptManager>` が使う | `.master` / `.aspx` |
| `System.Web.Razor` ほか 18 件 | **他のパッケージが要求する間接依存** | `.nuspec` の `<dependency>` |

**名前空間とアセンブリ名は一致しない。** `System.Web.Http.WebHost` が提供する型は
`System.Web.Http.GlobalConfiguration` で、ソースには `System.Web.Http` としか出ない。

> **`.nuspec` は展開されない。**
> `packages\<id>.<ver>\` に在るのは `.nupkg`(ZIP)だけで、`.nuspec` はその中にしか無い。
> 間接依存を調べるなら ZIP を開くこと。
>
> **`packages` フォルダはプロジェクト直下とは限らない。**
> ソリューション階層に在ることが多く、`HintPath` が `..\packages\...` になっている。

### 通しビルドの対象外は、消してはいけない

**消せるかどうかは「壊れていないことを確かめられるか」で決まる。**

`DamDB2` の `IBM.Data.DB2.Entity` は、Entity Framework の痕跡が無く候補に見える。
だが **`DamDB2` はどの `.sln` にも、どの `.bat` にも入っていない。**
消しても `0_RunAll.ps1` は何も言わないので、**判断の材料が得られない。**

`CS/NuGet/proj` 配下を `CompareRedirect.ps1` の対象から外したのと同じ理屈である(#557)。

### 手順

```powershell
# 1. 参照の実体を確かめる(packages が復元されている必要がある)
.\1_BuildAll.ps1

# 2. 消す。csproj / vbproj には触らず、packages.config の行だけを消す
# メタ パッケージは lib を持たないので、読まれるアセンブリは変わらない

# 3. 差分の行数を必ず見る。設定ファイルの編集は壊しやすい
git diff --numstat

# 4. 検証する
.\0_RunAll.ps1 -Lang Both
```
10 changes: 6 additions & 4 deletions root/programs/CHEATSHEET.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ cd root\programs

**既定は C# 側。VB 側は `-Lang` で回す**(3 節)。

- **`-IgnoreErrors` を付けないと `MSB3482` で NG になる。** ClickOnce の署名で、
証明書が無い環境では必ず出る([`BUILDING.md`](BUILDING.md) 4 節)。
**`0_RunAll.ps1` はこれを渡さない**ので、`1_BuildAll.ps1` が `1` を返すことがある。
終了コードだけで判断せず、エラー一覧の内容を見ること
- **`1_BuildAll.ps1` を単体で回すときは `-IgnoreErrors` を付ける。**
ClickOnce の署名(`MSB3482`)で、証明書が無い環境では必ず出る
([`BUILDING.md`](BUILDING.md) 4 節)。
**`0_RunAll.ps1` は既定でこれを渡すので、付けなくてよい**(#555)。
除外した内容は件数つきで別枠に出るため、そちらは目を通すこと
- `2_RunAllTests.ps1` は `Result*.txt` を書き換える。**差分 0 なら中身は同じ**
- 前提(DB・サービス・IIS Express)は [`RELEASE.md`](RELEASE.md) 2 節

Expand Down Expand Up @@ -186,6 +187,7 @@ powershell.exe -NoProfile -Command "Set-Location 'root\programs'; .\3_SmokeTest.
| `'xxx' is not recognized` が大量に出る | bat の非 ASCII とコード ページ | ASCII 化。[`CODING.md`](CODING.md) 4 節 |
| `MSB4226`(`Microsoft.WebApplication.targets`) | nuget が別製品の MSBuild を拾った | `nuget.exe restore ... %NUGET_MSBUILD%` |
| ビルドは通るのに `DllNotFoundException`(`...SNI...`) | `nuget restore` を呼んでおらず、ネイティブ DLL が出力に入らない | 該当 sln に restore を足す。[`BUILDING.md`](BUILDING.md) 10 節 |
| `packages.config` の id が `csproj` に無い=不要に見える | サテライト(`.ja`)とコンテンツ パッケージは**出なくて正常**(48 件中 44 件) | 消す前に [`BUILDING.md`](BUILDING.md) 11 節 |

**NuGet パッケージ作成の落とし穴は
[`CS/NuGet/README.md`](CS/NuGet/README.md) 9 節**にまとめてある。
Expand Down
Loading