belav / csharpier

CSharpier is an opinionated code formatter for c#.
https://csharpier.com
MIT License
1.41k stars 98 forks source link

csharpierignore not working in GitHub Workflow #1374

Closed achobanov closed 1 week ago

achobanov commented 2 weeks ago

Environments:

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 = lf insert_final_newline = true

.NET Coding Conventions

Organize usings

dotnet_sort_system_directives_first = true file_header_template = unset

Language keywords vs BCL types preferences

dotnet_style_predefined_type_for_locals_parameters_members = true:warning dotnet_style_predefined_type_for_member_access = true:warning

Parentheses preferences

dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary dotnet_style_parentheses_in_other_operators = never_if_unnecessary dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary

Expression-level preferences

dotnet_style_coalesce_expression = true:none dotnet_style_collection_initializer = true:warning dotnet_style_explicit_tuple_names = true:warning dotnet_style_namespace_match_folder = true:warning dotnet_style_null_propagation = true:warning dotnet_style_object_initializer = true:warning dotnet_style_operator_placement_when_wrapping = beginning_of_line:warning dotnet_style_prefer_compound_assignment = true:warning dotnet_style_prefer_conditional_expression_over_assignment = true:warning dotnet_style_prefer_conditional_expression_over_return = true:none dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed:warning dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning dotnet_style_prefer_inferred_tuple_names = true:warning dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning dotnet_style_prefer_simplified_boolean_expressions = true:warning dotnet_style_prefer_simplified_interpolation = true:warning dotnet_style_prefer_using_var_for_built_in_types = true:warning dotnet_style_prefer_using_var_when_declaring_anonymous_types = true:warning

Field preferences

dotnet_style_readonly_field = true:none

Parameter preferences

dotnet_code_quality_unused_parameters = all:warning

Suppression preferences

dotnet_remove_unnecessary_suppression_exclusions = true:warning

New line preferences

dotnet_style_allow_statement_immediately_after_block_experimental = true:warning

C# Coding Conventions

var preferences

csharp_style_var_for_built_in_types = true:warning csharp_style_var_when_type_is_apparent = true:warning

Expression-bodied members

csharp_style_expression_bodied_accessors = true:warning csharp_style_expression_bodied_indexers = true:warning csharp_style_expression_bodied_lambdas = true:warning ## test when_on_single_line csharp_style_expression_bodied_local_functions = when_on_single_line:warning csharp_style_expression_bodied_properties = true:warning

Pattern matching preferences

csharp_style_pattern_matching_over_as_with_null_check = true:warning csharp_style_pattern_matching_over_is_with_cast_check = true:warning csharp_style_prefer_extended_property_pattern = true:warning csharp_style_prefer_not_pattern = true:warning csharp_style_prefer_pattern_matching = true:warning csharp_style_prefer_switch_expression = true:warning

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,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:warning csharp_style_prefer_readonly_struct = true:warning

Code-block preferences

csharp_prefer_braces = true:warning csharp_prefer_simple_using_statement = true:suggestion csharp_style_namespace_declarations = file_scoped:silent csharp_style_prefer_method_group_conversion = true:warning csharp_style_prefer_top_level_statements = true:warning

Expression-level preferences

csharp_prefer_simple_default_expression = true:warning csharp_style_deconstructed_variable_declaration = true:warning csharp_style_implicit_object_creation_when_type_is_apparent = true:warning csharp_style_inlined_variable_declaration = true:warning csharp_style_prefer_index_operator = true:warning csharp_style_prefer_local_over_anonymous_function = true:warning csharp_style_prefer_null_check_over_type_check = true:warning csharp_style_prefer_tuple_swap = true:warning csharp_style_prefer_utf8_string_literals = true:warning 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

C# Formatting Rules

New line preferences

csharp_new_line_before_catch = true:warning csharp_new_line_before_else = true:warning csharp_new_line_before_finally = true:warning csharp_new_line_before_open_brace = all #:warning causes dotnet format to put brace on same line for some reason csharp_new_line_between_query_expression_clauses = true:warning

Indentation preferences

csharp_indent_block_contents = true:warning csharp_indent_case_contents = true:warning csharp_indent_case_contents_when_block = true:warning csharp_indent_labels = no_change csharp_indent_switch_labels = true:warning

Space preferences

csharp_space_after_colon_in_inheritance_clause = true:warning csharp_space_after_comma = true:warning csharp_space_after_keywords_in_control_flow_statements = true:warning csharp_space_after_semicolon_in_for_statement = true:warning csharp_space_around_binary_operators = before_and_after csharp_space_around_declaration_statements = true:warning csharp_space_before_colon_in_inheritance_clause = true:warning csharp_space_between_square_brackets = true:warning

Wrapping preferences

csharp_preserve_single_line_statements = true:warning

Naming styles

Naming rules

dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning 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 = warning 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.private_or_internal_field_should_be__underscorefield.severity = warning dotnet_naming_rule.private_or_internal_field_should_beunderscorefield.symbols = private_or_internal_field dotnet_naming_rule.private_or_internal_field_should_beunderscorefield.style = _underscorefield

