diff --git a/.appveyor.yml b/.appveyor.yml index afb3780..2794dd0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ # Build Script # #---------------------------------# build_script: - - ps: .\build.ps1 -Target AppVeyor + - ps: .\build.ps1 --target AppVeyor # Tests test: off @@ -22,5 +22,4 @@ branches: # Build Cache # #---------------------------------# cache: -- Source\packages -> Source\**\packages.config - tools -> setup.cake \ No newline at end of file diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..31e896e --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "2.0.0", + "commands": [ + "dotnet-cake" + ] + } + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7359804 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,255 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +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 = true + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = true +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_property = false:warning + +# 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 = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning + +# Expression-level preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace: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 = flush_left +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 = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +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 = 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.method_should_be_pascal_case.severity = warning +dotnet_naming_rule.method_should_be_pascal_case.symbols = method +dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.severity = warning +dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.symbols = public_or_protected_field +dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.severity = warning +dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.symbols = private_or_internal_static_field +dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.style = pascal_case + +#dotnet_naming_rule.private_or_internal_field_should_be_camelcase.severity = warning +#dotnet_naming_rule.private_or_internal_field_should_be_camelcase.symbols = private_or_internal_field +#dotnet_naming_rule.private_or_internal_field_should_be_camelcase.style = camelcase + +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 + +# 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.method.applicable_kinds = method +dotnet_naming_symbols.method.applicable_accessibilities = public +dotnet_naming_symbols.method.required_modifiers = + +dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field +dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected +dotnet_naming_symbols.public_or_protected_field.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 = + +dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected +dotnet_naming_symbols.private_or_internal_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 + +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.capitalization = camel_case + +dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion +dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields +dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style +dotnet_naming_symbols.instance_fields.applicable_kinds = field +dotnet_naming_style.instance_field_style.capitalization = camel_case +dotnet_naming_style.instance_field_style.required_prefix = _ + +# Rules: + +# SA1101: Prefix local calls with this +dotnet_diagnostic.SA1101.severity = none +dotnet_diagnostic.SA1309.severity = none +dotnet_diagnostic.SA1600.severity = none +dotnet_diagnostic.SA1633.severity = none \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 1f2d7a3..21821d2 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,189 +1,13 @@ -########################################################################## -# This is the Cake bootstrapper script for PowerShell. -# This file was downloaded from https://github.com/cake-build/resources -# Feel free to change this file to fit your needs. -########################################################################## +$ErrorActionPreference = 'Stop' -<# +Set-Location -LiteralPath $PSScriptRoot -.SYNOPSIS -This is a Powershell script to bootstrap a Cake build. +$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1' +$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1' +$env:DOTNET_NOLOGO = '1' -.DESCRIPTION -This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) -and execute your Cake build script with the parameters you provide. +dotnet tool restore +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -.PARAMETER Script -The build script to execute. -.PARAMETER Target -The build script target to run. -.PARAMETER Configuration -The build configuration to use. -.PARAMETER Verbosity -Specifies the amount of information to be displayed. -.PARAMETER Experimental -Tells Cake to use the latest Roslyn release. -.PARAMETER WhatIf -Performs a dry run of the build script. -No tasks will be executed. -.PARAMETER Mono -Tells Cake to use the Mono scripting engine. -.PARAMETER SkipToolPackageRestore -Skips restoring of packages. -.PARAMETER ScriptArgs -Remaining arguments are added here. - -.LINK -http://cakebuild.net - -#> - -[CmdletBinding()] -Param( - [string]$Script = "setup.cake", - [string]$Target = "Default", - [ValidateSet("Release", "Debug")] - [string]$Configuration = "Release", - [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity = "Verbose", - [switch]$Experimental, - [Alias("DryRun","Noop")] - [switch]$WhatIf, - [switch]$Mono, - [switch]$SkipToolPackageRestore, - [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] - [string[]]$ScriptArgs -) - -[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null -function MD5HashFile([string] $filePath) -{ - if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) - { - return $null - } - - [System.IO.Stream] $file = $null; - [System.Security.Cryptography.MD5] $md5 = $null; - try - { - $md5 = [System.Security.Cryptography.MD5]::Create() - $file = [System.IO.File]::OpenRead($filePath) - return [System.BitConverter]::ToString($md5.ComputeHash($file)) - } - finally - { - if ($file -ne $null) - { - $file.Dispose() - } - } -} - -Write-Host "Preparing to run build script..." - -if(!$PSScriptRoot){ - $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent -} - -$TOOLS_DIR = Join-Path $PSScriptRoot "tools" -$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" -$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" -$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" -$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" - -# Should we use mono? -$UseMono = ""; -if($Mono.IsPresent) { - Write-Verbose -Message "Using the Mono based scripting engine." - $UseMono = "-mono" -} - -# Should we use the new Roslyn? -$UseExperimental = ""; -if($Experimental.IsPresent -and !($Mono.IsPresent)) { - Write-Verbose -Message "Using experimental version of Roslyn." - $UseExperimental = "-experimental" -} - -# Is this a dry run? -$UseDryRun = ""; -if($WhatIf.IsPresent) { - $UseDryRun = "-dryrun" -} - -# Make sure tools folder exists -if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { - Write-Verbose -Message "Creating tools directory..." - New-Item -Path $TOOLS_DIR -Type directory | out-null -} - -# Make sure that packages.config exist. -if (!(Test-Path $PACKAGES_CONFIG)) { - Write-Verbose -Message "Downloading packages.config..." - try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { - Throw "Could not download packages.config." - } -} - -# Try find NuGet.exe in path if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Trying to find nuget.exe in PATH..." - $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } - $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 - if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { - Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." - $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName - } -} - -# Try download NuGet.exe if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Downloading NuGet.exe..." - try { - (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) - } catch { - Throw "Could not download NuGet.exe." - } -} - -# Save nuget.exe path to environment to be available to child processed -$ENV:NUGET_EXE = $NUGET_EXE - -# Restore tools from NuGet? -if(-Not $SkipToolPackageRestore.IsPresent) { - Push-Location - Set-Location $TOOLS_DIR - - # Check for changes in packages.config and remove installed tools if true. - [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) - if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or - ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { - Write-Verbose -Message "Missing or changed package.config hash..." - Remove-Item * -Recurse -Exclude packages.config,nuget.exe - } - - Write-Verbose -Message "Restoring tools from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occured while restoring NuGet tools." - } - else - { - $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" - } - Write-Verbose -Message ($NuGetOutput | out-string) - Pop-Location -} - -# Make sure that Cake has been installed. -if (!(Test-Path $CAKE_EXE)) { - Throw "Could not find Cake.exe at $CAKE_EXE" -} - -# Start Cake -Write-Host "Running build script..." -Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" -exit $LASTEXITCODE \ No newline at end of file +dotnet cake @args +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/nuspec/nuget/Cake.CsvHelper.nuspec b/nuspec/nuget/Cake.CsvHelper.nuspec index f9468cb..5749cd1 100644 --- a/nuspec/nuget/Cake.CsvHelper.nuspec +++ b/nuspec/nuget/Cake.CsvHelper.nuspec @@ -12,13 +12,19 @@ https://cdn.jsdelivr.net/gh/cake-contrib/graphics/png/addin/cake-contrib-addin-medium.png false Copyright (c) Radio Systems Corporation 2017 - Present - cake csv-helper csvhelper csv cake-addin cake-build cake-contrib addin script build + cake script build cake-build addin cake-addin csv-helper csvhelper csv - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/src/Cake.CsvHelper.Tests/Cake.CsvHelper.Tests.csproj b/src/Cake.CsvHelper.Tests/Cake.CsvHelper.Tests.csproj index 3188e97..8ca974b 100644 --- a/src/Cake.CsvHelper.Tests/Cake.CsvHelper.Tests.csproj +++ b/src/Cake.CsvHelper.Tests/Cake.CsvHelper.Tests.csproj @@ -1,157 +1,24 @@ - - - - + + - Debug - AnyCPU - {1691864A-29DA-4ED9-A2C1-3EE39D006F51} - Library - Properties - Cake.CsvHelper.Tests - Cake.CsvHelper.Tests - v4.6.1 - 512 - - - + netcoreapp3.1;net5.0;net6.0 + true - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Cake.Core.0.23.0\lib\net46\Cake.Core.dll - - - ..\packages\Cake.Testing.0.23.0\lib\net46\Cake.Testing.dll - - - ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll - - - ..\packages\CsvHelper.6.0.0\lib\net45\CsvHelper.dll - - - ..\packages\NSubstitute.3.1.0\lib\net46\NSubstitute.dll - - - ..\packages\Should.1.1.20\lib\Should.dll - True - - - - - - - ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll - True - - - ..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll - - - - ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll - True - - - ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll - - - ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll - - - ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll - - - ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll - - - ..\packages\System.Threading.Tasks.Extensions.4.4.0\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - - - - - - ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll - - - ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - True - - - ..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - - ..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - - ..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll - - - - - - - - - True - True - Resources.resx - - - - - {85c3e531-f53b-4344-9456-1b0176e547da} - Cake.CsvHelper - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - + - - + + + + + + + + + + - + - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - + \ No newline at end of file diff --git a/src/Cake.CsvHelper.Tests/CsvHelperAliasesTests.cs b/src/Cake.CsvHelper.Tests/CsvHelperAliasesTests.cs index 76bdd96..bcb314a 100644 --- a/src/Cake.CsvHelper.Tests/CsvHelperAliasesTests.cs +++ b/src/Cake.CsvHelper.Tests/CsvHelperAliasesTests.cs @@ -4,53 +4,58 @@ using Cake.Core.IO; using Cake.CsvHelper.Tests.Fixtures; using NSubstitute; -using Should; +using Shouldly; using Xunit; -namespace Cake.CsvHelper.Tests { - public sealed class CsvHelperAliasesTests { - public sealed class TheReadCsvMethod { +namespace Cake.CsvHelper.Tests +{ + public sealed class CsvHelperAliasesTests + { + public sealed class TheReadCsvMethod + { [Fact] - public void Should_Throw_If_Context_Is_Null() { + public void Should_Throw_If_Context_Is_Null() + { // Given var file = Substitute.For(); // When - var result = Record.Exception(() => CsvHelperAliases.ReadCsv(null, file.Path)); + var result = Record.Exception(() => CsvHelperAliases.ReadCsv(null!, file.Path)); // Then - result.ShouldBeType().ParamName.ShouldEqual("context"); + result.ShouldBeOfType().ParamName.ShouldBe("context"); } [Fact] - public void Should_Throw_If_CSV_File_Is_Null() { + public void Should_Throw_If_CSV_File_Is_Null() + { // Given var environment = Substitute.For(); var context = Substitute.For(); context.Environment.Returns(environment); // When - var result = Record.Exception(() => CsvHelperAliases.ReadCsv(context, null)); + var result = Record.Exception(() => CsvHelperAliases.ReadCsv(context, null!)); // Then - result.ShouldBeType().ParamName.ShouldEqual("csvFile"); + result.ShouldBeOfType().ParamName.ShouldBe("csvFile"); } } - public sealed class TheWriteCsvMethod { + public sealed class TheWriteCsvMethod + { [Fact] - public void Should_Throw_If_Context_Is_Null() { + public void Should_Throw_If_Context_Is_Null() + { // Given var file = Substitute.For(); // When - var result = Record.Exception(() => CsvHelperAliases.WriteCsv(null, file.Path, new List())); + var result = Record.Exception(() => CsvHelperAliases.WriteCsv(null!, file.Path, new List())); // Then - result.ShouldBeType().ParamName.ShouldEqual("context"); + result.ShouldBeOfType().ParamName.ShouldBe("context"); } } } - - } diff --git a/src/Cake.CsvHelper.Tests/CsvHelperTests.cs b/src/Cake.CsvHelper.Tests/CsvHelperTests.cs index a3dc40b..471f59d 100644 --- a/src/Cake.CsvHelper.Tests/CsvHelperTests.cs +++ b/src/Cake.CsvHelper.Tests/CsvHelperTests.cs @@ -4,176 +4,210 @@ using Cake.Core.IO; using Cake.CsvHelper.Tests.Fixtures; using Cake.CsvHelper.Tests.Properties; -using Should; +using Shouldly; using Xunit; using Xunit.Sdk; -namespace Cake.CsvHelper.Tests { - public sealed class CsvHelperTests { - public sealed class TheReadCsvMethod { +namespace Cake.CsvHelper.Tests +{ + public sealed class CsvHelperTests + { + public sealed class TheReadCsvMethod + { [Fact] - public void Should_Throw_If_CsvFile_Is_Null() { + public void Should_Throw_If_CsvFile_Is_Null() + { // Given var fixture = new CsvHelpersFixture(false); - - // When + + // When var result = Record.Exception(() => fixture.Read()); - + // Then - result.ShouldBeType().ParamName.ShouldEqual("csvFile"); + result.ShouldBeOfType().ParamName.ShouldBe("csvFile"); } [Fact] - public void Should_Throw_If_Settings_Are_Null() { + public void Should_Throw_If_Settings_Are_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.Settings = null; + var fixture = new CsvHelpersFixture { Settings = null! }; - // When + // When var result = Record.Exception(() => fixture.Read()); // Then - result.ShouldBeType().ParamName.ShouldEqual("settings"); + result.ShouldBeOfType().ParamName.ShouldBe("settings"); } [Fact] - public void Should_Throw_If_File_Does_Not_Exist() { + public void Should_Throw_If_File_Does_Not_Exist() + { // Given - var fixture = new CsvHelpersFixture(false); - fixture.CsvFilePath = "/Working/test.csv"; + var fixture = new CsvHelpersFixture(false) + { + CsvFilePath = "/Working/test.csv", + }; - // When + // When var result = Record.Exception(() => fixture.Read()); // Then - result.ShouldBeType(); + result.ShouldBeOfType(); } } - public sealed class TheWriteCsvNoMapMethod { + public sealed class TheWriteCsvNoMapMethod + { [Fact] - public void Should_Throw_If_CsvFile_Is_Null() { + public void Should_Throw_If_CsvFile_Is_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.ResultPath = null; + var fixture = new CsvHelpersFixture + { + ResultPath = null!, + }; - // When + // When var result = Record.Exception(() => fixture.WriteNoMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("csvFile"); + result.ShouldBeOfType().ParamName.ShouldBe("csvFile"); } [Fact] - public void Should_Throw_If_Records_Are_Null() { + public void Should_Throw_If_Records_Are_Null() + { // Given var fixture = new CsvHelpersFixture(peopleExists: false); - // When + // When var result = Record.Exception(() => fixture.WriteNoMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("records"); + result.ShouldBeOfType().ParamName.ShouldBe("records"); } - + [Fact] - public void Should_Throw_If_Settings_Are_Null() { + public void Should_Throw_If_Settings_Are_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.Settings = null; + var fixture = new CsvHelpersFixture + { + Settings = null!, + }; - // When + // When var result = Record.Exception(() => fixture.WriteNoMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("settings"); + result.ShouldBeOfType().ParamName.ShouldBe("settings"); } - + [Fact(Skip = "Experimental")] - public void Should_Write_Records_To_CsvFile_With_No_Map() { + public void Should_Write_Records_To_CsvFile_With_No_Map() + { // Given var fixture = new CsvHelpersFixture(false); - + // When fixture.WriteNoMapping(); // Then var resultFile = fixture.FileSystem.GetFile(fixture.ResultPath); - resultFile.Exists.ShouldEqual(true); + resultFile.Exists.ShouldBeTrue(); string resultString; - using(var resultStream = resultFile.OpenRead()) - using (var streamReader = new StreamReader(resultStream, Encoding.UTF8)) { + using (var resultStream = resultFile.OpenRead()) + using (var streamReader = new StreamReader(resultStream, Encoding.UTF8)) + { resultString = streamReader.ReadToEnd(); - resultString.Trim().ShouldEqual(Resources.CsvHelper_CsvFile.Trim()); + resultString.Trim().ShouldBe(Resources.CsvHelper_CsvFile.Trim()); } } } - public sealed class TheWriteCsvWithMapMethod { + public sealed class TheWriteCsvWithMapMethod + { [Fact] - public void Should_Throw_If_CsvFile_Is_Null() { + public void Should_Throw_If_CsvFile_Is_Null() + { // Given - var fixture = new CsvHelpersFixture(false); - fixture.ResultPath = null; + var fixture = new CsvHelpersFixture(false) + { + ResultPath = null!, + }; - // When + // When var result = Record.Exception(() => fixture.WriteWithMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("csvFile"); + result.ShouldBeOfType().ParamName.ShouldBe("csvFile"); } [Fact] - public void Should_Throw_If_Records_Are_Null() { + public void Should_Throw_If_Records_Are_Null() + { // Given var fixture = new CsvHelpersFixture(peopleExists: false); - // When + // When var result = Record.Exception(() => fixture.WriteWithMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("records"); + result.ShouldBeOfType().ParamName.ShouldBe("records"); } [Fact] - public void Should_Throw_If_ClassMap_Is_Null() { + public void Should_Throw_If_ClassMap_Is_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.ClassMap = null; - // When + var fixture = new CsvHelpersFixture + { + ClassMap = null!, + }; + + // When var result = Record.Exception(() => fixture.WriteWithMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("classMap"); + result.ShouldBeOfType().ParamName.ShouldBe("classMap"); } [Fact] - public void Should_Throw_If_Mapping_Is_Null() { + public void Should_Throw_If_Mapping_Is_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.DictionaryMap = null; - // When + var fixture = new CsvHelpersFixture + { + DictionaryMap = null!, + }; + + // When var result = Record.Exception(() => fixture.WriteWithMapping(true)); // Then - result.ShouldBeType().ParamName.ShouldEqual("mapping"); + result.ShouldBeOfType().ParamName.ShouldBe("mapping"); } [Fact] - public void Should_Throw_If_Settings_Are_Null() { + public void Should_Throw_If_Settings_Are_Null() + { // Given - var fixture = new CsvHelpersFixture(); - fixture.Settings = null; + var fixture = new CsvHelpersFixture + { + Settings = null!, + }; - // When + // When var result = Record.Exception(() => fixture.WriteWithMapping()); // Then - result.ShouldBeType().ParamName.ShouldEqual("settings"); + result.ShouldBeOfType().ParamName.ShouldBe("settings"); } [Fact(Skip = "Experimental")] - public void Should_Write_Records_To_CsvFile_With_Class_Map() { + public void Should_Write_Records_To_CsvFile_With_Class_Map() + { // Given var fixture = new CsvHelpersFixture(false); @@ -182,32 +216,15 @@ public void Should_Write_Records_To_CsvFile_With_Class_Map() { // Then var resultFile = fixture.FileSystem.GetFile(fixture.ResultPath); - resultFile.Exists.ShouldEqual(true); + resultFile.Exists.ShouldBeTrue(); string resultString; using (var resultStream = resultFile.OpenRead()) - using (var streamReader = new StreamReader(resultStream, Encoding.UTF8)) { + using (var streamReader = new StreamReader(resultStream, Encoding.UTF8)) + { resultString = streamReader.ReadToEnd(); } - resultString.Trim().ShouldEqual(Resources.CsvHelper_MappedFile.Trim()); - } - [Fact(Skip = "Experimental")] - public void Should_Write_Records_To_CsvFile_With_Dictionary_Map() { - // Given - var fixture = new CsvHelpersFixture(false); - - // When - fixture.WriteWithMapping(); - - // Then - var resultFile = fixture.FileSystem.GetFile(fixture.ResultPath); - resultFile.Exists.ShouldEqual(true); - string resultString; - using (var resultStream = resultFile.OpenRead()) - using (var streamReader = new StreamReader(resultStream, Encoding.UTF8)) { - resultString = streamReader.ReadToEnd(); - } - resultString.Trim().ShouldEqual(Resources.CsvHelper_MappedFile.Trim()); + resultString.Trim().ShouldBe(Resources.CsvHelper_MappedFile.Trim()); } } } diff --git a/src/Cake.CsvHelper.Tests/Fixtures/CsvHelpersFixture.cs b/src/Cake.CsvHelper.Tests/Fixtures/CsvHelpersFixture.cs index 1d99a20..8c81693 100644 --- a/src/Cake.CsvHelper.Tests/Fixtures/CsvHelpersFixture.cs +++ b/src/Cake.CsvHelper.Tests/Fixtures/CsvHelpersFixture.cs @@ -1,36 +1,34 @@ using System.Collections.Generic; + using Cake.Core; using Cake.Core.IO; using Cake.CsvHelper.Tests.Properties; using Cake.Testing; + using CsvHelper.Configuration; -using NSubstitute; -namespace Cake.CsvHelper.Tests.Fixtures { - internal sealed class CsvHelpersFixture { - public IFileSystem FileSystem { get; set; } - public ICakeContext Context { get; set; } - public FilePath CsvFilePath { get; set; } - public FilePath ResultPath { get; set; } - public CsvHelperSettings Settings { get; set; } - public List People { get; set; } - public Dictionary DictionaryMap { get; set; } - public ClassMap ClassMap { get; set; } +using NSubstitute; - public CsvHelpersFixture(bool csvFileExists = true, bool peopleExists = true) { +namespace Cake.CsvHelper.Tests.Fixtures +{ + internal sealed class CsvHelpersFixture + { + public CsvHelpersFixture(bool csvFileExists = true, bool peopleExists = true) + { Settings = new CsvHelperSettings(); - - ClassMap = new PersonMap(); - DictionaryMap = new Dictionary() { - {"Id", "EmployeeId" }, {"Name", "GivenName" } + DictionaryMap = new Dictionary(System.StringComparer.OrdinalIgnoreCase) + { + { "Id", "EmployeeId" }, + { "Name", "GivenName" }, }; var environment = FakeEnvironment.CreateUnixEnvironment(); var fileSystem = new FakeFileSystem(environment); fileSystem.CreateDirectory("/Working"); - if (csvFileExists) { + if (csvFileExists) + { var content = Resources.CsvHelper_CsvFile; var csvFile = fileSystem.CreateFile("/Working/people.csv").SetContent(content); CsvFilePath = csvFile.Path; @@ -38,10 +36,12 @@ public CsvHelpersFixture(bool csvFileExists = true, bool peopleExists = true) { ResultPath = "/Working/people.csv"; - if (peopleExists) { - People = new List { + if (peopleExists) + { + People = new List + { new Person { Id = 1, Name = "Jane" }, - new Person {Id = 2, Name="Mal" } + new Person { Id = 2, Name = "Mal" }, }; } @@ -52,36 +52,45 @@ public CsvHelpersFixture(bool csvFileExists = true, bool peopleExists = true) { Context.Environment.Returns(environment); } - public void Read() { + public IFileSystem FileSystem { get; set; } + + public ICakeContext Context { get; set; } + + public FilePath? CsvFilePath { get; set; } + + public FilePath ResultPath { get; set; } + + public CsvHelperSettings Settings { get; set; } + + public List? People { get; set; } + + public Dictionary DictionaryMap { get; set; } + + public ClassMap ClassMap { get; set; } + + public void Read() + { var csvHelper = new CsvHelpers(Context.FileSystem, Context.Environment); - csvHelper.ReadRecords(CsvFilePath, null, Settings); + csvHelper.ReadRecords(CsvFilePath!, null, Settings); } - public void WriteNoMapping() { + public void WriteNoMapping() + { var csvHelper = new CsvHelpers(Context.FileSystem, Context.Environment); - csvHelper.WriteRecords(ResultPath, People, Settings); + csvHelper.WriteRecords(ResultPath, People!, Settings); } - public void WriteWithMapping(bool useDictionaryMapping = false) { + public void WriteWithMapping(bool useDictionaryMapping = false) + { var csvHelper = new CsvHelpers(Context.FileSystem, Context.Environment); - if (useDictionaryMapping) { - csvHelper.WriteRecords(ResultPath, People, DictionaryMap, Settings); + if (useDictionaryMapping) + { + csvHelper.WriteRecords(ResultPath, People!, DictionaryMap, Settings); } - else { - csvHelper.WriteRecords(ResultPath, People, ClassMap, Settings); + else + { + csvHelper.WriteRecords(ResultPath, People!, ClassMap, Settings); } } } - - public sealed class Person { - public int Id { get; set; } - public string Name { get; set; } - } - - public class PersonMap : ClassMap { - public PersonMap() { - Map(m => m.Id).Name("EmployeeId"); - Map(m => m.Name).Name("GivenName"); - } - } } diff --git a/src/Cake.CsvHelper.Tests/Fixtures/Person.cs b/src/Cake.CsvHelper.Tests/Fixtures/Person.cs new file mode 100644 index 0000000..c8a60ce --- /dev/null +++ b/src/Cake.CsvHelper.Tests/Fixtures/Person.cs @@ -0,0 +1,8 @@ +namespace Cake.CsvHelper.Tests.Fixtures; + +public sealed class Person +{ + public int Id { get; set; } + + public string? Name { get; set; } +} diff --git a/src/Cake.CsvHelper.Tests/Fixtures/PersonMap.cs b/src/Cake.CsvHelper.Tests/Fixtures/PersonMap.cs new file mode 100644 index 0000000..116996b --- /dev/null +++ b/src/Cake.CsvHelper.Tests/Fixtures/PersonMap.cs @@ -0,0 +1,15 @@ +using CsvHelper.Configuration; + +namespace Cake.CsvHelper.Tests.Fixtures +{ + public sealed class PersonMap : ClassMap + { + public PersonMap() + { +#pragma warning disable MA0056 // Do not call overridable members in constructor + Map(m => m.Id).Name("EmployeeId"); + Map(m => m.Name).Name("GivenName"); +#pragma warning restore MA0056 // Do not call overridable members in constructor + } + } +} diff --git a/src/Cake.CsvHelper.Tests/Properties/AssemblyInfo.cs b/src/Cake.CsvHelper.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index cf8c6fd..0000000 --- a/src/Cake.CsvHelper.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Cake.CsvHelper.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Cake.CsvHelper.Tests")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1691864a-29da-4ed9-a2c1-3ee39d006f51")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Cake.CsvHelper.Tests/app.config b/src/Cake.CsvHelper.Tests/app.config deleted file mode 100644 index 7d8c922..0000000 --- a/src/Cake.CsvHelper.Tests/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Cake.CsvHelper.Tests/packages.config b/src/Cake.CsvHelper.Tests/packages.config deleted file mode 100644 index ccf02bd..0000000 --- a/src/Cake.CsvHelper.Tests/packages.config +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Cake.CsvHelper.sln b/src/Cake.CsvHelper.sln index c89d61d..c328c68 100644 --- a/src/Cake.CsvHelper.sln +++ b/src/Cake.CsvHelper.sln @@ -1,12 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.CsvHelper", "Cake.CsvHelper\Cake.CsvHelper.csproj", "{85C3E531-F53B-4344-9456-1B0176E547DA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.CsvHelper.Tests", "Cake.CsvHelper.Tests\Cake.CsvHelper.Tests.csproj", "{1691864A-29DA-4ED9-A2C1-3EE39D006F51}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution", "Solution", "{2FC30AF7-19E0-4647-8024-BEB10146805C}" + ProjectSection(SolutionItems) = preProject + ..\.editorconfig = ..\.editorconfig + Directory.Build.props = Directory.Build.props + stylecop.json = stylecop.json + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,4 +32,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {805AF374-B5FF-4CD6-8440-8BC85042D1F2} + EndGlobalSection EndGlobal diff --git a/src/Cake.CsvHelper/Cake.CsvHelper.csproj b/src/Cake.CsvHelper/Cake.CsvHelper.csproj index 1152c16..313ba94 100644 --- a/src/Cake.CsvHelper/Cake.CsvHelper.csproj +++ b/src/Cake.CsvHelper/Cake.CsvHelper.csproj @@ -1,68 +1,22 @@ - - - + + - Debug - AnyCPU - {85C3E531-F53B-4344-9456-1B0176E547DA} - Library - Properties - Cake.CsvHelper - Cake.CsvHelper - v4.6.1 - 512 - + netcoreapp3.1;net5.0;net6.0 + true + cake script build cake-build addin cake-addin csv-helper csvhelper csv - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\Cake.CsvHelper.XML - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Cake.CsvHelper.XML - - - - ..\packages\Cake.Core.0.23.0\lib\net46\Cake.Core.dll - - - ..\packages\CsvHelper.6.0.0\lib\net45\CsvHelper.dll - - - - - - - - - - - - - - - - + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - + \ No newline at end of file diff --git a/src/Cake.CsvHelper/CsvHelperAliases.cs b/src/Cake.CsvHelper/CsvHelperAliases.cs index abcc2c2..4d1f48a 100644 --- a/src/Cake.CsvHelper/CsvHelperAliases.cs +++ b/src/Cake.CsvHelper/CsvHelperAliases.cs @@ -10,7 +10,7 @@ namespace Cake.CsvHelper /// /// Contians functionality related to reading and writing CSV files. /// - [CakeAliasCategory("CsvHelper")] + [CakeAliasCategory(nameof(CsvHelper))] public static class CsvHelperAliases { /// @@ -26,8 +26,9 @@ public static class CsvHelperAliases /// /// [CakeMethodAlias] - [CakeAliasCategory("ReadCsv")] - public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile) { + [CakeAliasCategory(nameof(ReadCsv))] + public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile) + { var settings = new CsvHelperSettings(); return ReadCsv(context, csvFile, null, settings); } @@ -46,8 +47,9 @@ public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvF /// /// [CakeMethodAlias] - [CakeAliasCategory("ReadCsv")] - public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile, CsvHelperSettings settings) { + [CakeAliasCategory(nameof(ReadCsv))] + public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile, CsvHelperSettings settings) + { return ReadCsv(context, csvFile, null, settings); } @@ -56,16 +58,16 @@ public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvF /// /// The type. /// The context. - /// The CSV class map. /// The CSV to read. + /// The CSV class map. /// List objects as defined by type. /// - /// + /// /// ("./people.csv", new ClassMap());]]> /// /// [CakeMethodAlias] - [CakeAliasCategory("ReadCsv")] + [CakeAliasCategory(nameof(ReadCsv))] [CakeNamespaceImport("CsvHelper.Configuration.CsvClassMap")] public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile, ClassMap classMap) { @@ -88,14 +90,15 @@ public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvF /// /// [CakeMethodAlias] - [CakeAliasCategory("ReadCsv")] + [CakeAliasCategory(nameof(ReadCsv))] [CakeNamespaceImport("CsvHelper.Configuration.CsvClassMap")] - public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile, ClassMap classMap, CsvHelperSettings settings) + public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvFile, ClassMap? classMap, CsvHelperSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } + var csvHelpers = new CsvHelpers(context.FileSystem, context.Environment); return csvHelpers.ReadRecords(csvFile, classMap, settings); } @@ -107,15 +110,14 @@ public static IEnumerable ReadCsv(this ICakeContext context, FilePath csvF /// The context. /// The CSV to file to write. /// The list objects you want to write to a csv. - /// List objects as defined by type. /// /// /// ("./people.csv", new List());]]> /// /// [CakeMethodAlias] - [CakeAliasCategory("WriteCsv")] - public static void WriteCsv(this ICakeContext context, FilePath csvFile, List records) + [CakeAliasCategory(nameof(WriteCsv))] + public static void WriteCsv(this ICakeContext context, FilePath csvFile, IList records) { var settings = new CsvHelperSettings(); WriteCsv(context, csvFile, records, settings); @@ -129,20 +131,20 @@ public static void WriteCsv(this ICakeContext context, FilePath csvFile, List /// The CSV to file to write. /// The list objects you want to write to a csv. /// The settings. - /// List objects as defined by type. /// /// /// ("./people.csv", new List(), new CsvHelperSettings { HasHeaderRecord = true });]]> /// /// [CakeMethodAlias] - [CakeAliasCategory("WriteCsv")] - public static void WriteCsv(this ICakeContext context, FilePath csvFile, List records, CsvHelperSettings settings) + [CakeAliasCategory(nameof(WriteCsv))] + public static void WriteCsv(this ICakeContext context, FilePath csvFile, IList records, CsvHelperSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } + var csvHelpers = new CsvHelpers(context.FileSystem, context.Environment); csvHelpers.WriteRecords(csvFile, records, settings); } @@ -156,10 +158,9 @@ public static void WriteCsv(this ICakeContext context, FilePath csvFile, List /// The list objects you want to write to a csv. /// The property column mapping. /// The settings. - /// List objects as defined by type. /// /// - /// { + /// { /// {"Id", "EmployeeId"}, /// {"Name", "FirstName"} /// };]]> @@ -167,13 +168,14 @@ public static void WriteCsv(this ICakeContext context, FilePath csvFile, List /// /// [CakeMethodAlias] - [CakeAliasCategory("WriteCsv")] - public static void WriteCsv(this ICakeContext context, FilePath csvFile, List records, Dictionary mapping, CsvHelperSettings settings) + [CakeAliasCategory(nameof(WriteCsv))] + public static void WriteCsv(this ICakeContext context, FilePath csvFile, IList records, IDictionary mapping, CsvHelperSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } + var csvHelpers = new CsvHelpers(context.FileSystem, context.Environment); csvHelpers.WriteRecords(csvFile, records, mapping, settings); } @@ -187,9 +189,8 @@ public static void WriteCsv(this ICakeContext context, FilePath csvFile, List /// The list objects you want to write to a csv. /// The CSV Helper Class Map. /// The settings. - /// List objects as defined by type. /// - /// + /// /// public sealed class PersonMap : CsvClassMap<Person> /// { /// public PersonMap() @@ -202,16 +203,17 @@ public static void WriteCsv(this ICakeContext context, FilePath csvFile, List /// /// [CakeMethodAlias] - [CakeAliasCategory("WriteCsv")] + [CakeAliasCategory(nameof(WriteCsv))] [CakeNamespaceImport("CsvHelper.Configuration.CsvClassMap")] - public static void WriteCsv(this ICakeContext context, FilePath csvFile, List records, ClassMap classMap, CsvHelperSettings settings) + public static void WriteCsv(this ICakeContext context, FilePath csvFile, IList records, ClassMap classMap, CsvHelperSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } + var csvHelpers = new CsvHelpers(context.FileSystem, context.Environment); - csvHelpers.WriteRecords(csvFile,records, classMap, settings); + csvHelpers.WriteRecords(csvFile, records, classMap, settings); } } } diff --git a/src/Cake.CsvHelper/CsvHelperSettings.cs b/src/Cake.CsvHelper/CsvHelperSettings.cs index 574a280..5d1bb6d 100644 --- a/src/Cake.CsvHelper/CsvHelperSettings.cs +++ b/src/Cake.CsvHelper/CsvHelperSettings.cs @@ -3,103 +3,117 @@ using System.Text; using CsvHelper; -namespace Cake.CsvHelper { - +namespace Cake.CsvHelper +{ /// /// Contains settings used by . /// - public class CsvHelperSettings { + public class CsvHelperSettings + { + /// + /// Initializes a new instance of the class. + /// + public CsvHelperSettings() + { + Encoding = Encoding.UTF8; + BufferSize = 2048; + Comment = "#"; + CultureInfo = CultureInfo.InvariantCulture; + Delimiter = ","; + Quote = "\""; + } + /// - /// Gets or sets a value indicating if comments are allowed. - /// - /// - /// true to allow commented out lines; otherwise, false. - /// + /// Gets or sets a value indicating whether if comments are allowed. + /// + /// + /// true to allow commented out lines; otherwise, false. + /// public bool AllowComments { get; set; } /// - /// Gets or sets the size of the buffer used for reading and writing CSV files. - /// - /// - /// Default is 2048. - /// + /// Gets or sets the size of the buffer used for reading and writing CSV files. + /// + /// + /// Default is 2048. + /// public int BufferSize { get; set; } /// - /// Gets or sets the character used to denote a line that is commented out. - /// - /// - /// Default is '#'. - /// + /// Gets or sets the character used to denote a line that is commented out. + /// + /// + /// Default is '#'. + /// public string Comment { get; set; } /// - /// Gets or sets a value indicating whether the number of bytes should be counted while parsing. Default is false. This will slow down parsing - /// because it needs to get the byte count of every char for the given encoding. - /// The needs to be set correctly for this to be accurate. - /// + /// Gets or sets a value indicating whether the number of bytes should be counted while parsing. Default is false. This will slow down parsing + /// because it needs to get the byte count of every char for the given encoding. + /// The needs to be set correctly for this to be accurate. + /// public bool CountBytes { get; set; } /// - /// Gets or sets the culture info used to read an write CSV files. - /// + /// Gets or sets the culture info used to read an write CSV files. + /// public CultureInfo CultureInfo { get; set; } /// - /// Gets or sets the value used to separate the fields in a CSV row. - /// - /// - /// Defaults to Encoding.UTF8. - /// + /// Gets or sets the value used to separate the fields in a CSV row. + /// + /// + /// Defaults to ,. + /// public string Delimiter { get; set; } /// - /// Gets or sets a value indicating whether changes in the column count should be detected. If true, a will be thrown if a different column count is detected. - /// - /// - /// true if [detect column count changes]; otherwise, false. - /// + /// Gets or sets a value indicating whether changes in the column count should be detected. If true, a will be thrown if a different column count is detected. + /// + /// + /// true if [detect column count changes]; otherwise, false. + /// public bool DetectColumnCountChanges { get; set; } /// - /// Gets or sets the encoding used when counting bytes. - /// - /// - /// Defaults to Encoding.UTF8. - /// + /// Gets or sets the encoding used when counting bytes. + /// + /// + /// Defaults to Encoding.UTF8. + /// public Encoding Encoding { get; set; } /// - /// Gets or sets a value indicating if the CSV file has a header record. + /// Gets or sets a value indicating whether if the CSV file has a header record. /// public bool HasHeaderRecord { get; set; } /// - /// Gets or sets a value indicating to ignore white space in the headers when matching the columns to the properties by name. + /// Gets or sets a value indicating whether to ignore white space in the headers when matching the columns to the properties by name. /// public bool IgnoreHeaderWhiteSpace { get; set; } /// - /// Gets or sets a value indicating to ignore private accessors when reading and writing. By default you can't read from a private getter or + /// Gets or sets a value indicating whether to ignore private accessors when reading and writing. By default you can't read from a private getter or /// write to a private setter. Turn this on will allow that. Properties that can't be read from or written to are silently ignored. /// public bool IgnorePrivateAccessor { get; set; } /// - /// Gets or sets a value indicating whether exceptions that occur duruing reading should be ignored. - /// - /// + /// Gets or sets a value indicating whether exceptions that occur duruing reading should be ignored. + /// + /// /// true if to ignore exceptions; otherwise, false. /// public bool IgnoreReadingExceptions { get; set; } /// - /// Gets or sets a value indicating if quotes should be ingored when parsing and treated like any other character. - /// - /// - /// true if to ignore qoutes; otherwise, false. + /// Gets or sets a value indicating whether if quotes should be ignored when parsing and treated like any other character. + /// + /// + /// true if to ignore quotes; otherwise, false. /// - public bool IgnoreQoutes { get; set; } + public bool IgnoreQuotes { get; set; } /// /// Gets or sets a value indicating whether matching CSV header names will be case sensitive. @@ -117,25 +131,25 @@ public class CsvHelperSettings { /// /// Gets or sets a value used to escape fields that contain a delimiter, quote, or line ending. /// - public string Qoute { get; set; } + public string Quote { get; set; } /// - /// Gets or sets a value indicating whether all fields are quoted when writing, or just ones that have to be. and - /// cannot be true at the same time. Turning one on will turn the other off. - /// - /// - /// true if all fields should be quoted; otherwise, false. - /// - public bool QouteAllFields { get; set; } + /// Gets or sets a value indicating whether all fields are quoted when writing, or just ones that have to be. and + /// cannot be true at the same time. Turning one on will turn the other off. + /// + /// + /// true if all fields should be quoted; otherwise, false. + /// + public bool QuoteAllFields { get; set; } /// - /// Gets or sets a value indicating whether no fields are quoted when writing. and cannot be true - /// at the same time. Turning one on will turn the other off. - /// - /// - /// true if [quote no fields]; otherwise, false. - /// - public bool QouteNoFields { get; set; } + /// Gets or sets a value indicating whether no fields are quoted when writing. and cannot be true + /// at the same time. Turning one on will turn the other off. + /// + /// + /// true if [quote no fields]; otherwise, false. + /// + public bool QuoteNoFields { get; set; } /// /// Gets or sets a value indicating whether empty rows should be skipped when reading. A record is considered empty if all fields are empty. @@ -146,29 +160,22 @@ public class CsvHelperSettings { public bool SkipEmptyRecords { get; set; } /// - /// Gets or sets a value indicating if the reader to trim whitespace from the beginning and ending of the field value when reading. + /// Gets or sets a value indicating whether if the reader to trim whitespace from the beginning and ending of the field value when reading. /// public bool TrimFields { get; set; } /// - /// Gets or sets a value indicating ifthe reader to ignore white space from the beginning and ending of the headers + /// Gets or sets a value indicating whether if the reader to ignore white space from the beginning and ending of the headers /// when matching the columns to the properties by name. /// public bool TrimHeaders { get; set; } /// - /// Gets or sets a value indicating if an exception will be thrown if a field defined in a mapping is missing. True to throw an exception, otherwise false. Default is true. - /// - /// + /// Gets or sets a value indicating whether if an exception will be thrown if a field defined in a mapping is missing. True to throw an exception, otherwise false. Default is true. + /// + /// /// true if an exception is to be thrown; otherwise, false. Defaults to true. /// public bool WillThrowOnMissingField { get; set; } - - /// - /// Initializes the class. - /// - public CsvHelperSettings() { - Encoding = Encoding.UTF8; - } } } diff --git a/src/Cake.CsvHelper/CsvHelpers.cs b/src/Cake.CsvHelper/CsvHelpers.cs index cc066d1..261d7be 100644 --- a/src/Cake.CsvHelper/CsvHelpers.cs +++ b/src/Cake.CsvHelper/CsvHelpers.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using Cake.Core; @@ -7,20 +8,23 @@ using CsvHelper; using CsvHelper.Configuration; -namespace Cake.CsvHelper { +namespace Cake.CsvHelper +{ /// /// The CsvHelpers class for working with CSV Helper. /// - public sealed class CsvHelpers { + public sealed class CsvHelpers + { private readonly IFileSystem _fileSystem; private readonly ICakeEnvironment _environment; /// - /// Initializes new instance of the class. + /// Initializes a new instance of the class. /// /// The filesystem. /// The environment. - public CsvHelpers(IFileSystem fileSystem, ICakeEnvironment environment) { + public CsvHelpers(IFileSystem fileSystem, ICakeEnvironment environment) + { _fileSystem = fileSystem; _environment = environment; } @@ -33,19 +37,27 @@ public CsvHelpers(IFileSystem fileSystem, ICakeEnvironment environment) { /// The class map to use, null if not needed. /// The settings. /// List of defined type. - public IEnumerable ReadRecords(FilePath csvFile, ClassMap classMap, CsvHelperSettings settings) { - if (csvFile == null) { + public IEnumerable ReadRecords(FilePath csvFile, ClassMap? classMap, CsvHelperSettings settings) + { + if (csvFile == null) + { throw new ArgumentNullException(nameof(csvFile)); } - if (settings == null) { + + if (settings == null) + { throw new ArgumentNullException(nameof(settings)); } + var file = GetFile(csvFile); using (var textReader = new StreamReader(file.OpenRead())) - using (var csvReader = new CsvReader(textReader)) { - if (classMap != null) { - csvReader.Configuration.RegisterClassMap(classMap); + using (var csvReader = new CsvReader(textReader, CultureInfo.InvariantCulture)) + { + if (classMap != null) + { + csvReader.Context.RegisterClassMap(classMap); } + return csvReader.GetRecords().ToList(); } } @@ -58,29 +70,40 @@ public IEnumerable ReadRecords(FilePath csvFile, ClassMap classMap, CsvHel /// The records to write. /// The class map. /// The settings. - public void WriteRecords(FilePath csvFile, List records, ClassMap classMap, CsvHelperSettings settings) { - if (csvFile == null) { + public void WriteRecords(FilePath csvFile, IList records, ClassMap classMap, CsvHelperSettings settings) + { + if (csvFile == null) + { throw new ArgumentNullException(nameof(csvFile)); } - if (records == null) { + + if (records == null) + { throw new ArgumentNullException(nameof(records)); } - if (classMap == null) { + + if (classMap == null) + { throw new ArgumentNullException(nameof(classMap)); } - if (settings == null) { + + if (settings == null) + { throw new ArgumentNullException(nameof(settings)); } var file = GetFile(csvFile); using (var stream = file.OpenWrite()) using (var textWriter = new StreamWriter(stream, settings.Encoding)) - using (var csvWriter = new CsvWriter(textWriter)) { - csvWriter.Configuration.RegisterClassMap(classMap); + using (var csvWriter = new CsvWriter(textWriter, CultureInfo.InvariantCulture)) + { + csvWriter.Context.RegisterClassMap(classMap); csvWriter.WriteHeader(); - foreach (var record in records) { + foreach (var record in records) + { csvWriter.WriteRecord(record); } + textWriter.Close(); } } @@ -93,13 +116,19 @@ public void WriteRecords(FilePath csvFile, List records, ClassMap classMap /// The records to write. /// The property column mapping. /// The settings. - public void WriteRecords(FilePath csvFile, List records, Dictionary mapping, - CsvHelperSettings settings) { - if (mapping == null) { + public void WriteRecords( + FilePath csvFile, + IList records, + IDictionary mapping, + CsvHelperSettings settings) + { + if (mapping == null) + { throw new ArgumentNullException(nameof(mapping)); } + var customMap = new DefaultClassMap(); - customMap.AutoMap(); + customMap.AutoMap(CultureInfo.InvariantCulture); WriteRecords(csvFile, records, customMap, settings); } @@ -110,14 +139,20 @@ public void WriteRecords(FilePath csvFile, List records, DictionaryThe CSV file to write. /// The records to write. /// The settings. - public void WriteRecords(FilePath csvFile, List records, CsvHelperSettings settings) { - if (csvFile == null) { + public void WriteRecords(FilePath csvFile, IList records, CsvHelperSettings settings) + { + if (csvFile == null) + { throw new ArgumentNullException(nameof(csvFile)); } - if (records == null) { + + if (records == null) + { throw new ArgumentNullException(nameof(records)); } - if (settings == null) { + + if (settings == null) + { throw new ArgumentNullException(nameof(settings)); } @@ -125,16 +160,20 @@ public void WriteRecords(FilePath csvFile, List records, CsvHelperSettings var file = GetFile(csvFile); using (var stream = file.OpenWrite()) using (var textWriter = new StreamWriter(stream, settings.Encoding)) - using (var csvWriter = new CsvWriter(textWriter)) { + using (var csvWriter = new CsvWriter(textWriter, CultureInfo.InvariantCulture)) + { csvWriter.WriteHeader(); - foreach (var record in records) { + foreach (var record in records) + { csvWriter.WriteRecord(record); } + textWriter.Close(); } } - private IFile GetFile(FilePath path) { + private IFile GetFile(FilePath path) + { var file = path.IsRelative ? path.MakeAbsolute(_environment) : path; return _fileSystem.GetFile(file); } diff --git a/src/Cake.CsvHelper/Properties/AssemblyInfo.cs b/src/Cake.CsvHelper/Properties/AssemblyInfo.cs deleted file mode 100644 index 123232e..0000000 --- a/src/Cake.CsvHelper/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Cake.CsvHelper")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Cake.CsvHelper")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("85c3e531-f53b-4344-9456-1b0176e547da")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Cake.CsvHelper/packages.config b/src/Cake.CsvHelper/packages.config deleted file mode 100644 index 4772a52..0000000 --- a/src/Cake.CsvHelper/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000..64a7a94 --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,82 @@ + + + + + + 10.0 + enable + true + + $(NoWarn);1701;1702;1591 + true + + + + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + all + + + + + + + + diff --git a/src/stylecop.json b/src/stylecop.json new file mode 100644 index 0000000..b892eb0 --- /dev/null +++ b/src/stylecop.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "indentation": { + "indentationSize": 4, + "tabSize": 4, + "useTabs": false + }, + "orderingRules": { + "usingDirectivesPlacement": "outsideNamespace", + "blankLinesBetweenUsingGroups": "allow", + "systemUsingDirectivesFirst": true + }, + "documentationRules": { + "xmlHeader": false + } + } +} \ No newline at end of file diff --git a/tools/packages.config b/tools/packages.config deleted file mode 100644 index e0dd39b..0000000 --- a/tools/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - -