Skip to content

Commit 7a14012

Browse files
SimonCahillSimon Cahill
andauthored
Added support for param files (#28)
* Added support for Powershell-convention options. * Updated project file * Updated changelog * Updated README * Began adding support for param files * Began implementing support for param files. * Adding paramfile parsing. * Added tests for paramfile parsing. For some reason, TestParseParamFile() causes the test case to crash. * I fixed the infinite recursion. Whoops. * Updated reference implementations to add support for Powershell and Windows conventions. Also added support for paramfile args. * Added comment clarifying test. * Updated changelog, README and project file. * Fixed compiler warnings. Added support for net46 and 60 to reference implementations. * Fixed merge error --------- Signed-off-by: SimonC <simon@simonc.eu> Co-authored-by: Simon Cahill <simon@h3lix.de>
1 parent 1bd2a34 commit 7a14012

File tree

11 files changed

+252
-31
lines changed

11 files changed

+252
-31
lines changed

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[*.cs]
2+
3+
# Default severity for analyzer diagnostics with category 'Style'
4+
dotnet_analyzer_diagnostic.category-Style.severity = none

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# getop.net changelog
22

3+
# v0.8.0
4+
5+
Version 0.8.0 introduces a non-breaking change which enables support for paramfiles!
6+
7+
Some applications, notably GCC, use paramfiles as a way to pass a large amount of options and arguments to an application.
8+
Paramfiles are line-separated lists of arguments and can be enabled by setting `AllowParamFiles = true`.
9+
Each line in the paramfile will be parsed as if it were passed directly to getopt.net!
10+
To allow Powershell or Windows conventions, you will still need to enable `AllowWindowsConventions` or `AllowPowershellConventions` respectively.
11+
12+
## Changes
13+
- Added support for paramfiles
14+
- Updated reference implementations
15+
316
# v0.7.0
417

518
Version 0.7.0 introduces a non-breaking change which enables support for Powershell-style options!

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ There are several methods of installing and using getopt.net in your project.
5454
- `-myoption argument`
5555
- `-myoption` `argument`
5656

57+
### Support for paramfiles
58+
59+
Some applications, such as GCC, allow passing of paramfile arguments.
60+
A paramfile is a line-separated text file which contains one option (and argument) per line.
61+
Each line of the paramfile is parsed as if it were passed to getopt.net directly.
62+
63+
Syntax:
64+
```
65+
myapp @/path/to/paramfile
66+
```
67+
5768
### The standard getopt shortopt-string format is supported:
5869

5970
`:` denotes a **required** argument!

getopt.net.reference.cs/Program.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
namespace getopt.net.reference.cs {
1+
using System;
2+
3+
namespace getopt.net.reference.cs {
4+
5+
using System.IO;
26

37
internal class Program {
48

@@ -10,7 +14,10 @@ static int Main(string[] args) {
1014
new Option("version", ArgumentType.None, 'v'),
1115
new Option("file", ArgumentType.Required, 'f')
1216
},
13-
ShortOpts = "hvf:t;" // the last option isn't an error!
17+
ShortOpts = "hvf:t;", // the last option isn't an error!
18+
AllowParamFiles = true,
19+
AllowWindowsConventions = true,
20+
AllowPowershellConventions = true
1421
};
1522

1623
var optChar = 0;
@@ -60,16 +67,32 @@ myapp [-h/--help] [-v/--version]
6067
myapp -f /path/to/file
6168
myapp --file=/path/to/file
6269
myapp --file /path/to/file
70+
71+
myapp @/path/to/paramfile # load all args from param file
6372
6473
Arguments:
6574
--help, -h Displays this menu and exits
75+
/help, /h Displays this menu and exits (Windows conventions)
76+
-help, -h Displays this menu and exits (Powershell conventions)
77+
6678
--version, -v Displays the version and exits
79+
/version, /v Displays the version and exits (Windows conventions)
80+
-version, -v Displays the version and exits (Powershell conventions)
81+
6782
--file=<>, -f<> Reads the file back to stdout.
83+
--file <>, -f<> Reads the file back to stdout.
84+
--file:<>, -f<> Reads the file back to stdout. (Windows arg conventions)
85+
/file=<>, /f<> Reads the file back to stdout. (Windows opt and GNU/POSIX arg conventions)
86+
/file <>, /f<> Reads the file back to stdout. (Windows opt and GNU/POSIX arg conventions)
87+
/file:<>, /f<> Reads the file back to stdout. (Windows conventions)
88+
-file=<>, -f<> Reads the file back to stdout. (Powershell opt and GNU/POSIX arg conventions)
89+
-file <>, -f<> Reads the file back to stdout. (Powershell opt and GNU/POSIX arg conventions)
90+
-file:<>, -f<> Reads the file back to stdout. (Powershell opt and Windows arg conventions)
6891
""");
6992
}
7093

7194
static void PrintVersion() {
72-
Console.WriteLine("myapp v1.0.0");
95+
Console.WriteLine("myapp v0.8.0");
7396
}
7497
}
7598
}

getopt.net.reference.cs/getopt.net.reference.cs.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net7.0</TargetFramework>
6-
<ImplicitUsings>enable</ImplicitUsings>
5+
<TargetFrameworks>net6.0;net7.0;net46;</TargetFrameworks>
6+
<ImplicitUsings>disable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<AssemblyName>myapp</AssemblyName>
9+
<LangVersion>11</LangVersion>
910
</PropertyGroup>
1011

1112
<ItemGroup>

getopt.net.reference.vb/Program.vb

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ Module Program
1919
Dim getopt = New GetOpt With {
2020
.AppArgs = args,
2121
.Options = _progOptions,
22-
.ShortOpts = _progShortOptions
22+
.ShortOpts = _progShortOptions,
23+
.AllowParamFiles = True,
24+
.AllowPowershellConventions = True,
25+
.AllowWindowsConventions = True
2326
}
2427

2528
Dim optChar = 0
@@ -76,14 +79,30 @@ Usage:
7679
myapp --file=/path/to/file
7780
myapp --file /path/to/file
7881

82+
myapp @/path/to/paramfile # load all args from param file
83+
7984
Arguments:
80-
--help, -h Displays this text and exits
81-
--version, -v Displays the version and exits
82-
--file=[file], -f Reads a file and outputs its contents
85+
--help, -h Displays this menu and exits
86+
/help, /h Displays this menu and exits (Windows conventions)
87+
-help, -h Displays this menu and exits (Powershell conventions)
88+
89+
--version, -v Displays the version and exits
90+
/version, /v Displays the version and exits (Windows conventions)
91+
-version, -v Displays the version and exits (Powershell conventions)
92+
93+
--file=<>, -f<> Reads the file back to stdout.
94+
--file <>, -f<> Reads the file back to stdout.
95+
--file:<>, -f<> Reads the file back to stdout. (Windows arg conventions)
96+
/file=<>, /f<> Reads the file back to stdout. (Windows opt and GNU/POSIX arg conventions)
97+
/file <>, /f<> Reads the file back to stdout. (Windows opt and GNU/POSIX arg conventions)
98+
/file:<>, /f<> Reads the file back to stdout. (Windows conventions)
99+
-file=<>, -f<> Reads the file back to stdout. (Powershell opt and GNU/POSIX arg conventions)
100+
-file <>, -f<> Reads the file back to stdout. (Powershell opt and GNU/POSIX arg conventions)
101+
-file:<>, -f<> Reads the file back to stdout. (Powershell opt and Windows arg conventions)
83102
")
84103
End Sub
85104

86105
Sub PrintVersion()
87-
Console.WriteLine("myapp (VB) v1.0.0")
106+
Console.WriteLine("myapp (VB) v0.8.0")
88107
End Sub
89108
End Module

getopt.net.reference.vb/getopt.net.reference.vb.vbproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<RootNamespace>getopt.net.reference.vb</RootNamespace>
6-
<TargetFramework>net7.0</TargetFramework>
6+
<TargetFrameworks>net6.0;net7.0;net46;</TargetFrameworks>
77
<AssemblyName>myapp</AssemblyName>
88
</PropertyGroup>
99

getopt.net.sln

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getopt.net.tests", "getopt.
99
EndProject
1010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B994D393-9D31-4B65-BCCB-3FF2ACC910C3}"
1111
ProjectSection(SolutionItems) = preProject
12+
.editorconfig = .editorconfig
1213
CHANGELOG.md = CHANGELOG.md
1314
Doxyfile = Doxyfile
1415
LICENSE = LICENSE
@@ -17,9 +18,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1718
EndProject
1819
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Reference_Implementation", "Reference_Implementation", "{C10BBB00-F878-49DA-A820-096033490427}"
1920
EndProject
20-
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "getopt.net.reference.vb", "getopt.net.reference.vb\getopt.net.reference.vb.vbproj", "{37B43EE5-B988-486E-BED9-AA6A5835DC0D}"
21+
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "getopt.net.reference.vb", "getopt.net.reference.vb\getopt.net.reference.vb.vbproj", "{37B43EE5-B988-486E-BED9-AA6A5835DC0D}"
2122
EndProject
22-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "getopt.net.reference.cs", "getopt.net.reference.cs\getopt.net.reference.cs.csproj", "{A367E857-0105-4824-B3B7-1334C6C21236}"
23+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getopt.net.reference.cs", "getopt.net.reference.cs\getopt.net.reference.cs.csproj", "{A367E857-0105-4824-B3B7-1334C6C21236}"
2324
EndProject
2425
Global
2526
GlobalSection(SolutionConfigurationPlatforms) = preSolution

getopt.net.tests/GetOptTests_Inherited.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,70 @@ public void TestShortOptWithOptionalArg() {
179179
Assert.IsNull(ShortOptRequiresArg('z'));
180180
}
181181

182+
[TestMethod]
183+
public void TestIsParamFileArg() {
184+
var tmpFile = Path.GetTempFileName();
185+
AllowParamFiles = true;
186+
Assert.IsTrue(IsParamFileArg($"@{tmpFile}", out var paramFile));
187+
Assert.IsNotNull(paramFile);
188+
Assert.IsFalse(string.IsNullOrEmpty(paramFile));
189+
Assert.AreEqual(tmpFile, paramFile);
190+
191+
Assert.IsFalse(IsParamFileArg("--long-opt", out paramFile));
192+
Assert.IsNull(paramFile);
193+
194+
AllowParamFiles = false;
195+
Assert.IsFalse(IsParamFileArg($"@{tmpFile}", out paramFile));
196+
Assert.IsNull(paramFile);
197+
}
198+
199+
[TestMethod]
200+
public void TestParseParamFile() {
201+
var tmpFile = Path.GetTempFileName();
202+
File.WriteAllLines(tmpFile, new[] {
203+
"-1234", "--long"
204+
});
205+
AllowParamFiles = true;
206+
AppArgs = new[] { $"@{ tmpFile }", "--test" };
207+
ShortOpts = string.Empty;
208+
Options = new[] {
209+
new Option("first", ArgumentType.None, '1'),
210+
new Option("second", ArgumentType.None, '2'),
211+
new Option("third", ArgumentType.None, '3'),
212+
new Option("fourth", ArgumentType.None, '4'),
213+
new Option("long", ArgumentType.None, '5'),
214+
new Option("test", ArgumentType.None, 't')
215+
};
216+
217+
ReadParamFile(new FileInfo(tmpFile));
218+
Assert.AreEqual(4, AppArgs.Length);
219+
220+
// NOTE: GetNextOpt calls ReadParamFile too! AppArgs will now contain double the amount of args written to the file :)
221+
char optChar = (char)GetNextOpt(out var optArg);
222+
Assert.AreEqual('t', optChar);
223+
Assert.IsNull(optArg);
224+
225+
optChar = (char)GetNextOpt(out optArg);
226+
Assert.AreEqual('1', optChar);
227+
Assert.IsNull(optArg);
228+
229+
optChar = (char)GetNextOpt(out optArg);
230+
Assert.AreEqual('2', optChar);
231+
Assert.IsNull(optArg);
232+
233+
optChar = (char)GetNextOpt(out optArg);
234+
Assert.AreEqual('3', optChar);
235+
Assert.IsNull(optArg);
236+
237+
optChar = (char)GetNextOpt(out optArg);
238+
Assert.AreEqual('4', optChar);
239+
Assert.IsNull(optArg);
240+
241+
optChar = (char)GetNextOpt(out optArg);
242+
Assert.AreEqual('5', optChar);
243+
Assert.IsNull(optArg);
244+
}
245+
182246
}
183247

184248
}

0 commit comments

Comments
 (0)