Skip to content

Commit baa2aaf

Browse files
committed
Improve command line options
New --url option instead of --no-browser and overall better documentation of options
1 parent f65b365 commit baa2aaf

File tree

6 files changed

+59
-37
lines changed

6 files changed

+59
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77
## [Unreleased][Unreleased]
88

99
* Fixed an issue where a project reference (blue) could be wrongly identified as package reference (green)
10+
* Removed the `--no-browser` option, replaced with the `-u|--url` option
1011

1112
## [0.3.0][0.3.0] - 2025-06-24
1213

src/nugraph/GraphCommand.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,16 @@ protected override async Task<int> ExecuteAsync(CommandContext commandContext, G
5151
if (graphUrl != null)
5252
{
5353
var url = graphUrl.ToString();
54-
// Using "console.WriteLine(url)" (lowercase c) would insert newlines at the physical console length, making the written URL neither copyable nor clickable
55-
// At that point the status has terminated so it's fine not using the IAnsiConsole methods
56-
await stdOut.WriteLineAsync(url);
57-
if (!settings.NoBrowser)
54+
if (settings.UrlAction.HasFlag(UrlAction.print))
55+
{
56+
// Using "console.WriteLine(url)" (lowercase c) would insert newlines at the physical console length, making the written URL neither copyable nor clickable
57+
// At that point the status has terminated so it's fine not using the IAnsiConsole methods
58+
await stdOut.WriteLineAsync(url);
59+
}
60+
if (settings.UrlAction.HasFlag(UrlAction.open))
5861
{
5962
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
63+
console.WriteLine($"The {source} dependency graph has been opened in the default browser");
6064
}
6165
}
6266
else if (settings.OutputFile != null)

src/nugraph/GraphCommandSettings.cs

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212

1313
namespace nugraph;
1414

15+
[Flags]
16+
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Better fit for command line options")]
17+
public enum UrlAction
18+
{
19+
none = 0,
20+
open = 1 << 0,
21+
print = 1 << 1,
22+
}
23+
1524
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global", Justification = "Required for Spectre.Console.Cli binding")]
1625
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Required for Spectre.Console.Cli binding")]
1726
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Instantiated by Spectre.Console.Cli through reflection")]
@@ -21,66 +30,77 @@ internal sealed class GraphCommandSettings : CommandSettings
2130
public const string DefaultTitle = "Dependency graph of [SOURCE]";
2231

2332
[CommandArgument(0, "[SOURCE]")]
24-
[Description("The source of the graph. Can be either a directory containing a .NET project, a .NET project file (csproj/fsproj/vbproj) or the name of a NuGet package, " +
25-
"optionally with a specific version, e.g. [b]Newtonsoft.Json/13.0.3[/].")]
33+
[Description("The source of the graph\n" +
34+
"Can be either\n" +
35+
" * the name of a NuGet package, optionally with a specific version, e.g. [b]Newtonsoft.Json/13.0.3[/]\n" +
36+
" * a .NET project file (csproj/fsproj/vbproj)\n" +
37+
" * a directory containing a single .NET project\n")]
2638
public string? SourceInput { get; init; }
2739

2840
public FileOrPackage? Source { get; private set; }
2941

30-
[CommandOption("-o|--output <OUTPUT>")]
31-
[Description("The path to the dependency graph output file. If not specified, the dependency graph URL is written on the standard output and an online service is opened in the default browser.")]
32-
public FileInfo? OutputFile { get; init; }
33-
3442
[CommandOption("-f|--framework <FRAMEWORK>")]
35-
[Description("The target framework to consider when building the dependency graph.")]
43+
[Description("The target framework to consider when building the dependency graph\n" +
44+
"See https://learn.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-frameworks for the list of supported target frameworks")]
3645
[TypeConverter(typeof(NuGetFrameworkConverter))]
3746
public NuGetFramework? Framework { get; init; }
3847

3948
[CommandOption("-r|--runtime <RUNTIME_IDENTIFIER>")]
40-
[Description("The target runtime to consider when building the dependency graph.")]
49+
[Description("The target runtime to consider when building the dependency graph\n" +
50+
"See https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#known-rids for the list of known runtime identifiers")]
4151
public string? RuntimeIdentifier { get; init; }
4252

53+
[CommandOption("-o|--output <OUTPUT>")]
54+
[Description("The path to the dependency graph output file\n" +
55+
"A Mermaid diagram is written if the file name ends with either [b].mmd[/] or [b].mermaid[/], otherwise a Graphviz diagram is written\n" +
56+
"If not specified, the default web browser is used to render the dependency graph using an online service\n" +
57+
"See also the [b]--format[/] and [b]--url[/] options")]
58+
public FileInfo? OutputFile { get; init; }
59+
4360
[CommandOption("-m|--format <FORMAT>")]
44-
[Description($"The format to use when the [b]--output[/] option is not specified.\n" +
61+
[Description($"The format to use when the [b]--output[/] option is not specified\n" +
4562
$"Use [b]mmd[/] or [b]mermaid[/] for Mermaid Live Editor https://mermaid.live\n" +
4663
$"Use [b]dot[/], [b]gv[/] or [b]graphviz[/] for Edotor https://edotor.net\n" +
47-
"See https://github.com/0xced/nugraph/#output for even more supported formats.")]
64+
"See https://github.com/0xced/nugraph/#output for even more supported formats")]
4865
[DefaultValue("mermaid")]
4966
public string Format { get; init; } = "";
5067

5168
public OnlineService Service { get; private set; }
5269

70+
[CommandOption("-u|--url")]
71+
[Description("Defines what to do when the [b]--output[/] option is not specified\n" +
72+
"Use [b]open[/] (the default) for rendering the dependency graph using an online service or [b]print[/] for printing the graph URL on the standard output without opening the browser\n" +
73+
"Both options can be combined with a comma, i.e. [b]open,print[/] to both open the URL and print it")]
74+
[DefaultValue(UrlAction.open)]
75+
public UrlAction UrlAction { get; init; }
76+
5377
[CommandOption("-d|--direction <GRAPH_DIRECTION>")]
54-
[Description($"The direction of the dependency graph. Possible values are [b]{nameof(GraphDirection.LeftToRight)}[/] and [b]{nameof(GraphDirection.TopToBottom)}[/]")]
78+
[Description($"The direction of the dependency graph, possible values are [b]{nameof(GraphDirection.LeftToRight)}[/] (recommended for large graphs) and [b]{nameof(GraphDirection.TopToBottom)}[/] (good for small graphs)")]
5579
[DefaultValue(GraphDirection.LeftToRight)]
5680
public GraphDirection GraphDirection { get; init; }
5781

5882
[CommandOption("-t|--title <GRAPH_TITLE>")]
59-
[Description("The title of the dependency graph.")]
83+
[Description("The title of the dependency graph")]
6084
[DefaultValue(DefaultTitle)]
6185
public string Title { get; set; } = "";
6286

6387
[CommandOption("-s|--include-version")]
64-
[Description("Include package versions in the dependency graph. E.g. [b]Serilog/4.3.0[/] instead of [b]Serilog[/]")]
88+
[Description("Include package versions in the dependency graph nodes, e.g. [b]Serilog/4.3.0[/] instead of [b]Serilog[/]")]
6589
[DefaultValue(false)]
6690
public bool GraphIncludeVersions { get; init; }
6791

6892
[CommandOption("-i|--ignore <PACKAGE>")]
69-
[Description("Packages to ignore in the dependency graph. Supports * wildcards. May be used multiple times.")]
93+
[Description("Packages to ignore in the dependency graph, may be used multiple times and supports * wildcards, e.g. [b]--ignore \"System.*\"[/]")]
7094
public string[] GraphIgnore { get; init; } = [];
7195

7296
[CommandOption("--no-links")]
73-
[Description("Remove clickable links from the the dependency graph. Can be useful to reduce the size of the graph if you get \"Maximum text size in diagram exceeded\" in Mermaid Live Editor.")]
97+
[Description("Remove clickable links from the the dependency graph\n" +
98+
"Can be useful to reduce the size of the graph if it becomes too large and Mermaid Live Editor is returning \"Maximum text size in diagram exceeded\" ")]
7499
[DefaultValue(false)]
75100
public bool NoLinks { get; set; }
76101

77-
[CommandOption("--no-browser")]
78-
[Description("Do not open the default browser, only print the graph URL on the console when the [b]--output[/] option is not specified.")]
79-
[DefaultValue(false)]
80-
public bool NoBrowser { get; set; }
81-
82102
[CommandOption("-l|--log <LEVEL>")]
83-
[Description($"The NuGet operations log level. Possible values are [b]{nameof(LogLevel.Debug)}[/], [b]{nameof(LogLevel.Verbose)}[/], [b]{nameof(LogLevel.Information)}[/], [b]{nameof(LogLevel.Minimal)}[/], [b]{nameof(LogLevel.Warning)}[/] and [b]{nameof(LogLevel.Error)}[/]")]
103+
[Description($"The NuGet operations log level, possible values are [b]{nameof(LogLevel.Debug)}[/], [b]{nameof(LogLevel.Verbose)}[/], [b]{nameof(LogLevel.Information)}[/], [b]{nameof(LogLevel.Minimal)}[/], [b]{nameof(LogLevel.Warning)}[/] and [b]{nameof(LogLevel.Error)}[/]")]
84104
#if DEBUG
85105
[DefaultValue(LogLevel.Debug)]
86106
#else
@@ -89,20 +109,20 @@ internal sealed class GraphCommandSettings : CommandSettings
89109
public LogLevel LogLevel { get; init; }
90110

91111
[CommandOption("--nuget-root <PATH>", IsHidden = true)]
92-
[Description("The NuGet root directory. Can be used to completely isolate nugraph from default NuGet operations.")]
112+
[Description("The NuGet root directory, can be used to completely isolate nugraph from default NuGet operations")]
93113
public string? NuGetRoot { get; init; }
94114

95115
[CommandOption("--sdk <PATH>", IsHidden = true)]
96-
[Description("Path to the .NET SDK directory. E.g. [b]/usr/local/share/dotnet/sdk/8.0.410[/]")]
116+
[Description("Path to the .NET SDK directory, e.g. [b]/usr/local/share/dotnet/sdk/8.0.410[/]")]
97117
public DirectoryInfo? Sdk { get; init; }
98118

99119
[CommandOption("--include-ignored-packages", IsHidden = true)]
100-
[Description("Include ignored packages in the dependency graph. Used for debugging.")]
120+
[Description("Include ignored packages in the dependency graph, used for debugging")]
101121
[DefaultValue(false)]
102122
public bool GraphWriteIgnoredPackages { get; init; }
103123

104124
[CommandOption("--diagnose", IsHidden = true)]
105-
[Description("Prints diagnostics information.")]
125+
[Description("Prints diagnostics information")]
106126
[DefaultValue(false)]
107127
public bool Diagnose { get; init; }
108128

tests/nugraph.Tests/Nugraph.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace nugraph.Tests;
55

66
public abstract class Nugraph
77
{
8-
public abstract Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, bool noBrowser = true);
8+
public abstract Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, UrlAction action = UrlAction.print);
99

