Added an untested generation command.

This commit is contained in:
Harrison Deng 2022-05-16 01:21:51 -05:00
parent a46f8d4ef6
commit 68cd4fdcf2
5 changed files with 176 additions and 2 deletions

26
DotNetResxUtils/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net6.0/DotNetResxUtils.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
DotNetResxUtils/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotNetResxUtils.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/DotNetResxUtils.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/DotNetResxUtils.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.IO;
using System.CommandLine;
using System.Text.Json;
using System.Threading.Tasks;
using System.Resources.NetStandard;
namespace DotNetResxUtils.Commands
{
internal class GenerationCommand
{
const string NAME = "generate";
const string DESC = "Generate a .resx file.";
public GenerationCommand(RootCommand rootCmd)
{
Command cmd = new Command(NAME, DESC);
rootCmd.AddCommand(cmd);
Option<FileInfo?> fromOpt = new Option<FileInfo?>("--from", "Generates a .resx file from the given file.");
Argument<FileInfo> destArg = new Argument<FileInfo>("destination", "The destination path to store this file. If no extension is given, .resx will automatically be concatenated.");
cmd.AddOption(fromOpt);
cmd.AddArgument(destArg);
cmd.SetHandler<FileInfo, FileInfo?>(CommandHandler, destArg, fromOpt);
}
private async void CommandHandler(FileInfo to, FileInfo? from)
{
IDictionary<string, string> flattened = new Dictionary<string, string>();
if (from != null)
{
flattened = await FlattenJson(from);
}
using (ResXResourceWriter resxWriter = new ResXResourceWriter(to.FullName))
{
foreach (KeyValuePair<string, string> keyVal in flattened)
{
resxWriter.AddResource(keyVal.Key, keyVal.Value);
}
}
}
private async Task<IDictionary<string, string>> FlattenJson(FileInfo jsonFile)
{
JsonElement jsonObj;
using (FileStream readStream = jsonFile.OpenRead())
{
jsonObj = await JsonSerializer.DeserializeAsync<JsonElement>(readStream);
}
Dictionary<string, string> result = new Dictionary<string, string>();
FlattenJsonElement(result, jsonObj, "");
return result;
}
private void FlattenJsonElement(IDictionary<string, string> flattened, JsonElement jsonElement, string namepath)
{
if (jsonElement.ValueKind == JsonValueKind.Array)
{
int itemIndex = 0;
foreach (JsonElement item in jsonElement.EnumerateArray())
{
FlattenJsonElement(flattened, item, namepath + $"[{itemIndex}]");
}
}
else if (jsonElement.ValueKind == JsonValueKind.Object)
{
foreach (JsonProperty item in jsonElement.EnumerateObject())
{
FlattenJsonElement(flattened, item.Value, namepath + $".{item.Name}");
}
}
else
{
string? stored = jsonElement.GetString();
if (stored != null)
{
flattened[namepath] = stored;
}
}
}
}
}

View File

@ -1,14 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- not for choosing a file extension, just designating as executable item -->
<OutputType>exe</OutputType>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<PublishReadyToRun>true</PublishReadyToRun>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<PublishTrimmed>true</PublishTrimmed>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ResXResourceReader.NetStandard" Version="1.1.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta3.22114.1" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,6 @@
using System;
using System.IO;
using System;
using System.CommandLine;
namespace DotNetResxUtils
{
@ -6,8 +8,20 @@ namespace DotNetResxUtils
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
RootCommand rootCmd = new RootCommand(".Net Resx Utils provides tools for generating, and editing .resx files.");
Command genCmd = new Command("gen", "Generate a .resx file.");
rootCmd.AddCommand(genCmd);
// See: Collection organizers - https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers
Option<FileInfo?> convertOpt = new Option<FileInfo?>("--convert", "Generates a .resx file from the given file. Currently only supports .json files.");
genCmd.AddOption(convertOpt);
Argument<string> destArg = new Argument<string>("destination", "The destination path to store this file. If no extension is given, .resx will automatically be concatenated.");
genCmd.AddArgument(destArg);
genCmd.SetHandler(async (string dst, FileInfo? from))
}
}
}