Skip to content

Commit 114fc20

Browse files
committed
Added command line tool API and beginning of GUI tool API.
1 parent a263af0 commit 114fc20

File tree

62 files changed

+2220
-190
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2220
-190
lines changed

doc/public-api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// TODO

src/.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ csharp_style_var_for_built_in_types = false:warning
273273
csharp_style_var_when_type_is_apparent = true:warning
274274
csharp_style_var_elsewhere = false:warning
275275

276+
# IDE0160: Convert to file-scoped namespace
277+
csharp_style_namespace_declarations = file_scoped:warning
278+
276279
# dotnet_style_allow_multiple_blank_lines_experimental
277280
dotnet_diagnostic.IDE2000.severity = warning
278281

src/DevToys.sln

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
44
VisualStudioVersion = 17.4.33122.133
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.Wasm", "app\dev\platforms\DevToys.Wasm\DevToys.Wasm.csproj", "{40071C50-C26A-44EA-9AD4-B351BF75124C}"
7+
ProjectSection(ProjectDependencies) = postProject
8+
{5F7B5C76-BD3C-4FF4-85A7-2423623164FA} = {5F7B5C76-BD3C-4FF4-85A7-2423623164FA}
9+
EndProjectSection
710
EndProject
811
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.Windows", "app\dev\platforms\DevToys.Windows\DevToys.Windows.csproj", "{71E79DDF-7937-406B-83DA-D4B274EFC8CC}"
12+
ProjectSection(ProjectDependencies) = postProject
13+
{5F7B5C76-BD3C-4FF4-85A7-2423623164FA} = {5F7B5C76-BD3C-4FF4-85A7-2423623164FA}
14+
EndProjectSection
915
EndProject
1016
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{0AC87D9B-BBEC-4DCE-A9D4-82A159E5E7C1}"
1117
EndProject
@@ -22,6 +28,10 @@ EndProject
2228
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{396A7B69-D713-458B-B765-CCF53459A97A}"
2329
EndProject
2430
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "platforms", "platforms", "{3D2285D5-0E44-4B1A-9B74-2BBE3108D5B7}"
31+
ProjectSection(SolutionItems) = preProject
32+
app\dev\platforms\Directory.Build.props = app\dev\platforms\Directory.Build.props
33+
app\dev\platforms\Directory.Build.targets = app\dev\platforms\Directory.Build.targets
34+
EndProjectSection
2535
EndProject
2636
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{9771D1F8-D331-4B26-8E96-6024893009F4}"
2737
ProjectSection(SolutionItems) = preProject
@@ -43,11 +53,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.Api", "app\dev\DevT
4353
EndProject
4454
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.Core", "app\dev\DevToys.Core\DevToys.Core.csproj", "{1DC3D77F-B026-4FD0-9D73-81BC80B21F1C}"
4555
EndProject
46-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.DefaultTools", "app\dev\DevToys.DefaultTools\DevToys.DefaultTools.csproj", "{5F7B5C76-BD3C-4FF4-85A7-2423623164FA}"
56+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.Tools", "app\dev\DevToys.Tools\DevToys.Tools.csproj", "{5F7B5C76-BD3C-4FF4-85A7-2423623164FA}"
4757
EndProject
4858
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "DevToys.UI", "app\dev\DevToys.UI\DevToys.UI.shproj", "{6279C845-92F8-4333-AB99-3D213163593C}"
4959
EndProject
5060
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.CLI", "app\dev\platforms\DevToys.CLI\DevToys.CLI.csproj", "{A1CB6EEE-3CD2-416C-85E0-2C612FE2DF49}"
61+
ProjectSection(ProjectDependencies) = postProject
62+
{5F7B5C76-BD3C-4FF4-85A7-2423623164FA} = {5F7B5C76-BD3C-4FF4-85A7-2423623164FA}
63+
EndProjectSection
5164
EndProject
5265
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevToys.UnitTests", "app\tests\DevToys.UnitTests\DevToys.UnitTests.csproj", "{FBD1A1FE-C8F7-4A1F-8B89-C81D3780DADC}"
5366
EndProject

