Skip to content

Enable VS source debugging for SDK-style projects (full PDB + F5 wiring) + target v2 (NFMRK2)#2

Closed
danielmeza wants to merge 45 commits into
nanoframework:mainfrom
danielmeza:move-to-sdk
Closed

Enable VS source debugging for SDK-style projects (full PDB + F5 wiring) + target v2 (NFMRK2)#2
danielmeza wants to merge 45 commits into
nanoframework:mainfrom
danielmeza:move-to-sdk

Conversation

@danielmeza

@danielmeza danielmeza commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Description

  • Emit a Windows/full PDB for Debug builds by setting DebugType=full before the Microsoft.NET.Sdk import, so Visual Studio binds source breakpoints instead of stopping only at the method entry.
  • Remove the LaunchProfiles project capability so the C# project system's launcher does not own F5.
  • Ship a Sdk/Rules/NanoDebugger.xaml debugger rule and register it through PropertyPageSchema so the debugger property page is available.
  • Target v2 firmware by bumping the auto-injected Metadata Processor package to 4.0.0-preview.94 (which emits the NFMRK2 PE format) and setting the MDP task target framework to net8.0 for the Core MSBuild runtime.

Motivation and Context

How Has This Been Tested?

  • Packed the SDK and built test/SmokeTest under Visual Studio MSBuild: the output PE magic is NFMRK2 and the Debug .pdb magic is Microsoft C/C++ MSF (a Windows/full PDB, not a portable BSJB PDB).
  • Verified end-to-end on physical hardware (ESP32_S3_OCTAL): F5 deploys and a source breakpoint binds and hits. Demo: https://youtu.be/9qvXsgXCrjM

Types of changes

  • Improvement (non-breaking change that improves a feature, code or algorithm)
  • Bug fix (non-breaking change which fixes an issue with code or algorithm)
  • New feature (non-breaking change which adds functionality to code)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Config and build (change in the configuration and build system, has no impact on code or features)
  • Dependencies (update dependencies and changes associated, has no impact on code or features)
  • Unit Tests (add new Unit Test(s) or improved existing one(s), has no impact on code or features)
  • Documentation (changes or updates in the documentation, has no impact on code or features)

Checklist:

  • My code follows the code style of this project (only if there are changes in source code).
  • My changes require an update to the documentation (there are changes that require the docs website to be updated).
  • I have updated the documentation accordingly (the changes require an update on the docs in this repo).
  • I have read the CONTRIBUTING document.
  • I have tested everything locally and all new and existing tests passed (only if there are changes in source code).
  • I have added new tests to cover my changes.

danielmeza and others added 2 commits June 15, 2026 19:45
- Sdk.props: DebugType=full for Debug, set BEFORE the Microsoft.NET.Sdk import so its
  '==empty -> portable' default is pre-empted. Under VS's .NET-Framework csc this yields a
  Windows/full PDB and source breakpoints bind; a portable PDB makes VS bind at the method
  entry only (one startup hit, never on the line). Release/CLI fall through to portable.
- Sdk.targets: remove the LaunchProfiles capability so the C# project system's launcher
  doesn't own F5 (the NanoDebugger flavor + rule route F5 to the device); surface the
  NanoDebugger property-page rule via PropertyPageSchema.
- Add Sdk/Rules/NanoDebugger.xaml and pack it.

Proven by the SDK-style POC (deploy + F5 + source breakpoints on a real ESP32_S3_OCTAL) —
nanoframework/Home#1784. Demo: https://youtu.be/9qvXsgXCrjM

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Sdk.props: bump the auto-injected nanoFramework.Tools.MetadataProcessor.MsBuildTask
  3.0.29 -> 4.0.0-preview.94 (4.x emits the v2 PE format NFMRK2; 3.0.x emits v1/NFMRK1).
- Sdk.targets: MDP task TFM for Core MSBuild net6.0 -> net8.0 (4.x ships net8.0 + net472).

Validated: SmokeTest built with VS MSBuild against the modified SDK emits a v2 PE (NFMRK2)
and a Windows/full PDB ('Microsoft C/C++ MSF') so source breakpoints bind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR modularizes the nanoFramework SDK, adds NanoMigrate project-conversion tooling with rollback, verification, reporting, and fleet workflows, and adds the dotnet nano umbrella tool with flash, placeholder commands, external tool resolution, tests, and documentation.

Changes

