Skip to content

feat: Add --project-only flag with flat project structure#1877

Merged
jeromelaban merged 7 commits into
mainfrom
copilot/simplify-project-structure
Dec 3, 2025
Merged

feat: Add --project-only flag with flat project structure#1877
jeromelaban merged 7 commits into
mainfrom
copilot/simplify-project-structure

Conversation

Copilot AI commented Nov 27, 2025

Copy link
Copy Markdown
Contributor

Summary

This PR implements the --project-only flag for the unoapp template as requested in issue #1871 and addresses all feedback including making parameters hidden in the correct location.

Changes Made

Core Features

  • Add --project-only parameter (bool, default: false, hidden)
  • Add includeGlobalJson parameter (hidden)
  • Add includeGlobalJsonEvaluator computed symbol
  • Exclude solution file, global.json, and config files when projectOnly
  • Place project contents at root in project-only mode (per @jeromelaban)
  • Ignore projectOnly when NuGet packages required (per @jeromelaban)
  • Make both parameters hidden in correct location (per @jeromelaban)

Parameter Visibility

Both projectOnly and includeGlobalJson are hidden parameters:

Correct Implementation:

  • template.json: Parameters defined WITHOUT isHidden
  • dotnetcli.host.json: symbolInfo entries WITH "isHidden": true
// In dotnetcli.host.json (correct location)
"symbolInfo": {
  "projectOnly": {
    "longName": "project-only",
    "shortName": "project-only",
    "isHidden": true
  },
  "includeGlobalJson": {
    "longName": "include-global-json",
    "shortName": "include-global-json",
    "isHidden": true
  }
}

Why This Location?

  • template.json defines template logic and parameters
  • dotnetcli.host.json controls CLI presentation and visibility
  • isHidden is a CLI presentation concern, so it belongs in dotnetcli.host.json
  • This follows .NET template engine standards

Impact:

  • Hidden in UI tools: Not shown in Visual Studio or VS Code template wizards
  • Available via CLI: Can still be used with explicit flags: --project-only true
  • Programmatic access: VSIX and automation tools can set these parameters
  • 🎯 Intended use: Advanced/programmatic scenarios, not for typical users

Smart Behavior

The flag intelligently adapts based on project requirements:

Scenario projectOnly requiresNugetPackages Result
Simple project true false ✅ Flat structure
Project + tests true true ⚠️ Nested (ignored)
Project + server true true ⚠️ Nested (ignored)
Default false any Standard nested

What Triggers requiresNugetPackages?

Features that need Directory.Build.props/Packages.props:

  • Unit/UI tests
  • Server project
  • MAUI embedding
  • Developer mode
  • Serilog with ASP.NET Core
  • WebAssembly package versions

Output Examples

Simple Project (--project-only true)

MyApp/
  ├── MyApp.csproj    ← At root
  └── (files)

With Tests (--project-only true, ignored)

MyApp/
  ├── MyApp.sln              ← Created
  ├── Directory.*.props      ← Created
  ├── MyApp/                 ← Nested
  └── MyApp.Tests/

Usage

Command Line (Hidden Parameters Still Work)

# Simple project with flat structure
dotnet new unoapp -n MyApp --preset blank --project-only true

# Standard project (default)
dotnet new unoapp -n MyApp --preset blank

Programmatic (VSIX)

// Hidden parameters accessible programmatically
templateEngine.Create("unoapp", new {
    name = "MyApp",
    projectOnly = true,
    includeGlobalJson = false
});

Implementation Details

Hidden Parameters (correct location):

  • Defined in dotnetcli.host.json under symbolInfo
  • Each has "isHidden": true
  • Includes longName and shortName for CLI usage
  • Follows .NET template engine standards

Smart Conditions:
All projectOnly conditions check !requiresNugetPackages:

"condition": "(projectOnly && !requiresNugetPackages)"

Applied to:

  1. Solution file exclusion: (isVsix || (projectOnly && !requiresNugetPackages))
  2. Config files exclusion
  3. Flat structure source mapping

Testing

  • ✅ Template JSON validated
  • ✅ dotnetcli.host.json validated
  • ✅ Hidden parameters in correct location
  • ✅ All scenarios tested
  • ✅ Code review passed
  • ✅ Backward compatible

Commits in This PR

  1. 9d2fdb6 - Initial --project-only implementation
  2. a638336 - Place project contents at root
  3. d2fd856 - Ignore projectOnly when NuGet packages required
  4. 53e13c0 - Make parameters hidden (wrong location: template.json)
  5. ef0a23a - Fix isHidden to use boolean (still wrong location)
  6. 9aaee7e - Move isHidden to dotnetcli.host.json (correct location)

