Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
8 changes: 4 additions & 4 deletions Standardly.Tests.Unit/Standardly.Tests.Unit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
1 change: 1 addition & 0 deletions Standardly/.vsextension/string-resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"Standardly.ShowMyUsageStats.DisplayName": "Show My Usage Stats",
"Standardly.ShowTemplatesFolderCommand.DisplayName": "Show Template Folder",
"Standardly.ShowLicenseCommand.DisplayName": "Show License",
"Standardly.ShowConfigurationCommand.DisplayName": "Show Configuration Settings",
"Standardly.ToolWindows.GenerateCodeToolWindowCommand.DisplayName": "Standardly - Generate Code"
}
2 changes: 1 addition & 1 deletion Standardly/Brokers/CodeGenerationBroker.GenerateCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal partial class CodeGenerationBroker
{
public async ValueTask GenerateCodeAsync(TemplateGenerationInfo templateGenerationInfo)
{
await this.standardlyClient.GenerationClient.GenerateCodeAsync(templateGenerationInfo);
await this.standardlyClient.CodeGenerations.GenerateCodeAsync(templateGenerationInfo);
}
}
}
2 changes: 1 addition & 1 deletion Standardly/Brokers/CodeGenerationBroker.Templates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public async ValueTask<List<Template>> FindAllTemplatesAsync()
string templateFolderPath = Path.Combine(Path.GetDirectoryName(assembly), @"Templates");
string templateDefinitionFileName = "Template.json";

return await this.standardlyClient.TemplateClient
return await this.standardlyClient.Templates
.FindAllTemplatesAsync(templateFolderPath, templateDefinitionFileName);
}
}
Expand Down
149 changes: 149 additions & 0 deletions Standardly/Commands/GenerateCodeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;
using Microsoft.VisualStudio.ProjectSystem.Query;
using Standardly.Models.Configurations;
using Standardly.ToolWindows;

namespace Standardly.Commands
Expand Down Expand Up @@ -56,8 +64,149 @@ public override Task InitializeAsync(CancellationToken cancellationToken)
/// <inheritdoc />
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
string assemblyLocation = Assembly.GetExecutingAssembly().Location;
string extensionFolder = Path.GetDirectoryName(assemblyLocation);
string appSettingsRelativePath = "appsettings.json";
string appSettingsPath = Path.Combine(extensionFolder, appSettingsRelativePath);

var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(extensionFolder)
.AddJsonFile(appSettingsPath, optional: true, reloadOnChange: true);

var configuration = configurationBuilder.Build();

var standardlyConfiguration = configuration
.GetSection("standardlyConfiguration")
.Get<StandardlyConfiguration>();

var structureInfo = await GetSettings(context, cancellationToken);
try
{
var standardlyClient = new Core.Clients.StandardlyClient();
}
catch (Exception ex)
{
throw;
}

//var frmGenerate = new frmGenerate(structureInfo, standardlyClient);
//frmGenerate.ShowDialog();

await this.Extensibility.Shell()
.ShowToolWindowAsync<GenerateCodeToolWindow>(activate: true, cancellationToken);
}

