diff --git a/.editorconfig b/.editorconfig index 78976f9..975e555 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,7 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true dotnet_style_operator_placement_when_wrapping = beginning_of_line +max_line_length = 140 tab_width = 4 indent_size = 4 end_of_line = crlf @@ -27,24 +28,46 @@ dotnet_style_prefer_compound_assignment = true:suggestion dotnet_style_prefer_simplified_interpolation = true:suggestion dotnet_style_namespace_match_folder = true:suggestion -[{*.json,*.yml,*.yaml}] +# JSON config files +[*.json] +tab_width = 4 +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{yml,yaml,toml}] +tab_width = 2 indent_size = 2 indent_style = space - -[*.md] -trim_trailing_whitespace = false +insert_final_newline = true +trim_trailing_whitespace = true # XML project files -[*.{xml,config,*proj,nuspec,props,resx,targets,tasks}] +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] indent_size = 2 +insert_final_newline = true +indent_style = space -# Xml config files +# XML config files [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] indent_size = 2 +insert_final_newline = true +indent_style = space + +[*.{md,txt}] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = false +max_line_length = 120 # Code files -[*.cs] +[*.{cs,csx,vb,vbx}] +tab_width = 4 indent_size = 4 +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true dotnet_analyzer_diagnostic.severity = warning ############################### @@ -86,6 +109,11 @@ dotnet_style_namespace_match_folder = true ############################### # Style Definitions dotnet_naming_style.pascal_case_style.capitalization = pascal_case +dotnet_naming_rule.public_members_pascal_case.severity = suggestion +dotnet_naming_rule.public_members_pascal_case.symbols = public_members +dotnet_naming_rule.public_members_pascal_case.style = pascal_case_style +dotnet_naming_symbols.public_members.applicable_kinds = method,property,field,event +dotnet_naming_symbols.public_members.applicable_accessibilities = public # Use PascalCase for constant fields dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields @@ -121,38 +149,45 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false # Wrapping preferences csharp_preserve_single_line_blocks = true # Brace settings -csharp_prefer_braces = true:silent# Prefer curly braces even for one line of +csharp_prefer_braces = true:silent # Prefer curly braces even for one line of # Expression-bodied members -csharp_style_expression_bodied_methods = true:silent -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_operators = true:silent -csharp_style_expression_bodied_local_functions = true:silent -csharp_style_expression_bodied_constructors = when_on_single_line:silent +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_operators = true:suggestion +csharp_style_expression_bodied_local_functions = true:suggestion +csharp_style_expression_bodied_constructors = when_on_single_line:suggestion # Pattern matching preferences csharp_style_pattern_matching_over_is_with_cast_check = true csharp_style_pattern_matching_over_as_with_null_check = true -csharp_style_prefer_pattern_matching = true -csharp_style_prefer_not_pattern = true -csharp_style_prefer_extended_property_pattern = true -csharp_style_prefer_switch_expression = true -csharp_style_prefer_range_operator = true -csharp_style_prefer_index_operator = true +csharp_style_prefer_pattern_matching = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_index_operator = true:suggestion # Null-checking preferences csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true +csharp_style_conditional_delegate_call = true:suggestion # Modifier preferences csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion # dotnet format config -csharp_style_var_elsewhere = false +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_when_type_is_apparent = false:suggestion +csharp_style_var_elsewhere = false:warning +csharp_style_prefer_method_group_conversion = true csharp_style_implicit_object_creation_when_type_is_apparent = true -csharp_style_namespace_declarations = file_scoped:silent +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_prefer_simple_using_statement = true:suggestion +csharp_style_prefer_query_over_loop = false:silent +# Do not declare static members on generic types +dotnet_diagnostic.CA1000.severity = suggestion # use the LoggerMessage delegates dotnet_diagnostic.CA1848.severity = none -# static log message -dotnet_diagnostic.CA2254.severity = none + + # use Literals Where Appropriate dotnet_diagnostic.CA1802.severity = warning # ToLower behavior @@ -160,38 +195,84 @@ dotnet_diagnostic.CA1304.severity = none # Do not prefix enum values with type name dotnet_diagnostic.CA1712.severity = warning # Identifiers should not match keywords -dotnet_diagnostic.CA1716.severity = warning +dotnet_diagnostic.CA1716.severity = suggestion # Identifier contains type name dotnet_diagnostic.CA1720.severity = silent # Type names should not match namespaces dotnet_diagnostic.CA1724.severity = warning -# Mark members as static -dotnet_diagnostic.CA1822.severity = none # Specify IFormatProvider dotnet_diagnostic.CA1305.severity = none # Do not expose generic lists dotnet_diagnostic.CA1002.severity = warning # Do not directly await a Task -dotnet_diagnostic.CA2007.severity = none +dotnet_diagnostic.CA2007.severity = suggestion # Implement standard exception constructors -dotnet_diagnostic.CA1032.severity = none +dotnet_diagnostic.CA1032.severity = suggestion # Validate arguments of public methods dotnet_diagnostic.CA1062.severity = none # Remove the underscores from member name dotnet_diagnostic.CA1707.severity = none +# Do not initialize unnecessarily +dotnet_diagnostic.CA1805.severity = suggestion +# Do not ignore method results +dotnet_diagnostic.CA1806.severity = warning +# Avoid uninstantiated internal classes +dotnet_diagnostic.CA1812.severity = warning +# Avoid unsealed attributes +dotnet_diagnostic.CA1813.severity = warning +# Properties should not return arrays +dotnet_diagnostic.CA1819.severity = warning +# Test for empty strings using string length +dotnet_diagnostic.CA1820.severity = warning +# Remove empty finalizers +dotnet_diagnostic.CA1821.severity = error +# Mark members as static +dotnet_diagnostic.CA1822.severity = suggestion +# Avoid unused private fields +dotnet_diagnostic.CA1823.severity = suggestion +# Avoid zero-length array allocations +dotnet_diagnostic.CA1823.severity = suggestion +# Use property instead of Linq Enumerable method +dotnet_diagnostic.CA1826.severity = suggestion +# Do not use Count()/LongCount() when Any() can be used +dotnet_diagnostic.CA1827.severity = suggestion +# Do not use CountAsync/LongCountAsync when AnyAsync can be used +dotnet_diagnostic.CA1828.severity = suggestion +# Use Length/Count property instead of Enumerable.Count method +dotnet_diagnostic.CA1829.severity = suggestion +# Use AsSpan instead of Range-based indexers for string when appropriate +dotnet_diagnostic.CA1831.severity = suggestion +# Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array +dotnet_diagnostic.CA1832.severity = suggestion +# Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array +dotnet_diagnostic.CA1833.severity = suggestion +# Prefer IsEmpty over Count when available +dotnet_diagnostic.CA1836.severity = suggestion +# Provide correct arguments to formatting methods +dotnet_diagnostic.CA2241.severity = error +# Static log message +dotnet_diagnostic.CA2254.severity = none +# Do not use insecure randomness +dotnet_diagnostic.CA5394.severity = warning -# unused value -dotnet_diagnostic.IDE0058.severity = none +# Use 'var' instead of explicit type +dotnet_diagnostic.IDE0007.severity = none +# Use explicit type instead of 'var' +dotnet_diagnostic.IDE0008.severity = warning # Using directives must be placed outside of a namespace declaration dotnet_diagnostic.IDE0065.severity = none # Use conditional expression for return dotnet_diagnostic.IDE0046.severity = none # Remove unnecessary expression value -dotnet_diagnostic.IDE0058.severity = none +dotnet_diagnostic.IDE0058.severity = suggestion +# Use primary constructors +dotnet_diagnostic.IDE0290.severity = suggestion +# Collection initialization can be simplified +dotnet_diagnostic.IDE0305.severity = suggestion # Microsoft.CodeAnalysis.CSharp -dotnet_diagnostic.CS1591.severity = none +dotnet_diagnostic.CS1591.severity = suggestion # StyleCop.Analyzers @@ -372,6 +453,223 @@ dotnet_diagnostic.SA1648.severity = warning dotnet_diagnostic.SA1649.severity = none dotnet_diagnostic.SA1651.severity = none +### Nullable warnings as errors + +# Thrown value may be null +dotnet_diagnostic.CS8597.severity = error + +# Converting null literal or possible null value to non-nullable type +dotnet_diagnostic.CS8600.severity = error + +# Possible null reference assignment +dotnet_diagnostic.CS8601.severity = error + +# Dereference of a possibly null reference +dotnet_diagnostic.CS8602.severity = error + +# Possible null reference return +dotnet_diagnostic.CS8603.severity = error + +# Possible null reference argument for parameter +dotnet_diagnostic.CS8604.severity = error + +# Unboxing a possibly null value +dotnet_diagnostic.CS8605.severity = error + +# +dotnet_diagnostic.CS8606.severity = error + +# A possible null value may not be used for a type marked with [NotNull] or [DisallowNull] +dotnet_diagnostic.CS8607.severity = error + +# Nullability of reference types in type doesn't match overridden member +dotnet_diagnostic.CS8608.severity = error + +# Nullability of reference types in return type doesn't match overridden member +dotnet_diagnostic.CS8609.severity = error + +# Nullability of reference types in type parameter doesn't match overridden member +dotnet_diagnostic.CS8610.severity = error + +# Nullability of reference types in type parameter doesn't match partial method declaration +dotnet_diagnostic.CS8611.severity = error + +# Nullability of reference types in type doesn't match implicitly implemented member +dotnet_diagnostic.CS8612.severity = error + +# Nullability of reference types in return type doesn't match implicitly implemented member +dotnet_diagnostic.CS8613.severity = error + +# Nullability of reference types in type of parameter doesn't match implicitly implemented member +dotnet_diagnostic.CS8614.severity = error + +# Nullability of reference types in type doesn't match implemented member +dotnet_diagnostic.CS8615.severity = error + +# Nullability of reference types in return type doesn't match implemented member +dotnet_diagnostic.CS8616.severity = error + +# Nullability of reference types in type of parameter doesn't match implemented member +dotnet_diagnostic.CS8617.severity = error + +# Non-nullable variable must contain a non-null value when exiting constructor. Consider declaring it as nullable +dotnet_diagnostic.CS8618.severity = warning + +# Nullability of reference types in value doesn't match target type +dotnet_diagnostic.CS8619.severity = error + +# Argument cannot be used for parameter due to differences in the nullability of reference types +dotnet_diagnostic.CS8620.severity = error + +# Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes) +dotnet_diagnostic.CS8621.severity = error + +# Nullability of reference types in type of parameter doesn't match the target delegate (possibly because of nullability attributes) +dotnet_diagnostic.CS8622.severity = error + +# Argument cannot be used as an output due to differences in the nullability of reference types +dotnet_diagnostic.CS8624.severity = error + +# Cannot convert null literal to non-nullable reference type +dotnet_diagnostic.CS8625.severity = error + +# Nullable value type may be null +dotnet_diagnostic.CS8629.severity = error + +# The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type +dotnet_diagnostic.CS8631.severity = error + +# Nullability in constraints for type parameter of method doesn't match the constraints for type parameter of interface method. Consider using an explicit interface implementation instead +dotnet_diagnostic.CS8633.severity = error + +# The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'class' constraint +dotnet_diagnostic.CS8634.severity = error + +# Nullability of reference types in explicit interface specifier doesn't match interface implemented by the type +dotnet_diagnostic.CS8643.severity = error + +# Type does not implement interface member. Nullability of reference types in interface implemented by the base type doesn't match +dotnet_diagnostic.CS8644.severity = error + +# Member is already listed in the interface list on type with different nullability of reference types +dotnet_diagnostic.CS8645.severity = error + +# Partial method declarations have inconsistent nullability in constraints for type parameter +dotnet_diagnostic.CS8667.severity = error + +# Object or collection initializer implicitly dereferences possibly null member +dotnet_diagnostic.CS8670.severity = error + +# The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint +dotnet_diagnostic.CS8714.severity = error + +# Parameter must have a non-null value when exiting +dotnet_diagnostic.CS8762.severity = error + +# A method marked [DoesNotReturn] should not return +dotnet_diagnostic.CS8763.severity = error + +# Nullability of return type doesn't match overridden member (possibly because of nullability attributes) +dotnet_diagnostic.CS8764.severity = error + +# Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes) +dotnet_diagnostic.CS8765.severity = error + +# Nullability of reference types in return type of doesn't match implicitly implemented member (possibly because of nullability attributes) +dotnet_diagnostic.CS8766.severity = error + +# Nullability of reference types in type of parameter of doesn't match implicitly implemented member (possibly because of nullability attributes) +dotnet_diagnostic.CS8767.severity = error + +# Nullability of reference types in return type doesn't match implemented member (possibly because of nullability attributes) +dotnet_diagnostic.CS8768.severity = error + +# Nullability of reference types in type of parameter doesn't match implemented member (possibly because of nullability attributes) +dotnet_diagnostic.CS8769.severity = error + +# Method lacks [DoesNotReturn] annotation to match implemented or overridden member +dotnet_diagnostic.CS8770.severity = error + +# Member must have a non-null value when exiting +dotnet_diagnostic.CS8774.severity = error + +# Member must have a non-null value when exiting +dotnet_diagnostic.CS8775.severity = error + +# Member cannot be used in this attribute +dotnet_diagnostic.CS8776.severity = error + +# Parameter must have a non-null value when exiting +dotnet_diagnostic.CS8777.severity = error + +# Nullability of reference types in return type doesn't match partial method declaration +dotnet_diagnostic.CS8819.severity = error + +# Parameter must have a non-null value when exiting because parameter is non-null +dotnet_diagnostic.CS8824.severity = error + +# Return value must be non-null because parameter is non-null +dotnet_diagnostic.CS8825.severity = error + +# Sonar scaner + +dotnet_diagnostic.S1118.severity = suggestion +dotnet_diagnostic.S1135.severity = none +# Log message template should be syntactically correct +dotnet_diagnostic.S6674.severity = warning +# Non-async "Task/Task" methods should not return null +dotnet_diagnostic.S4586.severity = error +# Getters and setters should access the expected fields +dotnet_diagnostic.S4275.severity = warning +# Empty collections should not be accessed or iterated +dotnet_diagnostic.S4158.severity = warning +# Collection elements should not be replaced unconditionally +dotnet_diagnostic.S4143.severity = warning +# Exceptions should not be created without being thrown +dotnet_diagnostic.S3984.severity = warning +# Collection sizes and array length comparisons should make sense +dotnet_diagnostic.S3981.severity = suggestion +# All branches in a conditional structure should not have exactly the same implementation +dotnet_diagnostic.S3923.severity = warning +# Types should be defined in named namespaces +dotnet_diagnostic.S3903.severity = suggestion +# Empty nullable value should not be accessed +dotnet_diagnostic.S3655.severity = warning +# Methods with "Pure" attribute should return a value +dotnet_diagnostic.S3603.severity = suggestion +# Optional parameters should be passed to "base" calls +dotnet_diagnostic.S3466.severity = suggestion +# "async" methods should not return "void" +dotnet_diagnostic.S3168.severity = warning +# "IDisposables" created in a "using" statement should not be returned +dotnet_diagnostic.S2997.severity = error +# Generic parameters not constrained to reference types should not be compared to "null" +dotnet_diagnostic.S2955.severity = warning +# Classes should "Dispose" of members from the classes' own "Dispose" methods +dotnet_diagnostic.S2952.severity = warning +# Classes with "IDisposable" members should implement "IDisposable" +dotnet_diagnostic.S2931.severity = warning +# SQL keywords should be delimited by whitespace +dotnet_diagnostic.S2857.severity = warning +# Null pointers should not be dereferenced +dotnet_diagnostic.S2259.severity = error +# Variables should not be self-assigned +dotnet_diagnostic.S1656.severity = suggestion +# Method parameters, caught exceptions and foreach variables' initial values should not be ignored +dotnet_diagnostic.S1226.severity = suggestion +# ASP.NET controller actions should not have a route template starting with "/" +dotnet_diagnostic.S6931.severity = suggestion +# "StartsWith" and "EndsWith" overloads that take a "char" should be used instead of the ones that take a "string" +dotnet_diagnostic.S6610.severity = suggestion +# Exceptions should not be explicitly rethrown +dotnet_diagnostic.S3445.severity = error +# The simplest possible condition syntax should be used +dotnet_diagnostic.S3240.severity = suggestion +# "GC.SuppressFinalize" should not be invoked for types without destructors +dotnet_diagnostic.S3234.severity = error +# Multiple "OrderBy" calls should not be used +dotnet_diagnostic.S3169.severity = warning + ### Configuration for .Net analyzers executed on this repo ### # Default analyzed API surface = 'all' (public APIs + non-public APIs) @@ -384,11 +682,19 @@ csharp_prefer_simple_using_statement = true:suggestion csharp_style_prefer_method_group_conversion = true:silent csharp_style_prefer_top_level_statements = true:silent csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_xml_documentation = true:suggestion csharp_style_expression_bodied_lambdas = true:silent +### Settings for Asp.net + +# ASP0014: Suggest using top level route registrations +dotnet_diagnostic.ASP0014.severity = suggestion + [*Tests.cs] # Use local function instead of lambda dotnet_diagnostic.IDE0039.severity = none +dotnet_diagnostic.CS1591.severity = none + [**/Migrations/**] generated_code = true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..eafad23 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" + day: "sunday" + time: "12:00" + timezone: "Europe/Moscow" + open-pull-requests-limit: 10 + versioning-strategy: auto + labels: + - "dependencies" + - "nuget" + commit-message: + prefix: "chore" + include: "scope" + reviewers: + - "VladislavRudakoff" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..78bd06d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,37 @@ +name: CodeQL Analysis +on: + push: + branches: [master, main] + paths: + - '**.cs' + - '**.csproj' + pull_request: + branches: [master, main] + paths: + - '**.cs' + - '**.csproj' + schedule: + - cron: '0 12 * * 0' # Weekly on Sunday at 12:00 UTC +jobs: + analyze: + name: analyze + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ['csharp'] + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/docfx.yml b/.github/workflows/docfx.yml new file mode 100644 index 0000000..eb3f221 --- /dev/null +++ b/.github/workflows/docfx.yml @@ -0,0 +1,22 @@ +name: Generate Documentation +on: + push: + branches: [main] +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + - name: Install DocFX + run: dotnet tool install -g docfx + - name: Build Documentation + run: docfx docfx_project/docfx.json + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: docfx_project/_site diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..3085b23 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,17 @@ +name: Code Format Check +on: + push: + branches: [master, main] + pull_request: + branches: [master, main] +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + - name: Run dotnet format + run: dotnet format --verify-no-changes diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..492aec0 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +husky run --group pre-commit diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100644 index 0000000..a11a247 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +husky run --group pre-push diff --git a/.husky/task-runner.json b/.husky/task-runner.json new file mode 100644 index 0000000..e5eca61 --- /dev/null +++ b/.husky/task-runner.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://alirezanet.github.io/Husky.Net/schema.json", + "tasks": [ + { + "name": "format", + "group": "pre-commit", + "command": "dotnet", + "args": [ "format", "--verify-no-changes", "--include", "${staged}", "--exclude", "**/tests/**" ], + "include": [ "**/*.cs" ] + }, + { + "name": "simple-build", + "group": "pre-push", + "command": "dotnet", + "args": [ "build" ] + } + ] +} diff --git a/AlchemyLab.ToolBox.sln b/AlchemyLab.ToolBox.sln index 8fb8580..a9b6dd3 100644 --- a/AlchemyLab.ToolBox.sln +++ b/AlchemyLab.ToolBox.sln @@ -9,6 +9,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore Directory.Build.props = Directory.Build.props LICENSE = LICENSE + .husky\pre-commit = .husky\pre-commit + .husky\pre-push = .husky\pre-push + .husky\task-runner.json = .husky\task-runner.json EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{92987ACC-7E45-4F26-99BD-C0536C242D5B}" @@ -21,6 +24,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AlchemyLab.ToolBox.AspNet", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AlchemyLab.ToolBox.Decorating", "src\AlchemyLab.ToolBox.Decorating\AlchemyLab.ToolBox.Decorating.csproj", "{38931641-20F7-4068-A947-3FD7660DD5F1}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Github", "Github", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" + ProjectSection(SolutionItems) = preProject + .github\workflows\codeql.yml = .github\workflows\codeql.yml + .github\dependabot.yml = .github\dependabot.yml + .github\workflows\format.yml = .github\workflows\format.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Directory.Build.props b/Directory.Build.props index 0621543..9ed0ba4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,12 +16,16 @@ true + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/AlchemyLab.ToolBox.Common/ValueStopwatch.cs b/src/AlchemyLab.ToolBox.Common/ValueStopwatch.cs index e172a33..365f2b4 100644 --- a/src/AlchemyLab.ToolBox.Common/ValueStopwatch.cs +++ b/src/AlchemyLab.ToolBox.Common/ValueStopwatch.cs @@ -12,12 +12,21 @@ public readonly struct ValueStopwatch private readonly long startTimestamp; + /// + /// Флаг отражающий активность таймера + /// public bool IsActive => startTimestamp is not 0; private ValueStopwatch(long startTimestamp) => this.startTimestamp = startTimestamp; + /// + /// Запустить новый таймер + /// public static ValueStopwatch StartNew() => new(Stopwatch.GetTimestamp()); + /// + /// Получить информацию о только сколько прошло времени + /// public TimeSpan GetElapsedTime() { // Start timestamp can't be zero in an initialized ValueStopwatch. It would have to be literally the first thing executed when the machine boots to be 0.