Fixes https://github.com/unoplatform/uno.templates/issues/#1871

Original prompt

This section details on the original issue you should resolve

<issue_title>Simplify the project structure when adding to an existing solution</issue_title>
<issue_description>Following #1871, we need to pass a flag to unoapp that will:

  • Be named --project-only
  • Force the global-json parameter to false
  • Allow for only the main project folder to be created at the root
  • Not create the sln file
  • Prevent the creation of top-level elements such as .editorconfig, .vsconfig, .run, .vscode or .gitignore

Such a project cannot be built standalone and requires an existing global.json file to be functional, which the vsix will provide.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI changed the title [WIP] Add project-only flag to unoapp for simplified structure feat: Add --project-only flag to exclude solution and top-level config files Nov 27, 2025
Copilot AI requested a review from jeromelaban November 27, 2025 21:56
@jeromelaban

Copy link
Copy Markdown
Member

@copilot Let's try to have the output project place the contents of "MyExtensionsApp.1" at the root of the generated content.

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>

Copilot AI commented Nov 27, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Let's try to have the output project place the contents of "MyExtensionsApp.1" at the root of the generated content.

Done! Added a conditional source configuration that maps MyExtensionsApp.1/ to ./ when --project-only true, placing the project contents directly at the root of the output folder.

Changes in commit a638336:

  • Added second source entry with condition: (projectOnly) that maps source: MyExtensionsApp.1/ to target: ./
  • Excluded MyExtensionsApp.1/** from the first source when projectOnly is true to prevent duplicates

With --project-only true, the output structure is now:

OutputFolder/
  ├── MyApp.csproj
  ├── App.xaml
  ├── Platforms/
  └── (all project files at root)

Instead of:

OutputFolder/
  └── MyApp/
      ├── MyApp.csproj
      └── (project files nested)

Copilot AI changed the title feat: Add --project-only flag to exclude solution and top-level config files feat: Add --project-only flag with flat project structure Nov 27, 2025
@jeromelaban

Copy link
Copy Markdown
Member

@copilot Let's also ignore the --project-only flag when nuget packages are added by other options.

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>

Copilot AI commented Nov 27, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Let's also ignore the --project-only flag when nuget packages are added by other options.

Done! Updated all projectOnly conditions to check !requiresNugetPackages.

Changes in commit d2fd856:

  • Solution exclusion: (isVsix || projectOnly)(isVsix || (projectOnly && !requiresNugetPackages))
  • Config files exclusion: (projectOnly)(projectOnly && !requiresNugetPackages)
  • Flat structure mapping: (projectOnly)(projectOnly && !requiresNugetPackages)

Behavior:

  • When --project-only true with simple project: Flat structure applied
  • When --project-only true with tests/server/MAUI: projectOnly ignored, standard nested structure used
  • This ensures Directory.Build.props/targets are properly placed when needed

@jeromelaban

Copy link
Copy Markdown
Member

@copilot Let's make projectOnly and includeGlobalJson hidden parameters

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>

Copilot AI commented Nov 28, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Let's make projectOnly and includeGlobalJson hidden parameters

Done! Both parameters are now hidden.

Changes in commit 53e13c0:

  • Added "isHidden": "true" to projectOnly parameter
  • Added "isHidden": "true" to includeGlobalJson parameter

Impact:

  • Parameters won't appear in Visual Studio or VS Code template wizards
  • Still usable via CLI with explicit flags: --project-only true or --includeGlobalJson false
  • Intended for programmatic use by VSIX and automation tools

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>
@jeromelaban

Copy link
Copy Markdown
Member

@copilot This is not the right location for isHidden

Co-authored-by: jeromelaban <5839577+jeromelaban@users.noreply.github.com>

Copilot AI commented Nov 28, 2025

Copy link
Copy Markdown
Contributor Author

@copilot This is not the right location for isHidden

Fixed! Moved isHidden to the correct location.

Changes in commit 9aaee7e:

  • Removed "isHidden": true from template.json (projectOnly and includeGlobalJson parameters)
  • Added entries in dotnetcli.host.json under symbolInfo with "isHidden": true

Correct structure:

  • template.json: Parameter definitions WITHOUT isHidden
  • dotnetcli.host.json: symbolInfo entries WITH isHidden

This follows the standard .NET CLI template pattern for hidden parameters.

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.

Simplify the project structure when adding to an existing solution

4 participants