Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial groundwork for command builders (#19) #20

Open
wants to merge 97 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 92 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
a3bffa9
Initial changes
VelvetToroyashi Nov 25, 2022
1595549
Merge remote-tracking branch 'upstream/main' into feat/command-builders
VelvetToroyashi Nov 25, 2022
be84e1c
Add new constructors for parameter shapes
VelvetToroyashi Nov 26, 2022
b5329e2
Add `.FromBuilder` to `CommandShape`
VelvetToroyashi Nov 26, 2022
7d776ce
Fix shapes missing/not setting parameters and properties
VelvetToroyashi Nov 26, 2022
4c66ba4
Jerry-rig `CommandShape.FromMethod` to work with CommandParameterBuilder
VelvetToroyashi Nov 26, 2022
82997c3
Add new constructor for CommandNode, deprecate `CommandMethod`, and f…
VelvetToroyashi Nov 26, 2022
e52da64
Add `CommandBuilder` and necessary APIs; requires `GroupBuilder` to b…
VelvetToroyashi Nov 26, 2022
906facc
Implement GroupBuilder
VelvetToroyashi Nov 26, 2022
c87eceb
Fix various compiler errors
VelvetToroyashi Nov 26, 2022
7ebccb8
Temporary "fix" for registration. Rewrite pending.
VelvetToroyashi Nov 26, 2022
c2b5c3b
Create compiled expression and use new constructor for commands
VelvetToroyashi Nov 27, 2022
82ffb80
Fix typo in method name
VelvetToroyashi Nov 27, 2022
1ae9c23
Expose `Name` and `Children` in `GroupBuilder`
VelvetToroyashi Nov 27, 2022
42f6bca
Add `WithType` method to `CommandParameterBuilder`
VelvetToroyashi Nov 27, 2022
3977af2
Add `FromMethod` method to `CommnadBuilder`
VelvetToroyashi Nov 27, 2022
871efe7
Register commands using builders
VelvetToroyashi Nov 27, 2022
39c1f7d
Add invocation to command, oops
VelvetToroyashi Nov 27, 2022
a6dcdc7
Difference in nullability?
VelvetToroyashi Nov 27, 2022
9458e73
Add attributes and conditions to `IChildNode`
VelvetToroyashi Nov 28, 2022
b37a6a3
Rename properties on group node to fit `IChildNode`
VelvetToroyashi Nov 28, 2022
2292097
Pass cancellation token to invocation and make expression set token
VelvetToroyashi Nov 28, 2022
bdfb089
Simplify command execution by invoking delegate
VelvetToroyashi Nov 28, 2022
83f103f
Fix compiler errors before Jax kills me
VelvetToroyashi Nov 28, 2022
a7650f1
Add `GetAttributesAndConditions` method and use where appropriate
VelvetToroyashi Nov 28, 2022
697c61b
Add built command to registered list
VelvetToroyashi Nov 28, 2022
c465acb
Handle subcommands
VelvetToroyashi Nov 28, 2022
54e1294
Fix bug with pulling service from the container in the compiled expre…
VelvetToroyashi Nov 28, 2022
d371421
Add `GroupBuilder.FromType()`
VelvetToroyashi Nov 28, 2022
0026db3
🐛 Not all children are groups
VelvetToroyashi Nov 28, 2022
ecb5d3d
Remove code for builders
VelvetToroyashi Nov 28, 2022
4596c92
Add real indexes to parameter shapes and order by that
VelvetToroyashi Nov 28, 2022
9892b94
Fix null parameter names causing tests to fail
VelvetToroyashi Nov 28, 2022
ef0ee8d
Extract as much information about parameters as possible
VelvetToroyashi Nov 28, 2022
655486c
Restore prior collection shape default value behavior
VelvetToroyashi Nov 28, 2022
8873793
Fix deadlock when evaluating group conditions
VelvetToroyashi Nov 28, 2022
1ec2505
use block expression not call expression so that the CT is set
VelvetToroyashi Nov 28, 2022
5bdf616
Extract attributes from inhertance tree as needed
VelvetToroyashi Nov 29, 2022
fcb67d1
Attributes are now always attached to a node; fix tests
VelvetToroyashi Nov 29, 2022
b9241d1
Fix some compiler warnings and add cached version of method info
VelvetToroyashi Nov 29, 2022
d4697d1
Use reflection-free version of getting method infos
VelvetToroyashi Nov 29, 2022
d8e546f
Create API for registering builders
VelvetToroyashi Nov 29, 2022
96ae435
Nullable
VelvetToroyashi Nov 29, 2022
bb1ac29
Lets *not* get sued by Microsoft
VelvetToroyashi Nov 29, 2022
a01ee60
That method is internal, oops
VelvetToroyashi Nov 29, 2022
eeea846
Nonsensical null-forgiving operator usage
VelvetToroyashi Nov 29, 2022
554a2d1
Fix botched documentation in CoerceToValueTask
VelvetToroyashi Nov 29, 2022
fb9d087
Fix inconsistency in getting attributes in conditions in NamedGreedyP…
VelvetToroyashi Nov 29, 2022
bd99238
Create delegate type for command invocations
VelvetToroyashi Nov 29, 2022
4c0cae1
Improve(?) safety of builder for switches
VelvetToroyashi Nov 29, 2022
cc58f42
Inline variable
VelvetToroyashi Nov 29, 2022
b9cabcd
Various fixes suggested by Maxine
VelvetToroyashi Nov 29, 2022
81ef88f
Clean up code when creatin ga command shape
VelvetToroyashi Nov 29, 2022
4a07a68
Fix compiler errors
VelvetToroyashi Nov 29, 2022
ff66deb
RegisterBuilder ➜ RegisterNodeBuilder
VelvetToroyashi Nov 29, 2022
ff499d3
Indentation
VelvetToroyashi Dec 2, 2022
6b19431
Space (it builds this time I swear)
VelvetToroyashi Dec 2, 2022
be535a9
fix: Add paremeter builder to parent
VelvetToroyashi Jun 4, 2023
1690814
fix!: Allow `FromMethod` to create an invocation
VelvetToroyashi Jun 4, 2023
9ab6f10
test: Add tests for command builder and tree builder
VelvetToroyashi Jun 4, 2023
8b78a90
feat: Bind built commands to the tree
VelvetToroyashi Jun 4, 2023
3cdd5d9
test: Ensure that binding works
VelvetToroyashi Jun 4, 2023
1959c45
fix: Don't merge nonexistent groups
VelvetToroyashi Jun 4, 2023
2cc7f43
docs: Reword CommandBuilder.WithInvocation
VelvetToroyashi Jun 7, 2023
f2835c9
fix!: Use OneOf<char, string> in option methods
VelvetToroyashi Jun 7, 2023
ed4a4b9
fix: Conform to new API
VelvetToroyashi Jun 7, 2023
f7b0962
refactor: Formatting
VelvetToroyashi Jun 7, 2023
8649ed6
refactor!: Remove init from GroupBuilder.Children
VelvetToroyashi Jun 7, 2023
47e1816
refactor: Use `this.` where appropriate and remove unused usings.
VelvetToroyashi Jun 7, 2023
38eebcc
fix!: Use default value from base
VelvetToroyashi Jun 7, 2023
e3a60c1
fix: Use default value from base
VelvetToroyashi Jun 7, 2023
504b5c4
refactor: Place private readonly above
VelvetToroyashi Jun 7, 2023
dd439fb
refactor: Remove more erroneous `this.`
VelvetToroyashi Jun 7, 2023
aa7ac82
docs: Clarify "non-ephemeral"
VelvetToroyashi Jun 7, 2023
254a77b
Update Remora.Commands/Builders/CommandBuilder.cs
Nihlus Sep 17, 2023
f56179b
Update Remora.Commands/Builders/CommandBuilder.cs
Nihlus Sep 17, 2023
f9a205f
Update Remora.Commands/Builders/CommandBuilder.cs
Nihlus Sep 17, 2023
2aeb012
feat(builders)!: extract common features from builders into abstract …
VelvetToroyashi Mar 16, 2024
21a6352
fix(builders): Return TSelf and cast
VelvetToroyashi Mar 17, 2024
b8b6097
refactor(trees): Respect immutability (sorta) when merging commands
VelvetToroyashi Mar 17, 2024
60a89b1
fix(trees): Fix merging algorithm
VelvetToroyashi Mar 17, 2024
63f2207
refactor(backend)!: Remove parameter indexes
VelvetToroyashi Mar 17, 2024
30d2c4a
chore: fix merge conflict?
VelvetToroyashi Mar 17, 2024
6a4d11e
Merge branch 'main' into feat/command-builders
VelvetToroyashi Mar 17, 2024
91f9df0
refactor(builders): Make unecessarily static methods instanced
VelvetToroyashi Mar 17, 2024
6d4af34
chore: Address open issues/PR comments
VelvetToroyashi Mar 17, 2024
34a7854
fix(builders): Remove duplicate methods and pass parent down
VelvetToroyashi Mar 17, 2024
db7ea85
chore: fix compiler warnings
VelvetToroyashi Mar 17, 2024
5dac26a
Merge remote-tracking branch 'origin/feat/command-builders' into feat…
VelvetToroyashi Mar 17, 2024
0e5783d
chore: Fix build issue :v
VelvetToroyashi Mar 17, 2024
166667c
chore: :dumb: PackageVersion not PackageReference
VelvetToroyashi Mar 17, 2024
1cef637
fix(commands): Fix regression with commands that have named parameters
VelvetToroyashi Mar 17, 2024
8ec09ad
style: Fix `this.` qualifiers
VelvetToroyashi Mar 31, 2024
b2a760a
chore: Remove unused imports
VelvetToroyashi Mar 31, 2024
58a10bc
style: Reduce unecessary multi-line method sigs
VelvetToroyashi Mar 31, 2024
cd7ed3d
fix: Fix nullability in command parameters
VelvetToroyashi Mar 31, 2024
9a5530a
fix: Fix broken tests (and compiler warnings)
VelvetToroyashi Mar 31, 2024
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
6 changes: 6 additions & 0 deletions .idea/.idea.Remora.Commands/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<PackageVersion Include="Remora.Results" Version="7.4.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Remora.Results.Analyzers" Version="1.0.2" />
<PackageVersion Include="OneOf" Version="3.0.223" />
</ItemGroup>
</Project>
175 changes: 175 additions & 0 deletions Remora.Commands/Builders/AbstractCommandBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
//
// AbstractCommandBuilder.cs
//
// Author:
// Jarl Gullberg <[email protected]>
//
// Copyright (c) Jarl Gullberg
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using Remora.Commands.Conditions;
using Remora.Commands.DependencyInjection;

namespace Remora.Commands.Builders;

/// <summary>
/// An abstract builder class with shared functionality/data between commands and groups.
/// </summary>
/// <typeparam name="TSelf">The type of the builder.</typeparam>
public abstract class AbstractCommandBuilder<TSelf> where TSelf : AbstractCommandBuilder<TSelf>
{
/// <summary>
/// Gets or sets the description of the group or command.
/// </summary>
public string? Description { get; protected set; }

/// <summary>
/// Gets the associated list of aliases.
/// </summary>
protected List<string> Aliases { get; }

/// <summary>
/// Gets the associated list of attributes.
/// </summary>
protected List<Attribute> Attributes { get; }

/// <summary>
/// Gets the associated list of conditions.
/// </summary>
protected List<ConditionAttribute> Conditions { get; }

/// <summary>
/// Gets the associated parent node if any.
/// </summary>
protected GroupBuilder? Parent { get; }

/// <summary>
/// Gets the associated <see cref="TreeRegistrationBuilder"/> for the command or group.
/// </summary>
protected TreeRegistrationBuilder? TreeBuilder { get; }

/// <summary>
/// Gets or sets the name of the command or group.
/// </summary>
protected string Name { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="AbstractCommandBuilder{TSelf}"/> class.
/// </summary>
/// <param name="treeBuilder">The registration builder.</param>
protected AbstractCommandBuilder(TreeRegistrationBuilder treeBuilder)
: this()
{
TreeBuilder = treeBuilder;
}

/// <summary>
/// Initializes a new instance of the <see cref="AbstractCommandBuilder{TSelf}"/> class.
/// </summary>
/// <param name="parent">The parent of the builder.</param>
protected AbstractCommandBuilder(GroupBuilder? parent = null)
{
Name = string.Empty;
VelvetToroyashi marked this conversation as resolved.
Show resolved Hide resolved
Aliases = new();
Attributes = new();
Conditions = new();
Parent = parent;
}

/// <summary>
/// Initializes a new instance of the <see cref="AbstractCommandBuilder{TSelf}"/> class.
/// </summary>
private AbstractCommandBuilder()
{
Aliases = new();
Attributes = new();
Conditions = new();
Name = string.Empty;
}

/// <summary>
/// Sets the name of the builder.
/// </summary>
/// <param name="name">The name of the builder.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf WithName(string name)
{
Name = name;
return (TSelf)this;
}

/// <summary>
/// Sets the description of the builder.
/// </summary>
/// <param name="description">The description of the builder.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf WithDescription(string description)
{
Description = description;
return (TSelf)this;
}

/// <summary>
/// Adds an alias to the builder.
/// </summary>
/// <param name="alias">The alias to add.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf AddAlias(string alias)
{
Aliases.Add(alias);
return (TSelf)this;
}

/// <summary>
/// Adds multiple aliases to the builder.
/// </summary>
/// <param name="aliases">The aliases to add.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf AddAliases(IEnumerable<string> aliases)
{
Aliases.AddRange(aliases);
return (TSelf)this;
}

/// <summary>
/// Adds an attribute to the builder. Conditions must be added via <see cref="AddCondition"/>.
/// </summary>
/// <param name="attribute">The attribute to add.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf AddAttribute(Attribute attribute)
{
if (attribute is ConditionAttribute)
{
throw new InvalidOperationException("Conditions must be added via AddCondition.");
}

Attributes.Add(attribute);
return (TSelf)this;
}

/// <summary>
/// Adds a condition to the builder.
/// </summary>
/// <param name="condition">The condition to add.</param>
/// <returns>The current builder to chain calls with.</returns>
public TSelf AddCondition(ConditionAttribute condition)
{
Conditions.Add(condition);
return (TSelf)this;
}
}
Loading
Loading