From 87be56eb45922d1c46794232dc6d910d4a0d72fc Mon Sep 17 00:00:00 2001 From: Jason Barden Date: Thu, 17 Oct 2024 22:56:43 +0100 Subject: [PATCH] Initial commit --- .editorconfig | 276 ++++++++++++++++++ .gitattributes | 63 ++++ .github/dependabot.yml | 6 + .github/workflows/dotnet.yml | 67 +++++ .gitignore | 50 +--- AStar.Dev.Utilities.sln | 39 +++ AStar.png | Bin 0 -> 12513 bytes CodeMaid.config | 75 +++++ LICENSE | 2 +- Readme.md | 20 ++ .../AStar.Dev.Utilities.csproj | 57 ++++ .../AStar.Dev.Utilities.Unit.Tests.csproj | 39 +++ .../UnitTest1.cs | 10 + 13 files changed, 654 insertions(+), 50 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/dotnet.yml create mode 100644 AStar.Dev.Utilities.sln create mode 100644 AStar.png create mode 100644 CodeMaid.config create mode 100644 Readme.md create mode 100644 src/AStar.Dev.Utilities/AStar.Dev.Utilities.csproj create mode 100644 tests/unit/AStar.Dev.Utilities.Unit.Tests/AStar.Dev.Utilities.Unit.Tests.csproj create mode 100644 tests/unit/AStar.Dev.Utilities.Unit.Tests/UnitTest1.cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b95eeaf --- /dev/null +++ b/.editorconfig @@ -0,0 +1,276 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:error +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false:error +dotnet_style_qualification_for_property = false:error + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true:warning +dotnet_style_collection_initializer = true:error +dotnet_style_explicit_tuple_names = true:error +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true:warning +dotnet_style_object_initializer = true:error +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:warning +dotnet_style_prefer_collection_expression = when_types_loosely_match +dotnet_style_prefer_compound_assignment = true:error +dotnet_style_prefer_conditional_expression_over_assignment = true:error +dotnet_style_prefer_conditional_expression_over_return = true:error +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true:error +dotnet_style_prefer_inferred_tuple_names = true:error +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning +dotnet_style_prefer_simplified_boolean_expressions = true:error +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true:warning + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:error + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = false:error +dotnet_style_allow_statement_immediately_after_block_experimental = false:warning + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = true:silent +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:warning +csharp_style_expression_bodied_constructors = true:warning +csharp_style_expression_bodied_indexers = true:warning +csharp_style_expression_bodied_lambdas = true:warning +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = true:warning +csharp_style_expression_bodied_operators = true:warning +csharp_style_expression_bodied_properties = true:warning + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:error +csharp_style_pattern_matching_over_is_with_cast_check = true:error +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_not_pattern = true:error +csharp_style_prefer_pattern_matching = true:error +csharp_style_prefer_switch_expression = true:error + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:warning + +# Modifier preferences +csharp_prefer_static_local_function = true:warning +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async +csharp_style_prefer_readonly_struct = true:warning +csharp_style_prefer_readonly_struct_member = true:suggestion + +# Code-block preferences +csharp_prefer_braces = true:error +csharp_prefer_simple_using_statement = true:warning +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_prefer_method_group_conversion = true:warning +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_top_level_statements = false:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:error +csharp_style_deconstructed_variable_declaration = true:warning +csharp_style_implicit_object_creation_when_type_is_apparent = true:error +csharp_style_inlined_variable_declaration = true:warning +csharp_style_prefer_index_operator = true:error +csharp_style_prefer_local_over_anonymous_function = true:error +csharp_style_prefer_null_check_over_type_check = true:warning +csharp_style_prefer_range_operator = true:error +csharp_style_prefer_tuple_swap = true:error +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_throw_expression = true:warning +csharp_style_unused_value_assignment_preference = discard_variable:warning +csharp_style_unused_value_expression_statement_preference = discard_variable:warning + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:warning + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false:warning +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false:warning +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false:warning +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:error +csharp_style_allow_embedded_statements_on_same_line_experimental = true:warning + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = false +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = error +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = error +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning +dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field +dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.static_field.applicable_kinds = field +dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.static_field.required_modifiers = static + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +[*.{cs,vb}] +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_coalesce_expression = true:warning +dotnet_style_null_propagation = true:warning +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning +dotnet_style_prefer_auto_properties = true:warning +dotnet_style_object_initializer = true:error +dotnet_style_collection_initializer = true:error +dotnet_style_prefer_simplified_boolean_expressions = true:error +dotnet_style_prefer_conditional_expression_over_assignment = true:error +dotnet_style_explicit_tuple_names = true:error +dotnet_style_prefer_conditional_expression_over_return = true:error +dotnet_style_prefer_inferred_tuple_names = true:error +dotnet_style_prefer_inferred_anonymous_type_member_names = true:error +dotnet_style_prefer_compound_assignment = true:error +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_readonly_field = true:warning +dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_allow_multiple_blank_lines_experimental = false:error +dotnet_style_allow_statement_immediately_after_block_experimental = false:warning +dotnet_code_quality_unused_parameters = all:error +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:error +dotnet_style_qualification_for_method = false:error +dotnet_style_qualification_for_event = false:error \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..446b951 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..e09cb75 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,67 @@ +name: .NET + +on: + workflow_dispatch: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + name: Build and analyze + runs-on: windows-latest + steps: + - name: Set up JDK + uses: actions/setup-java@v4.4.0 + with: + java-version: 17 + distribution: 'zulu' + + - name: Checkout + uses: actions/checkout@v4.2.1 + with: + fetch-depth: 0 + + - name: Cache SonarCloud packages + uses: actions/cache@v4.1.1 + with: + path: ~\sonar\cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Cache SonarCloud scanner + id: cache-sonar-scanner + uses: actions/cache@v4.1.1 + with: + path: .\.sonar\scanner + key: ${{ runner.os }}-sonar-scanner + restore-keys: ${{ runner.os }}-sonar-scanner + + - name: Install SonarCloud scanner + if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' + shell: powershell + run: | + New-Item -Path .\.sonar\scanner -ItemType Directory + dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner + + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + shell: powershell + run: | + dotnet tool install --global dotnet-coverage + .\.sonar\scanner\dotnet-sonarscanner begin /k:"astar-development_astar-dev-utilities" /o:"astar-development" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml + dotnet build --configuration Release + dotnet-coverage collect 'dotnet test --filter "FullyQualifiedName!~Acceptance.Tests"' -f xml -o 'coverage.xml' + .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" + + - name: Pack NuGet package + if: github.ref == 'refs/heads/main' + run: dotnet pack .\src\AStar.Dev.Utilities\AStar.Dev.Utilities.csproj + + - name: Push to NuGet + if: github.ref == 'refs/heads/main' + run: dotnet nuget push "**\AStar.Dev.Utilities.*.nupkg" --api-key ${{secrets.nuget_api_key}} --skip-duplicate --source https://api.nuget.org/v3/index.json + diff --git a/.gitignore b/.gitignore index 8a30d25..dfcfd56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## -## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser @@ -23,7 +23,6 @@ mono_crash.* [Rr]eleases/ x64/ x86/ -[Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ @@ -62,9 +61,6 @@ project.lock.json project.fragment.lock.json artifacts/ -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - # StyleCop StyleCopReport.xml @@ -90,7 +86,6 @@ StyleCopReport.xml *.tmp_proj *_wpftmp.csproj *.log -*.tlog *.vspscc *.vssscc .builds @@ -142,11 +137,6 @@ _TeamCity* .axoCover/* !.axoCover/settings.json -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - # Visual Studio code coverage results *.coverage *.coveragexml @@ -294,17 +284,6 @@ node_modules/ # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw -# Visual Studio 6 auto-generated project file (contains which files were open etc.) -*.vbp - -# Visual Studio 6 workspace and project file (working project files containing files to include in project) -*.dsw -*.dsp - -# Visual Studio 6 technical files -*.ncb -*.aps - # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -361,9 +340,6 @@ ASALocalRun/ # Local History for Visual Studio .localhistory/ -# Visual Studio History (VSHistory) files -.vshistory/ - # BeatPulse healthcheck temp database healthchecksdb @@ -372,27 +348,3 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd - -# VS Code files for those working on multiple tools -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace - -# Local History for Visual Studio Code -.history/ - -# Windows Installer files from build outputs -*.cab -*.msi -*.msix -*.msm -*.msp - -# JetBrains Rider -*.sln.iml diff --git a/AStar.Dev.Utilities.sln b/AStar.Dev.Utilities.sln new file mode 100644 index 0000000..cbbfc9a --- /dev/null +++ b/AStar.Dev.Utilities.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{538ADD9A-B30C-4385-B1B0-5EF853807ED1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit", "unit", "{4FDD8291-A186-40FE-BB14-CA60EB3274FF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar.Dev.Utilities.Unit.Tests", "tests\unit\AStar.Dev.Utilities.Unit.Tests\AStar.Dev.Utilities.Unit.Tests.csproj", "{713622F6-BCF6-47AE-BBD2-45CCE257C664}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{21399C8D-85EE-4D9A-B57C-6EF16EEC03EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar.Dev.Utilities", "src\AStar.Dev.Utilities\AStar.Dev.Utilities.csproj", "{22F07837-7837-4AC9-9CBC-8906325B99A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {713622F6-BCF6-47AE-BBD2-45CCE257C664}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {713622F6-BCF6-47AE-BBD2-45CCE257C664}.Debug|Any CPU.Build.0 = Debug|Any CPU + {713622F6-BCF6-47AE-BBD2-45CCE257C664}.Release|Any CPU.ActiveCfg = Release|Any CPU + {713622F6-BCF6-47AE-BBD2-45CCE257C664}.Release|Any CPU.Build.0 = Release|Any CPU + {22F07837-7837-4AC9-9CBC-8906325B99A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22F07837-7837-4AC9-9CBC-8906325B99A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22F07837-7837-4AC9-9CBC-8906325B99A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22F07837-7837-4AC9-9CBC-8906325B99A7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4FDD8291-A186-40FE-BB14-CA60EB3274FF} = {538ADD9A-B30C-4385-B1B0-5EF853807ED1} + {713622F6-BCF6-47AE-BBD2-45CCE257C664} = {4FDD8291-A186-40FE-BB14-CA60EB3274FF} + {22F07837-7837-4AC9-9CBC-8906325B99A7} = {21399C8D-85EE-4D9A-B57C-6EF16EEC03EC} + EndGlobalSection +EndGlobal diff --git a/AStar.png b/AStar.png new file mode 100644 index 0000000000000000000000000000000000000000..8cac0a1d8136c82d5b582bdea30f24bf2e085e0f GIT binary patch literal 12513 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 MOs&qBpL2=*KT7L~lmGw# literal 0 HcmV?d00001 diff --git a/CodeMaid.config b/CodeMaid.config new file mode 100644 index 0000000..88f9bef --- /dev/null +++ b/CodeMaid.config @@ -0,0 +1,75 @@ + + + + +
+ + + + + + <?xml version="1.0" encoding="utf-16"?> +<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <string>ReSharper disable </string> + <string>ReSharper enable </string> +</ArrayOfString> + + + True + + + 1 + + + False + + + True + + + True + + + 1 + + + 2 + + + True + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + True + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE index aa83218..e97ac8b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 astar-development +Copyright (c) 2024 Jay Barden Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..c18f72a --- /dev/null +++ b/Readme.md @@ -0,0 +1,20 @@ +# AStar.Dev.Utilities + +## GitHub build + +[![Build and test solution](https://github.com/jbarden/astar-dev-utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/jbarden/astar-dev-utilities/actions/workflows/dotnet.yml) + +## SonarCloud Analysis Results + +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=bugs)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=coverage)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=jbarden_astar-dev-utilities&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=jbarden_astar-dev-utilities) + diff --git a/src/AStar.Dev.Utilities/AStar.Dev.Utilities.csproj b/src/AStar.Dev.Utilities/AStar.Dev.Utilities.csproj new file mode 100644 index 0000000..6317fe3 --- /dev/null +++ b/src/AStar.Dev.Utilities/AStar.Dev.Utilities.csproj @@ -0,0 +1,57 @@ + + + + net8.0 + enable + enable + + + + + True + + + + True + + + + True + AStar.Dev.Utilities + AStar Development + AStar Development, 2024 + README.md + LICENSE + True + snupkg + True + https://github.com/jbarden/astar-dev-utilities.git + git + https://github.com/jbarden/astar-dev-utilities + A collection of useful utilities. + 1.4.0 + AStar Development, Jason Barden + $(AssemblyName).xml + AStar.png + True + version 1.4.0, no changes - version increased as part of the migration to the new AStar NuGet / GitHub organisations. + + + + + True + \ + + + True + \ + + + True + \ + + + + + + diff --git a/tests/unit/AStar.Dev.Utilities.Unit.Tests/AStar.Dev.Utilities.Unit.Tests.csproj b/tests/unit/AStar.Dev.Utilities.Unit.Tests/AStar.Dev.Utilities.Unit.Tests.csproj new file mode 100644 index 0000000..5994372 --- /dev/null +++ b/tests/unit/AStar.Dev.Utilities.Unit.Tests/AStar.Dev.Utilities.Unit.Tests.csproj @@ -0,0 +1,39 @@ + + + + net8.0 + enable + enable + + false + true + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + True + + + + True + + + + diff --git a/tests/unit/AStar.Dev.Utilities.Unit.Tests/UnitTest1.cs b/tests/unit/AStar.Dev.Utilities.Unit.Tests/UnitTest1.cs new file mode 100644 index 0000000..6386f98 --- /dev/null +++ b/tests/unit/AStar.Dev.Utilities.Unit.Tests/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace AStar.Dev.Utilities.Unit.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} \ No newline at end of file