Symbol specifications

Constants should be UPPERCASE

dotnet_naming_rule.constants_should_be_uppercase.severity = warning dotnet_naming_rule.constants_should_be_uppercase.symbols = constants dotnet_naming_rule.constants_should_be_uppercase.style = constant_style

dotnet_naming_symbols.constants.applicable_kinds = field dotnet_naming_symbols.constants.required_modifiers = const

dotnet_naming_style.constant_style.capitalization = all_upper dotnet_naming_style.constant_style.wordseparator =

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.private_or_internal_field.applicable_kinds = field dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected dotnet_naming_symbols.private_or_internal_field.required_modifiers = none

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

dotnet_naming_style._underscorefield.requiredprefix = dotnet_naming_style._underscorefield.required_suffix = dotnet_naming_style._underscorefield.word_separator = dotnet_naming_style._underscorefield.capitalization = camel_case

IDE0046: Convert to conditional expression

dotnet_diagnostic.IDE0046.severity = none

IDE0058: Expression value is never used - i.e. when method's return value is not used

dotnet_diagnostic.IDE0058.severity = none

CA1822: Mark members as static

dotnet_diagnostic.CA1822.severity = none

IDE0290: Use primary constructor

dotnet_diagnostic.IDE0290.severity = none

Steps to reproduce:

  1. Add the following workflow to github:

    name: "Csharpier dotnet 8"
    on:
    pull_request:
    types:
      - opened
      - reopened
      - ready_for_review
      - synchronize
    jobs:
    format:
    runs-on: ubuntu-latest
    if: github.event.pull_request.draft == false
    steps:
      - name: Print pull_request event
        run: |
          echo Branch:
          echo "${{ github.event.pull_request }}"
    
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}  # Provisioned automatically by GitHub
          ref: ${{ github.event.pull_request.head.ref }}
    
      - name: Set up .NET
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '8.0.x'  #
    
      - name: Cache Csharpier tool
        id: cache-csharpier
        uses: actions/cache@v3
        with:
          path: ~/.dotnet/tools
          key: ${{ runner.os }}-dotnet-tools-csharpier
    
      - name: Install Csharpier if not cached
        run: dotnet tool install -g csharpier || echo "Csharpier already installed"
    
      - name: Run Csharpier
        run: dotnet csharpier .
    
      - name: Check for formatting changes
        run: |
          if [[ `git status --porcelain` ]]; then
            git config user.name "github-actions[bot]"
            git config user.email "github-actions[bot]@users.noreply.github.com"
            git add .
            git commit -m "Apply Csharpier code formatting"
            git push
          else
            echo "No formatting changes needed"
          fi
  2. Create the following .csharpierignore in project root

    *.dll
    *.json
    *resex
    *wwwroot/
  3. Add the following dlls to the project:

dlls.zip

I suspect it doesn't matter, but here's how the dlls are used:

  <ItemGroup>
    <Content Include="rfid.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="rfid_core.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Vup.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <Reference Include="Vup">
      <HintPath>Vup.dll</HintPath>
    </Reference>
  </ItemGroup>

Expected behavior: dotnet csharpier . should ignore the dll files.

Actual behavior: Seems to work locally, because it shows no changes when I run the command in terminal, however it still changes them in the workflow. IMO either csharpierignore is being ignored in the workflow, or it doesn't work at all and the problem is caused by different line endings between my Windows and the worker's Linux. However dlls are formatted every time, even if I don't modify them locally - csharpier just keeps changing them. Sometimes those changes are breaking, sometimes not.

achobanov commented 2 weeks ago

A bit of clarification regarding the current workaround: simply ignoring the *dll didn't work in my case, because it's being tracked since it's pushed. To fix it I've added the following step to my workflow:

      - name: Prevent dlls changes workaround
        run: |
          git update-index --assume-unchanged src-v2/Judge/NTS.Judge/rfid.dll
          git update-index --assume-unchanged src-v2/Judge/NTS.Judge/Vup.dll
          git update-index --assume-unchanged src-v2/Judge/NTS.Judge/rfid_core.dll

Seems to work alright for now, but I still think this should be investigated, as the workflow shouldn't have to be modified due to csharpier trying to format dlls..

belav commented 2 weeks ago

CSharpier doesn't format dll files because they are binary files and they shouldn't need to be ignored. I'm guessing something else is changing your dlls.

achobanov commented 2 weeks ago

@belav you can see the workflow I'm using in Actions. Nothing else acts. No other workflows.

belav commented 2 weeks ago

I understand that, but I can't imagine how it would be CSharpier that is modifying dlls. Adding --loglevel Debug will show you every file it formats.

achobanov commented 1 week ago

@belav I stand corrected - it had nothing to do with csharpier, but entirely with line endings and gitattributes. I've solved my problem by configuring gitattributes to treat dll files like binaries:

# .gitattributes at project root
# Treat DLL files as binary to prevent line ending modifications
*.dll binary
*.pdb binary