src/Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<CommunityToolkitVersion>8.0.0</CommunityToolkitVersion>
44
<DotNetVersion>6.0.0</DotNetVersion>
55
<UnoVersion>4.6.19</UnoVersion>
6-
<UnoWasmBootstrapVersion>7.0.11</UnoWasmBootstrapVersion>
6+
<UnoWasmBootstrapVersion>8.0.0-dev.65</UnoWasmBootstrapVersion>
77
</PropertyGroup>
88
<ItemGroup>
99
<PackageVersion Include="CommunityToolkit.Common" Version="$(CommunityToolkitVersion)" />
@@ -19,7 +19,7 @@
1919
<PackageVersion Include="Moq" Version="4.18.2" />
2020
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
2121
<PackageVersion Include="Nuke.Common" Version="6.2.1" />
22-
<PackageVersion Include="Spectre.Console" Version="0.45.0" />
22+
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
2323
<PackageVersion Include="System.ComponentModel.Composition" Version="$(DotNetVersion)" />
2424
<PackageVersion Include="Uno.Core.Extensions.Logging.Singleton" Version="4.0.1" />
2525
<PackageVersion Include="Uno.Extensions.Logging.WebAssembly.Console" Version="1.4.0" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace DevToys.Api;
2+
3+
public static class DictionaryExtensions
4+
{
5+
/// <summary>
6+
/// Gets the value at the given key, or a default value.
7+
/// </summary>
8+
public static TValue? GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
9+
{
10+
return dictionary.TryGetValue(key, out TValue? value) ? value : default;
11+
}
12+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
namespace DevToys.Api;
2+
3+
public static class ExtensionOrderer
4+
{
5+
public static IEnumerable<Lazy<TExtension, TMetadata>> Order<TExtension, TMetadata>(
6+
IEnumerable<Lazy<TExtension, TMetadata>> extensions)
7+
where TMetadata : IOrderableMetadata
8+
{
9+
var graph = new Graph<TExtension, TMetadata>(extensions);
10+
return graph.TopologicalSort();
11+
}
12+
13+
public static void CheckForCycles<TExtension, TMetadata>(
14+
IEnumerable<Lazy<TExtension, TMetadata>> extensions)
15+
where TMetadata : IOrderableMetadata
16+
{
17+
var graph = new Graph<TExtension, TMetadata>(extensions);
18+
graph.CheckForCycles();
19+
}
20+
21+
private sealed class Node<TExtension, TMetadata> where TMetadata : IOrderableMetadata
22+
{
23+
internal string Name => Extension.Metadata.InternalComponentName;
24+
25+
internal HashSet<Node<TExtension, TMetadata>> NodesBefore { get; }
26+
27+
internal Lazy<TExtension, TMetadata> Extension { get; }
28+
29+
internal Node(Lazy<TExtension, TMetadata> extension)
30+
{
31+
Extension = extension;
32+
NodesBefore = new HashSet<Node<TExtension, TMetadata>>();
33+
}
34+
35+
internal void CheckForCycles()
36+
{
37+
CheckForCycles(new HashSet<Node<TExtension, TMetadata>>());
38+
}
39+
40+
internal void Visit(List<Lazy<TExtension, TMetadata>> result, HashSet<Node<TExtension, TMetadata>> seenNodes)
41+
{
42+
if (!seenNodes.Add(this))
43+
{
44+
return;
45+
}
46+
47+
foreach (Node<TExtension, TMetadata> before in NodesBefore)
48+
{
49+
before.Visit(result, seenNodes);
50+
}
51+
52+
result.Add(Extension);
53+
}
54+
55+
private void CheckForCycles(HashSet<Node<TExtension, TMetadata>> seenNodes)
56+
{
57+
if (!seenNodes.Add(this))
58+
{
59+
throw new ArgumentException($"Cycle detected in extensions. Extension Name: '{Name}'");
60+
}
61+
62+
foreach (Node<TExtension, TMetadata> before in NodesBefore)
63+
{
64+
before.CheckForCycles(seenNodes);
65+
}
66+
67+
seenNodes.Remove(this);
68+
}
69+
}
70+
71+
private sealed class Graph<TExtension, TMetadata> where TMetadata : IOrderableMetadata
72+
{
73+
private readonly Dictionary<string, Node<TExtension, TMetadata>> _nodes = new();
74+
75+
internal Graph(IEnumerable<Lazy<TExtension, TMetadata>> extensions)
76+
{
77+
foreach (Lazy<TExtension, TMetadata> extension in extensions)
78+
{
79+
var node = new Node<TExtension, TMetadata>(extension);
80+
_nodes.Add(node.Name, node);
81+
}
82+
83+
foreach (Node<TExtension, TMetadata> node in _nodes.Values)
84+
{
85+
86+
foreach (string before in node.Extension.Metadata.Before)
87+
{
88+
Node<TExtension, TMetadata> nodeAfter = _nodes[before];
89+
nodeAfter.NodesBefore.Add(node);
90+
}
91+
92+
foreach (string after in node.Extension.Metadata.After)
93+
{
94+
Node<TExtension, TMetadata> nodeBefore = _nodes[after];
95+
node.NodesBefore.Add(nodeBefore);
96+
}
97+
}
98+
}
99+
100+
internal IList<Lazy<TExtension, TMetadata>> TopologicalSort()
101+
{
102+
CheckForCycles();
103+
104+
var result = new List<Lazy<TExtension, TMetadata>>();
105+
var seenNodes = new HashSet<Node<TExtension, TMetadata>>();
106+
107+
foreach (Node<TExtension, TMetadata> node in _nodes.Values)
108+
{
109+
node.Visit(result, seenNodes);
110+
}
111+
112+
return result;
113+
}
114+
115+
internal void CheckForCycles()
116+
{
117+
foreach (Node<TExtension, TMetadata> node in _nodes.Values)
118+
{
119+
node.CheckForCycles();
120+
}
121+
}
122+
}
123+
}

src/app/dev/DevToys.Api/DevToys.Api.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCore)</TargetFrameworks>
44
</PropertyGroup>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace DevToys.Api;
2+
3+
/// <summary>
4+
/// Provides a way to import MEF components on the fly.
5+
/// </summary>
6+
public interface IMefProvider
7+
{
8+
/// <summary>
9+
/// Imports the given type.
10+
/// </summary>
11+
TExport Import<TExport>();
12+
13+
/// <summary>
14+
/// Imports the given type.
15+
/// </summary>
16+
IEnumerable<Lazy<TExport, TMetadataView>> ImportMany<TExport, TMetadataView>();
17+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace DevToys.Api;
2+
3+
/// <summary>
4+
/// Provides a set of methods to manage the application's settings.
5+
/// </summary>
6+
public interface ISettingsProvider
7+
{
8+
/// <summary>
9+
/// Raised when a setting value has changed.
10+
/// </summary>
11+
event EventHandler<SettingChangedEventArgs>? SettingChanged;
12+
13+
/// <summary>
14+
/// Gets the value of a defined setting.
15+
/// </summary>
16+
/// <typeparam name="T">The type of value that will be retrieved.</typeparam>
17+
/// <param name="settingDefinition">The <see cref="SettingDefinition{T}"/> that defines the targetted setting.</param>
18+
/// <returns>Return the value of the setting or its default value.</returns>
19+
T GetSetting<T>(SettingDefinition<T> settingDefinition);
20+
21+
/// <summary>
22+
/// Sets the value of a given setting.
23+
/// </summary>
24+
/// <typeparam name="T">The type of value that will be set.</typeparam>
25+
/// <param name="settingDefinition">The <see cref="SettingDefinition{T}"/> that defines the targetted setting.</param>
26+
/// <param name="value">The value to set</param>
27+
void SetSetting<T>(SettingDefinition<T> settingDefinition, T value);
28+
29+
/// <summary>
30+
/// Resets a given setting to its default value.
31+
/// </summary>
32+
void ResetSetting<T>(SettingDefinition<T> settingDefinition);
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace DevToys.Api;
2+
3+
public sealed class SettingChangedEventArgs : EventArgs
4+
{
5+
public string SettingName { get; }
6+
7+
public object? NewValue { get; }
8+
9+
public SettingChangedEventArgs(string settingName, object? newValue)
10+
{
11+
SettingName = settingName;
12+
NewValue = newValue;
13+
}
14+
}

0 commit comments

Comments
 (0)