Skip to content

Commit fdeefe4

Browse files
committed
- Command name: fc → fcc (no more bash conflicts!)
- Package ID: ancp.fc → ancp.fcc - Directory: tools/ancp/fc → tools/ancp/fcc - Test directory: tests/fc.tests → tests/fcc.tests - Namespace: FcTool → FccTool - All project references updated
1 parent 4604c96 commit fdeefe4

File tree

9 files changed

+85
-55
lines changed

9 files changed

+85
-55
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Alexander Nachtmann
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Two cross-platform .NET tools for text and code cleanup:
77

88
- **f**: Count words in text files (txt/md/docx) with optional comment stripping
9-
- **fc**: Strip C# comments and regions in place (Roslyn-based)
9+
- **fcc**: Strip C# comments and regions in place (Roslyn-based)
1010

1111
## Prerequisites
1212

@@ -15,10 +15,13 @@ Two cross-platform .NET tools for text and code cleanup:
1515
## Installation
1616

1717
```bash
18-
# Option 1
19-
./scripts/install_tools.sh
18+
# From NuGet (recommended)
19+
dotnet tool install -g ancp
20+
dotnet tool install -g ancp.fcc
2021

21-
# Option 2
22+
# From source
23+
./scripts/install_tools.sh
24+
# OR
2225
make install
2326
```
2427

