From b8cc45680b155c444ddd7694f3e54db864e06492 Mon Sep 17 00:00:00 2001 From: yurvon_screamo Date: Tue, 19 Mar 2024 00:37:27 +0300 Subject: [PATCH 1/3] Prototype of the cli utility --- Saunter.sln | 17 +- src/Saunter.Cli/.editorconfig | 402 ++++++++++++++++++ src/Saunter.Cli/AsyncApiPrototype.cs | 18 + src/Saunter.Cli/Program.cs | 12 + src/Saunter.Cli/README.md | 15 + src/Saunter.Cli/Saunter.Cli.csproj | 28 ++ src/Saunter.Cli/Saunter.Cli.sln | 25 ++ src/Saunter.Cli/SpecificationGenerator.cs | 83 ++++ src/Saunter/AsyncApiOptions.cs | 14 +- .../AsyncApiServiceCollectionExtensions.cs | 2 +- .../Generation/AsyncApiDocumentProvider.cs | 12 +- src/Saunter/Generation/DocumentGenerator.cs | 6 +- src/Saunter/Saunter.csproj | 3 + .../Properties/launchSettings.json | 12 + test/Saunter.Tests/ServiceCollectionTests.cs | 2 +- 15 files changed, 635 insertions(+), 16 deletions(-) create mode 100644 src/Saunter.Cli/.editorconfig create mode 100644 src/Saunter.Cli/AsyncApiPrototype.cs create mode 100644 src/Saunter.Cli/Program.cs create mode 100644 src/Saunter.Cli/README.md create mode 100644 src/Saunter.Cli/Saunter.Cli.csproj create mode 100644 src/Saunter.Cli/Saunter.Cli.sln create mode 100644 src/Saunter.Cli/SpecificationGenerator.cs create mode 100644 test/Saunter.IntegrationTests.ReverseProxy/Properties/launchSettings.json diff --git a/Saunter.sln b/Saunter.sln index 71b9bc21..7b5dc76e 100644 --- a/Saunter.sln +++ b/Saunter.sln @@ -25,7 +25,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.IntegrationTests.ReverseProxy", "test\Saunter.IntegrationTests.ReverseProxy\Saunter.IntegrationTests.ReverseProxy.csproj", "{7CD09B89-130A-41AF-ADAE-2166C4ED695B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Saunter.Tests.MarkerTypeTests", "test\Saunter.Tests.MarkerTypeTests\Saunter.Tests.MarkerTypeTests.csproj", "{02284473-6DE7-4EE0-8433-2AC295045549}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.Tests.MarkerTypeTests", "test\Saunter.Tests.MarkerTypeTests\Saunter.Tests.MarkerTypeTests.csproj", "{02284473-6DE7-4EE0-8433-2AC295045549}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Saunter.Cli", "src\Saunter.Cli\Saunter.Cli.csproj", "{BC3D32A1-539C-4421-88A8-0F1EB27C85A9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -97,6 +99,18 @@ Global {02284473-6DE7-4EE0-8433-2AC295045549}.Release|x64.Build.0 = Release|Any CPU {02284473-6DE7-4EE0-8433-2AC295045549}.Release|x86.ActiveCfg = Release|Any CPU {02284473-6DE7-4EE0-8433-2AC295045549}.Release|x86.Build.0 = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|x64.ActiveCfg = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|x64.Build.0 = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|x86.ActiveCfg = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Debug|x86.Build.0 = Debug|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|Any CPU.Build.0 = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|x64.ActiveCfg = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|x64.Build.0 = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|x86.ActiveCfg = Release|Any CPU + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -107,6 +121,7 @@ Global {F188D4A7-BBCB-464F-A370-2BD84D18EA79} = {6ABD4842-47AF-49A5-B057-0EBA64416789} {7CD09B89-130A-41AF-ADAE-2166C4ED695B} = {6491E321-2D02-44AB-9116-D722FE169595} {02284473-6DE7-4EE0-8433-2AC295045549} = {6491E321-2D02-44AB-9116-D722FE169595} + {BC3D32A1-539C-4421-88A8-0F1EB27C85A9} = {28D4C365-FDED-49AE-A97D-36202E24A55A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2F85D9DA-DBCF-4F13-8C42-5719F1469B2E} diff --git a/src/Saunter.Cli/.editorconfig b/src/Saunter.Cli/.editorconfig new file mode 100644 index 00000000..c87a74f4 --- /dev/null +++ b/src/Saunter.Cli/.editorconfig @@ -0,0 +1,402 @@ +root = true + +[*] +indent_style = space +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.cs] +#### Стили именования #### + +# Правила именования + +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 = error +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_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.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 = + +# Стили именования + +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 + +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.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 +csharp_style_throw_expression = true:warning +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_prefer_simple_default_expression = true:warning +csharp_style_prefer_local_over_anonymous_function = true:warning +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:warning +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_space_around_binary_operators = before_and_after +csharp_indent_labels = one_less_than_current +csharp_style_deconstructed_variable_declaration = true:warning +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_style_conditional_delegate_call = true:warning +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_when_type_is_apparent = false:warning +csharp_style_var_elsewhere = false:warning +csharp_prefer_simple_using_statement = true:warning +csharp_prefer_braces = true:warning +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_prefer_method_group_conversion = true:warning +csharp_style_prefer_top_level_statements = true:warning +csharp_style_prefer_primary_constructors = false:error +csharp_using_directive_placement = outside_namespace:warning +csharp_style_allow_embedded_statements_on_same_line_experimental = false:warning +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:warning +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:warning +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:warning +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:warning +csharp_prefer_static_local_function = true:warning +csharp_style_prefer_readonly_struct = true:warning +csharp_style_prefer_readonly_struct_member = true:warning +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:warning +csharp_style_expression_bodied_indexers = true:warning +csharp_style_expression_bodied_accessors = true:warning +csharp_style_expression_bodied_lambdas = true:warning +csharp_style_expression_bodied_local_functions = true:warning +dotnet_diagnostic.CA1200.severity = warning +dotnet_diagnostic.SYSLIB1045.severity = warning +dotnet_diagnostic.CA1309.severity = warning +dotnet_diagnostic.CA1311.severity = warning +dotnet_diagnostic.SYSLIB1054.severity = error +dotnet_diagnostic.CA1507.severity = warning +dotnet_diagnostic.CA1805.severity = warning +dotnet_diagnostic.CA1824.severity = warning +dotnet_diagnostic.CA1825.severity = warning +dotnet_diagnostic.CA1841.severity = warning +dotnet_diagnostic.CA1845.severity = warning +dotnet_diagnostic.CA1855.severity = warning +dotnet_diagnostic.CA2016.severity = warning +dotnet_diagnostic.CA2020.severity = warning +dotnet_diagnostic.CA2244.severity = warning +dotnet_diagnostic.CA2246.severity = warning + +[*.vb] +#### Стили именования #### + +# Правила именования + +dotnet_naming_rule.interface_should_be_начинается_с_i.severity = suggestion +dotnet_naming_rule.interface_should_be_начинается_с_i.symbols = interface +dotnet_naming_rule.interface_should_be_начинается_с_i.style = начинается_с_i + +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.severity = suggestion +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.symbols = типы +dotnet_naming_rule.типы_should_be_всечастиспрописнойбуквы.style = всечастиспрописнойбуквы + +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.severity = suggestion +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.symbols = не_являющиеся_полем_члены +dotnet_naming_rule.не_являющиеся_полем_члены_should_be_всечастиспрописнойбуквы.style = всечастиспрописнойбуквы + +# Спецификации символов + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.типы.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.типы.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.типы.required_modifiers = + +dotnet_naming_symbols.не_являющиеся_полем_члены.applicable_kinds = property, event, method +dotnet_naming_symbols.не_являющиеся_полем_члены.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected +dotnet_naming_symbols.не_являющиеся_полем_члены.required_modifiers = + +# Стили именования + +dotnet_naming_style.начинается_с_i.required_prefix = I +dotnet_naming_style.начинается_с_i.required_suffix = +dotnet_naming_style.начинается_с_i.word_separator = +dotnet_naming_style.начинается_с_i.capitalization = pascal_case + +dotnet_naming_style.всечастиспрописнойбуквы.required_prefix = +dotnet_naming_style.всечастиспрописнойбуквы.required_suffix = +dotnet_naming_style.всечастиспрописнойбуквы.word_separator = +dotnet_naming_style.всечастиспрописнойбуквы.capitalization = pascal_case + +dotnet_naming_style.всечастиспрописнойбуквы.required_prefix = +dotnet_naming_style.всечастиспрописнойбуквы.required_suffix = +dotnet_naming_style.всечастиспрописнойбуквы.word_separator = +dotnet_naming_style.всечастиспрописнойбуквы.capitalization = pascal_case + +[*.{cs,vb}] +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = true +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning +dotnet_style_prefer_auto_properties = true:warning +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:warning +dotnet_style_prefer_inferred_tuple_names = true:warning +dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning +dotnet_style_prefer_compound_assignment = true:warning +dotnet_style_prefer_simplified_interpolation = true:warning +dotnet_style_namespace_match_folder = true:error +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +insert_final_newline = true +dotnet_code_quality_unused_parameters = all:warning +dotnet_style_predefined_type_for_locals_parameters_members = true:error +dotnet_style_predefined_type_for_member_access = true:error +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_property = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_event = false:warning +dotnet_style_allow_multiple_blank_lines_experimental = false:warning +dotnet_style_allow_statement_immediately_after_block_experimental = false:warning +dotnet_style_readonly_field = true:warning +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary: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:warning +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning +dotnet_diagnostic.CA1050.severity = error +dotnet_diagnostic.CA1010.severity = warning +dotnet_diagnostic.CA1018.severity = warning +dotnet_diagnostic.CA1041.severity = warning +dotnet_diagnostic.CA1061.severity = warning +dotnet_diagnostic.CA1068.severity = warning +dotnet_diagnostic.CA1069.severity = warning +dotnet_diagnostic.CA1304.severity = warning +dotnet_diagnostic.CA1305.severity = warning +dotnet_diagnostic.CA1310.severity = warning +dotnet_diagnostic.CA2101.severity = warning +dotnet_diagnostic.CA1401.severity = warning +dotnet_diagnostic.CA1707.severity = warning +dotnet_diagnostic.CA1708.severity = warning +dotnet_diagnostic.CA1710.severity = warning +dotnet_diagnostic.CA1711.severity = warning +dotnet_diagnostic.CA1712.severity = warning +dotnet_diagnostic.CA1715.severity = warning +dotnet_diagnostic.CA1716.severity = warning +dotnet_diagnostic.CA1720.severity = warning +dotnet_diagnostic.CA1725.severity = warning +dotnet_diagnostic.CA1727.severity = warning +dotnet_diagnostic.CA1826.severity = warning +dotnet_diagnostic.CA1827.severity = warning +dotnet_diagnostic.CA1828.severity = warning +dotnet_diagnostic.CA1829.severity = warning +dotnet_diagnostic.CA1830.severity = warning +dotnet_diagnostic.CA1832.severity = warning +dotnet_diagnostic.CA1833.severity = warning +dotnet_diagnostic.CA1834.severity = warning +dotnet_diagnostic.CA1835.severity = warning +dotnet_diagnostic.CA1836.severity = warning +dotnet_diagnostic.CA1837.severity = warning +dotnet_diagnostic.CA1839.severity = warning +dotnet_diagnostic.CA1840.severity = warning +dotnet_diagnostic.CA1842.severity = warning +dotnet_diagnostic.CA1843.severity = warning +dotnet_diagnostic.CA1846.severity = warning +dotnet_diagnostic.CA1847.severity = warning +dotnet_diagnostic.CA1848.severity = silent +dotnet_diagnostic.CA1850.severity = warning +dotnet_diagnostic.CA1852.severity = suggestion +dotnet_diagnostic.CA1853.severity = warning +dotnet_diagnostic.CA1854.severity = warning +dotnet_diagnostic.CA2009.severity = warning +dotnet_diagnostic.CA2011.severity = warning +dotnet_diagnostic.CA2012.severity = error +dotnet_diagnostic.CA2019.severity = warning +dotnet_diagnostic.CA3061.severity = warning +dotnet_diagnostic.CA3075.severity = warning +dotnet_diagnostic.CA3076.severity = warning +dotnet_diagnostic.CA3077.severity = warning +dotnet_diagnostic.CA3147.severity = warning +dotnet_diagnostic.CA5350.severity = warning +dotnet_diagnostic.CA5351.severity = warning +dotnet_diagnostic.CA5359.severity = warning +dotnet_diagnostic.CA5360.severity = warning +dotnet_diagnostic.CA5363.severity = warning +dotnet_diagnostic.CA5364.severity = warning +dotnet_diagnostic.CA5365.severity = warning +dotnet_diagnostic.CA5366.severity = warning +dotnet_diagnostic.CA5379.severity = warning +dotnet_diagnostic.CA5384.severity = warning +dotnet_diagnostic.CA5385.severity = warning +dotnet_diagnostic.CA5397.severity = warning +dotnet_diagnostic.CA1816.severity = warning +dotnet_diagnostic.CA2201.severity = warning +dotnet_diagnostic.CA2208.severity = warning +dotnet_diagnostic.CA2211.severity = warning +dotnet_diagnostic.CA2215.severity = warning +dotnet_diagnostic.CA2219.severity = warning +dotnet_diagnostic.CA2229.severity = warning +dotnet_diagnostic.CA2231.severity = warning +dotnet_diagnostic.CA2241.severity = warning +dotnet_diagnostic.CA2242.severity = error +dotnet_diagnostic.CA2245.severity = warning +dotnet_diagnostic.CA2248.severity = warning +dotnet_diagnostic.CA2249.severity = warning +dotnet_diagnostic.CA2250.severity = warning +dotnet_diagnostic.CA2253.severity = warning +dotnet_diagnostic.CA2254.severity = warning +dotnet_diagnostic.CA1047.severity = warning +dotnet_diagnostic.CA1802.severity = warning +dotnet_diagnostic.CA1810.severity = warning +dotnet_diagnostic.CA1821.severity = error +dotnet_diagnostic.CA1823.severity = warning +dotnet_diagnostic.CA2013.severity = warning +dotnet_diagnostic.CA2014.severity = error +dotnet_diagnostic.CA2200.severity = warning + +# Newline settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true + +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = error +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style + +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +dotnet_naming_rule.static_fields_should_have_prefix.severity = error +dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields +dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style + +dotnet_naming_symbols.static_fields.applicable_kinds = field +dotnet_naming_symbols.static_fields.required_modifiers = static +dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected + +dotnet_naming_style.static_prefix_style.required_prefix = s_ +dotnet_naming_style.static_prefix_style.capitalization = camel_case + +dotnet_naming_rule.camel_case_for_private_internal_fields.severity = error +dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style + +dotnet_naming_symbols.private_internal_fields.applicable_kinds = field +dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal + +dotnet_naming_style.camel_case_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case + +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning + +dotnet_diagnostic.IDE0005.severity = warning +dotnet_diagnostic.IDE0035.severity = warning +dotnet_diagnostic.IDE0036.severity = warning +dotnet_diagnostic.IDE0043.severity = warning +dotnet_diagnostic.IDE0044.severity = suggestion +dotnet_diagnostic.IDE0055.severity = warning +dotnet_diagnostic.IDE0161.severity = warning +dotnet_diagnostic.IDE0290.severity = error + +dotnet_diagnostic.HAA0101.severity = suggestion +dotnet_diagnostic.HAA0301.severity = suggestion +dotnet_diagnostic.HAA0303.severity = suggestion +dotnet_diagnostic.HAA0401.severity = suggestion +dotnet_diagnostic.HAA0601.severity = suggestion + +dotnet_diagnostic.CS8597.severity = error +dotnet_diagnostic.CS8600.severity = error +dotnet_diagnostic.CS8601.severity = error +dotnet_diagnostic.CS8602.severity = error +dotnet_diagnostic.CS8603.severity = error +dotnet_diagnostic.CS8604.severity = error +dotnet_diagnostic.CS8605.severity = error +dotnet_diagnostic.CS8607.severity = error +dotnet_diagnostic.CS8608.severity = error +dotnet_diagnostic.CS8609.severity = error +dotnet_diagnostic.CS8610.severity = error +dotnet_diagnostic.CS8611.severity = error +dotnet_diagnostic.CS8612.severity = error +dotnet_diagnostic.CS8613.severity = error +dotnet_diagnostic.CS8614.severity = error +dotnet_diagnostic.CS8615.severity = error +dotnet_diagnostic.CS8616.severity = error +dotnet_diagnostic.CS8617.severity = error +dotnet_diagnostic.CS8618.severity = error +dotnet_diagnostic.CS8619.severity = error +dotnet_diagnostic.CS8620.severity = error +dotnet_diagnostic.CS8621.severity = error +dotnet_diagnostic.CS8622.severity = error +dotnet_diagnostic.CS8624.severity = error +dotnet_diagnostic.CS8625.severity = error +dotnet_diagnostic.CS8629.severity = error +dotnet_diagnostic.CS8631.severity = error +dotnet_diagnostic.CS8633.severity = error +dotnet_diagnostic.CS8634.severity = error +dotnet_diagnostic.CS8643.severity = error +dotnet_diagnostic.CS8644.severity = error +dotnet_diagnostic.CS8645.severity = error +dotnet_diagnostic.CS8655.severity = error +dotnet_diagnostic.CS8667.severity = error +dotnet_diagnostic.CS8670.severity = error +dotnet_diagnostic.CS8714.severity = error +dotnet_diagnostic.CS8762.severity = error +dotnet_diagnostic.CS8763.severity = error +dotnet_diagnostic.CS8764.severity = error +dotnet_diagnostic.CS8765.severity = error +dotnet_diagnostic.CS8766.severity = error +dotnet_diagnostic.CS8767.severity = error +dotnet_diagnostic.CS8768.severity = error +dotnet_diagnostic.CS8769.severity = error +dotnet_diagnostic.CS8770.severity = error +dotnet_diagnostic.CS8774.severity = error +dotnet_diagnostic.CS8776.severity = error +dotnet_diagnostic.CS8775.severity = error +dotnet_diagnostic.CS8777.severity = error +dotnet_diagnostic.CS8819.severity = error +dotnet_diagnostic.CS8824.severity = error +dotnet_diagnostic.CS8825.severity = error +dotnet_diagnostic.CS8847.severity = error \ No newline at end of file diff --git a/src/Saunter.Cli/AsyncApiPrototype.cs b/src/Saunter.Cli/AsyncApiPrototype.cs new file mode 100644 index 00000000..0bfd9be6 --- /dev/null +++ b/src/Saunter.Cli/AsyncApiPrototype.cs @@ -0,0 +1,18 @@ +using Saunter.AsyncApiSchema.v2; + +namespace Saunter.Cli; + +/// +/// DTO to create specification prototype +/// +/// Identifier of the application the AsyncAPI document is defining. +/// Provides metadata about the API. The metadata can be used by the clients if needed. +/// Provides connection details of servers. +/// A string representing the default content type to use when encoding/decoding a message's payload. +/// Additional external documentation. +public record AsyncApiPrototype( + string Id, + Info? Info, + Dictionary? Servers, + string? DefaultContentType, + ExternalDocumentation? ExternalDocs); diff --git a/src/Saunter.Cli/Program.cs b/src/Saunter.Cli/Program.cs new file mode 100644 index 00000000..83fcfb84 --- /dev/null +++ b/src/Saunter.Cli/Program.cs @@ -0,0 +1,12 @@ +using Saunter; +using Saunter.Cli; + +ConsoleAppBuilder builder = ConsoleApp.CreateBuilder(args); + +builder.ConfigureServices(s => s.AddAsyncApiSchemaGeneration()); + +ConsoleApp app = builder.Build(); + +app.AddSubCommands(); + +app.Run(); diff --git a/src/Saunter.Cli/README.md b/src/Saunter.Cli/README.md new file mode 100644 index 00000000..42b47aa9 --- /dev/null +++ b/src/Saunter.Cli/README.md @@ -0,0 +1,15 @@ +# Saunter.Cli + +A simple utility for generating async api specifications from a set of dlls. + +## Idea + +For aot and trim assemblies, it is inject at the post-build stage, СЃreates a json document that is included in the build and used by the running application. + +## Usage + +So far, just an example: + +```bash +saunter-cli specification generate -p saunter/examples/StreetlightsAPI/bin/Release/net6.0/ --prototype '{ "id": "tester" }' +``` diff --git a/src/Saunter.Cli/Saunter.Cli.csproj b/src/Saunter.Cli/Saunter.Cli.csproj new file mode 100644 index 00000000..0e01bfea --- /dev/null +++ b/src/Saunter.Cli/Saunter.Cli.csproj @@ -0,0 +1,28 @@ + + + + Exe + net6.0 + enable + enable + true + true + + + + + + + + + + + + + + + + + + + diff --git a/src/Saunter.Cli/Saunter.Cli.sln b/src/Saunter.Cli/Saunter.Cli.sln new file mode 100644 index 00000000..3e613754 --- /dev/null +++ b/src/Saunter.Cli/Saunter.Cli.sln @@ -0,0 +1,25 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.Cli", "Saunter.Cli.csproj", "{CD1C0B2D-99A8-4C86-B90B-ED20A654BCD3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CD1C0B2D-99A8-4C86-B90B-ED20A654BCD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD1C0B2D-99A8-4C86-B90B-ED20A654BCD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD1C0B2D-99A8-4C86-B90B-ED20A654BCD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD1C0B2D-99A8-4C86-B90B-ED20A654BCD3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B4A02E6B-5357-475B-9CDA-233CFFE79CCB} + EndGlobalSection +EndGlobal diff --git a/src/Saunter.Cli/SpecificationGenerator.cs b/src/Saunter.Cli/SpecificationGenerator.cs new file mode 100644 index 00000000..15ce753f --- /dev/null +++ b/src/Saunter.Cli/SpecificationGenerator.cs @@ -0,0 +1,83 @@ +using System.Reflection; +using System.Runtime.Loader; + +using Saunter.AsyncApiSchema.v2; +using Saunter.Serialization; + +namespace Saunter.Cli; + +/// +/// Generate documentation from dll +/// +[Command("specification", "Generate documentation from dll")] +public class SpecificationGeneratorCommand : ConsoleAppBase +{ + private readonly IAsyncApiDocumentProvider _provider; + private readonly IAsyncApiDocumentSerializer _serializer; + + /// + /// Documentation generator from dll + /// + public SpecificationGeneratorCommand(IAsyncApiDocumentProvider provider, IAsyncApiDocumentSerializer serializer) + { + _provider = provider; + _serializer = serializer; + } + + /// + /// Generate specification from dll directory + /// + /// + /// + /// + [Command("generate", "Generate specification from dll directory")] + public async Task Generate([Option("p", "The path containing the target application's dll")] string dllDirectory, AsyncApiPrototype prototype) + { + AsyncApiDocument documentPrototype = new() + { + Id = prototype.Id, + }; + + if (!string.IsNullOrEmpty(prototype.DefaultContentType)) + { + documentPrototype.DefaultContentType = prototype.DefaultContentType; + } + + if (prototype.Info is not null) + { + documentPrototype.Info = prototype.Info; + } + + if (prototype.Servers is not null) + { + documentPrototype.Servers = prototype.Servers; + } + + if (prototype.ExternalDocs is not null) + { + documentPrototype.ExternalDocs = prototype.ExternalDocs; + } + + AsyncApiOptions options = new() + { + AsyncApi = documentPrototype, + }; + + string[] dllFiles = Directory.GetFiles(dllDirectory, "*.dll"); + + foreach (string dllFile in dllFiles) + { + Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(dllFile); + + options.Assemblies.Add(assembly); + } + + AsyncApiDocument document = _provider.GetDocument(options, options.AsyncApi); + + string jsonSpecification = _serializer.Serialize(document); + + await using StreamWriter writer = File.CreateText("asyncapi.json"); + + await writer.WriteAsync(jsonSpecification); + } +} diff --git a/src/Saunter/AsyncApiOptions.cs b/src/Saunter/AsyncApiOptions.cs index f246ff18..c1f21680 100644 --- a/src/Saunter/AsyncApiOptions.cs +++ b/src/Saunter/AsyncApiOptions.cs @@ -1,6 +1,7 @@ п»їusing System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -16,10 +17,9 @@ namespace Saunter { public class AsyncApiOptions { - private readonly List _documentFilters = new List(); - private readonly List _channelItemFilters = new List(); - private readonly List _operationFilters = new List(); - + private readonly List _documentFilters = new(); + private readonly List _channelItemFilters = new(); + private readonly List _operationFilters = new(); /// /// The base asyncapi schema. This will be augmented with other information auto-discovered @@ -32,6 +32,11 @@ public class AsyncApiOptions /// public IList AssemblyMarkerTypes { get; set; } = new List(); + /// + /// A list of assemblies to scan for Saunter attributes. + /// + public List Assemblies { get; set; } = new List(); + /// /// A list of filters that will be applied to the generated AsyncAPI document. /// @@ -73,7 +78,6 @@ public void AddOperationFilter() where T : IOperationFilter } - /// /// Options related to the Saunter middleware. /// diff --git a/src/Saunter/AsyncApiServiceCollectionExtensions.cs b/src/Saunter/AsyncApiServiceCollectionExtensions.cs index 700e35e6..155fc4cb 100644 --- a/src/Saunter/AsyncApiServiceCollectionExtensions.cs +++ b/src/Saunter/AsyncApiServiceCollectionExtensions.cs @@ -34,7 +34,7 @@ public static IServiceCollection AddAsyncApiSchemaGeneration(this IServiceCollec /// Add a named AsyncAPI document to the service collection. /// /// The collection to add the document to. - /// The name used to refer to the document. Used in the and in middleware HTTP paths. + /// The name used to refer to the document. Used in the and in middleware HTTP paths. /// An action used to configure the named document. /// The service collection so additional calls can be chained. public static IServiceCollection ConfigureNamedAsyncApi(this IServiceCollection services, string documentName, Action setupAction) diff --git a/src/Saunter/Generation/AsyncApiDocumentProvider.cs b/src/Saunter/Generation/AsyncApiDocumentProvider.cs index b370d8d0..d61faffa 100644 --- a/src/Saunter/Generation/AsyncApiDocumentProvider.cs +++ b/src/Saunter/Generation/AsyncApiDocumentProvider.cs @@ -36,10 +36,16 @@ public AsyncApiDocument GetDocument(AsyncApiOptions options, AsyncApiDocument pr /// private static TypeInfo[] GetAsyncApiTypes(AsyncApiOptions options, AsyncApiDocument prototype) { - var assembliesToScan = options.AssemblyMarkerTypes.Select(t => t.Assembly).Distinct(); + options.Assemblies.AddRange(options + .AssemblyMarkerTypes + .Select(t => t.Assembly) + .Distinct()); - var asyncApiTypes = assembliesToScan - .SelectMany(a => a.DefinedTypes.Where(t => t.GetCustomAttribute()?.DocumentName == prototype.DocumentName)) + options.AssemblyMarkerTypes.Clear(); + + var asyncApiTypes = options.Assemblies + .SelectMany(a => a.DefinedTypes + .Where(t => t.GetCustomAttribute()?.DocumentName == prototype.DocumentName)) .ToArray(); return asyncApiTypes; diff --git a/src/Saunter/Generation/DocumentGenerator.cs b/src/Saunter/Generation/DocumentGenerator.cs index 6b381c1e..b216121e 100644 --- a/src/Saunter/Generation/DocumentGenerator.cs +++ b/src/Saunter/Generation/DocumentGenerator.cs @@ -16,11 +16,7 @@ namespace Saunter.Generation { public class DocumentGenerator : IDocumentGenerator { - public DocumentGenerator() - { - } - - public AsyncApiSchema.v2.AsyncApiDocument GenerateDocument(TypeInfo[] asyncApiTypes, AsyncApiOptions options, AsyncApiDocument prototype, IServiceProvider serviceProvider) + public AsyncApiDocument GenerateDocument(TypeInfo[] asyncApiTypes, AsyncApiOptions options, AsyncApiDocument prototype, IServiceProvider serviceProvider) { var asyncApiSchema = prototype.Clone(); diff --git a/src/Saunter/Saunter.csproj b/src/Saunter/Saunter.csproj index 89875ef2..61990aa2 100644 --- a/src/Saunter/Saunter.csproj +++ b/src/Saunter/Saunter.csproj @@ -18,6 +18,9 @@ true snupkg true + true + true + true diff --git a/test/Saunter.IntegrationTests.ReverseProxy/Properties/launchSettings.json b/test/Saunter.IntegrationTests.ReverseProxy/Properties/launchSettings.json new file mode 100644 index 00000000..1fe9e759 --- /dev/null +++ b/test/Saunter.IntegrationTests.ReverseProxy/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Saunter.IntegrationTests.ReverseProxy": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:65155;http://localhost:65158" + } + } +} \ No newline at end of file diff --git a/test/Saunter.Tests/ServiceCollectionTests.cs b/test/Saunter.Tests/ServiceCollectionTests.cs index 82dffb9b..1fb7d801 100644 --- a/test/Saunter.Tests/ServiceCollectionTests.cs +++ b/test/Saunter.Tests/ServiceCollectionTests.cs @@ -19,7 +19,7 @@ public void TestAddAsyncApiSchemaGeneration() var services = new ServiceCollection() as IServiceCollection; services.AddAsyncApiSchemaGeneration(options => { - options.AsyncApi = new AsyncApiSchema.v2.AsyncApiDocument + options.AsyncApi = new AsyncApiDocument { Id = "urn:com:example:example-events", Info = new Info("Example API", "2019.01.12345") From 04409db6226859f8af1ddecb1d2e94c1d1798b6d Mon Sep 17 00:00:00 2001 From: yurvon_screamo Date: Tue, 19 Mar 2024 00:44:23 +0300 Subject: [PATCH 2/3] Prototype of the cli utility --- src/Saunter/AsyncApiOptions.cs | 2 +- src/Saunter/Generation/AsyncApiDocumentProvider.cs | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Saunter/AsyncApiOptions.cs b/src/Saunter/AsyncApiOptions.cs index c1f21680..cbfcf7bf 100644 --- a/src/Saunter/AsyncApiOptions.cs +++ b/src/Saunter/AsyncApiOptions.cs @@ -35,7 +35,7 @@ public class AsyncApiOptions /// /// A list of assemblies to scan for Saunter attributes. /// - public List Assemblies { get; set; } = new List(); + public IList Assemblies { get; set; } = new List(); /// /// A list of filters that will be applied to the generated AsyncAPI document. diff --git a/src/Saunter/Generation/AsyncApiDocumentProvider.cs b/src/Saunter/Generation/AsyncApiDocumentProvider.cs index d61faffa..e76d997b 100644 --- a/src/Saunter/Generation/AsyncApiDocumentProvider.cs +++ b/src/Saunter/Generation/AsyncApiDocumentProvider.cs @@ -36,14 +36,11 @@ public AsyncApiDocument GetDocument(AsyncApiOptions options, AsyncApiDocument pr /// private static TypeInfo[] GetAsyncApiTypes(AsyncApiOptions options, AsyncApiDocument prototype) { - options.Assemblies.AddRange(options + var asyncApiTypes = options .AssemblyMarkerTypes .Select(t => t.Assembly) - .Distinct()); - - options.AssemblyMarkerTypes.Clear(); - - var asyncApiTypes = options.Assemblies + .Distinct() + .Union(options.Assemblies) .SelectMany(a => a.DefinedTypes .Where(t => t.GetCustomAttribute()?.DocumentName == prototype.DocumentName)) .ToArray(); From 88d5b38f947b3e126ba8732fea47bad75506501f Mon Sep 17 00:00:00 2001 From: yurvon_screamo Date: Tue, 19 Mar 2024 00:45:21 +0300 Subject: [PATCH 3/3] fmt --- src/Saunter.Cli/Saunter.Cli.csproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Saunter.Cli/Saunter.Cli.csproj b/src/Saunter.Cli/Saunter.Cli.csproj index 0e01bfea..5c0c454c 100644 --- a/src/Saunter.Cli/Saunter.Cli.csproj +++ b/src/Saunter.Cli/Saunter.Cli.csproj @@ -13,14 +13,6 @@ - - - - - - - -