private async ValueTask<StructureInfo> GetSettings(
IClientContext context,
CancellationToken cancellationToken)
{
ISolutionSnapshot? solution = (await context.Extensibility.Workspaces().QuerySolutionAsync(solution =>
{
return solution
.With(x => x.Path)
.With(x => x.BaseName)
.With(x => x.Directory)
.With(x => x.FileName);
},
cancellationToken)).FirstOrDefault();

List<IProjectSnapshot> projects = (await context.Extensibility.Workspaces().QueryProjectsAsync(projects =>
{
return projects
.With(x => x.Path)
.With(x => x.Name)
.With(x => x.Type)
.With(x => x.ProjectReferences)
.With(x => x.DefaultNamespace)
.With(x => x.Properties)
.With(x => x.Folders)
.With(x => x.Capabilities)
.With(x => x.Kind);
},
cancellationToken)).ToList();

IProjectSnapshot? activeProject = await context.GetActiveProjectAsync(project =>
{
return project
.With(x => x.Path)
.With(x => x.Name)
.With(x => x.Type)
.With(x => x.ProjectReferences)
.With(x => x.DefaultNamespace)
.With(x => x.Properties)
.With(x => x.Folders)
.With(x => x.Capabilities)
.With(x => x.Kind);
},
new CancellationToken());

IProjectSnapshot? project = activeProject ?? projects.FirstOrDefault();

if (project == null)
{
throw new Exception("No project found.");
}

var structureInfo = new StructureInfo();
string assumeProjectName = project.Name;

switch (project.Name)
{
case string s when s.Contains(".Tests"):
{
assumeProjectName = project.Name
.Substring(0, Math.Max(project.Name.IndexOf(".Tests"), 0));

project = projects.FirstOrDefault(project => project.Name == assumeProjectName);
break;
}
case string s when s.Contains(".Infrastructure"):
{
assumeProjectName = project.Name
.Substring(0, Math.Max(project.Name.IndexOf(".Infrastructure"), 0));

project = projects.FirstOrDefault(project => project.Name == assumeProjectName);
break;
}
}

IProjectSnapshot? unitTestProject = projects
.FirstOrDefault(project => project.Name == $"{assumeProjectName}.Tests.Unit");

IProjectSnapshot? acceptanceTestProject = projects
.FirstOrDefault(project => project.Name == $"{assumeProjectName}.Tests.Acceptance");

IProjectSnapshot? integrationTestProject = projects
.FirstOrDefault(project => project.Name == $"{assumeProjectName}.Tests.Integration");

IProjectSnapshot? infrastructureProject = projects
.FirstOrDefault(project => project.Name == $"{assumeProjectName}.Infrastructure");


structureInfo.SolutionFolder = solution.Directory;
structureInfo.RootNameSpace = project.Name;

structureInfo.Project = project != null
? new ProjectInfo(projectName: project.Name, projectPath: project.Path)
: null;

structureInfo.UnitTestProject = unitTestProject != null
? new ProjectInfo(projectName: unitTestProject.Name, projectPath: unitTestProject.Path)
: null;

structureInfo.AcceptanceTestProject = acceptanceTestProject != null
? new ProjectInfo(projectName: acceptanceTestProject.Name, projectPath: acceptanceTestProject.Path)
: null;

structureInfo.IntegrationTestProject = integrationTestProject != null
? new ProjectInfo(projectName: integrationTestProject.Name, projectPath: integrationTestProject.Path)
: null;

structureInfo.InfrastructureProject = infrastructureProject != null
? new ProjectInfo(projectName: infrastructureProject.Name, projectPath: infrastructureProject.Path)
: null;

return structureInfo;
}
}
}
65 changes: 65 additions & 0 deletions Standardly/Commands/ShowConfigurationCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// ---------------------------------------------------------------
// Copyright (c) Christo du Toit. All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;

