5.7 KiB
sidebar_position |
---|
6 |
Command plugins
MycroForge has a plugin system that allows you to extend the CLI with your own commands.
This section will guide you through the process of creating your own extension to the m4g
command.
MycroForge is written in C# sharp and this is the same for plugins, so decent knowledge about C#
& .NET
is required.
In this tutorial we will create a command plugin that extens the m4g
command with a dotenv
sub command.
What this command will do is generate a .env
file in the current directory and print a message to the console.
Setup
To start creating command plugins for MycroFroge, make sure you've added the devdisciples package repository. This can be done by running the following command.
dotnet nuget add source --name devdisciples https://git.devdisciples.com/api/packages/devdisciples/nuget/index.json
Run the following command to add the MycroForge.PluginTemplate.Package
.
dotnet add package --source devdisciples --version 1.0.0 MycroForge.PluginTemplate.Package
Initialize a plugin package
Generate a template plugin project by running the following command.
m4g plugin init My.Dotenv.Plugin
This should generate the following folder structure.
My.Dotenv.Plugin
┣ 📜HelloWorldCommand.cs
┣ 📜HelloWorldCommandPlugin.cs
┗ 📜My.Dotenv.Plugin.csproj
Rename the following files. Also rename the classes in these files, the easiest way in vscode
is to right click the class name and select the Rename symbol
action. Note that this action does not (necessarily) rename the files!
HelloWorldCommand.cs => DotenvCommand.cs
HelloWorldCommandPlugin.cs => DotenvCommandPlugin.cs
Modify Name
property in DotenvCommandPlugin.cs
.
// Before
public class DotenvCommandPlugin : ICommandPlugin
{
public string Name => "My.Plugin";
public void RegisterServices(IServiceCollection services)
{
services.AddScoped<ISubCommandOf<RootCommand>, HelloWorldCommand>();
}
}
// After
public class DotenvCommandPlugin : ICommandPlugin
{
public string Name => "My.Dotenv.Plugin";
public void RegisterServices(IServiceCollection services)
{
services.AddScoped<ISubCommandOf<RootCommand>, HelloWorldCommand>();
}
}
Modify DotenvCommand.cs
.
// Before
public class DotenvCommand : Command, ISubCommandOf<RootCommand>
{
private readonly Argument<string> NameArgument =
new(name: "name", description: "The name of the person to greet");
private readonly Option<bool> AllCapsOption =
new(aliases: ["-a", "--all-caps"], description: "Print the name in all caps");
private readonly ProjectContext _context;
public DotenvCommand(ProjectContext context) :
base("hello", "An example command generated by dotnet new using the m4gp template")
{
_context = context;
AddArgument(NameArgument);
AddOption(AllCapsOption);
this.SetHandler(ExecuteAsync, NameArgument, AllCapsOption);
}
private async Task ExecuteAsync(string name, bool allCaps)
{
name = allCaps ? name.ToUpper() : name;
await _context.CreateFile("hello_world.txt",
$"Hello {name}!",
"This file was generated by your custom command!"
);
}
}
// After
public class DotenvCommand : Command, ISubCommandOf<RootCommand>
{
private readonly Argument<string> VarsArgument =
new(name: "vars", description: "Env vars to include in the .env file separated by ';'");
private readonly Option<bool> PrintOption =
new(aliases: ["-o", "--overwrite"], description: "Overwrite the .env file if it exists");
private readonly ProjectContext _context;
public DotenvCommand(ProjectContext context) :
// dotenv = the name of the sub command that will be added to the m4g command
base("dotenv", "Generate a .env file in the current directory")
{
_context = context;
AddArgument(VarsArgument);
AddOption(PrintOption);
this.SetHandler(ExecuteAsync, VarsArgument, PrintOption);
}
private async Task ExecuteAsync(string vars, bool overwrite)
{
var path = Path.Join(Environment.CurrentDirectory, ".env");
if (File.Exists(path))
{
if (overwrite)
{
await _context.WriteFile(".env", content);
return;
}
Console.WriteLine($"File {path} already exists, add the -o or --overwrite flag to overwrite it.");
}
var content = string.Join(Environment.NewLine, vars.Split(';'));
await _context.CreateFile(".env", content);
}
}
Install the plugin
Open a terminal an make sure you're in the root directory of the plugin, i.e. the My.Dotenv.Plugin
folder.
Run the following command to install the plugin.
m4g plugin install --platform <platform=linux_arm|linux_arm64|linux_x64|osx_arm64|osx_x64>
Make sure to choose the right platform option for your machine.
If everything went well then running m4g
should now also show a dotenv
command.
Test the plugin
Try running m4g dotenv "FIRSTNAME=JOHN;LASTNAME=JOE"
, this should generate a .env
in the current directory with the vars you specified.
Uninstall the plugin
Uninstall the plugin by running m4g plugin install My.Dotenv.Plugin
.
Resources
For examples of how the core commands are implemented, you can take a look at the commands in the MycroForge.CLI.Commands namespace.
The MycroForge.CLI project uses SystemCommand.Line for the CLI support, check out the Microsoft documentation for more info.