Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ file_header_template = Licensed to the .NET Foundation under one or more agreeme
dotnet_code_quality.ca1802.api_surface = private, internal
dotnet_code_quality.ca1822.api_surface = private, internal
dotnet_code_quality.ca2208.api_surface = public
dotnet_public_api_analyzer.require_api_files = true
# Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.CA1018.severity = warning
# Properties should not be write only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public override int Execute()
projectCollection,
VirtualProjectBuildingCommand.ThrowingReporter,
out var projectInstance,
out _,
out var evaluatedDirectives,
validateAllDirectives: !_force);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,7 @@ public ProjectInstance CreateProjectInstance(ProjectCollection projectCollection
projectCollection,
ThrowingReporter,
out var project,
out _,
out var evaluatedDirectives,
Directives,
addGlobalProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.DotNet.ProjectTools;

public sealed class ExecutableLaunchProfile : LaunchProfile
internal sealed class ExecutableLaunchProfile : LaunchProfile
{
public const string WorkingDirectoryPropertyName = "workingDirectory";
public const string ExecutablePathPropertyName = "executablePath";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Microsoft.DotNet.ProjectTools;

public abstract class LaunchProfile
internal abstract class LaunchProfile
{
[JsonIgnore]
public string? LaunchProfileName { get; init; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.DotNet.ProjectTools;

public sealed class LaunchProfileParseResult
internal sealed class LaunchProfileParseResult
{
public string? FailureReason { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Microsoft.DotNet.ProjectTools;

public static class LaunchSettings
internal static class LaunchSettings
{
private const string ProfilesKey = "profiles";
private const string CommandNameKey = "commandName";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.DotNet.ProjectTools;

public sealed class ProjectLaunchProfile : LaunchProfile
internal sealed class ProjectLaunchProfile : LaunchProfile
{
[JsonPropertyName("launchBrowser")]
public bool LaunchBrowser { get; init; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,33 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<StrongNameKeyId>MicrosoftAspNetCore</StrongNameKeyId>

<!-- NuGet -->
<IsPackable>true</IsPackable>
<IsShipping>true</IsShipping>
<PackageId>Microsoft.DotNet.ProjectTools</PackageId>
</PropertyGroup>

<ItemGroup>
<EmbeddedResource Update="Resources.resx" LinkBase="Resources" GenerateSource="true" Namespace="Microsoft.DotNet.ProjectTools" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build" />
<PackageReference Include="Microsoft.Build" PrivateAssets="all" />
Comment thread
jjonescz marked this conversation as resolved.
Outdated
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Condition=" '$(DotNetBuildSourceOnly)' != 'true' ">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="dotnet" />
<InternalsVisibleTo Include="dotnet.Tests" />
<InternalsVisibleTo Include="Microsoft.DotNet.HotReload.Watch" />
Comment thread
jjonescz marked this conversation as resolved.
Outdated
<InternalsVisibleTo Include="Microsoft.NET.Build.Tests" Key="$(MicrosoftSharedPublicKey)" />
<InternalsVisibleTo Include="Microsoft.TemplateEngine.Cli" />
<InternalsVisibleTo Include="Microsoft.TemplateEngine.Cli.UnitTests" />
</ItemGroup>

<Import Project="..\Cli\Microsoft.DotNet.FileBasedPrograms\Microsoft.DotNet.FileBasedPrograms.projitems" Label="Shared" />
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.DotNet.ProjectTools/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
4 changes: 4 additions & 0 deletions src/Microsoft.DotNet.ProjectTools/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#nullable enable
Microsoft.DotNet.ProjectTools.VirtualProjectBuilder
static Microsoft.DotNet.ProjectTools.VirtualProjectBuilder.CreateProjectRootElement(string! filePath, string! targetFrameworkVersion) -> Microsoft.Build.Construction.ProjectRootElement!
static Microsoft.DotNet.ProjectTools.VirtualProjectBuilder.IsValidEntryPointPath(string! entryPointFilePath) -> bool
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.DotNet.Utilities;

public static class Sha256Hasher
internal static class Sha256Hasher
{
/// <summary>
/// The hashed mac address needs to be the same hashed value as produced by the other distinct sources given the same input. (e.g. VsCode)
Expand Down
57 changes: 39 additions & 18 deletions src/Microsoft.DotNet.ProjectTools/VirtualProjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

namespace Microsoft.DotNet.ProjectTools;

internal sealed class VirtualProjectBuilder
public sealed class VirtualProjectBuilder
{
private readonly IEnumerable<(string name, string value)> _defaultProperties;

public string EntryPointFileFullPath { get; }
internal string EntryPointFileFullPath { get; }

public SourceFile EntryPointSourceFile
internal SourceFile EntryPointSourceFile
{
get
{
Expand All @@ -34,12 +34,12 @@ public SourceFile EntryPointSourceFile
}
}

public string ArtifactsPath
internal string ArtifactsPath
=> field ??= GetArtifactsPath(EntryPointFileFullPath);

public string[]? RequestedTargets { get; }
internal string[]? RequestedTargets { get; }

public VirtualProjectBuilder(
internal VirtualProjectBuilder(
string entryPointFileFullPath,
string targetFrameworkVersion,
string[]? requestedTargets = null,
Expand All @@ -56,7 +56,7 @@ public VirtualProjectBuilder(
/// <remarks>
/// Kept in sync with the default <c>dotnet new console</c> project file (enforced by <c>DotnetProjectConvertTests.SameAsTemplate</c>).
/// </remarks>
public static IEnumerable<(string name, string value)> GetDefaultProperties(string targetFrameworkVersion) =>
internal static IEnumerable<(string name, string value)> GetDefaultProperties(string targetFrameworkVersion) =>
[
("OutputType", "Exe"),
("TargetFramework", $"net{targetFrameworkVersion}"),
Expand All @@ -66,7 +66,7 @@ public VirtualProjectBuilder(
("PackAsTool", "true"),
];

public static string GetArtifactsPath(string entryPointFileFullPath)
internal static string GetArtifactsPath(string entryPointFileFullPath)
{
// Include entry point file name so the directory name is not completely opaque.
string fileName = Path.GetFileNameWithoutExtension(entryPointFileFullPath);
Expand All @@ -79,7 +79,7 @@ public static string GetArtifactsPath(string entryPointFileFullPath)
/// <summary>
/// Obtains a temporary subdirectory for file-based app artifacts, e.g., <c>/tmp/dotnet/runfile/</c>.
/// </summary>
public static string GetTempSubdirectory()
internal static string GetTempSubdirectory()
{
// We want a location where permissions are expected to be restricted to the current user.
string directory = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
Expand All @@ -97,7 +97,7 @@ public static string GetTempSubdirectory()
/// <summary>
/// Obtains a specific temporary path in a subdirectory for file-based app artifacts, e.g., <c>/tmp/dotnet/runfile/{name}</c>.
/// </summary>
public static string GetTempSubpath(string name)
internal static string GetTempSubpath(string name)
{
return Path.Join(GetTempSubdirectory(), name);
}
Expand Down Expand Up @@ -154,10 +154,29 @@ internal static ImmutableArray<CSharpDirective> EvaluateDirectives(
return directives;
}

public void CreateProjectInstance(
public static ProjectRootElement CreateProjectRootElement(string filePath, string targetFrameworkVersion)
{
var fullPath = Path.GetFullPath(filePath);

Comment thread
jjonescz marked this conversation as resolved.
Outdated
var projectCollection = new ProjectCollection();
Comment thread
jjonescz marked this conversation as resolved.
Outdated

var builder = new VirtualProjectBuilder(fullPath, targetFrameworkVersion);

builder.CreateProjectInstance(
projectCollection,
static (sourceFile, textSpan, message) => throw new InvalidOperationException($"{sourceFile.GetLocationString(textSpan)}: {FileBasedProgramsResources.DirectiveError}: {message}"),
out _,
out var projectRootElement,
out _);

return projectRootElement;
}
Comment thread
jjonescz marked this conversation as resolved.
Outdated

internal void CreateProjectInstance(
ProjectCollection projectCollection,
ErrorReporter errorReporter,
out ProjectInstance project,
out ProjectRootElement projectRootElement,
out ImmutableArray<CSharpDirective> evaluatedDirectives,
ImmutableArray<CSharpDirective> directives = default,
Action<IDictionary<string, string>>? addGlobalProperties = null,
Expand All @@ -168,16 +187,16 @@ public void CreateProjectInstance(
directives = FileLevelDirectiveHelpers.FindDirectives(EntryPointSourceFile, validateAllDirectives, errorReporter);
}

project = CreateProjectInstance(projectCollection, directives, addGlobalProperties);
(projectRootElement, project) = CreateProjectInstance(projectCollection, directives, addGlobalProperties);

evaluatedDirectives = EvaluateDirectives(project, directives, EntryPointSourceFile, errorReporter);
if (evaluatedDirectives != directives)
{
project = CreateProjectInstance(projectCollection, evaluatedDirectives, addGlobalProperties);
(projectRootElement, project) = CreateProjectInstance(projectCollection, evaluatedDirectives, addGlobalProperties);
}
}

private ProjectInstance CreateProjectInstance(
private (ProjectRootElement, ProjectInstance) CreateProjectInstance(
ProjectCollection projectCollection,
ImmutableArray<CSharpDirective> directives,
Action<IDictionary<string, string>>? addGlobalProperties = null)
Expand All @@ -191,12 +210,14 @@ private ProjectInstance CreateProjectInstance(
addGlobalProperties(globalProperties);
}

return ProjectInstance.FromProjectRootElement(projectRoot, new ProjectOptions
var projectInstance = ProjectInstance.FromProjectRootElement(projectRoot, new ProjectOptions
{
ProjectCollection = projectCollection,
GlobalProperties = globalProperties,
});

return (projectRoot, projectInstance);

ProjectRootElement CreateProjectRootElement(ProjectCollection projectCollection)
{
var projectFileFullPath = Path.ChangeExtension(EntryPointFileFullPath, ".csproj");
Expand All @@ -221,7 +242,7 @@ ProjectRootElement CreateProjectRootElement(ProjectCollection projectCollection)
}
}

public static void WriteProjectFile(
internal static void WriteProjectFile(
TextWriter writer,
ImmutableArray<CSharpDirective> directives,
IEnumerable<(string name, string value)> defaultProperties,
Expand Down Expand Up @@ -531,7 +552,7 @@ static void WriteImport(TextWriter writer, string project, CSharpDirective.Sdk s
}
}

public static SourceText? RemoveDirectivesFromFile(ImmutableArray<CSharpDirective> directives, SourceText text)
internal static SourceText? RemoveDirectivesFromFile(ImmutableArray<CSharpDirective> directives, SourceText text)
{
if (directives.Length == 0)
{
Expand All @@ -549,7 +570,7 @@ static void WriteImport(TextWriter writer, string project, CSharpDirective.Sdk s
return text;
}

public static void RemoveDirectivesFromFile(ImmutableArray<CSharpDirective> directives, SourceText text, string filePath)
internal static void RemoveDirectivesFromFile(ImmutableArray<CSharpDirective> directives, SourceText text, string filePath)
{
if (RemoveDirectivesFromFile(directives, text) is { } modifiedText)
{
Expand Down
1 change: 1 addition & 0 deletions test/dotnet-watch.Tests/dotnet-watch.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<ProjectReference Include="..\Microsoft.DotNet.HotReload.Test.Utilities\Microsoft.DotNet.HotReload.Test.Utilities.csproj" ExcludeAssets="Runtime" />
<ProjectReference Include="..\Microsoft.NET.TestFramework\Microsoft.NET.TestFramework.csproj" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" />
<PackageReference Include="Xunit.Combinatorial" />
<PackageReference Include="Moq" />
Expand Down
Loading