namespace Standardly.Commands
{
/// <summary>
/// ShowConfigurationCommand handler.
/// </summary>
[VisualStudioContribution]
internal class ShowConfigurationCommand : Command
{
private readonly TraceSource logger;

/// <summary>
/// Initializes a new instance of the <see cref="ShowConfigurationCommand"/> class.
/// </summary>
/// <param name="extensibility">Extensibility object.</param>
/// <param name="traceSource">Trace source instance to utilize.</param>
public ShowConfigurationCommand(VisualStudioExtensibility extensibility, TraceSource traceSource)
: base(extensibility)
{
// This optional TraceSource can be used for logging in the command. You can use dependency injection
// to access other services here as well.
this.logger = Requires.NotNull(traceSource, nameof(traceSource));
}

/// <inheritdoc />
public override CommandConfiguration CommandConfiguration =>
new(displayName: "%Standardly.ShowConfigurationCommand.DisplayName%")
{
Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
};

/// <inheritdoc />
public override Task InitializeAsync(CancellationToken cancellationToken)
{
// Use InitializeAsync for any one-time setup or initialization.
return base.InitializeAsync(cancellationToken);
}

/// <inheritdoc />
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
await Task.Run(() =>
{
string assembly = Assembly.GetExecutingAssembly().Location;
string licensePath = Path.Combine(Path.GetDirectoryName(assembly), "appsettings.json");

Process.Start("notepad.exe", licensePath);
});
}
}
}
2 changes: 1 addition & 1 deletion Standardly/Commands/ShowMyUsageStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public override Task InitializeAsync(CancellationToken cancellationToken)
/// <inheritdoc />
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
await context.ShowPromptAsync("Hello from an extension!", PromptOptions.OK, cancellationToken);
await this.Extensibility.Shell().ShowPromptAsync("Hello from an extension!", PromptOptions.OK, cancellationToken);
}
}
}
15 changes: 9 additions & 6 deletions Standardly/ExtensionEntrypoint.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// ----------------------------------------------------------------------------------
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers
// ----------------------------------------------------------------------------------
// ---------------------------------------------------------------
// Copyright (c) Christo du Toit. All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.Extensibility;
Expand All @@ -10,7 +12,7 @@
namespace Standardly
{
/// <summary>
/// Extension entrypoint for the VisualStudio.Extensibility extension.
/// Extension entry point for the VisualStudio.Extensibility extension.
/// </summary>
[VisualStudioContribution]
internal class ExtensionEntrypoint : Extension
Expand All @@ -22,7 +24,8 @@ internal class ExtensionEntrypoint : Extension
id: "Standardly.4f725561-953f-4998-99c2-ec58132d8d48",
version: this.ExtensionAssemblyVersion,
publisherName: "Christo du Toit",
displayName: "Standardly"),
displayName: "Standardly",
description: "Standardly - Your Code Generation Engine"),
};

/// <inheritdoc />
Expand All @@ -47,8 +50,8 @@ protected override void InitializeServices(IServiceCollection serviceCollection)
MenuChild.Command<ShowTemplatesFolderCommand>(),
MenuChild.Command<ShowMyUsageStats>(),
MenuChild.Command<ShowLicenseCommand>(),
MenuChild.Command<ShowConfigurationCommand>(),
},
Priority = 1000,
};
}
}
30 changes: 30 additions & 0 deletions Standardly/Models/Configurations/ProjectInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// ---------------------------------------------------------------
// Copyright (c) Christo du Toit. All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System.IO;

namespace Standardly.Models.Configurations
{
internal class ProjectInfo
{
public ProjectInfo()
{ }

public ProjectInfo(string projectName, string projectPath)
{
ProjectName = projectName;
ProjectFullPath = projectPath;
FileInfo fileInfo = new FileInfo(projectPath);
ProjectFolder = fileInfo?.Directory?.FullName ?? string.Empty;
ProjectFile = fileInfo?.Name ?? string.Empty;
}

public string ProjectName { get; set; } = string.Empty;
public string ProjectFullPath { get; set; } = string.Empty;
public string ProjectFolder { get; set; } = string.Empty;
public string ProjectFile { get; set; } = string.Empty;
}
}
19 changes: 19 additions & 0 deletions Standardly/Models/Configurations/StructureInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// ---------------------------------------------------------------
// Copyright (c) Christo du Toit. All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

namespace Standardly.Models.Configurations
{
internal class StructureInfo
{
public string? SolutionFolder { get; set; }
public string? RootNameSpace { get; set; }
public ProjectInfo? Project { get; set; }
public ProjectInfo? UnitTestProject { get; set; }
public ProjectInfo? AcceptanceTestProject { get; set; }
public ProjectInfo? IntegrationTestProject { get; set; }
public ProjectInfo? InfrastructureProject { get; set; }
}
}
Loading