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'