@@ -32,18 +35,18 @@ f --unique path/to/file.docx # Count unique words
3235
f --strip path/to/README.md # Strip comments before output
3336
```
3437

35-
### fc - C# Comment Stripper
38+
### fcc - C# Comment Stripper
3639

3740
```bash
38-
fc path/to/File.cs # Process single file
39-
fc path/to/Folder # Process folder recursively
41+
fcc path/to/File.cs # Process single file
42+
fcc path/to/Folder # Process folder recursively
4043
```
4144

4245
## Uninstall
4346

4447
```bash
4548
dotnet tool uninstall --global ancp
46-
dotnet tool uninstall --global ancp.fc
49+
dotnet tool uninstall --global ancp.fcc
4750
```
4851

4952
## License

ancpdevkit.sln

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "f", "f", "{3AA5AF39-EEC4-28
77
EndProject
88
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "f", "tools\ancp\f\f.fsproj", "{82DDEBF2-139A-43A5-B47F-D98827F29B7F}"
99
EndProject
10-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fc", "fc", "{08E67C62-4D79-79AE-2379-561D96047594}"
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fcc", "fcc", "{08E67C62-4D79-79AE-2379-561D96047594}"
1111
EndProject
12-
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "fc", "tools\ancp\fc\fc.fsproj", "{BEFD39FF-17E0-4602-823B-9FF210A56E7A}"
12+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "fcc", "tools\ancp\fcc\fcc.fsproj", "{BEFD39FF-17E0-4602-823B-9FF210A56E7A}"
1313
EndProject
1414
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "f.tests", "tests\f.tests\f.tests.fsproj", "{AFB5AB7D-8C34-4D2B-B698-D9B5D5F3A1CE}"
1515
EndProject
16-
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "fc.tests", "tests\fc.tests\fc.tests.fsproj", "{A017183F-5970-48EA-A2E3-8F93FC9168AB}"
16+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "fcc.tests", "tests\fcc.tests\fcc.tests.fsproj", "{A017183F-5970-48EA-A2E3-8F93FC9168AB}"
1717
EndProject
1818
Global
1919
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ open NUnit.Framework
88
open Microsoft.CodeAnalysis
99
open Microsoft.CodeAnalysis.CSharp
1010

11-
[<TestFixture; Category("FCTool")>]
12-
type FcToolTests() =
11+
[<TestFixture; Category("FCCTool")>]
12+
type FccToolTests() =
1313
let rec findUp (startDir: string) (marker: string) =
1414
let full = Path.GetFullPath(startDir)
1515
let candidate = Path.Combine(full, marker)
@@ -49,9 +49,9 @@ type FcToolTests() =
4949
run $"run --no-build --project {projPath} --framework net9.0 -- {pathArg}"
5050

5151
[<Test>]
52-
member _.``fc removes comments in-place, preserves strings, idempotent``() =
52+
member _.``fcc removes comments in-place, preserves strings, idempotent``() =
5353
let tmp =
54-
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "fc_it_" + Guid.NewGuid().ToString("N")))
54+
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "fcc_it_" + Guid.NewGuid().ToString("N")))
5555

5656
try
5757
let sample = Path.Combine(tmp.FullName, "sample.cs")
@@ -73,7 +73,7 @@ class C /* type */
7373

7474
File.WriteAllText(sample, input, UTF8Encoding(false))
7575

76-
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fc", "fc.fsproj")
76+
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fcc", "fcc.fsproj")
7777
let ec1, _, err1 = runProj proj sample
7878
Assert.That(ec1, Is.EqualTo(0), err1)
7979
let after1 = File.ReadAllText(sample, Encoding.UTF8)
@@ -97,7 +97,7 @@ class C /* type */
9797
()
9898

9999
[<Test>]
100-
member _.``fc semantic tokens unchanged (ignoring trivia)``() =
100+
member _.``fcc semantic tokens unchanged (ignoring trivia)``() =
101101
let input =
102102
"""
103103
using System; // import
@@ -113,7 +113,7 @@ class C /* type */
113113
}
114114
"""
115115

116-
let cleaned = FcTool.CommentStripper.strip input
116+
let cleaned = FccTool.CommentStripper.strip input
117117

118118
let opts =
119119
CSharpParseOptions(languageVersion = LanguageVersion.Latest, documentationMode = DocumentationMode.Parse)
@@ -132,9 +132,9 @@ class C /* type */
132132
Assert.That(snd b[i], Is.EqualTo(snd a[i]))
133133

134134
[<Test>]
135-
member _.``fc directory recursion processes all cs files``() =
135+
member _.``fcc directory recursion processes all cs files``() =
136136
let tmp =
137-
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "fc_dir_" + Guid.NewGuid().ToString("N")))
137+
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "fcc_dir_" + Guid.NewGuid().ToString("N")))
138138

139139
try
140140
let dir1 = tmp.FullName
@@ -144,7 +144,7 @@ class C /* type */
144144
File.WriteAllText(cs1, "class A { // c\nstring s=\"x/*y*/\"; /* z */}\n", UTF8Encoding(false))
145145
File.WriteAllText(cs2, "#region r\nclass B{ /* m */ }\n#endregion\n", UTF8Encoding(false))
146146

147-
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fc", "fc.fsproj")
147+
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fcc", "fcc.fsproj")
148148
let ec, _, err = runProj proj dir1
149149
Assert.That(ec, Is.EqualTo(0), err)
150150
let t1 = File.ReadAllText(cs1, Encoding.UTF8)
@@ -158,14 +158,14 @@ class C /* type */
158158
()
159159

160160
[<Test>]
161-
member _.``fc non-cs file returns error code 2``() =
162-
let tmp = Path.Combine(Path.GetTempPath(), "fc_err_" + Guid.NewGuid().ToString("N"))
161+
member _.``fcc non-cs file returns error code 2``() =
162+
let tmp = Path.Combine(Path.GetTempPath(), "fcc_err_" + Guid.NewGuid().ToString("N"))
163163
Directory.CreateDirectory(tmp) |> ignore
164164

165165
try
166166
let txt = Path.Combine(tmp, "note.txt")
167167
File.WriteAllText(txt, "not cs", UTF8Encoding(false))
168-
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fc", "fc.fsproj")
168+
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fcc", "fcc.fsproj")
169169
let ec, _, _ = runProj proj txt
170170
Assert.That(ec, Is.EqualTo(2))
171171
finally
@@ -175,13 +175,13 @@ class C /* type */
175175
()
176176

177177
[<Test>]
178-
member _.``fc path not found returns 1``() =
179-
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fc", "fc.fsproj")
178+
member _.``fcc path not found returns 1``() =
179+
let proj = Path.Combine(repoRoot.Value, "tools", "ancp", "fcc", "fcc.fsproj")
180180
let ec, _, err = runProj proj "__definitely_missing__"
181181
Assert.That(ec, Is.EqualTo(1), err)
182182

183-
[<TestFixture; Category("FCTool.Unit")>]
184-
type FcToolUnitTests() =
183+
[<TestFixture; Category("FCCTool.Unit")>]
184+
type FccToolUnitTests() =
185185
[<Test>]
186186
member _.``Cli.parse and toSettings parse all flags``() =
187187
let argv =
@@ -203,7 +203,7 @@ type FcToolUnitTests() =
203203
"file1.cs"
204204
"dir" |]
205205

206-
let o = FcTool.Cli.parse argv
206+
let o = FccTool.Cli.parse argv
207207
Assert.That(o.ShowHelp, Is.True)
208208
Assert.That(o.ShowVersion, Is.True)
209209
Assert.That(o.InPlace, Is.True)
@@ -213,7 +213,7 @@ type FcToolUnitTests() =
213213
Assert.That(o.Inputs, Is.EquivalentTo([ "file1.cs"; "dir" ]))
214214
Assert.That(o.KeepDocs && o.KeepHeaders && o.KeepRegions, Is.True)
215215
Assert.That(o.KeepIfMatch, Is.EquivalentTo([ "TODO"; "FIXME" ]))
216-
let s = FcTool.Cli.toSettings o
216+
let s = FccTool.Cli.toSettings o
217217
Assert.That(s.KeepDocs && s.KeepHeaders && s.KeepRegions, Is.True)
218218
Assert.That(s.KeepIfMatch, Is.EquivalentTo([ "TODO"; "FIXME" ]))
219219

@@ -235,7 +235,7 @@ class C {
235235
"""
236236

237237
let s1 =
238-
FcTool.CommentStripper.stripWith
238+
FccTool.CommentStripper.stripWith
239239
{ KeepDocs = true
240240
KeepHeaders = false
241241
KeepRegions = false
@@ -247,7 +247,7 @@ class C {
247247
Assert.That(s1.Contains("#region"), Is.False)
248248

249249
let s2 =
250-
FcTool.CommentStripper.stripWith
250+
FccTool.CommentStripper.stripWith
251251
{ KeepDocs = false
252252
KeepHeaders = true
253253
KeepRegions = false
@@ -258,7 +258,7 @@ class C {
258258
Assert.That(s2.Contains("/// <summary>Doc</summary>"), Is.False)
259259

260260
let s3 =
261-
FcTool.CommentStripper.stripWith
261+
FccTool.CommentStripper.stripWith
262262
{ KeepDocs = false
263263
KeepHeaders = false
264264
KeepRegions = true
@@ -268,7 +268,7 @@ class C {
268268
Assert.That(s3.Contains("#region"), Is.True)
269269

270270
let s4 =
271-
FcTool.CommentStripper.stripWith
271+
FccTool.CommentStripper.stripWith
272272
{ KeepDocs = false
273273
KeepHeaders = false
274274
KeepRegions = false
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<Compile Include="FcToolTests.fs"/>
8+
<Compile Include="FccToolTests.fs" />
99
</ItemGroup>
1010

1111
<ItemGroup>
@@ -16,7 +16,7 @@
1616
</ItemGroup>
1717

1818
<ItemGroup>
19-
<ProjectReference Include="..\..\tools\ancp\fc\fc.fsproj"/>
19+
<ProjectReference Include="..\..\tools\ancp\fcc\fcc.fsproj"/>
2020
</ItemGroup>
2121
</Project>
2222

tools/ancp/f/Program.fs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,15 @@ let tryReadPdf (path: string) =
163163
with _ ->
164164
None
165165

166-
let readInput (args: string array) =
167-
match args |> Array.toList with
168-
| [ path ] ->
166+
let readInput (pathArgs: string array) =
167+
match pathArgs |> Array.toList with
168+
| [] -> failwith "Usage: f [--strip|--unique] <file>"
169+
| paths ->
170+
let path = String.concat " " paths
171+
172+
if not (File.Exists(path)) then
173+
failwithf $"File not found: %s{path}"
174+
169175
let ext = Path.GetExtension(path).ToLowerInvariant()
170176

171177
match ext with
@@ -175,7 +181,6 @@ let readInput (args: string array) =
175181
| Some text -> text
176182
| None -> failwith "Failed to extract PDF text. Install 'pdftotext' or pipe text via stdin."
177183
| _ -> File.ReadAllText(path)
178-
| _ -> failwith "Usage: f [--strip|--unique] <file>"
179184

180185
[<EntryPoint>]
181186
let main argv =
@@ -188,7 +193,7 @@ let main argv =
188193
printfn "Usage: f [--strip|--unique] <file>"
189194
printfn " --strip Output text with #/HTML comments removed"
190195
printfn " --unique Print unique word count (default is total)"
191-
printfn " <file> .txt/.md/.docx/.pdf"
196+
printfn " <file> .txt/.md/.docx/.pdf (paths with spaces supported)"
192197
printfn "Notes: PDF extraction uses 'pdftotext' if available."
193198
0
194199
else

tools/ancp/f/f.fsproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<PackAsTool>true</PackAsTool>
77
<ToolCommandName>f</ToolCommandName>
88
<PackageId>ancp</PackageId>
9-
<Version>0.1.0</Version>
9+
<Version>0.3.0</Version>
1010
<Authors>ANcpLua</Authors>
1111
<Description>Word counter for text/markdown/docx files with unique count and comment stripping options</Description>
1212
<PackageTags>word-counter;cli-tool;text-processing;unicode;markdown;docx;fsharp;dotnet-tool;text-analysis;document-processing</PackageTags>
@@ -22,6 +22,7 @@
2222
<ItemGroup>
2323
<Compile Include="Program.fs"/>
2424
<None Include="../../../README.md" Pack="true" PackagePath="\"/>
25+
<Content Include="NewFile1.txt" />
2526
</ItemGroup>
2627

2728
</Project>
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace FcTool
1+
namespace FccTool
22

33
open System
44
open System.IO
@@ -163,7 +163,7 @@ module Cli =
163163

164164
let helpText =
165165
"""
166-
Usage: fc [options] [paths|-]
166+
Usage: fcc [options] [paths|-]
167167
168168
Strips C# comments and #region/#endregion from source while preserving strings.
169169
@@ -184,8 +184,8 @@ Inputs:
184184
path One or more files or, with -r, directories
185185
186186
Examples:
187-
fc path/to/File.cs
188-
fc path/to/Directory
187+
fcc path/to/File.cs
188+
fcc path/to/Directory
189189
"""
190190

191191
let parse (argv: string array) =
@@ -231,13 +231,13 @@ module Program =
231231
[<EntryPoint>]
232232
let main argv =
233233
let usage =
234-
"Usage: fc <file-or-directory>\nStrips C# comments and regions in-place. No stdout."
234+
"Usage: fcc <file-or-directory>\nStrips C# comments and regions in-place. No stdout."
235235

236-
if argv.Length <> 1 then
236+
if argv.Length = 0 then
237237
eprintfn $"%s{usage}"
238238
1
239239
else
240-
let path = argv[0]
240+
let path = String.concat " " argv
241241

242242
let stripFile (p: string) =
243243
let src = File.ReadAllText(p, Encoding.UTF8)
@@ -250,7 +250,7 @@ module Program =
250250
let isCs = String.Equals(ext, ".cs", StringComparison.OrdinalIgnoreCase)
251251

252252
if not isCs then
253-
eprintfn $"fc: not a .cs file: %s{path}"
253+
eprintfn $"fcc: not a .cs file: %s{path}"
254254
2
255255
else
256256
stripFile path
@@ -261,8 +261,8 @@ module Program =
261261

262262
0
263263
else
264-
eprintfn $"fc: path not found: %s{path}"
264+
eprintfn $"fcc: path not found: %s{path}"
265265
1
266266
with ex ->
267-
eprintfn $"fc: %s{ex.Message}"
267+
eprintfn $"fcc: %s{ex.Message}"
268268
1
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
<LangVersion>preview</LangVersion>
88

99
<PackAsTool>true</PackAsTool>
10-
<ToolCommandName>fc</ToolCommandName>
11-
<PackageId>ancp.fc</PackageId>
10+
<ToolCommandName>fcc</ToolCommandName>
11+
<PackageId>ancp.fcc</PackageId>
1212
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
13-
<Version>0.1.0</Version>
13+
<Version>0.3.0</Version>
1414
<Authors>ANcpLua</Authors>
1515
<Description>Strip C# comments/regions using Roslyn; functional F# CLI</Description>
1616
<PackageTags>csharp;comment-remover;code-cleanup;roslyn;syntax-tree;dotnet-tool;fsharp;code-formatting;refactoring</PackageTags>

0 commit comments

Comments
 (0)