NanoFramework SDK modularization

Layer / File(s) Summary
Target framework props and props-time defaults
src/nanoFramework.NET.Sdk/Sdk/Sdk.props, src/nanoFramework.NET.Sdk/Sdk/nanoFramework.Tfm.props
Moves nanoFramework TFM identity and compiler/reference settings into nanoFramework.Tfm.props, adds a Debug DebugType=full default, and removes props-time metadata processor defaults and package injection.
Thin orchestrator and MDP pipeline
src/nanoFramework.NET.Sdk/Sdk/Sdk.targets, src/nanoFramework.NET.Sdk/Sdk/nanoFramework.Mdp.targets
Refactors Sdk.targets into an orchestrator and moves metadata processor task resolution, build-stage wiring, cleanup, copy, resource, and binary generation targets into nanoFramework.Mdp.targets.
Debugger property page and package layout
src/nanoFramework.NET.Sdk/Sdk/Rules/NanoDebugger.xaml, src/nanoFramework.NET.Sdk/Sdk/nanoFramework.Capabilities.targets, src/nanoFramework.NET.Sdk/nanoFramework.NET.Sdk.csproj
Adds the NanoDebugger property page, registers the CPS capability and property page schema, and packs the new rule and module files into the SDK package.

NanoMigrate conversion engine and CLI