1010
public abstract string Version { get; }
1111
}

tests/nugraph.Tests/NugraphGlobalTool.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public NugraphGlobalTool()
2828

2929
public override string Version => _version ?? "N/A";
3030

31-
public override async Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, bool noBrowser = true)
31+
public override async Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, UrlAction action = UrlAction.print)
3232
{
3333
// https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools#install-a-global-tool
3434
var stdOut = new StringWriter { NewLine = "\n" };
@@ -44,10 +44,7 @@ public override async Task<NugraphResult> RunAsync(string[] arguments, string? w
4444
args.Add(argument);
4545
}
4646
args.Add("--log").Add(logLevel.ToString());
47-
if (noBrowser)
48-
{
49-
args.Add("--no-browser");
50-
}
47+
args.Add("--url").Add(action.ToString());
5148
})
5249
.WithWorkingDirectory(workingDirectory ?? toolsDirectory)
5350
.WithStandardOutputPipe(PipeTarget.ToDelegate(stdOut.WriteLine))

tests/nugraph.Tests/NugraphProgram.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ public NugraphProgram()
1717
Version = SemanticVersion.Parse(version).ToNormalizedString();
1818
}
1919

20-
public override async Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, bool noBrowser = true)
20+
public override async Task<NugraphResult> RunAsync(string[] arguments, string? workingDirectory = null, LogLevel logLevel = LogLevel.Warning, UrlAction action = UrlAction.print)
2121
{
2222
using var consoleOut = new TestConsole();
2323
consoleOut.Profile.Width = 256;
2424
using var consoleErr = new TestConsole();
2525
consoleErr.Profile.Width = 256;
2626
await using var stdOut = new StringWriter();
2727
var program = new Program(new DirectoryInfo(workingDirectory ?? Environment.CurrentDirectory), consoleOut, consoleErr, stdOut);
28-
var args = arguments.Append("--log").Append(logLevel.ToString()).Append("--no-browser").Append(noBrowser.ToString()).ToArray();
28+
var args = arguments.Append("--log").Append(logLevel.ToString()).Append("--url").Append(action.ToString()).ToArray();
2929
var exitCode = await program.RunAsync(args);
3030
return new NugraphResult(exitCode, GetOutput(consoleOut, stdOut), GetOutput(consoleErr, null));
3131
}

0 commit comments

Comments
 (0)