Aggiungi docs-as-code: indice Diátaxis, nuovi doc e controllo automatico
Nuovi doc: tutorial-primo-giro, risoluzione-problemi, sviluppo, rilascio, glossario e registro delle decisioni (docs/decisioni, 6 ADR). docs/README.md e' l'indice per categoria e la tabella delle fonti uniche; il README di root rimanda a sviluppo/rilascio invece di duplicarli. scripts/CheckDocs.cs verifica link e ancore, <Version> contro CHANGELOG, copertura di architettura.md e presenza di ogni doc nell'indice; .markdownlint-cli2.jsonc configura il lint Markdown. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5fac2edf52
commit
ccfa00ff52
19 files changed
+557
-86
No files matched your search
@@ -0,0 +1,15 @@
|
||||
{
|
||||
// Regole base; disattivate quelle che non servono a prosa italiana con tabelle larghe
|
||||
"config": {
|
||||
"default": true,
|
||||
"MD013": false, // lunghezza riga
|
||||
"MD033": false, // HTML inline
|
||||
"MD024": { "siblings_only": true }, // CHANGELOG ripete "Aggiunto/Modificato"
|
||||
"MD036": false,
|
||||
"MD040": false, // dump esadecimali/testuali senza linguaggio
|
||||
"MD060": false, // stile colonne tabelle
|
||||
"MD041": false
|
||||
},
|
||||
"globs": ["**/*.md"],
|
||||
"ignores": ["node_modules", "raw", "step", "**/bin", "**/obj"]
|
||||
}
|
||||
@@ -5,6 +5,17 @@ Tutte le modifiche rilevanti di questo progetto sono documentate in questo file.
|
||||
Il formato segue [Keep a Changelog](https://keepachangelog.com/it/1.1.0/), e il progetto
|
||||
aderisce a [Semantic Versioning](https://semver.org/lang/it/).
|
||||
|
||||
## [Non rilasciato]
|
||||
|
||||
### Aggiunto
|
||||
|
||||
- Docs-as-code: `scripts/CheckDocs.cs`, markdownlint, `docs/README.md` (indice Diátaxis e fonte unica).
|
||||
- Nuovi doc: `tutorial-primo-giro`, `risoluzione-problemi`, `sviluppo`, `rilascio`, `glossario` e registro delle decisioni `docs/decisioni/` (6 ADR).
|
||||
|
||||
### Modificato
|
||||
|
||||
- Il README rimanda a `docs/sviluppo.md` e `docs/rilascio.md` per build, test e setup, invece di duplicarli.
|
||||
|
||||
## [1.0.0] - 2026-09-23
|
||||
|
||||
Prima versione distribuita agli utenti tramite setup di installazione.
|
||||
|
||||
@@ -63,8 +63,14 @@ Dove scrivere cosa:
|
||||
| [`docs/formato-asm.md`](docs/formato-asm.md) | euristica testuale di fallback |
|
||||
| [`docs/db-cad-index.md`](docs/db-cad-index.md) | schema e vista di `cad_index.db` |
|
||||
| [`docs/copia-raw-parallela.md`](docs/copia-raw-parallela.md) | parallelizzazione della copia in `raw/` |
|
||||
| [`docs/README.md`](docs/README.md) | indice Diátaxis di tutti i doc (tutorial, how-to, reference, decisioni) e regola di fonte unica |
|
||||
| [`CHANGELOG.md`](CHANGELOG.md) | storico delle versioni (formato Keep a Changelog); ogni release che cambia `<Version>` nel csproj aggiunge qui la sua voce |
|
||||
|
||||
I doc sono trattati come codice: stanno in git e si verificano con
|
||||
`dotnet run scripts/CheckDocs.cs` (link, versione/CHANGELOG, copertura di `architettura.md`) e
|
||||
`npx markdownlint-cli2` (config `.markdownlint-cli2.jsonc`) — da lanciare prima di ogni commit che
|
||||
tocca i doc. Organizzazione (Diátaxis) e regola di fonte unica: [`docs/README.md`](docs/README.md).
|
||||
|
||||
Quando il cambiamento nasce da un fallimento reale di Creo, scrivere anche **il sintomo**: i
|
||||
messaggi di Creo non nominano il file o la causa, e senza quel ponte la prossima volta si
|
||||
riparte da zero (i §7.3/§7.4/§7.5 di `formato-asm-record.md` sono l'esempio del formato
|
||||
|
||||
@@ -40,7 +40,8 @@ passaggio, non lo sostituisce.
|
||||
manuale, fuori da quest'app): scrive in `step/`, dentro la cartella di
|
||||
lavoro.
|
||||
|
||||
Guida utente passo-passo completa in [`docs/guida-utente.md`](docs/guida-utente.md)
|
||||
Primo uso: [`docs/tutorial-primo-giro.md`](docs/tutorial-primo-giro.md). Guida utente completa in
|
||||
[`docs/guida-utente.md`](docs/guida-utente.md)
|
||||
(stessa sintesi anche in-app da **Aiuto → Guida**, F1).
|
||||
|
||||
## Requisiti
|
||||
@@ -50,83 +51,20 @@ Guida utente passo-passo completa in [`docs/guida-utente.md`](docs/guida-utente.
|
||||
- Accesso alla share di rete con i file CAD (`X:\` di default) per
|
||||
l'indicizzazione
|
||||
|
||||
## Build
|
||||
## Build, test e rilascio
|
||||
|
||||
```powershell
|
||||
cd PrepStep
|
||||
dotnet build -c Release
|
||||
```
|
||||
Build, avvio e test: [`docs/sviluppo.md`](docs/sviluppo.md). Pubblicazione dell'eseguibile e
|
||||
generazione del setup di installazione: [`docs/rilascio.md`](docs/rilascio.md).
|
||||
|
||||
## Avvio
|
||||
|
||||
Da sorgente:
|
||||
|
||||
```powershell
|
||||
cd PrepStep
|
||||
dotnet run -c Release
|
||||
```
|
||||
|
||||
Oppure l'eseguibile già compilato:
|
||||
|
||||
```powershell
|
||||
cd PrepStep\bin\Release\net10.0-windows
|
||||
.\PrepStep.exe
|
||||
```
|
||||
|
||||
## Pubblicazione (eseguibile standalone)
|
||||
|
||||
Genera un `.exe` self-contained per Windows x64, senza bisogno del runtime
|
||||
.NET installato sulla macchina di destinazione:
|
||||
|
||||
```powershell
|
||||
cd PrepStep
|
||||
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish
|
||||
```
|
||||
|
||||
L'eseguibile risultante è in `PrepStep\publish\PrepStep.exe` — un unico
|
||||
file, si copia e si lancia su un'altra macchina Windows senza bisogno di .NET
|
||||
installato.
|
||||
|
||||
## Setup di installazione
|
||||
|
||||
Per distribuire l'app agli utenti si genera un setup con
|
||||
[Inno Setup 6](https://jrsoftware.org/isinfo.php).
|
||||
|
||||
Una volta sola, per installare Inno Setup (per l'utente corrente, senza admin):
|
||||
|
||||
```powershell
|
||||
winget install --id JRSoftware.InnoSetup -e --scope user
|
||||
```
|
||||
|
||||
A ogni release, dalla root del repo:
|
||||
|
||||
```powershell
|
||||
# 1. aggiorna <Version> in PrepStep\PrepStep.csproj e la voce in CHANGELOG.md
|
||||
# 2. chiudi l'app se è aperta (l'exe in uso blocca la build)
|
||||
dotnet publish PrepStep -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o PrepStep\publish
|
||||
& "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe" installer\PrepStep.iss
|
||||
```
|
||||
|
||||
Produce `installer\Output\PrepStep-Setup-<versione>.exe` (versione letta dall'exe, cioè
|
||||
`<Version>` del csproj): è l'unico file da distribuire. Per provarlo sul proprio PC basta
|
||||
lanciarlo (`.\installer\Output\PrepStep-Setup-<versione>.exe`). Il setup:
|
||||
|
||||
- installa **solo per l'utente corrente**, in `%LOCALAPPDATA%\Programs\PrepStep`, senza
|
||||
chiedere i diritti di amministratore;
|
||||
- crea nel menu Start i collegamenti al programma e al disinstallatore (quello sul desktop
|
||||
è facoltativo);
|
||||
- compare in "Impostazioni → App installate", da cui si disinstalla.
|
||||
|
||||
Se l'app è già installata, il setup chiede prima cosa fare: **Sì** aggiorna/reinstalla (DB e
|
||||
impostazioni restano), **No** disinstalla, **Annulla** esce. Installazione silenziosa (aggiorna
|
||||
senza chiedere) — es. per distribuirla da script:
|
||||
`PrepStep-Setup-<versione>.exe /VERYSILENT /SUPPRESSMSGBOXES`.
|
||||
Il setup installa **solo per l'utente corrente**, in `%LOCALAPPDATA%\Programs\PrepStep`, senza
|
||||
diritti di amministratore; si disinstalla da "Impostazioni → App installate".
|
||||
|
||||
## Struttura del progetto
|
||||
|
||||
Il codice dell'app è tutto in `PrepStep/` (GUI e indicizzazione integrate); accanto ci sono
|
||||
il progetto di test `PrepStep.Tests/`, gli script standalone `scripts/` e lo script del setup
|
||||
`installer/`. Mappa file-per-file completa in [`docs/architettura.md`](docs/architettura.md).
|
||||
`installer/`. Mappa file-per-file completa in [`docs/architettura.md`](docs/architettura.md); indice di tutti i doc in
|
||||
[`docs/README.md`](docs/README.md).
|
||||
|
||||
- `Program.cs` — entry point.
|
||||
- `Form1.cs` — finestra principale, wizard a 5 fasi e menu; UI costruita interamente in
|
||||
@@ -145,18 +83,7 @@ Il database generato (`cad_index.db`), i file Excel/CSV della distinta
|
||||
trascinati nella root e le cartelle `raw/`/`step/` sono rigenerabili e non
|
||||
sono tracciati in git (vedi `.gitignore`).
|
||||
|
||||
## Test
|
||||
|
||||
`PrepStep.Tests/` (xUnit) contiene unit test (lettore esatto e euristica di
|
||||
estrazione dei componenti dai `.asm`, parsing del nome file Pro-E, import della
|
||||
distinta) e integration test (scansione su disco, schema/vista SQL reale con focus
|
||||
sui bug di case-sensitivity/duplicati già risolti, pipeline end-to-end). Da
|
||||
eseguire:
|
||||
|
||||
```powershell
|
||||
cd PrepStep.Tests
|
||||
dotnet test
|
||||
```
|
||||
Per i test vedi [`docs/sviluppo.md`](docs/sviluppo.md#test).
|
||||
|
||||
## Licenza
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Documentazione di PrepStep
|
||||
|
||||
Indice dei doc, organizzati secondo [Diátaxis](https://diataxis.fr/): ogni file ha **uno** scopo,
|
||||
e cambia solo quando cambia il programma.
|
||||
|
||||
## Tutorial — imparare facendo
|
||||
|
||||
- [`tutorial-primo-giro.md`](tutorial-primo-giro.md) — il primo giro completo con una distinta vera.
|
||||
|
||||
## How-to — svolgere un compito
|
||||
|
||||
- [`guida-utente.md`](guida-utente.md) — i passi dell'utente fino a Creo Distributed Batch.
|
||||
- [`risoluzione-problemi.md`](risoluzione-problemi.md) — sintomo → causa → cosa fare.
|
||||
- [`sviluppo.md`](sviluppo.md) — build, test, script e regole per scrivere i doc.
|
||||
- [`rilascio.md`](rilascio.md) — pubblicare e generare il setup di una nuova versione.
|
||||
|
||||
## Reference — consultare
|
||||
|
||||
- [`architettura.md`](architettura.md) — il processo delle 5 fasi e la mappa file-per-file.
|
||||
- [`db-cad-index.md`](db-cad-index.md) — schema, vista e query di `cad_index.db`.
|
||||
- [`formato-asm-record.md`](formato-asm-record.md) — parser esatto dei record `.asm`, casi limite (§7).
|
||||
- [`formato-asm.md`](formato-asm.md) — euristica testuale di fallback.
|
||||
- [`glossario.md`](glossario.md) — i termini usati nei doc e nell'app.
|
||||
- [`../CHANGELOG.md`](../CHANGELOG.md) — storico delle versioni.
|
||||
|
||||
## Explanation — capire il perché
|
||||
|
||||
- [`decisioni/`](decisioni/README.md) — registro delle scelte di progetto (ADR).
|
||||
- [`copia-raw-parallela.md`](copia-raw-parallela.md) — perché e come la copia in `raw/` è parallela.
|
||||
|
||||
## Fonte unica (SSOT)
|
||||
|
||||
Ogni informazione vive in **un** posto; altrove si mette un link, non una copia.
|
||||
|
||||
| Informazione | Fonte |
|
||||
|---|---|
|
||||
| Versione e nome prodotto | `PrepStep/PrepStep.csproj` (`<Version>`, `<Product>`) |
|
||||
| Schema e vista del DB | [`db-cad-index.md`](db-cad-index.md) |
|
||||
| Formato dei record `.asm` e casi limite | [`formato-asm-record.md`](formato-asm-record.md) |
|
||||
| Processo delle 5 fasi, mappa dei file | [`architettura.md`](architettura.md) |
|
||||
| Passi dell'utente | [`guida-utente.md`](guida-utente.md) |
|
||||
| Build, test, regole sui doc | [`sviluppo.md`](sviluppo.md) |
|
||||
| Procedura di rilascio e setup | [`rilascio.md`](rilascio.md) |
|
||||
| Perché una scelta è fatta così | [`decisioni/`](decisioni/README.md) |
|
||||
| Storico release | [`../CHANGELOG.md`](../CHANGELOG.md) |
|
||||
|
||||
`CLAUDE.md` e `README.md` riassumono soltanto e rimandano a questi file.
|
||||
|
||||
## Verifica
|
||||
|
||||
```powershell
|
||||
dotnet run scripts/CheckDocs.cs
|
||||
npx markdownlint-cli2
|
||||
```
|
||||
@@ -3,7 +3,7 @@
|
||||
Panoramica di tutti i file sorgente e di come collaborano. `PrepStep` è il nome
|
||||
tecnico del progetto (cartella, namespace, csproj, eseguibile `PrepStep.exe`);
|
||||
**PrepStep - Cevolani** è il nome mostrato all'utente finale (titolo finestra, icona,
|
||||
versione — vedi `<Version>`/`<Product>` in `PrepStep.csproj`). Per il "come si usa" vedi il `README.md` in root; per il
|
||||
versione — vedi `<Version>`/`<Product>` in `PrepStep.csproj`). Per il "come si usa" vedi il `README.md` in root e la [`guida-utente.md`](guida-utente.md); per il
|
||||
formato binario `.asm` vedi `docs/formato-asm.md` (euristica testuale) e
|
||||
`docs/formato-asm-record.md` (parser esatto dei record); per la parallelizzazione della
|
||||
copia in `raw/` vedi `docs/copia-raw-parallela.md`.
|
||||
@@ -282,7 +282,7 @@ l'`UninstallString`), perché Inno da solo aggiornerebbe sempre; con `/VERYSILEN
|
||||
La disinstallazione rimuove solo
|
||||
i file installati: `cad_index.db`, `raw/`/`step/`/CSV creati accanto all'exe e
|
||||
`%AppData%/PrepStep/` restano.
|
||||
Comandi di build del setup nel `README.md`.
|
||||
Comandi di build del setup in [`rilascio.md`](rilascio.md).
|
||||
|
||||
## Script standalone (`scripts/`)
|
||||
|
||||
@@ -301,6 +301,9 @@ dipendenze extra con `#:package Nome@versione` in testa al file):
|
||||
investigare a mano nuovi falsi positivi prima di toccare la regex di
|
||||
`AssemblyComponentScanner`.
|
||||
- **Query.cs** — query SQL ad-hoc contro `cad_index.db` da riga di comando.
|
||||
- **CheckDocs.cs** — controllo dei doc (docs-as-code): link relativi e ancore, `<Version>` del csproj
|
||||
uguale all'ultima voce del `CHANGELOG.md`, ogni `.cs` di `PrepStep/` e `scripts/` descritto qui.
|
||||
Exit 1 se qualcosa non torna.
|
||||
|
||||
> ⚠️ Nota importante di sicurezza: se `dotnet run` viene lanciato dentro `PrepStep/`
|
||||
> (che contiene un `.csproj` di tipo `WinExe`), esegue l'app GUI vera invece dello script
|
||||
@@ -310,7 +313,7 @@ dipendenze extra con `#:package Nome@versione` in testa al file):
|
||||
## Test
|
||||
|
||||
- **PrepStep.Tests/** (xUnit) — riferimento al progetto principale via `ProjectReference`
|
||||
+ `InternalsVisibleTo` (in `PrepStep.csproj`), così i test chiamano direttamente
|
||||
e `InternalsVisibleTo` (in `PrepStep.csproj`), così i test chiamano direttamente
|
||||
`Indexer.ParseFilename` e `AssemblyComponentScanner.EstraiCodiciReferenziati` senza esporli
|
||||
come API pubblica. File: `IndexerParseFilenameTests.cs`, `IndexerScanTests.cs`,
|
||||
`AssemblyComponentScannerTests.cs`, `AsmRecordReaderTests.cs`,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# 0001 — Indice dei file in un DB SQLite locale
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
La share `X:\` contiene centinaia di migliaia di file (ordine di ~200k righe indicizzate).
|
||||
Cercare un codice direttamente sul disco di rete a ogni distinta è lento: il costo è dominato
|
||||
dalla latenza di rete.
|
||||
|
||||
## Decisione
|
||||
|
||||
Scansionare la share una volta in un DB SQLite locale (`cad_index.db`) e interrogare quello.
|
||||
L'aggiornamento è incrementale (confronto su percorso, dimensione e data), la vista
|
||||
`files_ultima_versione` usa `ROW_NUMBER()` e non un self-join con `GROUP BY`.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- Le ricerche sono istantanee e non richiedono la share (la copia sì).
|
||||
- L'indice può essere vecchio: per questo la fase 2 ha "Verifica presenza".
|
||||
- Il DB è rigenerabile, quindi non è tracciato in git.
|
||||
- Schema e criteri di pareggio: [`../db-cad-index.md`](../db-cad-index.md).
|
||||
@@ -0,0 +1,18 @@
|
||||
# 0002 — UI WinForms costruita interamente in codice
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
L'app è un wizard a 5 fasi con stile condiviso (bottoni, card, barre) e stato comune tra fasi.
|
||||
|
||||
## Decisione
|
||||
|
||||
Nessun designer visuale: `Form1.BuildUi` e i `BuildFase*` costruiscono i controlli, `UiStile`
|
||||
centralizza lo stile. `Form1.Designer.cs` resta lo scheletro del template.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- Layout e stile modificabili e rivedibili come codice normale (diff leggibili).
|
||||
- Dimensioni con `AutoSize`+`Padding` invece di pixel fissi, per non tagliare il testo.
|
||||
- `Form1.cs` è grande (~1400 righe) perché contiene wizard e logica delle fasi.
|
||||
@@ -0,0 +1,29 @@
|
||||
# 0003 — Parser esatto dei `.asm` con fallback euristico
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
Il `.asm` Creo è un binario proprietario non documentato. La prima soluzione, un'euristica
|
||||
testuale (`AssemblyComponentScanner`), contava le occorrenze di stringhe candidate e produceva
|
||||
falsi positivi (riferimenti fantasma, componenti soppressi con placement residuo).
|
||||
|
||||
Inoltre la lista dei componenti della distinta **non coincide** con i file necessari a Creo per
|
||||
aprire l'assieme: ne servono di più (soppressi, riferimenti esterni). Se ne manca uno Creo
|
||||
risponde solo `[-4] Dati di input non completi`.
|
||||
|
||||
## Decisione
|
||||
|
||||
Per reverse engineering si è decodificata la struttura a record (`AsmRecordReader`), validata
|
||||
contro BOM esportate da Creo. È il metodo preferito. L'euristica resta come **fallback** quando
|
||||
il parser lancia `InvalidDataException`, perché la validazione copre solo un campione di file.
|
||||
La fase 4 tiene tre liste separate (distinta, soppressi, riferimenti esterni) con regole di
|
||||
ricorsione diverse.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- Estrazione esatta sui file che rispettano il formato; nessun falso positivo da conteggio.
|
||||
- Due implementazioni da mantenere, per ora; l'euristica serve anche a due script.
|
||||
- Ogni caso strano diventa un test minimale costruito byte per byte.
|
||||
- Dettagli: [`../formato-asm-record.md`](../formato-asm-record.md),
|
||||
[`../formato-asm.md`](../formato-asm.md).
|
||||
@@ -0,0 +1,27 @@
|
||||
# 0004 — Setup per-utente con DB nella cartella di installazione
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
Gli utenti non hanno diritti di amministratore. L'app scrive `cad_index.db` e, di default, la
|
||||
cartella di lavoro accanto all'eseguibile. In `C:\Program Files` non sarebbe scrivibile.
|
||||
|
||||
Prima il DB era scelto dall'utente e ricordato in `ultimo_db.txt`: si finiva con DB diversi tra
|
||||
postazioni e ricerche incoerenti.
|
||||
|
||||
## Decisione
|
||||
|
||||
- Setup Inno Setup 6 con `PrivilegesRequired=lowest`: installa in
|
||||
`%LOCALAPPDATA%\Programs\PrepStep`.
|
||||
- Il DB è sempre `cad_index.db` nella cartella di installazione; "Apri DB..." vale solo per la
|
||||
sessione e nulla viene ricordato.
|
||||
- `AppId` fisso per riconoscere gli aggiornamenti; se l'app è già installata il setup chiede se
|
||||
aggiornare o disinstallare.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- Nessun admin necessario; aggiornare non tocca DB e impostazioni.
|
||||
- La disinstallazione lascia DB, `raw/`, `step/`, CSV e `%AppData%\PrepStep\`.
|
||||
- In sviluppo il DB è nella cartella di build ([`../db-cad-index.md`](../db-cad-index.md)).
|
||||
- Procedura: [`../rilascio.md`](../rilascio.md).
|
||||
@@ -0,0 +1,22 @@
|
||||
# 0005 — Scegliere la copia di un componente dalla cartella dell'assieme
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
Per il 13% dei codici esiste più di una copia sulla share, con contenuto diverso e stessa
|
||||
versione. Il `.asm` non registra quale copia usa. Scegliere a caso, o per data, può mettere in
|
||||
`raw/` un modello diverso da quello atteso: Creo lo carica, i vincoli non si risolvono e
|
||||
l'assieme non si apre, con il solito `[-4]`.
|
||||
|
||||
## Decisione
|
||||
|
||||
`ScegliPerCartella` preferisce la copia nella stessa cartella dell'assieme che la referenzia
|
||||
(replica la regola di Creo) e solo in mancanza ripiega su versione più alta e data più recente.
|
||||
Nella vista `files_ultima_versione` il pareggio è deterministico (`data_modifica` e percorso
|
||||
nell'`ORDER BY`), ma serve solo a non sbagliare a caso.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- La fase 4 legge `files` (tutte le copie) e non la vista.
|
||||
- Dettaglio e casi reali: [`../formato-asm-record.md`](../formato-asm-record.md) §7.4.
|
||||
@@ -0,0 +1,21 @@
|
||||
# 0006 — Script standalone che referenziano il progetto principale
|
||||
|
||||
**Stato:** accettata
|
||||
|
||||
## Contesto
|
||||
|
||||
Servono strumenti da riga di comando (BOM, query, analisi di binari) senza duplicare la logica di
|
||||
lettura dei `.asm`.
|
||||
|
||||
## Decisione
|
||||
|
||||
Gli script in `scripts/` sono C# file-based apps (.NET 10) che referenziano
|
||||
`PrepStep/PrepStep.csproj` con `#:project`. La logica vive **solo** nel progetto principale: una
|
||||
sola fonte di verità per GUI e script.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
- Si lanciano dalla root del repo; da dentro `PrepStep/` partirebbe la GUI.
|
||||
- Due famiglie non intercambiabili: euristica + DB (`ExtractCreoStrings`, `BomViaDb`) e parser
|
||||
esatto + cartelle locali (`CreoBom`). Vedi [`../architettura.md`](../architettura.md).
|
||||
- `CheckDocs.cs` segue lo stesso schema per i doc.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Registro delle decisioni
|
||||
|
||||
Perché il programma è fatto così. Ogni voce spiega il contesto, la scelta e le conseguenze, così
|
||||
chi ci rimette mano non rifà il ragionamento da zero. Se cambia una scelta non si riscrive la
|
||||
vecchia voce: se ne aggiunge una nuova che la sostituisce.
|
||||
|
||||
| N. | Decisione | Stato |
|
||||
|---|---|---|
|
||||
| [0001](0001-indice-sqlite-locale.md) | Indice dei file in un DB SQLite locale | accettata |
|
||||
| [0002](0002-ui-winforms-in-codice.md) | UI WinForms costruita interamente in codice | accettata |
|
||||
| [0003](0003-parser-esatto-con-fallback.md) | Parser esatto dei `.asm` con fallback euristico | accettata |
|
||||
| [0004](0004-installazione-per-utente.md) | Setup per-utente con DB nella cartella di installazione | accettata |
|
||||
| [0005](0005-copia-nella-cartella-dell-assieme.md) | Scegliere la copia di un componente dalla cartella dell'assieme | accettata |
|
||||
| [0006](0006-script-che-riusano-il-progetto.md) | Script standalone che referenziano il progetto principale | accettata |
|
||||
@@ -0,0 +1,20 @@
|
||||
# Glossario
|
||||
|
||||
| Termine | Significato |
|
||||
|---|---|
|
||||
| Assieme generale | l'assieme di primo livello di una distinta; il foglio del gestionale non lo elenca, l'app lo aggiunge come riga se il file è `DBP_<codice>_<timestamp>` |
|
||||
| `.asm` / `.prt` | file Creo/Pro-E di assieme e di parte; il nome è `<codice>.<tipo>.<versione>` |
|
||||
| Cartella di lavoro | dove finiscono CSV, `raw/` e `step/`; di default la cartella di installazione |
|
||||
| Codice | identificativo del componente, ricavato dal nome del file (può avere una lettera di revisione attaccata) |
|
||||
| Creo Distributed Batch | strumento PTC che esporta in batch (qui in STEP); usato a mano, fuori dall'app |
|
||||
| Distinta Base (DBP) | estrazione dal gestionale (Fata) dei componenti di un assieme |
|
||||
| Family table | tabella di varianti di un modello; il nome dell'istanza sta nel parametro `ConfigName` |
|
||||
| Indice | il DB `cad_index.db` con i metadati dei file della share |
|
||||
| `members` | sezione del `.asm` con i componenti diretti dell'assieme |
|
||||
| `raw/` | cartella con i file CAD da passare a Creo |
|
||||
| Riferimento esterno | modello citato da un assembly feature o datum copiato; non è un membro, ma Creo lo carica con il suo albero |
|
||||
| Share | disco di rete con i file CAD, `X:\` di default |
|
||||
| Soppresso | componente tolto dalla distinta ma il cui file serve comunque ad aprire l'assieme |
|
||||
| `step/` | cartella degli STEP esportati da Creo; non scritta dall'app |
|
||||
| `temp_*` | cartelle personali della share, escluse dall'indice |
|
||||
| Ultima versione | per ogni `(cartella_radice, codice, tipo_file)` la riga con versione più alta (vista `files_ultima_versione`) |
|
||||
@@ -0,0 +1,47 @@
|
||||
# Rilasciare una nuova versione
|
||||
|
||||
Procedura per produrre il setup `PrepStep-Setup-<versione>.exe`, l'unico file da distribuire.
|
||||
Il comportamento del setup (installazione per-utente, aggiornamento, `/VERYSILENT`) è descritto
|
||||
in [`architettura.md`](architettura.md#installazione); qui ci sono solo i passi da eseguire.
|
||||
|
||||
## Una volta sola
|
||||
|
||||
Installa Inno Setup 6 per l'utente corrente (niente admin):
|
||||
|
||||
```powershell
|
||||
winget install --id JRSoftware.InnoSetup -e --scope user
|
||||
```
|
||||
|
||||
## A ogni release
|
||||
|
||||
1. Aggiorna `<Version>` in `PrepStep/PrepStep.csproj` (SemVer).
|
||||
2. In [`CHANGELOG.md`](../CHANGELOG.md) trasforma "Non rilasciato" nella nuova versione con la
|
||||
data e riscrivi sotto le modifiche (Aggiunto/Modificato/Corretto/Rimosso).
|
||||
3. Controlla i doc: `dotnet run scripts/CheckDocs.cs` deve confermare che versione e CHANGELOG
|
||||
coincidono.
|
||||
4. Esegui i test: `dotnet test` in `PrepStep.Tests/`.
|
||||
5. Chiudi l'app se è aperta (l'exe in uso blocca la build), poi dalla root del repo:
|
||||
|
||||
```powershell
|
||||
dotnet publish PrepStep -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o PrepStep\publish
|
||||
& "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe" installer\PrepStep.iss
|
||||
```
|
||||
|
||||
6. Il setup è in `installer\Output\PrepStep-Setup-<versione>.exe`; la versione è letta
|
||||
dall'exe, quindi coincide con `<Version>`. Provalo lanciandolo.
|
||||
7. Commit con codice, doc e CHANGELOG insieme (regola in [`README.md`](README.md)).
|
||||
|
||||
## Solo l'eseguibile, senza setup
|
||||
|
||||
```powershell
|
||||
cd PrepStep
|
||||
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish
|
||||
```
|
||||
|
||||
Produce `PrepStep\publish\PrepStep.exe`, un file unico che gira su un Windows x64 senza .NET
|
||||
installato.
|
||||
|
||||
## Da non toccare
|
||||
|
||||
`AppGuid` in `installer/PrepStep.iss`: è ciò che fa riconoscere a Windows le versioni nuove
|
||||
come aggiornamento della stessa app. Cambiarlo produce un'installazione doppia.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Risoluzione dei problemi
|
||||
|
||||
Sintomo → causa probabile → cosa fare. I messaggi di Creo non nominano il file né la causa, per
|
||||
questo il sintomo è il punto di partenza.
|
||||
|
||||
## Dentro l'app
|
||||
|
||||
| Sintomo | Causa probabile | Cosa fare |
|
||||
|---|---|---|
|
||||
| Pallino rosso in fase 1, "Database non trovato" | non c'è `cad_index.db` nella cartella di installazione | **Aggiorna indice** (lo crea lì), oppure **Apri DB...** per usarne un altro solo per la sessione |
|
||||
| "Disco non raggiungibile: X:\" | la share non è montata o non hai accesso | monta `X:\` e riprova; la radice è fissa in `Form1.RadiceDiscoDefault` |
|
||||
| Componente rosso in "Verifica presenza" | il codice non è nell'indice: indice vecchio, oppure il nome su disco ha una lettera di revisione in più o in meno | **Aggiorna indice**; poi cerca il codice con `LIKE` (vedi sotto) |
|
||||
| "Avanti" resta grigio in fase 2 | manca il passo **Verifica presenza** | premila: non basta l'import |
|
||||
| Alcuni file non compaiono in `raw/` dopo fase 3/4 | la copia salta in silenzio i file irraggiungibili (share offline, permessi) | controlla l'accesso alla share e ripeti la fase |
|
||||
| In fase 4 compaiono codici "non trovati" | disegni, componenti davvero assenti dalla share o falsi positivi della scansione | controllali a mano; non bloccano il lavoro |
|
||||
| Risultati incoerenti in sviluppo | l'app sta usando il DB della cartella di build, non quello che credi | guarda il percorso mostrato in fase 1; apri il DB giusto con **Apri DB...** |
|
||||
|
||||
Per capire se un codice è nell'indice:
|
||||
|
||||
```powershell
|
||||
dotnet run scripts/Query.cs -- cad_index.db "SELECT codice, tipo_file, percorso_completo FROM files_ultima_versione WHERE codice LIKE '925%' LIMIT 20"
|
||||
```
|
||||
|
||||
Nessuna riga nemmeno con `LIKE` → il file non è indicizzato. Una riga con codice leggermente
|
||||
diverso → revisione, maiuscole o spazi.
|
||||
|
||||
## In Creo Distributed Batch
|
||||
|
||||
| Sintomo | Causa probabile | Cosa fare |
|
||||
|---|---|---|
|
||||
| `[-4] Dati di input non completi` | nell'albero manca un file che Creo deve caricare, ma non dice quale | rifai la fase 4 e leggi l'elenco dei "non trovati"; poi vedi sotto |
|
||||
| L'assieme non si apre, nessun messaggio chiaro | in `raw/` c'è una copia sbagliata di un componente (lo stesso codice esiste in più cartelle, 13% dei casi) | l'app sceglie la copia nella cartella dell'assieme: [`formato-asm-record.md`](formato-asm-record.md) §7.4 |
|
||||
| Assieme con un componente soppresso che non si apre | il file del soppresso non era in `raw/` | §7.3; oggi la fase 4 lo copia |
|
||||
| Assieme con feature di assembly o datum copiati che non si apre | manca il modello citato per riferimento esterno | §7.5; oggi la fase 4 lo copia con il suo albero |
|
||||
|
||||
## Da sviluppatore
|
||||
|
||||
| Sintomo | Causa | Cosa fare |
|
||||
|---|---|---|
|
||||
| `dotnet run` apre la GUI e si blocca | lanciato dentro `PrepStep/` | lanciare gli script dalla root del repo |
|
||||
| `dotnet publish` fallisce con file in uso | l'app è aperta | chiudila e ripeti |
|
||||
| `CheckDocs.cs` segnala un file non descritto | nuovo `.cs` o doc non documentato | aggiungilo a `architettura.md` o a `docs/README.md` |
|
||||
|
||||
## Dopo la disinstallazione
|
||||
|
||||
Restano `cad_index.db`, `raw/`, `step/`, i CSV e `%AppData%\PrepStep\`: vanno cancellati a mano.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Guida per chi sviluppa
|
||||
|
||||
Come lavorare sul codice e sui doc. Per capire com'è fatto il programma parti da
|
||||
[`architettura.md`](architettura.md); per rilasciare vedi [`rilascio.md`](rilascio.md).
|
||||
|
||||
## Requisiti
|
||||
|
||||
- Windows e [.NET 10 SDK](https://dotnet.microsoft.com/download).
|
||||
- Accesso alla share `X:\` solo per indicizzare davvero; i test non ne hanno bisogno.
|
||||
- Node.js (per `npx markdownlint-cli2`, solo per i doc).
|
||||
|
||||
## Build e avvio
|
||||
|
||||
```powershell
|
||||
cd PrepStep
|
||||
dotnet build -c Release
|
||||
dotnet run -c Release
|
||||
```
|
||||
|
||||
In sviluppo `cad_index.db` si cerca nella cartella di build, non nella radice del repo: vedi
|
||||
[`db-cad-index.md`](db-cad-index.md#come-lapp-trova-il-db-allavvio).
|
||||
|
||||
## Test
|
||||
|
||||
```powershell
|
||||
cd PrepStep.Tests
|
||||
dotnet test
|
||||
```
|
||||
|
||||
I test xUnit chiamano gli `internal` del progetto principale grazie a `InternalsVisibleTo`. I
|
||||
`.asm` dei test si costruiscono byte per byte con piccoli helper invece di versionare file
|
||||
binari: ogni caso strano trovato sulla share diventa un test minimale. Elenco dei file di test in
|
||||
[`architettura.md`](architettura.md#test).
|
||||
|
||||
## Script standalone
|
||||
|
||||
Si lanciano dalla **root del repo**, mai da dentro `PrepStep/` (che è un `WinExe`: `dotnet run`
|
||||
avvierebbe la GUI e resterebbe bloccato). Elenco in
|
||||
[`architettura.md`](architettura.md#script-standalone-scripts).
|
||||
|
||||
```powershell
|
||||
dotnet run scripts/Query.cs -- cad_index.db "SELECT COUNT(*) FROM files"
|
||||
```
|
||||
|
||||
## Documentazione come codice
|
||||
|
||||
I doc stanno in git, si modificano nello stesso commit del codice e si verificano a mano:
|
||||
|
||||
```powershell
|
||||
dotnet run scripts/CheckDocs.cs # link, ancore, versione/CHANGELOG, copertura dei doc
|
||||
npx markdownlint-cli2 # stile Markdown (.markdownlint-cli2.jsonc)
|
||||
```
|
||||
|
||||
Regole di scrittura:
|
||||
|
||||
- **Una sola fonte per ogni informazione**, altrove un link (tabella in [`README.md`](README.md)).
|
||||
- **Ogni doc ha un solo scopo** (Diátaxis): non mescolare istruzioni, riferimento e motivazioni.
|
||||
- Un cambiamento strutturale (fasi, formato `.asm`, schema DB, criterio di scelta di un file)
|
||||
aggiorna i doc e il CHANGELOG **nello stesso commit**.
|
||||
- Se la modifica nasce da un fallimento reale di Creo scrivi **il sintomo**: i messaggi di Creo
|
||||
non nominano il file né la causa (esempio: §7.3-7.5 di
|
||||
[`formato-asm-record.md`](formato-asm-record.md)).
|
||||
- Una scelta con alternative reali non banali merita una voce in
|
||||
[`decisioni/`](decisioni/README.md).
|
||||
- Un nuovo `.cs` va descritto in `architettura.md` e un nuovo doc elencato in `docs/README.md`:
|
||||
`CheckDocs.cs` lo verifica.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Tutorial: il tuo primo giro con PrepStep
|
||||
|
||||
Questo tutorial ti porta, con una distinta vera, dall'app appena installata ai file `raw/` pronti
|
||||
per Creo. Alla fine saprai cosa produce ogni fase e come capire se è andata bene. Per il
|
||||
dettaglio di ogni schermata e per l'esportazione in Creo vedi [`guida-utente.md`](guida-utente.md).
|
||||
|
||||
**Ti serve:** il programma installato (setup in [`rilascio.md`](rilascio.md)), la share `X:\`
|
||||
raggiungibile e un'estrazione "Distinta Base" `.xls` del gestionale, meglio se piccola (poche
|
||||
decine di righe) per il primo giro.
|
||||
|
||||
## 1. Avvia e carica l'indice
|
||||
|
||||
Apri **PrepStep - Cevolani**. Accanto a "Database" c'è un pallino.
|
||||
|
||||
- **Verde:** l'indice c'è già, vai al passo 2.
|
||||
- **Rosso:** premi **Aggiorna indice**. La prima volta scansiona tutta la share e richiede
|
||||
qualche minuto; vedi una barra di avanzamento con i conteggi.
|
||||
|
||||
Risultato atteso: pallino verde, percorso di `cad_index.db` e data dell'aggiornamento.
|
||||
Premi **Avanti**.
|
||||
|
||||
## 2. Importa la distinta
|
||||
|
||||
Trascina il `.xls` nella finestra. Risultato atteso: la griglia si riempie con
|
||||
Componente/Descrizione e nella cartella di lavoro compare un CSV con lo stesso nome base.
|
||||
Poi premi **Verifica presenza**: le righe diventano verdi (trovato nell'indice) o rosse (non
|
||||
trovato). Solo ora **Avanti** si sblocca.
|
||||
|
||||
Se vedi righe rosse non fermarti: nel primo giro è normale scoprire che l'indice è vecchio o
|
||||
che un componente non è sulla share. Vedi [`risoluzione-problemi.md`](risoluzione-problemi.md).
|
||||
|
||||
## 3. Crea la cartella raw
|
||||
|
||||
Premi **Crea cartella raw**. Risultato atteso: nella cartella di lavoro nasce `raw/` con i file
|
||||
`.prt`/`.asm` dei componenti trovati, e la griglia mostra il percorso CAD di ciascuno.
|
||||
|
||||
## 4. Trova i componenti referenziati
|
||||
|
||||
Premi **Trova componenti referenziati**. L'app legge i `.asm` in `raw/` e copia anche tutto
|
||||
quello che serve a Creo per aprirli (sotto-assiemi, componenti soppressi, riferimenti esterni).
|
||||
Risultato atteso: una finestra con l'elenco di quanto copiato e, in fondo, i codici "non
|
||||
trovati". `raw/` ora contiene più file di prima: è giusto così, perché la lista dei file
|
||||
necessari è più lunga di quella della distinta (il perché, in
|
||||
[`decisioni/0003-parser-esatto-con-fallback.md`](decisioni/0003-parser-esatto-con-fallback.md)).
|
||||
|
||||
## 5. Porta i `.asm` a Creo
|
||||
|
||||
La fase 5 mostra i `.asm` della distinta come icone trascinabili. Trascinali su **Creo
|
||||
Distributed Batch** (passi in
|
||||
[`guida-utente.md`](guida-utente.md#5-verifica-completezza-e-creo-distributed-batch)):
|
||||
i file STEP finiscono in `step/`.
|
||||
|
||||
## Cosa hai imparato
|
||||
|
||||
| Fase | Entra | Esce |
|
||||
|---|---|---|
|
||||
| 1 | share `X:\` | `cad_index.db` |
|
||||
| 2 | `.xls` del gestionale | CSV + verifica sull'indice |
|
||||
| 3 | CSV + indice | `raw/` con i componenti della distinta |
|
||||
| 4 | `.asm` in `raw/` | `raw/` completa dell'albero |
|
||||
| 5 | `raw/` | `.asm` da trascinare su Creo |
|
||||
|
||||
Per un secondo giro con un'altra distinta usa **File → Nuovo** (Ctrl+N), e prima ripulisci
|
||||
`raw/`/`step/` da **File → Pulisci raw e step...**.
|
||||
@@ -0,0 +1,59 @@
|
||||
// dotnet run scripts/CheckDocs.cs (dalla root del repo; exit 1 se i doc sono fuori allineamento)
|
||||
// Controlla anche che ogni doc di docs/ e docs/decisioni/ sia nell'indice.
|
||||
// Controlla: link relativi (file e #ancora), <Version> del csproj == ultima voce del CHANGELOG,
|
||||
// ogni .cs di PrepStep/ e scripts/ citato in docs/architettura.md.
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
var errori = new List<string>();
|
||||
var mdFiles = Directory.EnumerateFiles(".", "*.md", SearchOption.AllDirectories)
|
||||
.Where(f => !f.Contains($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}")
|
||||
&& !f.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}")
|
||||
&& !f.Contains($"{Path.DirectorySeparatorChar}raw{Path.DirectorySeparatorChar}")
|
||||
&& !f.Contains($"{Path.DirectorySeparatorChar}step{Path.DirectorySeparatorChar}")).ToList();
|
||||
|
||||
// slug delle intestazioni come lo calcola GitHub/Gitea
|
||||
static HashSet<string> Ancore(string path) =>
|
||||
File.ReadLines(path).Where(l => l.StartsWith('#'))
|
||||
.Select(l => Regex.Replace(Regex.Replace(l.TrimStart('#').Trim().ToLowerInvariant(), @"[`*]", ""), @"[^\p{L}\p{N}\- _]", "").Replace(' ', '-'))
|
||||
.ToHashSet();
|
||||
|
||||
// 1. link relativi
|
||||
foreach (var f in mdFiles)
|
||||
{
|
||||
var testo = Regex.Replace(File.ReadAllText(f), @"```.*?```", "", RegexOptions.Singleline);
|
||||
foreach (Match m in Regex.Matches(testo, @"\]\(([^)\s]+)\)"))
|
||||
{
|
||||
var url = m.Groups[1].Value;
|
||||
if (Regex.IsMatch(url, @"^[a-z]+:")) continue; // http:, mailto:, ...
|
||||
var parti = url.Split('#', 2);
|
||||
var target = parti[0] == "" ? f : Path.GetFullPath(Path.Combine(Path.GetDirectoryName(f)!, parti[0]));
|
||||
if (!File.Exists(target) && !Directory.Exists(target)) { errori.Add($"{f}: link rotto -> {url}"); continue; }
|
||||
if (parti.Length == 2 && target.EndsWith(".md") && !Ancore(target).Contains(parti[1].ToLowerInvariant()))
|
||||
errori.Add($"{f}: ancora inesistente -> {url}");
|
||||
}
|
||||
}
|
||||
|
||||
// 2. versione
|
||||
var version = Regex.Match(File.ReadAllText("PrepStep/PrepStep.csproj"), @"<Version>(.+?)</Version>").Groups[1].Value;
|
||||
var ultima = Regex.Match(File.ReadAllText("CHANGELOG.md"), @"^## \[(\d[^\]]*)\]", RegexOptions.Multiline).Groups[1].Value;
|
||||
if (version != ultima) errori.Add($"CHANGELOG.md: ultima voce {ultima} != <Version> {version} del csproj");
|
||||
|
||||
// 3. ogni sorgente citato nella mappa file-per-file
|
||||
var arch = File.ReadAllText("docs/architettura.md");
|
||||
foreach (var cs in Directory.EnumerateFiles("PrepStep", "*.cs").Concat(Directory.EnumerateFiles("scripts", "*.cs")))
|
||||
{
|
||||
var nome = Path.GetFileName(cs);
|
||||
if (!arch.Contains(nome) && !nome.EndsWith(".Designer.cs")) errori.Add($"docs/architettura.md: {cs} non è descritto");
|
||||
}
|
||||
|
||||
// 4. ogni doc in docs/ è raggiungibile dall'indice della sua cartella
|
||||
foreach (var dir in new[] { "docs", Path.Combine("docs", "decisioni") })
|
||||
{
|
||||
var indice = File.ReadAllText(Path.Combine(dir, "README.md")) + (dir == "docs" ? File.ReadAllText(Path.Combine(dir, "decisioni", "README.md")) : "");
|
||||
foreach (var md in Directory.EnumerateFiles(dir, "*.md").Where(f => Path.GetFileName(f) != "README.md"))
|
||||
if (!indice.Contains(Path.GetFileName(md))) errori.Add($"{dir}/README.md: {Path.GetFileName(md)} non è nell'indice");
|
||||
}
|
||||
|
||||
errori.ForEach(Console.Error.WriteLine);
|
||||
Console.WriteLine(errori.Count == 0 ? $"Doc OK ({mdFiles.Count} file md)" : $"{errori.Count} problemi");
|
||||
return errori.Count == 0 ? 0 : 1;
|
||||
Reference in new issue
Block a user