Skip to content

Commit 735f383

Browse files
authored
Merge pull request #411 from nblumhardt/align-config-commands
Switch `config` command to a command group, including `clear`, `get`, `set`, and `list` to match Seq's CLI
2 parents 8718668 + 330dceb commit 735f383

22 files changed

+312
-34
lines changed

src/SeqCli/Cli/CommandAttribute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ public class CommandAttribute : Attribute, ICommandMetadata
2323
public string? SubCommand { get; }
2424
public string HelpText { get; }
2525
public string? Example { get; set; }
26-
public bool IsPreview { get; set; }
26+
public FeatureVisibility Visibility { get; set; }
2727

2828
public CommandAttribute(string name, string helpText)
2929
{
3030
Name = name;
3131
HelpText = helpText;
32+
Visibility = FeatureVisibility.Visible;
3233
}
3334

3435
public CommandAttribute(string name, string subCommand, string helpText) : this(name, helpText)

src/SeqCli/Cli/CommandFeature.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using System;
1615
using System.Collections.Generic;
1716

1817
namespace SeqCli.Cli;
@@ -21,5 +20,5 @@ abstract class CommandFeature
2120
{
2221
public abstract void Enable(OptionSet options);
2322

24-
public virtual IEnumerable<string> GetUsageErrors() => Array.Empty<string>();
23+
public virtual IEnumerable<string> GetUsageErrors() => [];
2524
}

src/SeqCli/Cli/CommandLineHost.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,30 @@ public async Task<int> Run(string[] args, LoggingLevelSwitch levelSwitch)
4141
{
4242
const string prereleaseArg = "--pre", verboseArg = "--verbose";
4343

44-
var norm = args[0].ToLowerInvariant();
45-
var subCommandNorm = args.Length > 1 && !args[1].Contains('-') ? args[1].ToLowerInvariant() : null;
44+
var commandName = args[0].ToLowerInvariant();
45+
var subCommandName = args.Length > 1 && !args[1].Contains('-') ? args[1].ToLowerInvariant() : null;
4646

47-
var pre = args.Any(a => a == prereleaseArg);
47+
var hiddenLegacyCommand = false;
48+
if (subCommandName == null && commandName == "config")
49+
{
50+
hiddenLegacyCommand = true;
51+
subCommandName = "legacy";
52+
}
53+
54+
var featureVisibility = FeatureVisibility.Visible | FeatureVisibility.Hidden;
55+
if (args.Any(a => a.Trim() is prereleaseArg))
56+
featureVisibility |= FeatureVisibility.Preview;
4857

4958
var cmd = _availableCommands.SingleOrDefault(c =>
50-
(!c.Metadata.IsPreview || pre) &&
51-
c.Metadata.Name == norm &&
52-
(c.Metadata.SubCommand == subCommandNorm || c.Metadata.SubCommand == null));
59+
featureVisibility.HasFlag(c.Metadata.Visibility) &&
60+
c.Metadata.Name == commandName &&
61+
(c.Metadata.SubCommand == subCommandName || c.Metadata.SubCommand == null));
5362