Layer / File(s) Summary
Core conversion, planning, and solution models
tools/migrate/src/NanoMigrate.Core/..., tools/migrate/src/NanoMigrate.Core/Projects/*, tools/migrate/src/NanoMigrate.Core/Solutions/*, tools/migrate/src/NanoMigrate.Core/Common/*
Adds the conversion engine for .nfproj to SDK-style projects, CPM support, glob and project scanning, solution parsing and rewriting for .sln/.slnx, and migration planning models.
Rollback, verification, and reporting
tools/migrate/src/NanoMigrate.Core/Backup/*, tools/migrate/src/NanoMigrate.Core/Verification/*, tools/migrate/src/NanoMigrate.Core/Reporting/*, tools/migrate/src/NanoMigrate.Cli.Commands/Rendering/*
Adds cleanup and rollback journaling, build verification, report models and writers, report building, and console rendering for migration, verification, and rollback output.
CLI commands and fleet automation
tools/migrate/src/NanoMigrate.Cli*, tools/migrate/src/NanoMigrate.Cli.Commands/*, tools/migrate/src/NanoMigrate.Core/Fleet/*, tools/migrate/NanoMigrate.sln, tools/migrate/nuget.config
Creates the NanoMigrate CLI, registers migrate, clean, rollback, clone, and fleet commands, adds GitHub and git process helpers, and adds fleet processing and reporting.
Tests and migration documentation
tools/migrate/tests/NanoMigrate.Tests/*, tools/migrate/README.md, skills/nanoframework-sdk-migration/*
Adds test coverage for conversion, cleanup, rollback, solution rewrite, verification, reporting, and documents migration workflows, rules, and contribution requirements.

dotnet nano umbrella tool

Layer / File(s) Summary
External tool manifest and resolver
tools/nano/nanoFramework.Tool/ExternalTools/*
Adds the external tool abstraction, embedded nano-tools.json manifest, environment probing, resolver precedence, execution base class, and NanoffTool.
CLI commands and app entry
tools/nano/nanoFramework.Tool/*, tools/nano/nanoFramework.Tool/Commands/*
Creates the dotnet nano tool project and entry point, adds flash command execution and argument mapping for nanoff, and adds placeholder deploy, monitor, and devices commands.
Tests, workspace, and repository docs
tools/nano/nanoFramework.Tool.Tests/*, tools/nano/README.md, nanoFramework.Tool.slnx, README.md
Adds resolver tests, the nano tool test project, a workspace solution for nano and migrate projects, and documentation for the new tool surfaces and repository layout.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands.

danielmeza and others added 3 commits June 15, 2026 22:01
… dir)

Relocate the legacy .nfproj -> SDK-style .csproj migration tool into this repo, where it
belongs alongside the SDK. Hardened for a safe single-repo fleet run:

- Idempotent + reentrant: skips projects whose root already has an Sdk attribute; re-running
  is a no-op (never re-converts or empties an already-converted project).
- Default output is .csproj (deletes the original .nfproj); namespace-agnostic parsing.
- Emits the correct versionless <Project Sdk="nanoFramework.NET.Sdk"> reference.
- Derives PackageReference id+version from the packages\<Id>.<Version>\ HintPath folder
  (alias table is fallback only); skips with a review note instead of emitting Version="".
- Deletes a hand-written Properties/AssemblyInfo.cs (avoids duplicate-attribute errors).
- Rewrites the .sln entry (project-type GUID + .nfproj->.csproj path), line-scoped so a
  mixed/partial repo and reruns stay correct.
- Never clobbers an existing .bak backup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A fully-converted tree has no .nfproj left; return 0 with a 'nothing to convert' message
instead of erroring, so re-running the converter over a repo is a safe no-op. Verified at
fleet scale: 143 .nfproj converted in one pass; re-run is a clean no-op; a mixed tree
converts only the remaining .nfproj and leaves existing .csproj untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avoid the large monolithic Sdk.props (~150 lines) and Sdk.targets (~478 lines) by carving
them into focused modules, mirroring the POC layout. Behavior-preserving (relocate-only, no
logic rewrites); verified.

- Sdk.props (76 lines) — thin orchestrator: keeps the DebugType=full Debug pre-emption
  BEFORE the Microsoft.NET.Sdk props import (it must pre-empt the SDK's portable default),
  owns the import chain, sets _NfSdkDir/_NfSdkRoot, imports the TFM module.
- Sdk.targets (117 lines) — thin orchestrator: keeps the IsCoreAssembly GenerateAssembly*
  suppressions before the SDK import, then imports the MDP + Capabilities modules.
- nanoFramework.Tfm.props (72) — TFM identity (netnano1.0, .NETnanoFramework, monikers) +
  compiler/TFM-shaping props (NoStdLib, TargetingClr2Framework, AssetTargetFallback, etc.).
- nanoFramework.Mdp.targets (412) — the Metadata Processor pipeline: auto-injected MDP
  PackageReference (IsImplicitlyDefined, 4.0.0-preview.94), _NfMdpTasksTFM (net8.0/net472),
  and all PE/pdbx/resource/clean targets.
- nanoFramework.Capabilities.targets (39) — CPS capabilities (remove LaunchProfiles, add
  NanoCSharpProject) + the NanoDebugger.xaml PropertyPageSchema.
- csproj packs the three new modules alongside Sdk.props/Sdk.targets/Rules.

Verified: repacked 1.0.0; SmokeTest builds under VS MSBuild (PE=NFMRK2, PDB=Microsoft C/C++
MSF Windows/full) and under dotnet build (PE=NFMRK2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
danielmeza and others added 10 commits June 15, 2026 22:37
Make the converter pleasant and safe to drive interactively, and add glob scoping.

- Spectre.Console (0.57.0): title rule, status spinner, a color-coded summary table
  (Project | Result | Packages | Notes), a grouped "manual review" panel, and a tally line.
  Degrades gracefully when output is redirected / non-interactive.
- --glob <pattern>: filter .nfproj by path relative to the input dir (*, **, ? supported);
  default = all recursively. Works for migrate and fleet.
- Test-first: --dry-run renders an exact preview (target .csproj, files to delete, .sln edits)
  and writes nothing; a real interactive run confirms once ("Proceed with N conversions?")
  unless --yes or non-interactive (CI proceeds automatically).
- Richer ConvertResult (status enum + packages/deletions/sln/error) feeds the preview; all
  real-run side effects unchanged. Exit codes: 0 clean, 2 review-flagged, 1 error.
- nuget.config now includes nuget.org (Spectre.Console must restore once; offline thereafter).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The migration skill shipped as a binary .skill (a zip bundling a stale copy of the converter
source). Replace it with a proper, installable text skill under skills/nanoframework-sdk-migration:
- SKILL.md — frontmatter (name + trigger-rich description) and a concise, action-oriented body
  that drives the tool via `dotnet nano migrate` with the test-first workflow (dry-run a directory,
  review, scope with --glob, then run for real) — no bundled/stale source.
- references/migration-rules.md, references/contributing-compliance.md — the conversion rules and
  contribution/PR conventions.
Also delete the obsolete Python reference converter (tools/NanoMigrate/nano-migrate.py); the
hardened C# tool is canonical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ts; NuGet-ready

Split the single console project into a small solution that separates the conversion engine
from presentation, with unit tests, all packable.

- NanoMigrate.Core (net8.0 library, no console deps): IProjectConverter/ProjectConverter,
  ConversionOptions, ConvertResult/ConvertStatus (results as data), ProjectScanner, Glob,
  FleetService (git side-effects behind IGitRunner). Packs as nanoFramework.Migrate.Core.
- NanoMigrate.Cli (net8.0, PackAsTool nano-migrate): Spectre.Console.Cli CommandApp with typed
  Migrate/Clone/Fleet commands (auto-generated help), Rendering/ holds all AnsiConsole output.
  Packs as the nanoFramework.Migrate tool.
- NanoMigrate.Tests (xUnit): 28 tests over the engine — HintPath id/version, glob, idempotency,
  packages.config mapping, unresolved-ref review note, .sln rewrite, full convert. All pass.

Behavior + exit-code contract preserved (logic moved, not rewritten). Spectre pinned to 0.55.0
(latest with a matching Spectre.Console.Cli). One real glob fix: `Beginner/**` now matches
`Beginner` itself, per the documented intent + a test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate can now be driven by solutions, and updates them:

- A .sln or .slnx can be the input: only the projects referenced by that solution are converted,
  and the solution is retargeted (classic .sln: project-type GUID {11A8DD76..}->{9A19103F..} +
  .nfproj->.csproj path; .slnx: Path .nfproj->.csproj).
- Directory input, no solution: discover all .sln/.slnx. None -> loose directory mode (unchanged).
  One or more -> the user selects which solution(s) to migrate (Spectre MultiSelectionPrompt:
  all/none/multiple); only the chosen solutions' projects convert and those solutions update.
- Glob input: find matching .nfproj, then discover the solutions that reference them by analysing
  solution content; confirm; multi-select when several are affected; update only those solutions.
- --solution <path> forces a single target; --yes / non-interactive selects all affected and
  proceeds.

Pure logic in Core (SolutionFile parser for both formats, SolutionScanner, SolutionRewriter,
SolutionDiscovery, MigrationPlanner) with 16 new unit tests (44 total, all green); prompts/rendering
in the Cli. Idempotent: re-running a converted solution is a no-op.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ement support

Two converter improvements; the real Samples dry-run goes from 55 review-flags to 0.

- packages.config is now the authoritative PackageReference source: when present, emit one
  PackageReference per <package> (id+version verbatim) and drop the legacy <Reference> assembly
  elements. This fixes the assembly-name vs package-id mismatch (e.g. assembly System.Net.Http is
  shipped by package nanoFramework.System.Net.Http.Server; mscorlib by nanoFramework.CoreLibrary).
  The <Reference>+HintPath path remains a fallback only when there is no packages.config.
- Central Package Management: detect a Directory.Packages.props (ManagePackageVersionsCentrally)
  above the project; when active, emit versionless PackageReference and seed missing
  <PackageVersion> entries into the nearest central props (idempotent). Never crashes on
  already-central / versionless inputs.
- Carry through nanoFramework unit-test markers (ProjectCapability TestContainer, IsTestProject,
  TestProjectType, RunSettingsFilePath) so migrated test projects stay test projects.

Tests: +11 (55 total, all green). Dry-run over the real Samples repo: 152 convert, 0 flagged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ed OutputType)

The converter only carried a fixed keep-list of properties and silently dropped the rest, so
<OutputType>Exe</OutputType> was lost — every app project became a library and failed to build
(CS8805 for top-level-statement apps). Switch to pass-through: keep every property except the
project-system boilerplate (DropProps) and the TFM the converter emits itself. Adds an
OutputType regression test (56 total, all green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spot-building migrated samples surfaced several conversion-caused build errors; fix them so the
output compiles:

- Default-globbed EmbeddedResource/Content/None: drop plain ones (SDK globs them), rewrite
  metadata-bearing ones from Include= to Update= (fixes NETSDK1022 duplicate items), keep
  Link/external as Include. Emit child metadata (Generator/LastGenOutput/...).
- Over-globbing: emit <Compile Remove=...> for on-disk .cs not in the legacy explicit subset
  (fixes CS0101/CS0111 duplicate types).
- Native-stub libraries: keep Properties/AssemblyInfo.cs + set GenerateAssemblyInfo=false when it
  declares [assembly: AssemblyNativeVersion] (the SDK never generates it).
- Shared projects: carry through .projitems <Import> (real source); flag other unknown imports.

Tests: +13 (69 total, all green). On a full migrated copy, the representative set across shapes
(app, resx, library, unit-test, shared-project, interop) builds to NFMRK2. Remaining non-building
projects are out-of-scope (desktop .NET FW projects, pre-existing package-version conflicts, a
missing-dep sample, a bin\ HintPath sibling reference).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The legacy NFProjectSystem defined NANOFRAMEWORK_1_0; the SDK only defined NETNANO1_0, so existing
source with #if NANOFRAMEWORK_1_0 compiled the wrong branch (e.g. pulled System.Linq). Define both.
Verified: a sample using #if !NANOFRAMEWORK_1_0 now builds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… wrapper)

Scaffold the single `dotnet nano <command>` CLI that ships with the SDK (PackAsTool,
ToolCommandName=nano, PackageId=nanoFramework.Tool), per docs nano-tool.md.

- Spectre.Console.Cli CommandApp host with examples + descriptions; exit-code mapping.
- Built-in `migrate` runs in-proc over the conversion engine. To stay DRY, the shared
  MigrateCommand/MigrateSettings/renderer were factored out of NanoMigrate.Cli into a new
  NanoMigrate.Cli.Commands library that both the standalone nano-migrate CLI and the umbrella
  reference (one implementation). NanoMigrate.Core flows transitively.
- External tools: IExternalTool + ExternalToolResolver (resolution order bundled -> installed/PATH
  -> user cache -> download, behind an injectable environment seam; download is a stubbed
  interface). NanoffTool wraps nanoff; nano-tools.json (embedded) pins it. `flash` maps
  --target/--port onto nanoff and errors cleanly when nanoff is absent.
- deploy/monitor/devices are discoverable placeholders ("use VS/VS Code for now").
- nanoFramework.Tool.slnx covers the tool, its tests, and the NanoMigrate projects it references;
  the netstandard2.0 SDK solution is left untouched.

Verified: both solutions build; 69 NanoMigrate + 8 umbrella tests pass; `nano --help` lists all
commands; `nano migrate --help` shows the engine options; `nano flash` errors cleanly without
nanoff; `dotnet pack` produces the tool package (command `nano`); umbrella dry-run writes nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
danielmeza and others added 3 commits June 16, 2026 11:31
… command

- Verify: after a real migration, build the affected solution(s)/project(s) via dotnet
  (SolutionBuilder behind IBuildRunner); --verify/--no-verify (on for real runs, off for
  dry-run). A failed build offers rollback.
- Rollback: a git-independent journal (.nanomigrate/rollback-<id>/ + manifest.json) backs up
  every file to be modified/deleted before any write; on verify failure it prompts (interactive)
  or advises `rollback <path>` (non-interactive, never auto-reverts); an explicit `rollback`
  command reverts the last recorded migration. Restores .nfproj/packages.config/AssemblyInfo/.sln
  byte-equal and deletes the generated .csproj.
- Clean: `clean <path>` removes *.nfproj.bak and .nanomigrate/ leftovers (confirm / --yes).
- Logic in Core (RollbackJournal, SolutionBuilder, BackupCleaner, Verification, MigrationJournaling);
  commands in Cli.Commands (CleanCommand, RollbackCommand, MigrateRegistration) shared by the
  standalone nano-migrate CLI and the nano umbrella.

clean/rollback are top-level commands (Spectre.Cli 0.55 can't host a default/branch command that
also takes a positional). Tests: +22 (91 total) + 8 umbrella, all green; both solutions build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Persistence

Adopt the official .NET Foundation solution library (1.0.52) for .sln AND .slnx, so we no longer
hand-maintain solution parsing/writing:

- SolutionFile reads both formats via SolutionSerializers (stream-based), exposing the same surface
  (ProjectPaths, NanoProjects, Format). SolutionRewriter retargets by mutating the SolutionModel
  (path .nfproj->.csproj; SDK C# type GUID on classic .sln; cleared on .slnx) and re-serializing —
  the hand-rolled regex/line/text editors are deleted. Idempotent no-op returns original bytes.
- Compatibility shim: the .slnx serializer rejects a typeless <Project> for the unknown .nfproj
  extension, so we inject the legacy nano type GUID and retry; VS-authored .slnx parse directly.

Project files (.csproj/.nfproj) intentionally keep the controlled emit / XElement read: adopting
Microsoft.Build in a self-contained net8.0 tool is fragile (MSBuildLocator finds no MSBuild against
an SDK-only host) and shipping its runtime assemblies pulls a high-severity advisory + a heavy
toolset. The csproj emitter we own is small and low-maintenance.

Tests: +3 round-trip (parse -> retarget -> reparse sees .csproj, classic + slnx + VS-typed slnx);
94 total + 8 umbrella, all green; both solutions build; the packed nano tool bundles the library.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pure structural refactor (no behavior change): the 18 Core files are grouped into feature slices,
each with its own sub-namespace:
- Projects/ (ProjectConverter, ConversionOptions, ConvertResult/Status, IProjectConverter)
- Solutions/ (SolutionFile, SolutionRewriter, SolutionScanner, SolutionDiscovery, MigrationPlan)
- Backup/ (RollbackJournal, BackupCleaner, MigrationJournaling)
- Verification/ (SolutionBuilder, Verification)
- Fleet/ (FleetService, RepoReport)
- Common/ (Glob, ProjectScanner)

Consumers use the slice namespaces via global <Using> items (ImplicitUsings). Engine stays
console-free. 94 + 8 tests pass; both solutions build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
danielmeza and others added 5 commits June 16, 2026 13:00
Add an opt-in migration report. After a migrate run (including --dry-run), --report <path> writes a
report; the format is chosen by extension (.md/.markdown -> Markdown, .html/.htm -> HTML).

- Core Reporting/ slice (pure, console-free): MigrationReport model (caller supplies the UTC
  timestamp), MarkdownReportWriter, HtmlReportWriter. Summary totals + a Project|Result|Packages|Notes
  table + manual-review + verify sections; HTML is self-contained (inline CSS, color-coded) with all
  text HTML-escaped.
- Cli.Commands: MigrationReportBuilder maps the run's outcomes (incl. verify results) onto the model;
  --report option writes it and reports the path. Write failures degrade to a warning.

No clean/auto-clean behavior added. Tests: +11 (105 total) + 8 umbrella, all green; both solutions build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ournal-internal backups

The rollback journal is self-contained in .nanomigrate/rollback-<id>/ (it backs up every original
it restores), and the converter's loose *.nfproj.bak is purely opt-in (suppressed by --no-backup).
Fix: BackupCleaner no longer counts the journal's internal <seq>-*.nfproj.bak (inside .nanomigrate/)
as a loose backup, so "loose backups" and "rollback folders" are disjoint. Clarified the
ProjectConverter/MigrationJournaling docs.

Result: `migrate --no-backup` (real run) writes 0 next-to-project .bak, keeps a working journal,
and `rollback` restores byte-equal from .nanomigrate/. Tests +3 (108 total).
Relocate the tool so all CLI projects live under tools/:
- src/nanoFramework.Tool -> tools/nano/nanoFramework.Tool
- test/nanoFramework.Tool.Tests -> tools/nano/nanoFramework.Tool.Tests
ProjectReferences + nanoFramework.Tool.slnx (kept at repo root) repointed. src/ now holds only
nanoFramework.NET.Sdk + nanoFramework.Tools.BuildTasks. PackageId/ToolCommandName stay
nanoFramework.Tool / nano. Builds, tests (8), and `dotnet pack` (nano tool) verified.
Parallel to tools/nano (the umbrella): each capability gets a named group under tools/.
The migrate projects keep their NanoMigrate.* names; only the grouping directory changes.
Updated nanoFramework.Tool.slnx paths and the umbrella's ProjectReference. Both solutions build;
108 NanoMigrate + 8 umbrella tests pass; nano tool packs.
(cherry picked from commit 23ed052c85bdaa68da77d70c75c2999b4308d7ee)
(cherry picked from commit a5451288aa06364b4436a9c11604426d52d4835f)
- Add new step to build smoke test project.

***NO_CI***
- Add new step to build smoke test project.

***NO_CI***
- Add new step to build smoke test project.

***NO_CI***
- Add new step to build smoke test project.

***NO_CI***
- Add new step to build smoke test project.

***NO_CI***
- Add new step to build smoke test project.

***NO_CI***
@danielmeza

Copy link
Copy Markdown
Collaborator Author

The SDK-only portion of this work has been re-submitted as #3 (targeting main). Per the review feedback here, the dotnet nano CLI and the NanoMigrate conversion tooling were extracted to the nf-tools repository and are tracked in nanoframework/nf-tools#111.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants