diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 1b08f7d..0000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-version: 2
-jobs:
- build:
- docker:
- - image: mcr.microsoft.com/dotnet/core/sdk:3.1.300
- steps:
- - run:
- name: Install Git LFS
- command: |
- curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
- apt-get install git-lfs
- - checkout
- - run: pwd
- - run: dotnet restore
- - run:
- name: Check BOM
- command: |
- dotnet tool install -g BomSweeper.GlobalTool
- /root/.dotnet/tools/bomsweeper '**/*.cs' '**/*.csproj' '**/*.sln'
- - run:
- name: Build
- command: |
- dotnet build
- - run:
- name: Test
- command: |
- dotnet test -p:CollectCoverage=true -p:CoverletOutputFormat=opencover --no-build BomSweeper.Test
- - run:
- name: Coverage
- command: |
- dotnet tool install -g dotnet-reportgenerator-globaltool
- /root/.dotnet/tools/reportgenerator --reports:BomSweeper.Test/coverage.opencover.xml --targetdir:Coverlet-html
- - store_artifacts:
- path: /root/project/Coverlet-html
-workflows:
- version: 2
- build_and_test:
- jobs:
- - build
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..c57ec45
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,37 @@
+name: .NET 9 CI
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+ workflow_dispatch:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ dotnet: [ '9.0.x' ]
+ steps:
+ - name: Check out
+ uses: actions/checkout@v4
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: ${{ matrix.dotnet }}
+ - name: Build
+ run: dotnet build --configuration Release
+ - name: Install
+ run: dotnet tool install -g dotnet-reportgenerator-globaltool
+ - name: Test
+ run: |
+ rm -rf MsTestResults
+ dotnet test --configuration Release --no-build --logger "console;verbosity=detailed" --collect:"XPlat Code Coverage" --results-directory MsTestResults
+ reportgenerator -reports:MsTestResults/*/coverage.cobertura.xml -targetdir:Coverlet-html
+ - name: Archive artifacts (code coverage)
+ uses: actions/upload-artifact@v4
+ with:
+ name: code-coverage-report-${{ matrix.dotnet }}
+ path: Coverlet-html
diff --git a/BomSweeper.GlobalTool/.editorconfig b/BomSweeper.GlobalTool/.editorconfig
new file mode 100644
index 0000000..b023fa6
--- /dev/null
+++ b/BomSweeper.GlobalTool/.editorconfig
@@ -0,0 +1,25 @@
+[*.cs]
+
+# SA1101: Prefix local calls with this
+dotnet_diagnostic.SA1101.severity = none
+
+# SA1122: Use string.Empty for empty strings
+dotnet_diagnostic.SA1122.severity = none
+
+# SA1302: Interface names should begin with I
+dotnet_diagnostic.SA1302.severity = none
+
+# SA1513: Closing brace should be followed by blank line
+dotnet_diagnostic.SA1513.severity = none
+
+# SA1633: File should have header
+dotnet_diagnostic.SA1633.severity = none
+
+# IsNull: Do not use 'is' pattern matching with 'null'.
+dotnet_diagnostic.IsNull.severity = none
+
+# SA1012: Opening braces should be spaced correctly
+dotnet_diagnostic.SA1012.severity = none
+
+# SA1013: Closing braces should be spaced correctly
+dotnet_diagnostic.SA1013.severity = none
diff --git a/BomSweeper.GlobalTool/BomSweeper.GlobalTool.csproj b/BomSweeper.GlobalTool/BomSweeper.GlobalTool.csproj
index c552b45..d52c05b 100644
--- a/BomSweeper.GlobalTool/BomSweeper.GlobalTool.csproj
+++ b/BomSweeper.GlobalTool/BomSweeper.GlobalTool.csproj
@@ -2,7 +2,8 @@
Exe
- netcoreapp3.1
+ net9
+ 13.0
true
bomsweeper
@@ -14,14 +15,15 @@
https://maroontress.github.io/BomSweeper-CSharp/
https://github.com/maroontress/BomSweeper.CSharp
false
- BomSweeper is a command line tool that finds the files starting with a UTF-8 Byte Order Mark (BOM) in the directory tree and removes a BOM from those files.
+ BomSweeper is a command line tool that finds the files starting with a UTF-8 Byte Order Mark (BOM) in the directory tree and removes BOMs from those files.
See https://maroontress.github.io/BomSweeper-CSharp/releasenotes.html
Copyright (c) 2019 Maroontress Fast Software
csharp, dotnet-core, global-tool, bomsweeper
true
- 1.0.1.0
+ 2.0.0
Maroontress Fast Software
+ README.md
COPYRIGHT.txt
true
@@ -45,4 +47,7 @@
+
+
+
diff --git a/BomSweeper.GlobalTool/Program.cs b/BomSweeper.GlobalTool/Program.cs
index 351e6df..aaa66f4 100644
--- a/BomSweeper.GlobalTool/Program.cs
+++ b/BomSweeper.GlobalTool/Program.cs
@@ -1,10 +1,9 @@
-namespace BomSweeper.GlobalTool
+namespace BomSweeper.GlobalTool;
+
+public sealed class Program
{
- class Program
+ static void Main(string[] args)
{
- static void Main(string[] args)
- {
- BomSweeper.Program.Main(args);
- }
+ BomSweeper.Program.Main(args);
}
}
diff --git a/BomSweeper.Test/BomSweeper.Test.csproj b/BomSweeper.Test/BomSweeper.Test.csproj
index 92e560f..b03e852 100644
--- a/BomSweeper.Test/BomSweeper.Test.csproj
+++ b/BomSweeper.Test/BomSweeper.Test.csproj
@@ -1,9 +1,9 @@
-
+
- netcoreapp3.1
+ net9
false
- 8.0
+ 13.0
enable
@@ -26,14 +26,17 @@
-
-
-
-
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
-
+
diff --git a/BomSweeper.Test/ElementsTest.cs b/BomSweeper.Test/ElementsTest.cs
index d2149a5..2ba70d7 100644
--- a/BomSweeper.Test/ElementsTest.cs
+++ b/BomSweeper.Test/ElementsTest.cs
@@ -1,33 +1,32 @@
-namespace BomSweeper.Test
-{
- using System;
- using System.Linq;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace BomSweeper.Test;
+
+using System;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
- [TestClass]
- public sealed class ElementsTest
+[TestClass]
+public sealed class ElementsTest
+{
+ [TestMethod]
+ public void SeparateWithEmpty()
{
- [TestMethod]
- public void SeparateWithEmpty()
- {
- var actual = Elements.Separate(Array.Empty(), "foo");
- Assert.IsFalse(actual.Any());
- }
+ var actual = Elements.Separate([], "foo");
+ Assert.IsFalse(actual.Any());
+ }
- [TestMethod]
- public void SeparateWithSingle()
- {
- var actual = Elements.Separate(new[] { "bar" }, "foo");
- Assert.AreEqual(actual.Count(), 1);
- Assert.AreEqual(actual.First(), "bar");
- }
+ [TestMethod]
+ public void SeparateWithSingle()
+ {
+ var actual = Elements.Separate(["bar"], "foo");
+ Assert.AreEqual(actual.Count(), 1);
+ Assert.AreEqual(actual.First(), "bar");
+ }
- [TestMethod]
- public void SeparateWithDouble()
- {
- var actual = Elements.Separate(new[] { "bar", "baz" }, "foo");
- var expected = new[] { "bar", "foo", "baz" };
- Assert.IsTrue(Enumerable.SequenceEqual(actual, expected));
- }
+ [TestMethod]
+ public void SeparateWithDouble()
+ {
+ var actual = Elements.Separate(["bar", "baz"], "foo");
+ var expected = new[] { "bar", "foo", "baz" };
+ Assert.IsTrue(Enumerable.SequenceEqual(actual, expected));
}
}
diff --git a/BomSweeper.Test/GlobsTest.cs b/BomSweeper.Test/GlobsTest.cs
index 7a62798..92392e2 100644
--- a/BomSweeper.Test/GlobsTest.cs
+++ b/BomSweeper.Test/GlobsTest.cs
@@ -1,100 +1,99 @@
-namespace BomSweeper.Test
-{
- using BomSweeper;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace BomSweeper.Test;
+
+using BomSweeper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
- [TestClass]
- public sealed class GlobsTest
+[TestClass]
+public sealed class GlobsTest
+{
+ [TestMethod]
+ public void NoWildcardSingleArgument()
{
- [TestMethod]
- public void NoWildcardSingleArgument()
- {
- var p = Globs.ToPattern(new[] { "foo" });
- Assert.AreEqual("^(foo)$", p);
- }
+ var p = Globs.ToPattern(["foo"]);
+ Assert.AreEqual("^(foo)$", p);
+ }
- [TestMethod]
- public void NoWildCardMultipleArguments()
- {
- var p = Globs.ToPattern(new[] { "foo", "bar" });
- Assert.AreEqual("^(foo|bar)$", p);
- }
+ [TestMethod]
+ public void NoWildCardMultipleArguments()
+ {
+ var p = Globs.ToPattern(["foo", "bar"]);
+ Assert.AreEqual("^(foo|bar)$", p);
+ }
- [TestMethod]
- public void Asterisk()
- {
- var p = Globs.ToPattern(new[] { "foo*" });
- Assert.AreEqual("^(foo[^/]*)$", p);
- }
+ [TestMethod]
+ public void Asterisk()
+ {
+ var p = Globs.ToPattern(["foo*"]);
+ Assert.AreEqual("^(foo[^/]*)$", p);
+ }
- [TestMethod]
- public void TwoAsterisks()
- {
- var p = Globs.ToPattern(new[] { "foo**" });
- Assert.AreEqual("^(foo[^/]*)$", p);
- }
+ [TestMethod]
+ public void TwoAsterisks()
+ {
+ var p = Globs.ToPattern(["foo**"]);
+ Assert.AreEqual("^(foo[^/]*)$", p);
+ }
- [TestMethod]
- public void ThreeAsterisks()
- {
- var p = Globs.ToPattern(new[] { "foo***" });
- Assert.AreEqual("^(foo[^/]*)$", p);
- }
+ [TestMethod]
+ public void ThreeAsterisks()
+ {
+ var p = Globs.ToPattern(["foo***"]);
+ Assert.AreEqual("^(foo[^/]*)$", p);
+ }
- [TestMethod]
- public void DoubleAsteriskOnly()
- {
- var p = Globs.ToPattern(new[] { "**" });
- Assert.AreEqual("^(.+)$", p);
- }
+ [TestMethod]
+ public void DoubleAsteriskOnly()
+ {
+ var p = Globs.ToPattern(["**"]);
+ Assert.AreEqual("^(.+)$", p);
+ }
- [TestMethod]
- public void BeginsWithDoubleAsteriskSlash()
- {
- var p = Globs.ToPattern(new[] { "**/foo" });
- Assert.AreEqual("^(([^/]+/)*foo)$", p);
- }
+ [TestMethod]
+ public void BeginsWithDoubleAsteriskSlash()
+ {
+ var p = Globs.ToPattern(["**/foo"]);
+ Assert.AreEqual("^(([^/]+/)*foo)$", p);
+ }
- [TestMethod]
- public void BeginsWithDoubleAsteriskSlashRepeating()
- {
- var p = Globs.ToPattern(new[] { "**/**/foo" });
- Assert.AreEqual("^(([^/]+/)*foo)$", p);
- }
+ [TestMethod]
+ public void BeginsWithDoubleAsteriskSlashRepeating()
+ {
+ var p = Globs.ToPattern(["**/**/foo"]);
+ Assert.AreEqual("^(([^/]+/)*foo)$", p);
+ }
- [TestMethod]
- public void EndsWithDoubleAsteriskSlash()
- {
- var p = Globs.ToPattern(new[] { "foo/**" });
- Assert.AreEqual("^(foo/.+)$", p);
- }
+ [TestMethod]
+ public void EndsWithDoubleAsteriskSlash()
+ {
+ var p = Globs.ToPattern(["foo/**"]);
+ Assert.AreEqual("^(foo/.+)$", p);
+ }
- [TestMethod]
- public void ContainsSlashDoubleAsteriskSlash()
- {
- var p = Globs.ToPattern(new[] { "foo/**/bar" });
- Assert.AreEqual("^(foo/([^/]+/)*bar)$", p);
- }
+ [TestMethod]
+ public void ContainsSlashDoubleAsteriskSlash()
+ {
+ var p = Globs.ToPattern(["foo/**/bar"]);
+ Assert.AreEqual("^(foo/([^/]+/)*bar)$", p);
+ }
- [TestMethod]
- public void ContainsSlashDoubleAsteriskSlashRepeating()
- {
- var p = Globs.ToPattern(new[] { "foo/**/**/bar" });
- Assert.AreEqual("^(foo/([^/]+/)*bar)$", p);
- }
+ [TestMethod]
+ public void ContainsSlashDoubleAsteriskSlashRepeating()
+ {
+ var p = Globs.ToPattern(["foo/**/**/bar"]);
+ Assert.AreEqual("^(foo/([^/]+/)*bar)$", p);
+ }
- [TestMethod]
- public void PatternTwoCharacter()
- {
- var p = Globs.ToPattern(new[] { "ok" });
- Assert.AreEqual("^(ok)$", p);
- }
+ [TestMethod]
+ public void PatternTwoCharacter()
+ {
+ var p = Globs.ToPattern(["ok"]);
+ Assert.AreEqual("^(ok)$", p);
+ }
- [TestMethod]
- public void PatternEscapeCharacter()
- {
- var p = Globs.ToPattern(new[] { "a.b" });
- Assert.AreEqual("^(a\\.b)$", p);
- }
+ [TestMethod]
+ public void PatternEscapeCharacter()
+ {
+ var p = Globs.ToPattern(["a.b"]);
+ Assert.AreEqual("^(a\\.b)$", p);
}
}
diff --git a/BomSweeper.Test/PathFinder/BasicTest.cs b/BomSweeper.Test/PathFinder/BasicTest.cs
index 63cf42c..1345f27 100644
--- a/BomSweeper.Test/PathFinder/BasicTest.cs
+++ b/BomSweeper.Test/PathFinder/BasicTest.cs
@@ -1,116 +1,115 @@
-namespace BomSweeper.Test.PathFinder
+namespace BomSweeper.Test.PathFinder;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using BomSweeper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+[TestClass]
+public sealed class BasicTest
{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using BomSweeper;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
+ [TestMethod]
+ public void GetFilesWithNegativeMaxDepth()
+ {
+ Assert.ThrowsException(
+ () => PathFinder.GetFiles(".", -1));
+ }
- [TestClass]
- public sealed class BasicTest
+ [TestMethod]
+ public void GetFilesWithZeroMaxDepth()
{
- [TestMethod]
- public void GetFilesWithNegativeMaxDepth()
- {
- Assert.ThrowsException(
- () => PathFinder.GetFiles(".", -1));
- }
+ var actual = PathFinder.GetFiles(".", 0);
+ Assert.AreEqual(0, actual.Count());
+ }
- [TestMethod]
- public void GetFilesWithZeroMaxDepth()
- {
- var actual = PathFinder.GetFiles(".", 0);
- Assert.AreEqual(0, actual.Count());
- }
+ [TestMethod]
+ public void GetFilesWithOneMaxDepth()
+ {
+ Toolkit.TheInstance = new TestToolkit();
+ var actual = PathFinder.GetFiles(".", 1);
+ var array = actual.ToArray();
+ Assert.AreEqual(1, array.Length);
+ Assert.AreEqual(Path.Combine(".", "foo"), array[0]);
+ }
- [TestMethod]
- public void GetFilesWithOneMaxDepth()
+ [TestMethod]
+ public void GetFilesWithTwoMaxDepth()
+ {
+ Toolkit.TheInstance = new TestToolkit();
+ var actual = PathFinder.GetFiles(".", 2);
+ var array = actual.ToArray();
+ Array.Sort(array);
+ var expected = new[]
{
- Toolkit.TheInstance = new TestToolkit();
- var actual = PathFinder.GetFiles(".", 1);
- var array = actual.ToArray();
- Assert.AreEqual(1, array.Count());
- Assert.AreEqual(Path.Combine(".", "foo"), array[0]);
- }
+ Path.Combine(".", "bar", "foo"),
+ Path.Combine(".", "baz", "foo"),
+ Path.Combine(".", "foo"),
+ };
+ Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
+ }
+
+ [TestMethod]
+ public void GetFilesWithThreeOrMoreMaxDepth()
+ {
+ Toolkit.TheInstance = new TestToolkit();
- [TestMethod]
- public void GetFilesWithTwoMaxDepth()
+ static void Perform(int depth)
{
- Toolkit.TheInstance = new TestToolkit();
- var actual = PathFinder.GetFiles(".", 2);
+ var actual = PathFinder.GetFiles(".", depth);
var array = actual.ToArray();
Array.Sort(array);
var expected = new[]
{
Path.Combine(".", "bar", "foo"),
+ Path.Combine(".", "baz", "bar", "foo"),
Path.Combine(".", "baz", "foo"),
Path.Combine(".", "foo"),
};
Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
}
+ Perform(3);
+ Perform(4);
+ }
- [TestMethod]
- public void GetFilesWithThreeOrMoreMaxDepth()
+ private sealed class TestToolkit : Toolkit
+ {
+ private readonly Dictionary map;
+
+ public TestToolkit()
{
- Toolkit.TheInstance = new TestToolkit();
+ /*
+ ./foo
+ ./bar/foo
+ ./baz/foo
+ ./baz/bar/foo
+ */
+
+ var bazBar = new TestDirectoryAct("bar")
+ .AddFile(new TestFileAct("foo"));
+ var bar = new TestDirectoryAct("bar")
+ .AddFile(new TestFileAct("foo"));
+ var baz = new TestDirectoryAct("baz")
+ .AddFile(new TestFileAct("foo"))
+ .AddDir(bazBar);
+ var current = new TestDirectoryAct("base")
+ .AddFile(new TestFileAct("foo"))
+ .AddDir(bar)
+ .AddDir(baz);
- static void Perform(int depth)
+ map = new Dictionary
{
- var actual = PathFinder.GetFiles(".", depth);
- var array = actual.ToArray();
- Array.Sort(array);
- var expected = new[]
- {
- Path.Combine(".", "bar", "foo"),
- Path.Combine(".", "baz", "bar", "foo"),
- Path.Combine(".", "baz", "foo"),
- Path.Combine(".", "foo"),
- };
- Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
- }
- Perform(3);
- Perform(4);
+ ["."] = current,
+ [Path.Combine(".", "bar")] = bar,
+ [Path.Combine(".", "baz")] = baz,
+ [Path.Combine(".", "baz", "bar")] = bazBar,
+ };
}
- private sealed class TestToolkit : Toolkit
+ public override DirectoryAct GetDirectoryAct(string path)
{
- private readonly Dictionary map;
-
- public TestToolkit()
- {
- /*
- ./foo
- ./bar/foo
- ./baz/foo
- ./baz/bar/foo
- */
-
- var bazBar = new TestDirectoryAct("bar")
- .AddFile(new TestFileAct("foo"));
- var bar = new TestDirectoryAct("bar")
- .AddFile(new TestFileAct("foo"));
- var baz = new TestDirectoryAct("baz")
- .AddFile(new TestFileAct("foo"))
- .AddDir(bazBar);
- var current = new TestDirectoryAct("base")
- .AddFile(new TestFileAct("foo"))
- .AddDir(bar)
- .AddDir(baz);
-
- map = new Dictionary
- {
- ["."] = current,
- [Path.Combine(".", "bar")] = bar,
- [Path.Combine(".", "baz")] = baz,
- [Path.Combine(".", "baz", "bar")] = bazBar,
- };
- }
-
- public override DirectoryAct GetDirectoryAct(string path)
- {
- return map[path];
- }
+ return map[path];
}
}
}
diff --git a/BomSweeper.Test/PathFinder/ExceptionThrowingDirectoryAct.cs b/BomSweeper.Test/PathFinder/ExceptionThrowingDirectoryAct.cs
index 0baa97f..bf919d8 100644
--- a/BomSweeper.Test/PathFinder/ExceptionThrowingDirectoryAct.cs
+++ b/BomSweeper.Test/PathFinder/ExceptionThrowingDirectoryAct.cs
@@ -1,58 +1,38 @@
-namespace BomSweeper.Test.PathFinder
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using BomSweeper;
-
- ///
- /// A implementation. All the methods throw
- /// an exception.
- ///
- public sealed class ExceptionThrowingDirectoryAct : DirectoryAct
- {
- private readonly Func newException;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The function that returns a new exception. Calling any method of
- /// this class throws the exception this function supplies.
- ///
- ///
- /// The directory's name.
- ///
- ///
- /// The directory's attribute.
- ///
- public ExceptionThrowingDirectoryAct(
- Func newException,
- string name,
- FileAttributes attributes = FileAttributes.Directory)
- {
- this.newException = newException;
- Name = name;
- Attributes = attributes;
- }
-
- ///
- public string Name { get; }
+namespace BomSweeper.Test.PathFinder;
- ///
- public FileAttributes Attributes { get; }
+using System;
+using System.Collections.Generic;
+using System.IO;
+using BomSweeper;
- ///
- public IEnumerable GetDirectories()
- {
- throw newException();
- }
+///
+/// A implementation. All the methods throw an
+/// exception.
+///
+///
+/// The function that returns a new exception. Calling any method of this class
+/// throws the exception this function supplies.
+///
+///
+/// The directory's name.
+///
+///
+/// The directory's attribute.
+///
+public record class ExceptionThrowingDirectoryAct(
+ Func NewException,
+ string Name,
+ FileAttributes Attributes = FileAttributes.Directory) : DirectoryAct
+{
+ ///
+ public IEnumerable GetDirectories()
+ {
+ throw NewException();
+ }
- ///
- public IEnumerable GetFiles()
- {
- throw newException();
- }
+ ///
+ public IEnumerable GetFiles()
+ {
+ throw NewException();
}
}
diff --git a/BomSweeper.Test/PathFinder/HiddenAttributeTest.cs b/BomSweeper.Test/PathFinder/HiddenAttributeTest.cs
index 90efb64..2beb7fe 100644
--- a/BomSweeper.Test/PathFinder/HiddenAttributeTest.cs
+++ b/BomSweeper.Test/PathFinder/HiddenAttributeTest.cs
@@ -1,74 +1,73 @@
-namespace BomSweeper.Test.PathFinder
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using BomSweeper;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace BomSweeper.Test.PathFinder;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using BomSweeper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
- [TestClass]
- public sealed class HiddenAttributeTest
+[TestClass]
+public sealed class HiddenAttributeTest
+{
+ [TestMethod]
+ public void GetFiles()
{
- [TestMethod]
- public void GetFiles()
+ static void Perform(int depth)
{
- Toolkit.TheInstance = new TestToolkit();
-
- void Perform(int depth)
+ var actual = PathFinder.GetFiles(".", depth);
+ var array = actual.ToArray();
+ Array.Sort(array);
+ var expected = new[]
{
- var actual = PathFinder.GetFiles(".", depth);
- var array = actual.ToArray();
- Array.Sort(array);
- var expected = new[]
- {
- Path.Combine(".", "baz", "bar", "foo"),
- Path.Combine(".", "foo"),
- };
- Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
- }
- Perform(3);
+ Path.Combine(".", "baz", "bar", "foo"),
+ Path.Combine(".", "foo"),
+ };
+ Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
}
- private sealed class TestToolkit : Toolkit
- {
- private readonly Dictionary map;
+ Toolkit.TheInstance = new TestToolkit();
+ Perform(3);
+ }
- public TestToolkit()
- {
- /*
- ./foo
- ./bar/foo
- ./baz/foo
- ./baz/bar/foo
- */
- var hidden = FileAttributes.Hidden;
+ private sealed class TestToolkit : Toolkit
+ {
+ private readonly Dictionary map;
- var bazBar = new TestDirectoryAct("bar")
- .AddFile(new TestFileAct("foo"));
- var bar = new TestDirectoryAct("bar", hidden)
- .AddFile(new TestFileAct("foo"));
- var baz = new TestDirectoryAct("baz")
- .AddFile(new TestFileAct("foo", hidden))
- .AddDir(bazBar);
- var current = new TestDirectoryAct("base")
- .AddFile(new TestFileAct("foo"))
- .AddDir(bar)
- .AddDir(baz);
+ public TestToolkit()
+ {
+ /*
+ ./foo
+ ./bar/foo
+ ./baz/foo
+ ./baz/bar/foo
+ */
+ var hidden = FileAttributes.Hidden;
- map = new Dictionary
- {
- ["."] = current,
- [Path.Combine(".", "bar")] = bar,
- [Path.Combine(".", "baz")] = baz,
- [Path.Combine(".", "baz", "bar")] = bazBar,
- };
- }
+ var bazBar = new TestDirectoryAct("bar")
+ .AddFile(new TestFileAct("foo"));
+ var bar = new TestDirectoryAct("bar", hidden)
+ .AddFile(new TestFileAct("foo"));
+ var baz = new TestDirectoryAct("baz")
+ .AddFile(new TestFileAct("foo", hidden))
+ .AddDir(bazBar);
+ var current = new TestDirectoryAct("base")
+ .AddFile(new TestFileAct("foo"))
+ .AddDir(bar)
+ .AddDir(baz);
- public override DirectoryAct GetDirectoryAct(string path)
+ map = new Dictionary
{
- return map[path];
- }
+ ["."] = current,
+ [Path.Combine(".", "bar")] = bar,
+ [Path.Combine(".", "baz")] = baz,
+ [Path.Combine(".", "baz", "bar")] = bazBar,
+ };
+ }
+
+ public override DirectoryAct GetDirectoryAct(string path)
+ {
+ return map[path];
}
}
}
diff --git a/BomSweeper.Test/PathFinder/TestDirectoryAct.cs b/BomSweeper.Test/PathFinder/TestDirectoryAct.cs
index b00684a..fce265f 100644
--- a/BomSweeper.Test/PathFinder/TestDirectoryAct.cs
+++ b/BomSweeper.Test/PathFinder/TestDirectoryAct.cs
@@ -1,79 +1,60 @@
-namespace BomSweeper.Test.PathFinder
+namespace BomSweeper.Test.PathFinder;
+
+using System.Collections.Generic;
+using System.IO;
+using BomSweeper;
+
+///
+/// A implementation for unit test.
+///
+///
+/// The directory's name.
+///
+///
+/// The directory's attribute.
+///
+public record class TestDirectoryAct(
+ string Name,
+ FileAttributes Attributes = FileAttributes.Directory) : DirectoryAct
{
- using System.Collections.Generic;
- using System.IO;
- using BomSweeper;
+ private readonly List dirList = [];
+ private readonly List fileList = [];
+
+ ///
+ public IEnumerable GetDirectories()
+ => dirList;
+
+ ///
+ public IEnumerable GetFiles()
+ => fileList;
///
- /// A implementation for unit test.
+ /// Add a child directory to this directory.
///
- public sealed class TestDirectoryAct : DirectoryAct
+ ///
+ /// The directory to be added to this.
+ ///
+ ///
+ /// This object.
+ ///
+ public TestDirectoryAct AddDir(DirectoryAct dir)
{
- private readonly List dirList;
- private readonly List fileList;
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- ///
- /// The directory's name.
- ///
- ///
- /// The directory's attribute.
- ///
- public TestDirectoryAct(
- string name,
- FileAttributes attributes = FileAttributes.Directory)
- {
- Name = name;
- Attributes = attributes;
- dirList = new List();
- fileList = new List();
- }
-
- ///
- public string Name { get; }
-
- ///
- public FileAttributes Attributes { get; }
-
- ///
- public IEnumerable GetDirectories()
- => dirList;
-
- ///
- public IEnumerable GetFiles()
- => fileList;
-
- ///
- /// Add a child directory to this directory.
- ///
- ///
- /// The directory to be added to this.
- ///
- ///
- /// This object.
- ///
- public TestDirectoryAct AddDir(DirectoryAct dir)
- {
- dirList.Add(dir);
- return this;
- }
+ dirList.Add(dir);
+ return this;
+ }
- ///
- /// Add a file to this directory.
- ///
- ///
- /// The file to be added to this.
- ///
- ///
- /// This object.
- ///
- public TestDirectoryAct AddFile(FileAct file)
- {
- fileList.Add(file);
- return this;
- }
+ ///
+ /// Add a file to this directory.
+ ///
+ ///
+ /// The file to be added to this.
+ ///
+ ///
+ /// This object.
+ ///
+ public TestDirectoryAct AddFile(FileAct file)
+ {
+ fileList.Add(file);
+ return this;
}
}
diff --git a/BomSweeper.Test/PathFinder/TestFileAct.cs b/BomSweeper.Test/PathFinder/TestFileAct.cs
index 51ae6ca..1d2fe8e 100644
--- a/BomSweeper.Test/PathFinder/TestFileAct.cs
+++ b/BomSweeper.Test/PathFinder/TestFileAct.cs
@@ -1,32 +1,19 @@
-namespace BomSweeper.Test.PathFinder
-{
- using System.IO;
- using BomSweeper;
-
- ///
- /// A implementation for unit test.
- ///
- public sealed class TestFileAct : FileAct
- {
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The file's name.
- ///
- ///
- /// The file's attribute.
- ///
- public TestFileAct(string name, FileAttributes attributes = default)
- {
- Name = name;
- Attributes = attributes;
- }
+namespace BomSweeper.Test.PathFinder;
- ///
- public string Name { get; }
+using System.IO;
+using BomSweeper;
- ///
- public FileAttributes Attributes { get; }
- }
+///
+/// A implementation for unit test.
+///
+///
+/// The file's name.
+///
+///
+/// The file's attribute.
+///
+public record class TestFileAct(
+ string Name, FileAttributes Attributes = default)
+ : FileAct
+{
}
diff --git a/BomSweeper.Test/PathFinder/ThrowExceptionTest.cs b/BomSweeper.Test/PathFinder/ThrowExceptionTest.cs
index de7ad1e..3f55d1f 100644
--- a/BomSweeper.Test/PathFinder/ThrowExceptionTest.cs
+++ b/BomSweeper.Test/PathFinder/ThrowExceptionTest.cs
@@ -1,73 +1,72 @@
-namespace BomSweeper.Test.PathFinder
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Security;
- using BomSweeper;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace BomSweeper.Test.PathFinder;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security;
+using BomSweeper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
- [TestClass]
- public sealed class ThrowExceptionTest
+[TestClass]
+public sealed class ThrowExceptionTest
+{
+ [TestMethod]
+ public void GetFiles()
{
- [TestMethod]
- public void GetFiles()
+ static void Perform(int depth)
{
- Toolkit.TheInstance = new TestToolkit();
-
- void Perform(int depth)
+ var actual = PathFinder.GetFiles(".", depth);
+ var array = actual.ToArray();
+ Array.Sort(array);
+ var expected = new[]
{
- var actual = PathFinder.GetFiles(".", depth);
- var array = actual.ToArray();
- Array.Sort(array);
- var expected = new[]
- {
- Path.Combine(".", "baz", "foo"),
- Path.Combine(".", "foo"),
- };
- Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
- }
- Perform(3);
+ Path.Combine(".", "baz", "foo"),
+ Path.Combine(".", "foo"),
+ };
+ Assert.IsTrue(Enumerable.SequenceEqual(expected, array));
}
- private sealed class TestToolkit : Toolkit
- {
- private readonly Dictionary map;
+ Toolkit.TheInstance = new TestToolkit();
+ Perform(3);
+ }
- public TestToolkit()
- {
- /*
- ./foo
- ./bar/ <-- DirectryNotFound
- ./baz/foo
- ./baz/bar/ <-- Security
- */
- var bazBar = new ExceptionThrowingDirectoryAct(
- () => new SecurityException(), "bar");
- var bar = new ExceptionThrowingDirectoryAct(
- () => new DirectoryNotFoundException(), "bar");
- var baz = new TestDirectoryAct("baz")
- .AddFile(new TestFileAct("foo"))
- .AddDir(bazBar);
- var current = new TestDirectoryAct("base")
- .AddFile(new TestFileAct("foo"))
- .AddDir(bar)
- .AddDir(baz);
+ private sealed class TestToolkit : Toolkit
+ {
+ private readonly Dictionary map;
- map = new Dictionary
- {
- ["."] = current,
- [Path.Combine(".", "bar")] = bar,
- [Path.Combine(".", "baz")] = baz,
- [Path.Combine(".", "baz", "bar")] = bazBar,
- };
- }
+ public TestToolkit()
+ {
+ /*
+ ./foo
+ ./bar/ <-- DirectryNotFound
+ ./baz/foo
+ ./baz/bar/ <-- Security
+ */
+ var bazBar = new ExceptionThrowingDirectoryAct(
+ () => new SecurityException(), "bar");
+ var bar = new ExceptionThrowingDirectoryAct(
+ () => new DirectoryNotFoundException(), "bar");
+ var baz = new TestDirectoryAct("baz")
+ .AddFile(new TestFileAct("foo"))
+ .AddDir(bazBar);
+ var current = new TestDirectoryAct("base")
+ .AddFile(new TestFileAct("foo"))
+ .AddDir(bar)
+ .AddDir(baz);
- public override DirectoryAct GetDirectoryAct(string path)
+ map = new Dictionary
{
- return map[path];
- }
+ ["."] = current,
+ [Path.Combine(".", "bar")] = bar,
+ [Path.Combine(".", "baz")] = baz,
+ [Path.Combine(".", "baz", "bar")] = bazBar,
+ };
+ }
+
+ public override DirectoryAct GetDirectoryAct(string path)
+ {
+ return map[path];
}
}
}
diff --git a/BomSweeper/.editorconfig b/BomSweeper/.editorconfig
index 6eb8761..b023fa6 100644
--- a/BomSweeper/.editorconfig
+++ b/BomSweeper/.editorconfig
@@ -17,3 +17,9 @@ dotnet_diagnostic.SA1633.severity = none
# IsNull: Do not use 'is' pattern matching with 'null'.
dotnet_diagnostic.IsNull.severity = none
+
+# SA1012: Opening braces should be spaced correctly
+dotnet_diagnostic.SA1012.severity = none
+
+# SA1013: Closing braces should be spaced correctly
+dotnet_diagnostic.SA1013.severity = none
diff --git a/BomSweeper/BomSweeper.csproj b/BomSweeper/BomSweeper.csproj
index 1a9d200..05a3bd4 100644
--- a/BomSweeper/BomSweeper.csproj
+++ b/BomSweeper/BomSweeper.csproj
@@ -2,8 +2,8 @@
Exe
- netcoreapp3.1
- 8.0
+ net9
+ 13.0
enable
@@ -26,9 +26,11 @@
-
+
-
+
+
+
diff --git a/BomSweeper/BomSweeper/BomKit.cs b/BomSweeper/BomSweeper/BomKit.cs
index c8604d3..5a1de7f 100644
--- a/BomSweeper/BomSweeper/BomKit.cs
+++ b/BomSweeper/BomSweeper/BomKit.cs
@@ -1,137 +1,124 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System;
+using System.Collections.Immutable;
+using System.IO;
+using System.Linq;
+using System.Security;
+
+///
+/// Manipulates a BOM.
+///
+public static class BomKit
{
- using System;
- using System.Collections.Immutable;
- using System.IO;
- using System.Linq;
- using System.Security;
+ private static readonly ImmutableArray Utf8ByteOrderMark
+ = [0xef, 0xbb, 0xbf];
///
- /// Manipulates a BOM.
+ /// Gets whether the file of the specified path starts with UTF-8 BOM.
///
- public static class BomKit
+ ///
+ /// The path of the file to be checked.
+ ///
+ ///
+ /// true if the file is readable and it starts with UTF-8 BOM,
+ /// false otherwise.
+ ///
+ public static bool StartsWithBom(string path)
{
- private static readonly ImmutableArray Utf8ByteOrderMark
- = ImmutableArray.Create(0xef, 0xbb, 0xbf);
-
- ///
- /// Gets whether the file of the specified path starts with UTF-8 BOM.
- ///
- ///
- /// The path of the file to be checked.
- ///
- ///
- /// true if the file is readable and it starts with UTF-8 BOM,
- /// false otherwise.
- ///
- public static bool StartsWithBom(string path)
+ try
{
- try
- {
- return StartsWithUtf8Bom(path);
- }
- catch (EndOfStreamException)
- {
- return false;
- }
- catch (DirectoryNotFoundException)
- {
- return false;
- }
- catch (FileNotFoundException)
- {
- return false;
- }
- catch (IOException)
- {
- return false;
- }
- catch (UnauthorizedAccessException)
- {
- return false;
- }
+ return StartsWithUtf8Bom(path);
+ }
+ catch (Exception e) when (e is EndOfStreamException
+ || e is DirectoryNotFoundException
+ || e is FileNotFoundException
+ || e is IOException
+ || e is UnauthorizedAccessException)
+ {
+ return false;
}
+ }
- ///
- /// Remove the BOM of the specified file.
- ///
- ///
- /// The path of the file to remove a BOM.
- ///
- public static void RemoveBom(string path)
+ ///
+ /// Remove the BOM of the specified file.
+ ///
+ ///
+ /// The path of the file to remove a BOM.
+ ///
+ public static void RemoveBom(string path)
+ {
+ void PrintError(Exception e)
{
- void PrintError(Exception e)
- {
- Console.WriteLine(
- $"{path}: Unable to remove a BOM: {e.Message}");
- }
+ Console.WriteLine(
+ $"{path}: Unable to remove a BOM: {e.Message}");
+ }
- try
- {
- var file = File.ReadAllBytes(path);
- if (file.Length < 3)
- {
- return;
- }
- var newFile = file.Skip(3).ToArray();
- File.WriteAllBytes(path, newFile);
- }
- catch (SecurityException e)
- {
- PrintError(e);
- }
- catch (UnauthorizedAccessException e)
- {
- PrintError(e);
- }
- catch (NotSupportedException e)
- {
- PrintError(e);
- }
- catch (FileNotFoundException)
- {
- return;
- }
- catch (DirectoryNotFoundException)
+ try
+ {
+ var file = File.ReadAllBytes(path);
+ if (file.Length < 3)
{
return;
}
- catch (PathTooLongException e)
- {
- PrintError(e);
- }
- catch (ArgumentException e)
- {
- PrintError(e);
- }
- catch (IOException e)
- {
- PrintError(e);
- }
+ var newFile = file.Skip(3).ToArray();
+ File.WriteAllBytes(path, newFile);
+ }
+ catch (SecurityException e)
+ {
+ PrintError(e);
+ }
+ catch (UnauthorizedAccessException e)
+ {
+ PrintError(e);
}
+ catch (NotSupportedException e)
+ {
+ PrintError(e);
+ }
+ catch (FileNotFoundException)
+ {
+ return;
+ }
+ catch (DirectoryNotFoundException)
+ {
+ return;
+ }
+ catch (PathTooLongException e)
+ {
+ PrintError(e);
+ }
+ catch (ArgumentException e)
+ {
+ PrintError(e);
+ }
+ catch (IOException e)
+ {
+ PrintError(e);
+ }
+ }
- private static bool StartsWithUtf8Bom(string path)
+ private static bool StartsWithUtf8Bom(string path)
+ {
+ static void ReadFully(Stream s, byte[] a, int o, int n)
{
- static void ReadFully(Stream s, byte[] a, int o, int n)
+ var offset = o;
+ var length = n;
+ while (length > 0)
{
- var offset = o;
- var length = n;
- while (length > 0)
+ var size = s.Read(a, offset, length);
+ if (size == 0)
{
- var size = s.Read(a, offset, length);
- if (size == 0)
- {
- throw new EndOfStreamException();
- }
- offset += size;
- length -= size;
+ throw new EndOfStreamException();
}
+ offset += size;
+ length -= size;
}
-
- var array = new byte[Utf8ByteOrderMark.Length];
- using var stream = new FileStream(path, FileMode.Open);
- ReadFully(stream, array, 0, array.Length);
- return array.SequenceEqual(Utf8ByteOrderMark);
}
+
+ var array = new byte[Utf8ByteOrderMark.Length];
+ using var stream = new FileStream(path, FileMode.Open);
+ ReadFully(stream, array, 0, array.Length);
+ return array.SequenceEqual(Utf8ByteOrderMark);
}
}
diff --git a/BomSweeper/BomSweeper/DefaultDirectoryAct.cs b/BomSweeper/BomSweeper/DefaultDirectoryAct.cs
index 0b74699..62e0c1a 100644
--- a/BomSweeper/BomSweeper/DefaultDirectoryAct.cs
+++ b/BomSweeper/BomSweeper/DefaultDirectoryAct.cs
@@ -1,49 +1,48 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+///
+/// The default implementation of interface.
+///
+public sealed class DefaultDirectoryAct : DirectoryAct
{
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
+ private readonly DirectoryInfo impl;
///
- /// The default implementation of interface.
+ /// Initializes a new instance of the
+ /// class.
///
- public sealed class DefaultDirectoryAct : DirectoryAct
+ ///
+ /// The path on which to create the .
+ ///
+ public DefaultDirectoryAct(string path)
+ => impl = new DirectoryInfo(path);
+
+ private DefaultDirectoryAct(DirectoryInfo info)
+ => impl = info;
+
+ ///
+ public string Name
+ => impl.Name;
+
+ ///
+ public FileAttributes Attributes
+ => impl.Attributes;
+
+ ///
+ public IEnumerable GetDirectories()
+ {
+ return impl.EnumerateDirectories()
+ .Select(d => new DefaultDirectoryAct(d));
+ }
+
+ ///
+ public IEnumerable GetFiles()
{
- private readonly DirectoryInfo impl;
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- ///
- /// The path on which to create the .
- ///
- public DefaultDirectoryAct(string path)
- => impl = new DirectoryInfo(path);
-
- private DefaultDirectoryAct(DirectoryInfo info)
- => impl = info;
-
- ///
- public string Name
- => impl.Name;
-
- ///
- public FileAttributes Attributes
- => impl.Attributes;
-
- ///
- public IEnumerable GetDirectories()
- {
- return impl.EnumerateDirectories()
- .Select(d => new DefaultDirectoryAct(d));
- }
-
- ///
- public IEnumerable GetFiles()
- {
- return impl.EnumerateFiles()
- .Select(f => new DefaultFileAct(f));
- }
+ return impl.EnumerateFiles()
+ .Select(f => new DefaultFileAct(f));
}
}
diff --git a/BomSweeper/BomSweeper/DefaultFileAct.cs b/BomSweeper/BomSweeper/DefaultFileAct.cs
index 5c3ff45..e44e7a6 100644
--- a/BomSweeper/BomSweeper/DefaultFileAct.cs
+++ b/BomSweeper/BomSweeper/DefaultFileAct.cs
@@ -1,40 +1,37 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System.IO;
+
+///
+/// The default implementation of interface.
+///
+public sealed class DefaultFileAct : FileAct
{
- using System.IO;
+ private readonly FileInfo impl;
///
- /// The default implementation of interface.
+ /// Initializes a new instance of the class.
///
- public sealed class DefaultFileAct : FileAct
- {
- private readonly FileInfo impl;
-
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- ///
- /// The path on which to create the .
- ///
- public DefaultFileAct(string path)
- => impl = new FileInfo(path);
+ ///
+ /// The path on which to create the .
+ ///
+ public DefaultFileAct(string path)
+ => impl = new FileInfo(path);
- ///
- /// Initializes a new instance of the
- /// class.
- ///
- ///
- /// The file information.
- ///
- public DefaultFileAct(FileInfo info)
- => impl = info;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The file information.
+ ///
+ public DefaultFileAct(FileInfo info)
+ => impl = info;
- ///
- public string Name
- => impl.Name;
+ ///
+ public string Name
+ => impl.Name;
- ///
- public FileAttributes Attributes
- => impl.Attributes;
- }
+ ///
+ public FileAttributes Attributes
+ => impl.Attributes;
}
diff --git a/BomSweeper/BomSweeper/DefaultToolkit.cs b/BomSweeper/BomSweeper/DefaultToolkit.cs
index 3b5bf37..1c8d733 100644
--- a/BomSweeper/BomSweeper/DefaultToolkit.cs
+++ b/BomSweeper/BomSweeper/DefaultToolkit.cs
@@ -1,14 +1,13 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+///
+/// The default implementation of class.
+///
+public sealed class DefaultToolkit : Toolkit
{
- ///
- /// The default implementation of class.
- ///
- public sealed class DefaultToolkit : Toolkit
+ ///
+ public override DirectoryAct GetDirectoryAct(string path)
{
- ///
- public override DirectoryAct GetDirectoryAct(string path)
- {
- return new DefaultDirectoryAct(path);
- }
+ return new DefaultDirectoryAct(path);
}
}
diff --git a/BomSweeper/BomSweeper/DirectoryAct.cs b/BomSweeper/BomSweeper/DirectoryAct.cs
index 0fdacfb..9674e76 100644
--- a/BomSweeper/BomSweeper/DirectoryAct.cs
+++ b/BomSweeper/BomSweeper/DirectoryAct.cs
@@ -1,27 +1,25 @@
-namespace BomSweeper
-{
- using System.Collections.Generic;
+namespace BomSweeper;
+
+using System.Collections.Generic;
+///
+/// Provides a way to manipulate directories.
+///
+public interface DirectoryAct : FileAct
+{
///
- /// Provides a way to manipulate directories.
+ /// Returns an enumerable collection of directory act in this directory.
///
- public interface DirectoryAct : FileAct
- {
- ///
- /// Returns an enumerable collection of directory act in this
- /// directory.
- ///
- ///
- /// An enumerable collection of the directories in this directory.
- ///
- IEnumerable GetDirectories();
+ ///
+ /// An enumerable collection of the directories in this directory.
+ ///
+ IEnumerable GetDirectories();
- ///
- /// Returns an enumerable collection of file act in this directory.
- ///
- ///
- /// An enumerable collection of the files in this directory.
- ///
- IEnumerable GetFiles();
- }
+ ///
+ /// Returns an enumerable collection of file act in this directory.
+ ///
+ ///
+ /// An enumerable collection of the files in this directory.
+ ///
+ IEnumerable GetFiles();
}
diff --git a/BomSweeper/BomSweeper/Elements.cs b/BomSweeper/BomSweeper/Elements.cs
index 8a2b367..4452642 100644
--- a/BomSweeper/BomSweeper/Elements.cs
+++ b/BomSweeper/BomSweeper/Elements.cs
@@ -1,39 +1,37 @@
-namespace BomSweeper
-{
- using System.Collections.Generic;
- using System.Linq;
+namespace BomSweeper;
+
+using System.Collections.Generic;
+using System.Linq;
+///
+/// Provides The extension methods of class.
+///
+public static class Elements
+{
///
- /// Provides The extension methods of class.
+ /// Inserts the specified element between each
+ /// element of the specified object.
///
- public static class Elements
+ ///
+ /// The type of elements.
+ ///
+ ///
+ /// The elements to insert the into.
+ ///
+ ///
+ /// The separator to be inserted.
+ ///
+ ///
+ /// The new object. If the length of is zero or one, it has the same sequence of the and does not contain the .
+ ///
+ public static IEnumerable Separate(
+ this IEnumerable all, T separator)
{
- ///
- /// Inserts the specified element between
- /// each element of the specified object.
- ///
- ///
- /// The type of elements.
- ///
- ///
- /// The elements to insert the into.
- ///
- ///
- /// The separator to be inserted.
- ///
- ///
- /// The new object. If the length of
- /// is zero or one, it has the same sequence of
- /// the and does not contain the .
- ///
- public static IEnumerable Separate(
- this IEnumerable all, T separator)
- {
- return !all.Any()
- ? all
- : all.Skip(1).SelectMany(e => new[] { separator, e })
- .Prepend(all.First());
- }
+ return !all.Any()
+ ? all
+ : all.SelectMany(e => new[] { separator, e })
+ .Skip(1);
}
}
diff --git a/BomSweeper/BomSweeper/FileAct.cs b/BomSweeper/BomSweeper/FileAct.cs
index 330ceeb..8c31d69 100644
--- a/BomSweeper/BomSweeper/FileAct.cs
+++ b/BomSweeper/BomSweeper/FileAct.cs
@@ -1,20 +1,19 @@
-namespace BomSweeper
-{
- using System.IO;
+namespace BomSweeper;
+
+using System.IO;
+///
+/// Provides a way to manipulate files.
+///
+public interface FileAct
+{
///
- /// Provides a way to manipulate files.
+ /// Gets the name of this file.
///
- public interface FileAct
- {
- ///
- /// Gets the name of this file.
- ///
- string Name { get; }
+ string Name { get; }
- ///
- /// Gets the attributes for this file.
- ///
- FileAttributes Attributes { get; }
- }
+ ///
+ /// Gets the attributes for this file.
+ ///
+ FileAttributes Attributes { get; }
}
diff --git a/BomSweeper/BomSweeper/Globs.cs b/BomSweeper/BomSweeper/Globs.cs
index 18a4ba0..814fe8c 100644
--- a/BomSweeper/BomSweeper/Globs.cs
+++ b/BomSweeper/BomSweeper/Globs.cs
@@ -1,185 +1,173 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+///
+/// Provides utilities to convert a glob pattern (path containing wildcard
+/// characters) to the Regular Expression (RE) pattern.
+///
+public static partial class Globs
{
- using System;
- using System.Collections.Generic;
- using System.Collections.Immutable;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
+ private const string DoubleAsteriskSlash = "**/";
+
+ private static readonly Regex SlashSequencePattern
+ = NewSlashSequencePattern();
+
+ private static readonly ImmutableHashSet NeedsEscapeCharSet = [
+ '\\', '[', ']', '.', '*', '+', '?', '^', '$', '(', ')', '{', '}', '|'];
///
- /// Provides utilities to convert a glob pattern (path containing
- /// wildcard characters) to the Regular Expression (RE) pattern.
+ /// Gets the RE string corresponding to the specified glob patterns.
///
- public static class Globs
+ ///
+ /// All the glob patterns. The path separator must be slash ('/').
+ ///
+ ///
+ /// The RE string corresponding to the specified glob patterns, which
+ /// starts with '^' and ends with '$' for the single-line mode of .
+ ///
+ public static string ToPattern(IEnumerable all)
{
- private const string DoubleAsteriskSlah = "**/";
-
- private static readonly Regex SlashSequencePattern = new Regex("//+");
-
- private static readonly ImmutableHashSet NeedsEscapeCharSet
- = ImmutableHashSet.Create(
- '\\',
- '[',
- ']',
- '.',
- '*',
- '+',
- '?',
- '^',
- '$',
- '(',
- ')',
- '{',
- '}',
- '|');
-
- ///
- /// Gets the RE string corresponding to the specified glob patterns.
- ///
- ///
- /// All the glob patterns. The path separator must be slash ('/').
- ///
- ///
- /// The RE string corresponding to the specified glob patterns, which
- /// starts with '^' and ends with '$' for the single-line mode of .
- ///
- public static string ToPattern(IEnumerable all)
- {
- return string.Join(
- string.Empty,
- all.Select(ToPattern)
- .Separate("|")
- .Prepend("^(")
- .Append(")$"));
- }
+ return string.Join(
+ string.Empty,
+ all.Select(ToPattern)
+ .Separate("|")
+ .Prepend("^(")
+ .Append(")$"));
+ }
- private static string ToPattern(string rawInput)
- {
- /*
- Case 1. just equals double asterisk
- |*|*|
+ private static string ToPattern(string rawInput)
+ {
+ static void EndsWithAny(StringBuilder b)
+ => b.Append(".+");
- Case 2-a. starts with double asterisk and slash
- |*|*|/|...
+ /*
+ Case 1. just equals double asterisk
+ |*|*|
- Case 2-b. ends with slash and double asterisk
- ...|/|*|*|
+ Case 2-a. starts with double asterisk and slash
+ |*|*|/|...
- Case 2-c. contains double asterisk between slashes (one or more times)
- ...|/|*|*|/|...
- */
+ Case 2-b. ends with slash and double asterisk
+ ...|/|*|*|
- // Case 1
- if (rawInput is "**")
- {
- return ".+";
- }
+ Case 2-c. contains double asterisk between slashes (one or more times)
+ ...|/|*|*|/|...
+ */
+
+ // Case 1
+ if (rawInput is "**")
+ {
+ return ".+";
+ }
- var input = SlashSequencePattern.Replace(rawInput, "/");
- var n = input.Length;
- var b = new StringBuilder(n);
- var k = 0;
- Action lastHook = () => { };
+ var input = SlashSequencePattern.Replace(rawInput, "/");
+ var inputLength = input.Length;
+ var b = new StringBuilder(inputLength);
+ var k = 0;
+ var (n, lastHook) = EndsWith(input, inputLength, "/**")
+ ? // case 2-b
+ (inputLength - 2, EndsWithAny)
+ : (inputLength, new Action(b => {}));
- // case 2-b
- if (EndsWith(input, n, "/**"))
+ void SkipRepeating(string p)
+ {
+ var m = p.Length;
+ while (StartsWith(input, k, n, p))
{
- n -= 2;
- lastHook = () => b.Append(".+");
+ k += m;
}
+ }
- void SkipRepeating(string p)
+ void SkipRepeatingChar(char c)
+ {
+ while (k < n && input[k] == c)
{
- var m = p.Length;
- while (StartsWith(input, k, n, p))
- {
- k += m;
- }
+ ++k;
}
+ }
- void SkipRepeatingChar(char c)
+ bool SkipIfStartsWith(string p)
+ {
+ if (!StartsWith(input, k, n, p))
{
- while (k < n && input[k] == c)
- {
- ++k;
- }
+ return false;
}
+ k += p.Length;
+ return true;
+ }
- bool SkipIfStartsWith(string p)
+ bool SkipIfStartsWithChar(char c)
+ {
+ if (input[k] == c)
{
- if (!StartsWith(input, k, n, p))
- {
- return false;
- }
- k += p.Length;
+ ++k;
return true;
}
+ return false;
+ }
+
+ // Case 2-a
+ if (SkipIfStartsWith(DoubleAsteriskSlash))
+ {
+ b.Append("([^/]+/)*");
+ SkipRepeating(DoubleAsteriskSlash);
+ }
- bool SkipIfStartsWithChar(char c)
+ while (k < n)
+ {
+ // Case 2-c
+ // |0|1|2|3|
+ // |/|*|*|/|
+ if (SkipIfStartsWith("/**/"))
{
- if (input[k] == c)
- {
- ++k;
- return true;
- }
- return false;
+ b.Append("/([^/]+/)*");
+ SkipRepeating(DoubleAsteriskSlash);
+ continue;
}
- // Case 2-a
- if (SkipIfStartsWith(DoubleAsteriskSlah))
+ // |0|
+ // |*|
+ if (SkipIfStartsWithChar('*'))
{
- b.Append("([^/]+/)*");
- SkipRepeating(DoubleAsteriskSlah);
+ b.Append("[^/]*");
+ SkipRepeatingChar('*');
+ continue;
}
- while (k < n)
+ var c = input[k];
+ if (NeedsEscapeCharSet.Contains(c))
{
- // Case 2-c
- // |0|1|2|3|
- // |/|*|*|/|
- if (SkipIfStartsWith("/**/"))
- {
- b.Append("/([^/]+/)*");
- SkipRepeating(DoubleAsteriskSlah);
- continue;
- }
-
- // |0|
- // |*|
- if (SkipIfStartsWithChar('*'))
- {
- b.Append("[^/]*");
- SkipRepeatingChar('*');
- continue;
- }
-
- var c = input[k];
- if (NeedsEscapeCharSet.Contains(c))
- {
- b.Append('\\');
- }
- ++k;
- b.Append(c);
+ b.Append('\\');
}
-
- lastHook();
- return b.ToString();
+ ++k;
+ b.Append(c);
}
- private static bool StartsWith(string s, int o, int n, string p)
- {
- var m = p.Length;
- return o + m <= n
- && string.CompareOrdinal(s, o, p, 0, m) == 0;
- }
+ lastHook(b);
+ return b.ToString();
+ }
- private static bool EndsWith(string s, int n, string p)
- {
- var m = p.Length;
- return n >= m
- && s.EndsWith(p, StringComparison.Ordinal);
- }
+ private static bool StartsWith(string s, int o, int n, string p)
+ {
+ var m = p.Length;
+ return o + m <= n
+ && string.CompareOrdinal(s, o, p, 0, m) == 0;
}
+
+ private static bool EndsWith(string s, int n, string p)
+ {
+ var m = p.Length;
+ return n >= m
+ && s.EndsWith(p, StringComparison.Ordinal);
+ }
+
+ [GeneratedRegex("//+")]
+ private static partial Regex NewSlashSequencePattern();
}
diff --git a/BomSweeper/BomSweeper/PathFinder.cs b/BomSweeper/BomSweeper/PathFinder.cs
index a79fe06..889a59d 100644
--- a/BomSweeper/BomSweeper/PathFinder.cs
+++ b/BomSweeper/BomSweeper/PathFinder.cs
@@ -1,95 +1,93 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security;
+
+///
+/// Provides an ability to find files in a file tree.
+///
+public static class PathFinder
{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Security;
+ ///
+ /// The default value of the maximum number of directory levels to search.
+ ///
+ public const int DefaultMaxDepth = 16;
///
- /// Provides an ability to find files in a file tree.
+ /// Returns an enumerable collection of file path in the specified
+ /// directory and its subdirectories.
///
- public static class PathFinder
+ ///
+ /// The path of the directory that is the root of a file tree to search
+ /// files.
+ ///
+ ///
+ /// The maximum number of directory levels to search.
+ ///
+ ///
+ /// The enumerable collection of file path in the specified directory and
+ /// its subdirectories.
+ ///
+ public static IEnumerable GetFiles(
+ string root, int depth = DefaultMaxDepth)
{
- ///
- /// The default value of the maximum number of directory levels to
- /// search.
- ///
- public const int DefaultMaxDepth = 16;
+ if (depth < 0)
+ {
+ throw new ArgumentException($"{nameof(depth)} is negative.");
+ }
+ var dir = Toolkit.TheInstance.GetDirectoryAct(root);
+ return GetFilesRecursively(dir, root, depth);
+ }
- ///
- /// Returns an enumerable collection of file path in the specified
- /// directory and its subdirectories.
- ///
- ///
- /// The path of the directory that is the root of a file tree to search
- /// files.
- ///
- ///
- /// The maximum number of directory levels to search.
- ///
- ///
- /// The enumerable collection of file path in the specified directory
- /// and its subdirectories.
- ///
- public static IEnumerable GetFiles(
- string root, int depth = DefaultMaxDepth)
+ private static IEnumerable GetFilesRecursively(
+ DirectoryAct dir, string root, int depth)
+ {
+ if (depth == 0)
{
- if (depth < 0)
- {
- throw new ArgumentException($"{nameof(depth)} is negative.");
- }
- var dir = Toolkit.TheInstance.GetDirectoryAct(root);
- return GetFilesRecursively(dir, root, depth);
+ return [];
}
- private static IEnumerable GetFilesRecursively(
- DirectoryAct dir, string root, int depth)
+ static bool IsNormalFile(FileAct f)
{
- if (depth == 0)
- {
- return Enumerable.Empty();
- }
+ var a = f.Attributes;
+ return (a & FileAttributes.Hidden) == 0;
+ }
+
+ static bool IsNormalDirectory(DirectoryAct d)
+ {
+ var a = d.Attributes;
+ return (a & FileAttributes.Hidden) == 0;
+ }
- static bool IsNormalFile(FileAct f)
+ static IEnumerable Of(Func> action)
+ {
+ try
{
- var a = f.Attributes;
- return (a & FileAttributes.Hidden) == 0;
+ return action();
}
-
- static bool IsNormalDirectory(DirectoryAct d)
+ catch (DirectoryNotFoundException)
{
- var a = d.Attributes;
- return (a & FileAttributes.Hidden) == 0;
+ return [];
}
-
- static IEnumerable Of(Func> action)
+ catch (SecurityException)
{
- try
- {
- return action();
- }
- catch (DirectoryNotFoundException)
- {
- return Enumerable.Empty();
- }
- catch (SecurityException)
- {
- return Enumerable.Empty();
- }
+ return [];
}
+ }
- string CombinePath(string n)
- => Path.Combine(root, n);
+ string CombinePath(string n)
+ => Path.Combine(root, n);
- var currentDirNames = Of(() => dir.GetFiles())
- .Where(IsNormalFile)
- .Select(f => CombinePath(f.Name));
- var subDirNames = Of(() => dir.GetDirectories())
- .Where(IsNormalDirectory)
- .SelectMany(d => GetFilesRecursively(d, d.Name, depth - 1))
- .Select(n => CombinePath(n));
- return currentDirNames.Concat(subDirNames);
- }
+ var currentDirNames = Of(() => dir.GetFiles())
+ .Where(IsNormalFile)
+ .Select(f => CombinePath(f.Name));
+ var subDirNames = Of(() => dir.GetDirectories())
+ .Where(IsNormalDirectory)
+ .SelectMany(d => GetFilesRecursively(d, d.Name, depth - 1))
+ .Select(n => CombinePath(n));
+ return currentDirNames.Concat(subDirNames);
}
}
diff --git a/BomSweeper/BomSweeper/Program.cs b/BomSweeper/BomSweeper/Program.cs
index efe8c0a..7665a88 100644
--- a/BomSweeper/BomSweeper/Program.cs
+++ b/BomSweeper/BomSweeper/Program.cs
@@ -1,292 +1,272 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using Maroontress.Cui;
+
+///
+/// The bootstrap class.
+///
+public sealed class Program
{
- using System;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text.RegularExpressions;
- using Maroontress.Cui;
+ private Action doIfVerbose = a => {};
+ private Action chdirAction = () => {};
+ private Strategy strategy = FindStategy;
+ private int maxDepth = PathFinder.DefaultMaxDepth;
///
- /// The bootstrap class.
+ /// Initializes a new instance of the class.
///
- public sealed class Program
+ ///
+ /// The command-line options.
+ ///
+ public Program(string[] args)
{
- private Action doIfVerbose = a => { };
- private Action chdirAction = () => { };
- private Strategy strategy = FindStategy;
- private int maxDepth = PathFinder.DefaultMaxDepth;
+ var maxDepthDescription
+ = "The maximum number of directory levels to search.\n"
+ + $"(Default: '{maxDepth}')";
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The command-line options.
- ///
- public Program(string[] args)
+ static int ParseMaxDepth(RequiredArgumentOption o)
{
- var maxDepthDescription
- = "The maximum number of directory levels to search.\n"
- + $"(Default: '{maxDepth}')";
-
- static int ParseMaxDepth(RequiredArgumentOption o)
+ var s = o.ArgumentValue;
+ if (!int.TryParse(s, out var value)
+ || value <= 0)
{
- var s = o.ArgumentValue;
- if (!int.TryParse(s, out var value)
- || value <= 0)
- {
- throw new OptionParsingException(
- o, $"invalid number for the maximum depth: {s}");
- }
- return value;
+ throw new OptionParsingException(
+ o, $"invalid number for the maximum depth: {s}");
}
+ return value;
+ }
- static void ShowUsageAndExit(Option o)
- {
- Usage(o.Schema, Console.Out);
- throw new TerminateProgramException(1);
- }
+ static void ShowUsageAndExit(Option o)
+ {
+ Usage(o.Schema, Console.Out);
+ throw new TerminateProgramException(1);
+ }
- static void ShowVersionAndExit()
- {
- Version(Console.Out);
- throw new TerminateProgramException(1);
- }
+ static void ShowVersionAndExit()
+ {
+ Version(Console.Out);
+ throw new TerminateProgramException(1);
+ }
- var schema = Options.NewSchema()
- .Add(
- "remove",
- 'R',
- "Remove a BOM",
- o => strategy = RemoveStategy)
- .Add(
- "directory",
- 'C',
- "DIR",
- "Change to directory. (Default: '.')",
- o => chdirAction = () => ChangeDirectory(o))
- .Add(
- "max-depth",
- 'D',
- "N",
- maxDepthDescription,
- o => maxDepth = ParseMaxDepth(o))
- .Add(
- "verbose",
- 'v',
- "Be verbose",
- o => doIfVerbose = a => a())
- .Add(
- "version",
- 'V',
- "Show version and exit",
- o => ShowVersionAndExit())
- .Add(
- "help",
- 'h',
- "Show this message and exit",
- ShowUsageAndExit);
+ var schema = Options.NewSchema()
+ .Add(
+ "remove",
+ 'R',
+ "Remove a BOM",
+ o => strategy = RemoveStategy)
+ .Add(
+ "directory",
+ 'C',
+ "DIR",
+ "Change to directory. (Default: '.')",
+ o => chdirAction = () => ChangeDirectory(o))
+ .Add(
+ "max-depth",
+ 'D',
+ "N",
+ maxDepthDescription,
+ o => maxDepth = ParseMaxDepth(o))
+ .Add(
+ "verbose",
+ 'v',
+ "Be verbose",
+ o => doIfVerbose = a => a())
+ .Add(
+ "version",
+ 'V',
+ "Show version and exit",
+ o => ShowVersionAndExit())
+ .Add(
+ "help",
+ 'h',
+ "Show this message and exit",
+ ShowUsageAndExit);
- Setting = schema.Parse(args);
+ Setting = schema.Parse(args);
- if (!Setting.Arguments.Any())
- {
- Usage(schema, Console.Error);
- throw new TerminateProgramException(1);
- }
+ if (!Setting.Arguments.Any())
+ {
+ Usage(schema, Console.Error);
+ throw new TerminateProgramException(1);
}
+ }
- private static Strategy FindStategy { get; }
- = new Strategy(PrintBomFilename, b => b ? 1 : 0);
+ private static Strategy FindStategy { get; }
+ = new Strategy(PrintBomFilename, b => b ? 1 : 0);
- private static Strategy RemoveStategy { get; }
- = new Strategy(BomKit.RemoveBom, b => 0);
+ private static Strategy RemoveStategy { get; }
+ = new Strategy(BomKit.RemoveBom, b => 0);
- ///
- /// Gets the setting of the command-line options.
- ///
- private Setting Setting { get; }
+ ///
+ /// Gets the setting of the command-line options.
+ ///
+ private Setting Setting { get; }
- ///
- /// The entry point.
- ///
- ///
- /// The command line options.
- ///
- public static void Main(string[] args)
+ ///
+ /// The entry point.
+ ///
+ ///
+ /// The command line options.
+ ///
+ public static void Main(string[] args)
+ {
+ try
{
- try
- {
- var program = new Program(args);
- program.Launch();
- Environment.Exit(0);
- }
- catch (OptionParsingException e)
- {
- var stderr = Console.Error;
- stderr.WriteLine(e.Message);
- Usage(e.Schema, stderr);
- Environment.Exit(1);
- }
- catch (TerminateProgramException e)
- {
- Environment.Exit(e.StatusCode);
- }
+ var program = new Program(args);
+ program.Launch();
+ Environment.Exit(0);
}
-
- private static void ChangeDirectory(RequiredArgumentOption o)
+ catch (OptionParsingException e)
{
- var dir = o.ArgumentValue;
- if (dir is null)
- {
- return;
- }
-
- static void Abort(string m)
- {
- Console.Error.WriteLine(m);
- throw new TerminateProgramException(1);
- }
-
- try
- {
- Directory.SetCurrentDirectory(dir);
- }
- catch (ArgumentException)
- {
- Abort($"{dir}: Invalid path.");
- }
- catch (PathTooLongException)
- {
- Abort($"{dir}: Too long path.");
- }
- catch (FileNotFoundException)
- {
- Abort($"{dir}: Not found.");
- }
- catch (DirectoryNotFoundException)
- {
- Abort($"{dir}: Not found.");
- }
- catch (IOException)
- {
- Abort($"{dir}: An I/O error occurred.");
- }
+ var stderr = Console.Error;
+ stderr.WriteLine(e.Message);
+ Usage(e.Schema, stderr);
+ Environment.Exit(1);
}
-
- private static string GetDllName()
- => typeof(Program).Assembly.GetName().Name;
-
- private static void Version(TextWriter @out)
+ catch (TerminateProgramException e)
{
- var dllName = GetDllName();
- var version = Assembly.GetEntryAssembly()
- .GetCustomAttribute()
- .InformationalVersion;
- @out.WriteLine($"{dllName} version {version}");
+ Environment.Exit(e.StatusCode);
}
+ }
- private static void Usage(OptionSchema schema, TextWriter @out)
+ private static void ChangeDirectory(RequiredArgumentOption o)
+ {
+ var dir = o.ArgumentValue;
+ if (dir is null)
{
- var dllName = GetDllName();
- var all = new[]
- {
- $"usage: dotnet {dllName}.dll [Options]... [--] PATTERN...",
- "",
- "Options are:",
- };
- var lines = all.Concat(schema.GetHelpMessage());
- foreach (var m in lines)
- {
- @out.WriteLine(m);
- }
+ return;
}
- private static void PrintBomFilename(string file)
+ static void Abort(string m)
{
- Console.WriteLine($"{file}: Starts with a BOM.");
+ Console.Error.WriteLine(m);
+ throw new TerminateProgramException(1);
}
- private void Launch()
+ try
{
- chdirAction();
-
- static Regex NewRegex(string p)
- {
- var options = RegexOptions.CultureInvariant
- | RegexOptions.Singleline;
- return new Regex(p, options);
- }
+ Directory.SetCurrentDirectory(dir);
+ }
+ catch (ArgumentException)
+ {
+ Abort($"{dir}: Invalid path.");
+ }
+ catch (PathTooLongException)
+ {
+ Abort($"{dir}: Too long path.");
+ }
+ catch (FileNotFoundException)
+ {
+ Abort($"{dir}: Not found.");
+ }
+ catch (DirectoryNotFoundException)
+ {
+ Abort($"{dir}: Not found.");
+ }
+ catch (IOException)
+ {
+ Abort($"{dir}: An I/O error occurred.");
+ }
+ }
- var pattern = Globs.ToPattern(Setting.Arguments);
+ private static string GetDllName()
+ => typeof(Program).Assembly.GetName().Name;
- doIfVerbose(() =>
- {
- Console.WriteLine($"Pattern: {pattern}");
- });
+ private static void Version(TextWriter @out)
+ {
+ var dllName = GetDllName();
+ var version = Assembly.GetEntryAssembly()
+ .GetCustomAttribute()
+ .InformationalVersion;
+ @out.WriteLine($"{dllName} version {version}");
+ }
- var regex = NewRegex(pattern);
- var prefix = "." + Path.DirectorySeparatorChar;
- var files = PathFinder.GetFiles(".", maxDepth)
- .Where(f => f.StartsWith(prefix))
- .Select(f => f.Substring(prefix.Length)
- .Replace(Path.DirectorySeparatorChar, '/'))
- .Where(f => regex.IsMatch(f))
- .Select(f => f.Replace('/', Path.DirectorySeparatorChar));
+ private static void Usage(OptionSchema schema, TextWriter @out)
+ {
+ var dllName = GetDllName();
+ var all = new[]
+ {
+ $"usage: dotnet {dllName}.dll [Options]... [--] PATTERN...",
+ "",
+ "Options are:",
+ };
+ var lines = all.Concat(schema.GetHelpMessage());
+ foreach (var m in lines)
+ {
+ @out.WriteLine(m);
+ }
+ }
- doIfVerbose(() =>
- {
- Console.WriteLine("Matched files:");
- foreach (var f in files)
- {
- Console.WriteLine(f);
- }
- });
+ private static void PrintBomFilename(string file)
+ {
+ Console.WriteLine($"{file}: Starts with a BOM.");
+ }
- var bomFiles = files.Where(BomKit.StartsWithBom);
- foreach (var f in bomFiles)
- {
- strategy.ConsumeBomFile(f);
- }
+ private void Launch()
+ {
+ chdirAction();
- throw new TerminateProgramException(
- strategy.SupplyStatusCode(bomFiles.Any()));
+ static Regex NewRegex(string p)
+ {
+ var options = RegexOptions.CultureInvariant
+ | RegexOptions.Singleline;
+ return new Regex(p, options);
}
- private sealed class Strategy
+ var pattern = Globs.ToPattern(Setting.Arguments);
+
+ doIfVerbose(() =>
{
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The action that consumes the file path, which matches the
- /// specified pattern.
- ///
- ///
- /// The function that consumes a boolean value and returns the
- /// status code.
- ///
- public Strategy(
- Action consumeBomFile,
- Func supplyStatusCode)
+ Console.WriteLine($"Pattern: {pattern}");
+ });
+
+ var regex = NewRegex(pattern);
+ var prefix = "." + Path.DirectorySeparatorChar;
+ var files = PathFinder.GetFiles(".", maxDepth)
+ .Where(f => f.StartsWith(prefix))
+ .Select(f => f[prefix.Length..].Replace(
+ Path.DirectorySeparatorChar, '/'))
+ .Where(f => regex.IsMatch(f))
+ .Select(f => f.Replace('/', Path.DirectorySeparatorChar));
+
+ doIfVerbose(() =>
+ {
+ Console.WriteLine("Matched files:");
+ foreach (var f in files)
{
- ConsumeBomFile = consumeBomFile;
- SupplyStatusCode = supplyStatusCode;
+ Console.WriteLine(f);
}
+ });
- ///
- /// Gets the action that consumes the file path, which matches the
- /// specified pattern.
- ///
- public Action ConsumeBomFile { get; }
-
- ///
- /// Gets the function that consumes a boolean value and returns the
- /// status code. When the boolean value is true, it
- /// represents that one or more files starting with a BOM are
- /// found.
- ///
- public Func SupplyStatusCode { get; }
+ var bomFiles = files.Where(BomKit.StartsWithBom);
+ foreach (var f in bomFiles)
+ {
+ strategy.ConsumeBomFile(f);
}
+
+ throw new TerminateProgramException(
+ strategy.SupplyStatusCode(bomFiles.Any()));
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The action that consumes the file path, which matches the specified
+ /// pattern.
+ ///
+ ///
+ /// The function that consumes a boolean value and returns the status code.
+ /// When the boolean value is true, it represents that one or more
+ /// files starting with a BOM are found.
+ ///
+ private sealed record class Strategy(
+ Action ConsumeBomFile, Func SupplyStatusCode)
+ {
}
}
diff --git a/BomSweeper/BomSweeper/Toolkit.cs b/BomSweeper/BomSweeper/Toolkit.cs
index 6b9d6b0..7ff3634 100644
--- a/BomSweeper/BomSweeper/Toolkit.cs
+++ b/BomSweeper/BomSweeper/Toolkit.cs
@@ -1,26 +1,24 @@
-namespace BomSweeper
+namespace BomSweeper;
+
+///
+/// Provides abstraction of and classes.
+///
+public abstract class Toolkit
{
///
- /// Provides abstraction of and classes.
+ /// Gets or sets the singleton instance.
///
- public abstract class Toolkit
- {
- ///
- /// Gets or sets the singleton instance.
- ///
- public static Toolkit TheInstance { get; set; }
- = new DefaultToolkit();
+ public static Toolkit TheInstance { get; set; } = new DefaultToolkit();
- ///
- /// Gets a new of the specified path.
- ///
- ///
- /// The path on which to create the .
- ///
- ///
- /// The new object.
- ///
- public abstract DirectoryAct GetDirectoryAct(string path);
- }
+ ///
+ /// Gets a new of the specified path.
+ ///
+ ///
+ /// The path on which to create the .
+ ///
+ ///
+ /// The new object.
+ ///
+ public abstract DirectoryAct GetDirectoryAct(string path);
}
diff --git a/README.md b/README.md
index 2f7bf29..4f3989d 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@ Byte Order Mark (BOM) in the directory tree and removing a BOM from those files.
## Requirements
-- [.NET Core 3.1 Runtime (Runtime 3.1.4)][dotnet-core-runtime]
+- [.NET 9.0 Runtime][dotnet-core-runtime]
## Get started
-BomSweeper is available as [the NuGet Package][bomsweeper.globaltool],
+BomSweeper is available as the [NuGet Package][bomsweeper.globaltool],
so it can be installed as follows:
```plaintext
@@ -66,37 +66,36 @@ Options are as follows:
### Exit status
-BomSweeper exits 0 if no files starting with a UTF-8 BOM are found,
-and >0 if one or more files are found or if an error occurs.
+BomSweeper exits 0 if no files starting with a UTF-8 BOM are found, and >0 if
+one or more files are found or if an error occurs.
-When the `-R` or `--remove` option is specified,
-it exits 0 on success, and >0 if an error occurs.
+When the `-R` or `--remove` option is specified, it exits 0 on success, and
+>0 if an error occurs.
### Example
-Note that, in the following examples,
-the glob pattern is enclosed in apostrophes (`'`...`'`)
-to prevent the shell from expanding the pattern.
+Note that, in the following examples, the glob pattern is enclosed in
+apostrophes (`'`...`'`) to prevent the shell from expanding the pattern.
```plaintext
bomsweeper '**/*.cs'
```
-Find `.cs` files starting with a UTF-8 BOM in the current directory and subdirectories.
+Find `.cs` files starting with a UTF-8 BOM in the current directory and
+subdirectories.
```plaintext
bomsweeper -R '**/*.cs'
```
-Find `.cs` files in the current directory and subdirectories,
-and remove a UTF-8 BOM from the files if any.
+Find `.cs` files in the current directory and subdirectories, and remove a UTF-8
+BOM from the files if any.
## How to build
### Requirements to build
-- Visual Studio 2019 Version 16.5
- or [.NET Core 3.1 SDK (SDK 3.1.300)][dotnet-core-sdk]
+- Visual Studio 2022 Version 17.12 or [.NET 9.0 SDK (SDK 9.0.100)][dotnet-core-sdk]
### Build with .NET Core SDK
@@ -125,9 +124,6 @@ dotnet pack
dotnet tool install --global --add-source bin/Debug BomSweeper.GlobalTool
```
-[dotnet-core-sdk]:
- https://dotnet.microsoft.com/download/dotnet-core/3.1
-[dotnet-core-runtime]:
- https://dotnet.microsoft.com/download/dotnet-core/3.1
-[bomsweeper.globaltool]:
- https://www.nuget.org/packages/BomSweeper.GlobalTool/
+[dotnet-core-sdk]: https://dotnet.microsoft.com/en-us/download/dotnet/9.0
+[dotnet-core-runtime]: https://dotnet.microsoft.com/en-us/download/dotnet/9.0
+[bomsweeper.globaltool]: https://www.nuget.org/packages/BomSweeper.GlobalTool/
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index a55be0c..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-version: '{build}'
-image: Visual Studio 2019
-configuration: Debug
-platform: Any CPU
-init:
-- cmd: git config --global core.autocrlf true
-before_build:
-- cmd: nuget restore
-build:
- verbosity: minimal
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index d151df7..0000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-trigger:
- branches:
- include:
- - '*'
-
-pool:
- vmImage: 'windows-2019'
-steps:
-- checkout: self
- lfs: true
-- task: UseDotNet@2
- displayName: install .NET Core SDK
- inputs:
- packageType: sdk
- version: 3.1.300
-- task: DotNetCoreCLI@2
- displayName: dotnet build
- inputs:
- command: 'build'
-- task: DotNetCoreCLI@2
- displayName: dotnet test
- inputs:
- command: 'test'
- arguments: '-p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --no-build BomSweeper.Test'
-- task: PublishCodeCoverageResults@1
- displayName: publish coverage report
- inputs:
- codeCoverageTool: Cobertura
- summaryFileLocation: 'BomSweeper.Test/coverage.cobertura.xml'