From 1f65e1c8e341dde0522d5877c047e6f3e315ac70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 00:04:06 +0000 Subject: [PATCH 1/8] Bump NLog from 6.0.4 to 6.0.6 --- updated-dependencies: - dependency-name: NLog dependency-version: 6.0.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- MyNumberNET_CLI/MyNumberNET_CLI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MyNumberNET_CLI/MyNumberNET_CLI.csproj b/MyNumberNET_CLI/MyNumberNET_CLI.csproj index 67fa9d0..06c6d0b 100644 --- a/MyNumberNET_CLI/MyNumberNET_CLI.csproj +++ b/MyNumberNET_CLI/MyNumberNET_CLI.csproj @@ -17,7 +17,7 @@ latest - + From 585180cd6f7257b4e8a99ae1e9ccac33abd3f0d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:02:59 +0000 Subject: [PATCH 2/8] Bump MSTest.TestAdapter and MSTest.TestFramework Bumps MSTest.TestAdapter from 3.10.4 to 4.0.2 Bumps MSTest.TestFramework from 3.10.4 to 4.0.2 --- updated-dependencies: - dependency-name: MSTest.TestAdapter dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: MSTest.TestFramework dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- MyNumberNET_Test/MyNumberNET_Test.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MyNumberNET_Test/MyNumberNET_Test.csproj b/MyNumberNET_Test/MyNumberNET_Test.csproj index a02ca83..0fac31f 100644 --- a/MyNumberNET_Test/MyNumberNET_Test.csproj +++ b/MyNumberNET_Test/MyNumberNET_Test.csproj @@ -18,8 +18,8 @@ - - + + From 8c0dce66c5b000be800e8f5ef2e90537a4a298a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 04:23:11 +0000 Subject: [PATCH 3/8] Bump Microsoft.NET.Test.Sdk from 17.14.1 to 18.0.1 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- MyNumberNET_Test/MyNumberNET_Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MyNumberNET_Test/MyNumberNET_Test.csproj b/MyNumberNET_Test/MyNumberNET_Test.csproj index 0fac31f..255d685 100644 --- a/MyNumberNET_Test/MyNumberNET_Test.csproj +++ b/MyNumberNET_Test/MyNumberNET_Test.csproj @@ -17,7 +17,7 @@ latest - + From 927efdd7c7855eec150ccfe328ef3c2155547bbb Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 3 Dec 2025 23:23:02 -0800 Subject: [PATCH 4/8] Fix: Use Assert.ThrowsExactly for MSTest 4.x compatibility and sync MyNumberValue to develop branch - Updated MyNumberValueTests.cs to use Assert.ThrowsExactly instead of Assert.ThrowsException for MSTest 4.0.2 compatibility - Synced MyNumberValue struct from mynumber-object branch to develop branch - All 38 tests now pass successfully - No security issues detected by Snyk code scan --- MyNumberNET/MyNumber.cs | 311 ++++++++++++++++++++- MyNumberNET_Test/MyNumberValueTests.cs | 359 +++++++++++++++++++++++++ 2 files changed, 661 insertions(+), 9 deletions(-) create mode 100644 MyNumberNET_Test/MyNumberValueTests.cs diff --git a/MyNumberNET/MyNumber.cs b/MyNumberNET/MyNumber.cs index a130121..1283359 100644 --- a/MyNumberNET/MyNumber.cs +++ b/MyNumberNET/MyNumber.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; namespace MyNumberNET { @@ -40,18 +43,13 @@ public static int CalculateCheckDigits(int[] number) throw new MyNumberMalformedException("Malformed sequence. Must be 11 digits."); if (Array.Exists(number, n => n < 0 || n > 9)) throw new MyNumberMalformedException("All digits must be between 0 and 9."); - - // Calculate check digit using the official My Number algorithm - // Process digits from right to left with specific weights - // Array indexing: number[11-n] safely accesses indices 10,9,8,...,0 for n=1,2,3,...,11 - // This avoids Array.Reverse() while maintaining correct algorithm behavior + Array.Reverse(number); var sum = 0; - // First loop: rightmost 6 digits (indices 10,9,8,7,6,5) with weights 2,3,4,5,6,7 for (var n = 1; n < 7; n++) - sum += (n + 1) * number[11 - n]; - // Second loop: leftmost 5 digits (indices 4,3,2,1,0) with weights 2,3,4,5,6 + sum += (n + 1) * number[n - 1]; for (var n = 7; n < 12; n++) - sum += (n - 5) * number[11 - n]; + sum += (n - 5) * number[n - 1]; + Array.Reverse(number); if (sum % 11 <= 1) return 0; return 11 - sum % 11; @@ -108,4 +106,299 @@ public MyNumberMalformedException(string message) #endregion } + + /// + /// Represents a valid My Number that enforces correct format and provides type safety. + /// This is an immutable value type that ensures the My Number is always in a valid state. + /// + public readonly struct MyNumberValue : IEquatable, IFormattable + { + private readonly int[] _digits; + + /// + /// Gets the 12-digit array representation of this My Number. + /// + public int[] Digits => (int[])_digits?.Clone() ?? throw new InvalidOperationException("MyNumberValue is not initialized."); + + /// + /// Gets whether this MyNumberValue instance has been properly initialized. + /// + public bool IsInitialized => _digits != null; + + /// + /// Initializes a new instance of MyNumberValue from a 12-digit array. + /// + /// A 12-digit array representing a valid My Number. + /// Thrown when the digits don't represent a valid My Number. + public MyNumberValue(int[] digits) + { + if (!MyNumber.VerifyNumber(digits)) + { + throw new MyNumber.MyNumberMalformedException("The provided digits do not represent a valid My Number."); + } + _digits = (int[])digits.Clone(); + } + + /// + /// Initializes a new instance of MyNumberValue from individual digit parameters. + /// + /// First digit + /// Second digit + /// Third digit + /// Fourth digit + /// Fifth digit + /// Sixth digit + /// Seventh digit + /// Eighth digit + /// Ninth digit + /// Tenth digit + /// Eleventh digit + /// Twelfth digit (check digit) + /// Thrown when the digits don't represent a valid My Number. + public MyNumberValue(int d1, int d2, int d3, int d4, int d5, int d6, int d7, int d8, int d9, int d10, int d11, int d12) + : this(new[] { d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12 }) + { + } + + /// + /// Creates a MyNumberValue from the first 11 digits, automatically calculating the check digit. + /// + /// The first 11 digits of the My Number. + /// A valid MyNumberValue with the calculated check digit. + /// Thrown when the input is invalid. + public static MyNumberValue FromFirstElevenDigits(int[] firstElevenDigits) + { + if (firstElevenDigits == null || firstElevenDigits.Length != 11) + { + throw new MyNumber.MyNumberMalformedException("Must provide exactly 11 digits."); + } + + var checkDigit = MyNumber.CalculateCheckDigits(firstElevenDigits); + var allDigits = new int[12]; + Array.Copy(firstElevenDigits, allDigits, 11); + allDigits[11] = checkDigit; + + return new MyNumberValue(allDigits); + } + + /// + /// Attempts to parse a string representation of a My Number. + /// + /// String containing 12 digits (may include separators like spaces or hyphens). + /// The parsed MyNumberValue if successful. + /// True if parsing was successful, false otherwise. + public static bool TryParse(string value, out MyNumberValue result) + { + result = default; + + if (string.IsNullOrWhiteSpace(value)) + return false; + + // Remove common separators + var cleanValue = value.Replace(" ", "").Replace("-", "").Replace("_", ""); + + if (cleanValue.Length != 12) + return false; + + var digits = new int[12]; + for (int i = 0; i < 12; i++) + { + if (!char.IsDigit(cleanValue[i])) + return false; + digits[i] = cleanValue[i] - '0'; + } + + try + { + result = new MyNumberValue(digits); + return true; + } + catch (MyNumber.MyNumberMalformedException) + { + return false; + } + } + + /// + /// Parses a string representation of a My Number. + /// + /// String containing 12 digits (may include separators like spaces or hyphens). + /// A valid MyNumberValue. + /// Thrown when the string cannot be parsed as a valid My Number. + public static MyNumberValue Parse(string value) + { + if (TryParse(value, out var result)) + return result; + + throw new ArgumentException($"Unable to parse '{value}' as a valid My Number.", nameof(value)); + } + + /// + /// Generates a random valid My Number. + /// + /// A randomly generated valid MyNumberValue. + public static MyNumberValue GenerateRandom() + { + var generator = new MyNumber(); + var digits = generator.GenerateRandomNumber(); + return new MyNumberValue(digits); + } + + /// + /// Returns the string representation of this My Number. + /// + /// A 12-digit string representation. + public override string ToString() + { + return ToString("N", CultureInfo.InvariantCulture); + } + + /// + /// Returns the string representation of this My Number with the specified format. + /// + /// + /// Format string: + /// "N" or null = no separators (default): "123456789012" + /// "S" = with spaces: "1234 5678 9012" + /// "H" = with hyphens: "1234-5678-9012" + /// "G" = grouped format: "1234-5678-901-2" + /// + /// Formatted string representation. + public string ToString(string format) + { + return ToString(format, CultureInfo.InvariantCulture); + } + + /// + /// Returns the string representation of this My Number with the specified format and format provider. + /// + /// Format string (see ToString(string) for options). + /// Format provider (currently not used). + /// Formatted string representation. + public string ToString(string format, IFormatProvider formatProvider) + { + if (!IsInitialized) + throw new InvalidOperationException("MyNumberValue is not initialized."); + + var digitString = string.Join("", _digits); + + return format?.ToUpperInvariant() switch + { + null or "N" => digitString, + "S" => $"{digitString.Substring(0, 4)} {digitString.Substring(4, 4)} {digitString.Substring(8, 4)}", + "H" => $"{digitString.Substring(0, 4)}-{digitString.Substring(4, 4)}-{digitString.Substring(8, 4)}", + "G" => $"{digitString.Substring(0, 4)}-{digitString.Substring(4, 4)}-{digitString.Substring(8, 3)}-{digitString.Substring(11, 1)}", + _ => throw new FormatException($"Format string '{format}' is not supported.") + }; + } + + /// + /// Determines whether this instance is equal to another MyNumberValue. + /// + /// The other MyNumberValue to compare. + /// True if equal, false otherwise. + public bool Equals(MyNumberValue other) + { + if (!IsInitialized && !other.IsInitialized) + return true; + if (!IsInitialized || !other.IsInitialized) + return false; + + return _digits.SequenceEqual(other._digits); + } + + /// + /// Determines whether this instance is equal to the specified object. + /// + /// The object to compare. + /// True if equal, false otherwise. + public override bool Equals(object obj) + { + return obj is MyNumberValue other && Equals(other); + } + + /// + /// Gets the hash code for this MyNumberValue. + /// + /// A hash code for this instance. + public override int GetHashCode() + { + if (!IsInitialized) + return 0; + + unchecked + { + int hash = 17; + foreach (var digit in _digits) + { + hash = hash * 31 + digit; + } + return hash; + } + } + + /// + /// Determines whether two MyNumberValue instances are equal. + /// + /// The first MyNumberValue. + /// The second MyNumberValue. + /// True if equal, false otherwise. + public static bool operator ==(MyNumberValue left, MyNumberValue right) + { + return left.Equals(right); + } + + /// + /// Determines whether two MyNumberValue instances are not equal. + /// + /// The first MyNumberValue. + /// The second MyNumberValue. + /// True if not equal, false otherwise. + public static bool operator !=(MyNumberValue left, MyNumberValue right) + { + return !left.Equals(right); + } + + /// + /// Implicitly converts a MyNumberValue to an int array. + /// + /// The MyNumberValue to convert. + /// A 12-digit int array. + public static implicit operator int[](MyNumberValue myNumber) + { + return myNumber.Digits; + } + + /// + /// Implicitly converts a MyNumberValue to a string. + /// + /// The MyNumberValue to convert. + /// A 12-digit string representation. + public static implicit operator string(MyNumberValue myNumber) + { + return myNumber.ToString(); + } + + /// + /// Explicitly converts an int array to a MyNumberValue. + /// + /// The 12-digit array to convert. + /// A MyNumberValue instance. + /// Thrown when the array is not a valid My Number. + public static explicit operator MyNumberValue(int[] digits) + { + return new MyNumberValue(digits); + } + + /// + /// Explicitly converts a string to a MyNumberValue. + /// + /// The string to convert. + /// A MyNumberValue instance. + /// Thrown when the string is not a valid My Number. + public static explicit operator MyNumberValue(string value) + { + return Parse(value); + } + } } \ No newline at end of file diff --git a/MyNumberNET_Test/MyNumberValueTests.cs b/MyNumberNET_Test/MyNumberValueTests.cs new file mode 100644 index 0000000..67854a3 --- /dev/null +++ b/MyNumberNET_Test/MyNumberValueTests.cs @@ -0,0 +1,359 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using MyNumberNET; + +namespace MyNumberNET_Test +{ + [TestClass] + public class MyNumberValueTests + { + private readonly int[] _validMyNumber = { 6, 1, 4, 1, 0, 6, 5, 2, 6, 0, 0, 0 }; + private readonly int[] _invalidMyNumber = { 6, 1, 4, 1, 0, 6, 5, 2, 6, 0, 0, 1 }; + + [TestMethod] + public void Constructor_ValidDigits_CreatesMyNumberValue() + { + // Act + var myNumber = new MyNumberValue(_validMyNumber); + + // Assert + Assert.IsTrue(myNumber.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, myNumber.Digits); + } + + [TestMethod] + public void Constructor_InvalidDigits_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => new MyNumberValue(_invalidMyNumber)); + } + + [TestMethod] + public void Constructor_NullDigits_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => new MyNumberValue(null)); + } + + [TestMethod] + public void Constructor_WrongLength_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => new MyNumberValue(new int[10])); + Assert.ThrowsExactly(() => new MyNumberValue(new int[13])); + } + + [TestMethod] + public void Constructor_IndividualDigits_CreatesMyNumberValue() + { + // Act + var myNumber = new MyNumberValue(6, 1, 4, 1, 0, 6, 5, 2, 6, 0, 0, 0); + + // Assert + Assert.IsTrue(myNumber.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, myNumber.Digits); + } + + [TestMethod] + public void FromFirstElevenDigits_ValidDigits_CreatesMyNumberValue() + { + // Arrange + var firstEleven = new int[] { 6, 1, 4, 1, 0, 6, 5, 2, 6, 0, 0 }; + + // Act + var myNumber = MyNumberValue.FromFirstElevenDigits(firstEleven); + + // Assert + Assert.IsTrue(myNumber.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, myNumber.Digits); + } + + [TestMethod] + public void FromFirstElevenDigits_InvalidLength_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => + MyNumberValue.FromFirstElevenDigits(new int[10])); + Assert.ThrowsExactly(() => + MyNumberValue.FromFirstElevenDigits(null)); + } + + [TestMethod] + public void TryParse_ValidString_ReturnsTrue() + { + // Act + var success = MyNumberValue.TryParse("614106526000", out var result); + + // Assert + Assert.IsTrue(success); + Assert.IsTrue(result.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, result.Digits); + } + + [TestMethod] + public void TryParse_ValidStringWithSeparators_ReturnsTrue() + { + // Arrange + var testCases = new[] + { + "6141-0652-6000", + "6141 0652 6000", + "6141_0652_6000" + }; + + foreach (var testCase in testCases) + { + // Act + var success = MyNumberValue.TryParse(testCase, out var result); + + // Assert + Assert.IsTrue(success, $"Failed to parse: {testCase}"); + Assert.IsTrue(result.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, result.Digits); + } + } + + [TestMethod] + public void TryParse_InvalidString_ReturnsFalse() + { + // Arrange + var invalidCases = new[] + { + null, + "", + "abc", + "12345678901", // too short + "1234567890123", // too long + "614106526001", // invalid check digit + "61a106526000" // non-digit character + }; + + foreach (var invalidCase in invalidCases) + { + // Act + var success = MyNumberValue.TryParse(invalidCase, out var result); + + // Assert + Assert.IsFalse(success, $"Should have failed to parse: {invalidCase}"); + Assert.IsFalse(result.IsInitialized); + } + } + + [TestMethod] + public void Parse_ValidString_ReturnsMyNumberValue() + { + // Act + var result = MyNumberValue.Parse("614106526000"); + + // Assert + Assert.IsTrue(result.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, result.Digits); + } + + [TestMethod] + public void Parse_InvalidString_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => MyNumberValue.Parse("invalid")); + } + + [TestMethod] + public void GenerateRandom_Always_ReturnsValidMyNumberValue() + { + // Act + for (int i = 0; i < 100; i++) + { + var random = MyNumberValue.GenerateRandom(); + + // Assert + Assert.IsTrue(random.IsInitialized); + Assert.IsTrue(MyNumber.VerifyNumber(random.Digits)); + } + } + + [TestMethod] + public void ToString_DefaultFormat_ReturnsPlainDigits() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act + var result = myNumber.ToString(); + + // Assert + Assert.AreEqual("614106526000", result); + } + + [TestMethod] + public void ToString_VariousFormats_ReturnsCorrectFormat() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act & Assert + Assert.AreEqual("614106526000", myNumber.ToString("N")); + Assert.AreEqual("6141 0652 6000", myNumber.ToString("S")); + Assert.AreEqual("6141-0652-6000", myNumber.ToString("H")); + Assert.AreEqual("6141-0652-600-0", myNumber.ToString("G")); + } + + [TestMethod] + public void ToString_InvalidFormat_ThrowsException() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act & Assert + Assert.ThrowsExactly(() => myNumber.ToString("X")); + } + + [TestMethod] + public void Equals_SameValues_ReturnsTrue() + { + // Arrange + var myNumber1 = new MyNumberValue(_validMyNumber); + var myNumber2 = new MyNumberValue(_validMyNumber); + + // Act & Assert + Assert.IsTrue(myNumber1.Equals(myNumber2)); + Assert.IsTrue(myNumber1 == myNumber2); + Assert.IsFalse(myNumber1 != myNumber2); + } + + [TestMethod] + public void Equals_DifferentValues_ReturnsFalse() + { + // Arrange + var myNumber1 = new MyNumberValue(_validMyNumber); + var myNumber2 = MyNumberValue.GenerateRandom(); + + // Act & Assert + if (!myNumber1.Equals(myNumber2)) // They might be equal by chance + { + Assert.IsFalse(myNumber1.Equals(myNumber2)); + Assert.IsFalse(myNumber1 == myNumber2); + Assert.IsTrue(myNumber1 != myNumber2); + } + } + + [TestMethod] + public void Equals_UninitializedValues_ReturnsTrue() + { + // Arrange + var myNumber1 = new MyNumberValue(); + var myNumber2 = new MyNumberValue(); + + // Act & Assert + Assert.IsTrue(myNumber1.Equals(myNumber2)); + Assert.IsTrue(myNumber1 == myNumber2); + } + + [TestMethod] + public void GetHashCode_SameValues_ReturnsSameHashCode() + { + // Arrange + var myNumber1 = new MyNumberValue(_validMyNumber); + var myNumber2 = new MyNumberValue(_validMyNumber); + + // Act & Assert + Assert.AreEqual(myNumber1.GetHashCode(), myNumber2.GetHashCode()); + } + + [TestMethod] + public void ImplicitConversion_ToIntArray_ReturnsDigits() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act + int[] digits = myNumber; + + // Assert + CollectionAssert.AreEqual(_validMyNumber, digits); + } + + [TestMethod] + public void ImplicitConversion_ToString_ReturnsString() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act + string str = myNumber; + + // Assert + Assert.AreEqual("614106526000", str); + } + + [TestMethod] + public void ExplicitConversion_FromIntArray_CreatesMyNumberValue() + { + // Act + var myNumber = (MyNumberValue)_validMyNumber; + + // Assert + Assert.IsTrue(myNumber.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, myNumber.Digits); + } + + [TestMethod] + public void ExplicitConversion_FromString_CreatesMyNumberValue() + { + // Act + var myNumber = (MyNumberValue)"614106526000"; + + // Assert + Assert.IsTrue(myNumber.IsInitialized); + CollectionAssert.AreEqual(_validMyNumber, myNumber.Digits); + } + + [TestMethod] + public void ExplicitConversion_FromInvalidIntArray_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => (MyNumberValue)_invalidMyNumber); + } + + [TestMethod] + public void ExplicitConversion_FromInvalidString_ThrowsException() + { + // Act & Assert + Assert.ThrowsExactly(() => (MyNumberValue)"invalid"); + } + + [TestMethod] + public void Digits_PropertyAccess_ReturnsCopy() + { + // Arrange + var myNumber = new MyNumberValue(_validMyNumber); + + // Act + var digits1 = myNumber.Digits; + var digits2 = myNumber.Digits; + + // Assert + CollectionAssert.AreEqual(digits1, digits2); + Assert.AreNotSame(digits1, digits2); // Should be different instances + } + + [TestMethod] + public void Digits_UninitializedValue_ThrowsException() + { + // Arrange + var myNumber = new MyNumberValue(); + + // Act & Assert + Assert.ThrowsExactly(() => myNumber.Digits); + } + + [TestMethod] + public void ToString_UninitializedValue_ThrowsException() + { + // Arrange + var myNumber = new MyNumberValue(); + + // Act & Assert + Assert.ThrowsExactly(() => myNumber.ToString()); + } + } +} From 932465cc47ed531031c3731bdf72e1912f4ac77a Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 3 Dec 2025 23:26:17 -0800 Subject: [PATCH 5/8] Add Snyk security best practices instructions --- .github/instructions/snyk_rules.instructions.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/instructions/snyk_rules.instructions.md diff --git a/.github/instructions/snyk_rules.instructions.md b/.github/instructions/snyk_rules.instructions.md new file mode 100644 index 0000000..eef0634 --- /dev/null +++ b/.github/instructions/snyk_rules.instructions.md @@ -0,0 +1,14 @@ +--- +alwaysApply: true +always_on: true +trigger: always_on +applyTo: "**" +description: Snyk Security At Inception +--- + +# Project security best practices + +- Always run snyk_code_scan tool for new first party code that is generated in a Snyk-supported language. +- If any security issues are found based on newly introduced or modified code or dependencies, attempt to fix the issues using the results context from Snyk. +- Rescan the code after fixing the issues to ensure that the issues were fixed and that there are no newly introduced issues. +- Repeat this process until no new issues are found. From 5085d8b38beaae49ffc991c3ad54c4467e395d60 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 3 Dec 2025 23:31:12 -0800 Subject: [PATCH 6/8] Refactor: Centralize version and package properties in Directory.Build.props - Created Directory.Build.props with shared version, author, and package dependency properties - Updated all four project files to reference centralized properties - Reduces duplication and makes version management easier - All projects build and tests pass successfully --- Directory.Build.props | 37 ++++++++++++++++++++++++ MyNumberNET/MyNumberNET.csproj | 19 ++---------- MyNumberNET_CLI/MyNumberNET_CLI.csproj | 24 ++++----------- MyNumberNET_Test/MyNumberNET_Test.csproj | 27 +++++------------ 4 files changed, 53 insertions(+), 54 deletions(-) create mode 100644 Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..a39e4b7 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,37 @@ + + + + Hideki Saito + Hideki Saito + Copyright (c) 2017 Hideki Saito + https://github.com/hsaito/MyNumber.NET/blob/master/LICENSE + https://github.com/hsaito/MyNumber.NET + latest + + + + + 1.0.6.0 + 1.0.5.0 + 1.0.5.0 + + + + + 6.0.6 + 4.3.1 + 4.3.0 + 18.0.1 + 4.0.2 + 4.0.2 + 2.9.3 + + + + + true + /_/ + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)')) + $(RepoRoot)=$(DeterministicSourceRoot) + + diff --git a/MyNumberNET/MyNumberNET.csproj b/MyNumberNET/MyNumberNET.csproj index 953d34c..5e799e9 100644 --- a/MyNumberNET/MyNumberNET.csproj +++ b/MyNumberNET/MyNumberNET.csproj @@ -1,25 +1,12 @@  net8.0 - Hideki Saito - Hideki Saito MyNumberNET My Number Validation Library MyNumberNET MyNumberNET My Number for .NET (Library) - Copyright (c) 2019 Hideki Saito - https://github.com/hsaito/MyNumber.NET/blob/master/LICENSE - https://github.com/hsaito/MyNumber.NET - 1.0.6.0 - 1.0.6.0 - 1.0.6.0 - latest - - - - true - /_/ - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\')) - $(RepoRoot)=$(DeterministicSourceRoot) + $(MyNumberNETVersion) + $(MyNumberNETVersion) + $(MyNumberNETVersion) diff --git a/MyNumberNET_CLI/MyNumberNET_CLI.csproj b/MyNumberNET_CLI/MyNumberNET_CLI.csproj index 06c6d0b..23c2c0b 100644 --- a/MyNumberNET_CLI/MyNumberNET_CLI.csproj +++ b/MyNumberNET_CLI/MyNumberNET_CLI.csproj @@ -2,32 +2,20 @@ Exe net8.0 - Hideki Saito - Hideki Saito MyNumber My Number Validation Command Line Tool MyNumberNET_CLI MyNumberNET_CLI My Number for .NET (CLI) - Copyright (c) 2017 Hideki Saito - https://github.com/hsaito/MyNumber.NET/blob/master/LICENSE - https://github.com/hsaito/MyNumber.NET - 1.0.5.0 - 1.0.5.0 - 1.0.5.0 - latest + $(MyNumberNETCliVersion) + $(MyNumberNETCliVersion) + $(MyNumberNETCliVersion) - - - + + + - - true - /_/ - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\')) - $(RepoRoot)=$(DeterministicSourceRoot) - diff --git a/MyNumberNET_Test/MyNumberNET_Test.csproj b/MyNumberNET_Test/MyNumberNET_Test.csproj index 255d685..1f88fcd 100644 --- a/MyNumberNET_Test/MyNumberNET_Test.csproj +++ b/MyNumberNET_Test/MyNumberNET_Test.csproj @@ -2,35 +2,22 @@ net8.0 false - Hideki Saito - Hideki Saito MyNumberNet My Number Validation Unit Tests MyNumberNET_Test MyNumberNET_Test My Number for .NET (Unit Test) - Copyright (c) 2019 Hideki Saito - https://github.com/hsaito/MyNumber.NET/blob/master/LICENSE - https://github.com/hsaito/MyNumber.NET - 1.0.5.0 - 1.0.5.0 - 1.0.5.0 - latest + $(MyNumberNETTestVersion) + $(MyNumberNETTestVersion) + $(MyNumberNETTestVersion) - - - - - + + + + - - true - /_/ - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\')) - $(RepoRoot)=$(DeterministicSourceRoot) - From 3a4707516a7929805a7a7820f4c1ea74563d20ee Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 3 Dec 2025 23:32:44 -0800 Subject: [PATCH 7/8] Refactor: Move package dependency versions back to individual projects - Removed package dependency version properties from Directory.Build.props - Package versions (NLog, MSTest, xunit, etc.) now stay in respective project files - Library versions (MyNumberNET, MyNumberNET_CLI, MyNumberNET_Test) remain centralized - Keeps project-specific dependencies with their corresponding projects --- Directory.Build.props | 11 ----------- MyNumberNET_CLI/MyNumberNET_CLI.csproj | 6 +++--- MyNumberNET_Test/MyNumberNET_Test.csproj | 8 ++++---- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index a39e4b7..b03fda8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,17 +16,6 @@ 1.0.5.0 - - - 6.0.6 - 4.3.1 - 4.3.0 - 18.0.1 - 4.0.2 - 4.0.2 - 2.9.3 - - true diff --git a/MyNumberNET_CLI/MyNumberNET_CLI.csproj b/MyNumberNET_CLI/MyNumberNET_CLI.csproj index 23c2c0b..6b6ce64 100644 --- a/MyNumberNET_CLI/MyNumberNET_CLI.csproj +++ b/MyNumberNET_CLI/MyNumberNET_CLI.csproj @@ -11,9 +11,9 @@ $(MyNumberNETCliVersion) - - - + + + diff --git a/MyNumberNET_Test/MyNumberNET_Test.csproj b/MyNumberNET_Test/MyNumberNET_Test.csproj index 1f88fcd..59e02ed 100644 --- a/MyNumberNET_Test/MyNumberNET_Test.csproj +++ b/MyNumberNET_Test/MyNumberNET_Test.csproj @@ -11,10 +11,10 @@ $(MyNumberNETTestVersion) - - - - + + + + From 31af9c52d9d46983bc18c51a886e50ef387036c1 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 3 Dec 2025 23:33:17 -0800 Subject: [PATCH 8/8] Fix: Update copyright year and library version numbers in Directory.Build.props --- Directory.Build.props | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index b03fda8..92b9b78 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ Hideki Saito Hideki Saito - Copyright (c) 2017 Hideki Saito + Copyright (c) 2025 Hideki Saito https://github.com/hsaito/MyNumber.NET/blob/master/LICENSE https://github.com/hsaito/MyNumber.NET latest @@ -11,9 +11,9 @@ - 1.0.6.0 - 1.0.5.0 - 1.0.5.0 + 1.0.7.0 + 1.0.7.0 + 1.0.7.0