diff --git a/Standardly.Tests.Unit/Standardly.Tests.Unit.csproj b/Standardly.Tests.Unit/Standardly.Tests.Unit.csproj
index 901806b..4cfdc53 100644
--- a/Standardly.Tests.Unit/Standardly.Tests.Unit.csproj
+++ b/Standardly.Tests.Unit/Standardly.Tests.Unit.csproj
@@ -10,13 +10,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Standardly/.vsextension/string-resources.json b/Standardly/.vsextension/string-resources.json
index 7ad79ab..7396b3f 100644
--- a/Standardly/.vsextension/string-resources.json
+++ b/Standardly/.vsextension/string-resources.json
@@ -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"
}
diff --git a/Standardly/Brokers/CodeGenerationBroker.GenerateCode.cs b/Standardly/Brokers/CodeGenerationBroker.GenerateCode.cs
index e04f720..3555cd4 100644
--- a/Standardly/Brokers/CodeGenerationBroker.GenerateCode.cs
+++ b/Standardly/Brokers/CodeGenerationBroker.GenerateCode.cs
@@ -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);
}
}
}
diff --git a/Standardly/Brokers/CodeGenerationBroker.Templates.cs b/Standardly/Brokers/CodeGenerationBroker.Templates.cs
index 70c56eb..17cd996 100644
--- a/Standardly/Brokers/CodeGenerationBroker.Templates.cs
+++ b/Standardly/Brokers/CodeGenerationBroker.Templates.cs
@@ -20,7 +20,7 @@ public async ValueTask> 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);
}
}
diff --git a/Standardly/Commands/GenerateCodeCommand.cs b/Standardly/Commands/GenerateCodeCommand.cs
index b26c783..b4e3ca5 100644
--- a/Standardly/Commands/GenerateCodeCommand.cs
+++ b/Standardly/Commands/GenerateCodeCommand.cs
@@ -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
@@ -56,8 +64,149 @@ public override Task InitializeAsync(CancellationToken cancellationToken)
///
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();
+
+ 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(activate: true, cancellationToken);
}
+
+ private async ValueTask 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 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;
+ }
}
}
diff --git a/Standardly/Commands/ShowConfigurationCommand.cs b/Standardly/Commands/ShowConfigurationCommand.cs
new file mode 100644
index 0000000..d40d6be
--- /dev/null
+++ b/Standardly/Commands/ShowConfigurationCommand.cs
@@ -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
+{
+ ///
+ /// ShowConfigurationCommand handler.
+ ///
+ [VisualStudioContribution]
+ internal class ShowConfigurationCommand : Command
+ {
+ private readonly TraceSource logger;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Extensibility object.
+ /// Trace source instance to utilize.
+ 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));
+ }
+
+ ///
+ public override CommandConfiguration CommandConfiguration =>
+ new(displayName: "%Standardly.ShowConfigurationCommand.DisplayName%")
+ {
+ Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
+ };
+
+ ///
+ public override Task InitializeAsync(CancellationToken cancellationToken)
+ {
+ // Use InitializeAsync for any one-time setup or initialization.
+ return base.InitializeAsync(cancellationToken);
+ }
+
+ ///
+ 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);
+ });
+ }
+ }
+}
diff --git a/Standardly/Commands/ShowMyUsageStats.cs b/Standardly/Commands/ShowMyUsageStats.cs
index 2db07b5..aa1f1ed 100644
--- a/Standardly/Commands/ShowMyUsageStats.cs
+++ b/Standardly/Commands/ShowMyUsageStats.cs
@@ -52,7 +52,7 @@ public override Task InitializeAsync(CancellationToken cancellationToken)
///
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);
}
}
}
diff --git a/Standardly/ExtensionEntrypoint.cs b/Standardly/ExtensionEntrypoint.cs
index 328c508..d98859f 100644
--- a/Standardly/ExtensionEntrypoint.cs
+++ b/Standardly/ExtensionEntrypoint.cs
@@ -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;
@@ -10,7 +12,7 @@
namespace Standardly
{
///
- /// Extension entrypoint for the VisualStudio.Extensibility extension.
+ /// Extension entry point for the VisualStudio.Extensibility extension.
///
[VisualStudioContribution]
internal class ExtensionEntrypoint : Extension
@@ -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"),
};
///
@@ -47,8 +50,8 @@ protected override void InitializeServices(IServiceCollection serviceCollection)
MenuChild.Command(),
MenuChild.Command(),
MenuChild.Command(),
+ MenuChild.Command(),
},
- Priority = 1000,
};
}
}
diff --git a/Standardly/Models/Configurations/ProjectInfo.cs b/Standardly/Models/Configurations/ProjectInfo.cs
new file mode 100644
index 0000000..0bdb4b4
--- /dev/null
+++ b/Standardly/Models/Configurations/ProjectInfo.cs
@@ -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;
+ }
+}
diff --git a/Standardly/Models/Configurations/StructureInfo.cs b/Standardly/Models/Configurations/StructureInfo.cs
new file mode 100644
index 0000000..ee53520
--- /dev/null
+++ b/Standardly/Models/Configurations/StructureInfo.cs
@@ -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; }
+ }
+}
diff --git a/Standardly/Standardly.csproj b/Standardly/Standardly.csproj
index 3f0b078..530c086 100644
--- a/Standardly/Standardly.csproj
+++ b/Standardly/Standardly.csproj
@@ -1,7 +1,7 @@
- net7.0-windows
+ net8.0-windows
disable
enable
true
@@ -11,9 +11,16 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -23,14 +30,26 @@
-
-
- MSBuild:Compile
-
-
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+ MSBuild:Compile
+
+
+
+
+
+
+
-
-
-
-
diff --git a/Standardly/ToolWindows/GenerateCodeToolWindow.cs b/Standardly/ToolWindows/GenerateCodeToolWindow.cs
index 31673ea..c952ca8 100644
--- a/Standardly/ToolWindows/GenerateCodeToolWindow.cs
+++ b/Standardly/ToolWindows/GenerateCodeToolWindow.cs
@@ -29,7 +29,7 @@ public class GenerateCodeToolWindow : ToolWindow
public GenerateCodeToolWindow(VisualStudioExtensibility extensibility)
: base(extensibility)
{
- this.Title = "My Tool Window";
+ this.Title = "Standardly - Generate Code";
}
///
diff --git a/Standardly/ToolWindows/GenerateCodeToolWindowCommand.cs b/Standardly/ToolWindows/GenerateCodeToolWindowCommand.cs
index 185bff0..f38ee4a 100644
--- a/Standardly/ToolWindows/GenerateCodeToolWindowCommand.cs
+++ b/Standardly/ToolWindows/GenerateCodeToolWindowCommand.cs
@@ -22,23 +22,18 @@ public class GenerateCodeToolWindowCommand : Command
/// Extensibility object instance.
public GenerateCodeToolWindowCommand(VisualStudioExtensibility extensibility)
: base(extensibility)
- {
- }
+ { }
///
- public override CommandConfiguration CommandConfiguration => new(displayName: "%Standardly.ToolWindows.GenerateCodeToolWindowCommand.DisplayName%")
- {
- // Use this object initializer to set optional parameters for the command. The required parameter,
- // displayName, is set above. To localize the displayName, add an entry in .vsextension\string-resources.json
- // and reference it here by passing "%Standardly.ToolWindows.GenerateCodeToolWindowCommand.DisplayName%" as a constructor parameter.
- Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
- Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
- };
+ public override CommandConfiguration CommandConfiguration =>
+ new(displayName: "Standardly.ToolWindows.GenerateCodeToolWindowCommand.DisplayName%")
+ { };
///
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
- await this.Extensibility.Shell().ShowToolWindowAsync(activate: true, cancellationToken);
+ await this.Extensibility.Shell()
+ .ShowToolWindowAsync(activate: true, cancellationToken);
}
}
}
diff --git a/Standardly/appsettings.json b/Standardly/appsettings.json
new file mode 100644
index 0000000..cf15228
--- /dev/null
+++ b/Standardly/appsettings.json
@@ -0,0 +1,28 @@
+{
+ "standardlyConfiguration": {
+ "general": {
+ "addEditorConfigFile": true,
+ "addGitIgnoreFile": true,
+ "addGitAttributesFile": true,
+ "addReadmeFile": true,
+ "addLicenseFile": true,
+ "licenseType": "MIT"
+ },
+ "user": {
+ "name": "",
+ "githubEmail": "",
+ "githubUsername": ""
+ },
+ "locations": {
+ "brokers": "Brokers",
+ "controllers": "Controllers",
+ "clients": "Clients",
+ "coordinationServices": "Coordinations",
+ "foundationServices": "Foundations",
+ "models": "Models",
+ "orchestrationServices": "Orchestrations",
+ "processingServices": "Processings",
+ "services": "Services"
+ }
+ }
+}
diff --git a/Standardly/models/configurations/General.cs b/Standardly/models/configurations/General.cs
new file mode 100644
index 0000000..4197304
--- /dev/null
+++ b/Standardly/models/configurations/General.cs
@@ -0,0 +1,18 @@
+// ---------------------------------------------------------------
+// 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 General
+ {
+ public bool addEditorConfigFile { get; set; }
+ public bool addGitIgnoreFile { get; set; }
+ public bool addGitAttributesFile { get; set; }
+ public bool addReadmeFile { get; set; }
+ public bool addLicenseFile { get; set; }
+ public string LicenseType { get; set; }
+ }
+}
diff --git a/Standardly/models/configurations/Locations.cs b/Standardly/models/configurations/Locations.cs
new file mode 100644
index 0000000..070bf8f
--- /dev/null
+++ b/Standardly/models/configurations/Locations.cs
@@ -0,0 +1,21 @@
+// ---------------------------------------------------------------
+// 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 Locations
+ {
+ public string Brokers { get; set; }
+ public string Controllers { get; set; }
+ public string Clients { get; set; }
+ public string CoordinationServices { get; set; }
+ public string FoundationServices { get; set; }
+ public string Models { get; set; }
+ public string OrchestrationServices { get; set; }
+ public string ProcessingServices { get; set; }
+ public string Services { get; set; }
+ }
+}
diff --git a/Standardly/models/configurations/StandardlyConfiguration.cs b/Standardly/models/configurations/StandardlyConfiguration.cs
new file mode 100644
index 0000000..494001c
--- /dev/null
+++ b/Standardly/models/configurations/StandardlyConfiguration.cs
@@ -0,0 +1,15 @@
+// ---------------------------------------------------------------
+// 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 StandardlyConfiguration
+ {
+ public General General { get; set; }
+ public User User { get; set; }
+ public Locations Locations { get; set; }
+ }
+}
diff --git a/Standardly/models/configurations/User.cs b/Standardly/models/configurations/User.cs
new file mode 100644
index 0000000..724a45e
--- /dev/null
+++ b/Standardly/models/configurations/User.cs
@@ -0,0 +1,15 @@
+// ---------------------------------------------------------------
+// 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 User
+ {
+ public string Name { get; set; }
+ public string GithubEmail { get; set; }
+ public string GithubUsername { get; set; }
+ }
+}