5463
if (cmd != null)
5564
{
56-
var amountToSkip = cmd.Metadata.SubCommand == null ? 1 : 2;
57-
var commandSpecificArgs = args.Skip(amountToSkip).Where(arg => cmd.Metadata.Name == "help" || arg != prereleaseArg).ToArray();
58-
65+
var amountToSkip = cmd.Metadata.SubCommand == null || hiddenLegacyCommand ? 1 : 2;
66+
var commandSpecificArgs = args.Skip(amountToSkip).Where(arg => cmd.Metadata.Name == "help" || arg is not prereleaseArg).ToArray();
67+
5968
var verbose = commandSpecificArgs.Any(arg => arg == verboseArg);
6069
if (verbose)
6170
{

src/SeqCli/Cli/CommandMetadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ public class CommandMetadata : ICommandMetadata
2020
public string? SubCommand { get; set; }
2121
public required string HelpText { get; set; }
2222
public string? Example { get; set; }
23-
public bool IsPreview { get; set; }
23+
public FeatureVisibility Visibility { get; set; }
2424
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright © Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System.Threading.Tasks;
16+
using SeqCli.Cli.Features;
17+
using SeqCli.Config;
18+
19+
// ReSharper disable once UnusedType.Global
20+
21+
namespace SeqCli.Cli.Commands.Config;
22+
23+
[Command("config", "clear", "Clear fields in the `SeqCli.json` file")]
24+
class ClearCommand : Command
25+
{
26+
readonly StoragePathFeature _storagePath;
27+
readonly ConfigKeyFeature _key;
28+
29+
public ClearCommand()
30+
{
31+
_storagePath = Enable<StoragePathFeature>();
32+
_key = Enable<ConfigKeyFeature>();
33+
}
34+
35+
protected override Task<int> Run()
36+
{
37+
var config = SeqCliConfig.ReadFromFile(_storagePath.ConfigFilePath);
38+
39+
KeyValueSettings.Clear(config, _key.GetKey());
40+
SeqCliConfig.WriteToFile(config, _storagePath.ConfigFilePath);
41+
return Task.FromResult(0);
42+
}
43+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright © Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Threading.Tasks;
17+
using SeqCli.Cli.Features;
18+
using SeqCli.Config;
19+
20+
// ReSharper disable once UnusedType.Global
21+
22+
namespace SeqCli.Cli.Commands.Config;
23+
24+
[Command("config", "get", "View a field from the `SeqCli.json` file")]
25+
class GetCommand : Command
26+
{
27+
readonly StoragePathFeature _storagePath;
28+
readonly ConfigKeyFeature _key;
29+
30+
public GetCommand()
31+
{
32+
_storagePath = Enable<StoragePathFeature>();
33+
_key = Enable<ConfigKeyFeature>();
34+
}
35+
36+
protected override Task<int> Run()
37+
{
38+
var config = SeqCliConfig.ReadFromFile(_storagePath.ConfigFilePath);
39+
if (!KeyValueSettings.TryGetValue(config, _key.GetKey(), out var value, out _))
40+
throw new ArgumentException($"Field `{_key.GetKey()}` not found.");
41+
42+
Console.WriteLine(value);
43+
return Task.FromResult(0);
44+
}
45+
}

src/SeqCli/Cli/Commands/ConfigCommand.cs renamed to src/SeqCli/Cli/Commands/Config/LegacyCommand.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
using SeqCli.Util;
2020
using Serilog;
2121

22-
namespace SeqCli.Cli.Commands;
22+
namespace SeqCli.Cli.Commands.Config;
2323

24-
[Command("config", "View and set fields in `SeqCli.json`; run with no arguments to list all fields")]
25-
class ConfigCommand : Command
24+
[Command("config", "legacy", "View and set fields in `SeqCli.json`; run with no arguments to list all fields", Visibility = FeatureVisibility.Hidden)]
25+
class LegacyCommand : Command
2626
{
2727
string? _key, _value;
2828
bool _clear;
2929
readonly StoragePathFeature _storagePath;
3030

31-
public ConfigCommand()
31+
public LegacyCommand()
3232
{
3333
Options.Add("k|key=", "The field, for example `connection.serverUrl`", k => _key = k);
3434
Options.Add("v|value=", "The field value; if not specified, the command will print the current value", v => _value = v);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright © Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Threading.Tasks;
17+
using SeqCli.Cli.Features;
18+
using SeqCli.Config;
19+
20+
// ReSharper disable once UnusedType.Global
21+
22+
namespace SeqCli.Cli.Commands.Config;
23+
24+
[Command("config", "list", "View all fields in the `SeqCli.json` file")]
25+
class ListCommand : Command
26+
{
27+
readonly StoragePathFeature _storagePath;
28+
29+
public ListCommand()
30+
{
31+
_storagePath = Enable<StoragePathFeature>();
32+
}
33+
34+
protected override Task<int> Run()
35+
{
36+
var config = SeqCliConfig.ReadFromFile(_storagePath.ConfigFilePath);
37+
foreach (var (key, value, _) in KeyValueSettings.Inspect(config))
38+
{
39+
Console.WriteLine($"{key}={value}");
40+
}
41+
return Task.FromResult(0);
42+
}
43+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright © Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.IO;
17+
using System.Threading.Tasks;
18+
using SeqCli.Cli.Features;
19+
using SeqCli.Config;
20+
using Serilog;
21+
22+
// ReSharper disable once UnusedType.Global
23+
24+
namespace SeqCli.Cli.Commands.Config;
25+
26+
[Command("config", "set", "Set a field in the `SeqCli.json` file")]
27+
class SetCommand : Command
28+
{
29+
readonly StoragePathFeature _storagePath;
30+
readonly ConfigKeyFeature _key;
31+
readonly ConfigValueFeature _value;
32+
33+
public SetCommand()
34+
{
35+
_storagePath = Enable<StoragePathFeature>();
36+
_key = Enable<ConfigKeyFeature>();
37+
_value = Enable<ConfigValueFeature>();
38+
}
39+
40+
protected override Task<int> Run()
41+
{
42+
var config = SeqCliConfig.ReadFromFile(_storagePath.ConfigFilePath);
43+
44+
KeyValueSettings.Set(config, _key.GetKey(), _value.ReadValue());
45+
SeqCliConfig.WriteToFile(config, _storagePath.ConfigFilePath);
46+
return Task.FromResult(0);
47+
}
48+
}

src/SeqCli/Cli/Commands/Forwarder/InstallCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
namespace SeqCli.Cli.Commands.Forwarder
3333
{
34-
[Command("forwarder", "install", "Install the forwarder as a Windows service", IsPreview = true)]
34+
[Command("forwarder", "install", "Install the forwarder as a Windows service", Visibility = FeatureVisibility.Preview)]
3535
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")]
3636
class InstallCommand : Command
3737
{

0 commit comments

Comments
 (0)