diff --git a/.editorconfig b/.editorconfig index 2bfde114..c434eb53 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,11 +13,11 @@ indent_style = space indent_size = 4 # Xml project files -[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,msbuildproj,props,targets}] indent_size = 2 # Xml config files -[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +[*.{ruleset,config,nuspec,resx,vsixmanifest,vsct}] indent_size = 2 # YAML files @@ -50,16 +50,23 @@ dotnet_style_null_propagation = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion # CSharp code style settings: + +# IDE0040: Add accessibility modifiers +dotnet_style_require_accessibility_modifiers = omit_if_default:error + +# IDE0040: Add accessibility modifiers +dotnet_diagnostic.IDE0040.severity = error + [*.cs] # Prefer "var" everywhere csharp_style_var_for_built_in_types = true:suggestion csharp_style_var_when_type_is_apparent = true:suggestion csharp_style_var_elsewhere = true:suggestion -# Prefer method-like constructs to have a block body -csharp_style_expression_bodied_methods = false:none -csharp_style_expression_bodied_constructors = false:none -csharp_style_expression_bodied_operators = false:none +# Prefer method-like constructs to have an expression-body +csharp_style_expression_bodied_methods = true:none +csharp_style_expression_bodied_constructors = true:none +csharp_style_expression_bodied_operators = true:none # Prefer property-like constructs to have an expression-body csharp_style_expression_bodied_properties = true:none @@ -67,8 +74,8 @@ csharp_style_expression_bodied_indexers = true:none csharp_style_expression_bodied_accessors = true:none # Suggest more modern language features when available -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:error +csharp_style_pattern_matching_over_as_with_null_check = true:error csharp_style_inlined_variable_declaration = true:suggestion csharp_style_throw_expression = true:suggestion csharp_style_conditional_delegate_call = true:suggestion diff --git a/.gitattributes b/.gitattributes index 1ff0c423..7c375796 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,63 +1,24 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto +# sln, csproj files (and friends) are always CRLF, even on linux +*.sln text eol=crlf +*.proj text eol=crlf +*.csproj text eol=crlf -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp +# These are windows specific files which we may as well ensure are +# always crlf on checkout +*.bat text eol=crlf +*.cmd text eol=crlf -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary +# Opt in known filetypes to always normalize line endings on checkin +# and always use native endings on checkout +*.c text +*.config text +*.h text +*.cs text +*.md text +*.tt text +*.txt text -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain +# Some must always be checked out as lf so enforce that for those files +# If these are not lf then bash/cygwin on windows will not be able to +# excute the files +*.sh text eol=lf \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..ef77f215 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +custom: https://paypal.me/kzu +patreon: danielkzu +open_collective: kzu +liberapay: kzu diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..67f75950 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,50 @@ +--- +name: Bug Report +about: Create a report to help us fix a problem. +title: '' +labels: 'bug' +assignees: '' +--- + +## Describe the Bug + + + +## Steps to Reproduce + + + +```c# +public class ReproTest +{ + [Fact] + public void Repro() + { + // arrange + + // act + + // assert + } +} +``` + +## Expected Behavior + + + +## Exception with Stack Trace + + + +```text +Put the exception with stack trace here. +``` + +## Version Info + + + +## Additional Info + + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 00000000..0b3de9db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,33 @@ +--- +name: Feature Request +about: Suggest an idea to make the project better. +title: '' +labels: 'enhancement' +assignees: '' +--- + +## Problem Statement + + + +## Desired Solution + + + +## Alternatives You've Considered + + + +## Additional Context + + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f46fae2..d8ae9593 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,30 +1,75 @@ -name: build +# Builds and runs tests in all three supported OSes +# Pushes CI feed if secrets.SLEET_CONNECTION is provided + +name: build on: push: - branches: [ '*' ] + branches: [ main, dev, 'feature/*', 'rel/*' ] pull_request: types: [opened, synchronize, reopened] + env: DOTNET_NOLOGO: true +defaults: + run: + shell: bash + jobs: build: - runs-on: ubuntu-latest + name: build-${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] steps: - name: 🤘 checkout uses: actions/checkout@v2 + with: + submodules: recursive + fetch-depth: 0 + - name: ⚙ dotnet 5.0.x uses: actions/setup-dotnet@v1 with: dotnet-version: 5.0.x + - name: ⚙ dotnet 3.1.x + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x - name: ⚙ dotnet 2.1.x uses: actions/setup-dotnet@v1 with: dotnet-version: 2.1.x + + - name: ✓ check formatting + run: | + dotnet tool update -g --version 4.1.* dotnet-format >nul || dotnet tool list -g + dotnet format -f src --check -v:diag + - name: 🙏 build - run: dotnet build -p:versionsuffix="$(git name-rev --name-only --refs=refs/heads/* HEAD).$GITHUB_RUN_NUMBER" + run: dotnet build -m:1 -bl:build.binlog -p:VersionLabel="$GITHUB_REF.$GITHUB_RUN_NUMBER" + + - name: 🧪 test + run: dotnet test --no-build -m:1 --blame-hang --blame-hang-timeout 5m -d $GITHUB_WORKSPACE/logs/${{ matrix.os }}.txt -r $GITHUB_WORKSPACE/logs + + - name: 📦 pack + run: dotnet pack -m:1 -bl:pack.binlog -p:VersionLabel="$GITHUB_REF.$GITHUB_RUN_NUMBER" + + - name: 🔼 logs + if: always() + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.os }} + path: | + *.binlog + logs/**/*.* + + # Only push CI package to sleet feed if building on ubuntu (fastest) - name: 🚀 sleet - if: ${{ !github.event.pull_request.head.repo.fork }} + env: + SLEET_CONNECTION: ${{ secrets.SLEET_CONNECTION }} + if: matrix.os == 'ubuntu-latest' && env.SLEET_CONNECTION != '' run: | dotnet tool install -g --version 3.2.0 sleet - sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure" \ No newline at end of file + sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e42d04a3..2f2da4c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,21 +1,53 @@ -name: release +# Builds a final release version and pushes to nuget.org +# whenever a release is published. +# Requires: secrets.NUGET_API_KEY + +name: release on: release: types: [published] + env: DOTNET_NOLOGO: true + Configuration: Release jobs: - push: + build: runs-on: ubuntu-latest steps: - name: 🤘 checkout uses: actions/checkout@v2 + with: + submodules: recursive + fetch-depth: 0 + - name: ⚙ dotnet 5.0.x uses: actions/setup-dotnet@v1 with: dotnet-version: 5.0.x + - name: ⚙ dotnet 3.1.x + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x + - name: ⚙ dotnet 2.1.x + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.1.x + - name: 🙏 build - run: dotnet build -p:version=${GITHUB_REF#refs/*/v} - - name: 🚀 push + run: dotnet build -m:1 -bl:build.binlog -p:version=${GITHUB_REF#refs/*/v} + + - name: 🧪 test + run: dotnet test --no-build -m:1 + + - name: 📦 pack + run: dotnet pack -m:1 -bl:pack.binlog -p:version=${GITHUB_REF#refs/*/v} + + - name: 🔼 logs + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + path: '*.binlog' + + - name: 🚀 nuget run: dotnet nuget push ./bin/**/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{secrets.NUGET_API_KEY}} --skip-duplicate \ No newline at end of file diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index 51420505..3f42147f 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -1,9 +1,11 @@ -name: tag +# Creates a draft release whenever a tag v* is pushed, +# with a changelog from the previous tag. If the tag +# contains a label, the release is flagged as a prerelease. + +name: tag on: push: tags: [ 'v*' ] -env: - DOTNET_NOLOGO: true jobs: release: @@ -24,10 +26,16 @@ jobs: - name: ⚙ changelog uses: faberNovel/github-changelog-generator-action@master + if: env.SINCE_TAG != '' with: - # See https://github.com/github-changelog-generator/github-changelog-generator/wiki/Advanced-change-log-generation-examples options: --token ${{ secrets.GITHUB_TOKEN }} --since-tag ${{ env.SINCE_TAG }} + - name: ⚙ changelog + uses: faberNovel/github-changelog-generator-action@master + if: env.SINCE_TAG == '' + with: + options: --token ${{ secrets.GITHUB_TOKEN }} + - name: 😺 changelog run: cat CHANGELOG.md diff --git a/.gitignore b/.gitignore index aff10638..23fe6bd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,22 @@ -.nuget -.vs -.idea -out bin obj -*.nupkg -*.lock.json -*.nuget.props -*.nuget.targets +artifacts +pack +.vs +.vscode + *.suo +*.sdf +*.userprefs *.user +*.nupkg +*.metaproj +*.tmp *.cache -*.log *.binlog -*.rsp -/src/Usage -/src/Backup -/src/TestResults -dotnet-nugetize.items +*.zip + +.nuget +*.lock.json +*.nuget.props +*.nuget.targets \ No newline at end of file diff --git a/.netconfig b/.netconfig new file mode 100644 index 00000000..e34de777 --- /dev/null +++ b/.netconfig @@ -0,0 +1,92 @@ +[file] + url = https://github.com/kzu/oss +[file "readme.md"] + url = https://github.com/kzu/oss/blob/main/readme.md + skip + etag = 1963a9db5d9ee9a89da7ec5f00c4c7daf10862f10e31583b05716697e7e75526 + weak +[file "src/icon.png"] + url = https://github.com/kzu/oss/blob/main/src/icon.png + skip + etag = 8b42109e3bd1da0fc50c67679c6d20aeac98f922870675e127cf19b8f2919971 + weak +[file ".editorconfig"] + url = https://github.com/kzu/oss/blob/main/.editorconfig + etag = 985aa022503959d35b03c870f07ae604cead7580d260775235ef6665aa9a6cbe + weak +[file ".gitattributes"] + url = https://github.com/kzu/oss/blob/main/.gitattributes + etag = 7acb32f5fa6d4ccd9c824605a7c2b8538497f0068c165567807d393dcf4d6bb7 + weak +[file ".github/FUNDING.yml"] + url = https://github.com/kzu/oss/blob/main/.github/FUNDING.yml + etag = dbc0e0c56e48bf06a70f50ba2fdaf6f048bb81ac8558b743c8e919487da3bfcf + weak +[file ".github/ISSUE_TEMPLATE/bug.md"] + url = https://github.com/kzu/oss/blob/main/.github/ISSUE_TEMPLATE/bug.md + etag = 026852ba1f1921f3a043bb5e09cd7a2c3d9a33ec51f48e524dc3a2ab72de3141 + weak +[file ".github/ISSUE_TEMPLATE/feature.md"] + url = https://github.com/kzu/oss/blob/main/.github/ISSUE_TEMPLATE/feature.md + etag = c5b7de1bc9eaf1f2ae6d1d2021e68084a5b1ab4800e9f129416d2838c128cad1 + weak +[file ".github/dependabot.yml"] + url = https://github.com/kzu/oss/blob/main/.github/dependabot.yml + etag = 2fc8a0d2b47091b058ae3e1f68333492044b49a684621f4939a0bce5bff869d5 + weak +[file ".github/workflows/build.yml"] + url = https://github.com/kzu/oss/blob/main/.github/workflows/build.yml + etag = c56db40b37f8dbcff13aea20eefc263caf825d17d86b0dc055ce504d8cb8ae9d + weak +[file ".github/workflows/release.yml"] + url = https://github.com/kzu/oss/blob/main/.github/workflows/release.yml + etag = fe4eae2bf3738645bca3b8f9f90ace482802fdd818c6d6651dccbb311ebeb231 + weak +[file ".github/workflows/tag.yml"] + url = https://github.com/kzu/oss/blob/main/.github/workflows/tag.yml + etag = 26e271cf76e00c6922552af104b1e496103bdfa75ebef253447594207b10153e + weak +[file ".github_changelog_generator"] + url = https://github.com/kzu/oss/blob/main/.github_changelog_generator + etag = a724e0cbbad99a04e6cd3738a5f3ec5416dd5f29ae7073e7afe5471e73107e42 + weak +[file ".gitignore"] + url = https://github.com/kzu/oss/blob/main/.gitignore + etag = 4698b35abed1f3941de6bed08bc80278c30569de3ead5b878b27b4bb79f8718a + weak +[file "license.txt"] + url = https://github.com/kzu/oss/blob/main/license.txt + etag = 2c6335b37e4ae05eea7c01f5d0c9d82b49c488f868a8b5ba7bff7c6ff01f3994 + weak +[file "security.md"] + url = https://github.com/kzu/oss/blob/main/security.md + etag = 80070e3a380796b13d180b82f43694eac9e7a29d8d2f8549ccb2920fd5c88828 + weak +[file "src/Directory.Build.props"] + url = https://github.com/kzu/oss/blob/main/src/Directory.Build.props + etag = d0b93d7533832a4d62cff69c71540bad3284bf92a7d2096b1a91607d72099d2b + weak +[file "src/Directory.Build.targets"] + url = https://github.com/kzu/oss/blob/main/src/Directory.Build.targets + etag = 87357cb36379ac589c3981bddec4c5f7f89c55356573bd203acbea4b66fe3427 + weak +[file "src/kzu.snk"] + url = https://github.com/kzu/oss/blob/main/src/kzu.snk + etag = b8d789b5b6bea017cdcc8badcea888ad78de3e34298efca922054e9fb0e7b6b9 + weak +[file "code-of-conduct.md"] + url = https://github.com/kzu/oss/blob/main/code-of-conduct.md + etag = 4857c01bb695f09bf6912d778951c3065d9dd565e5de3d0827f40432d0e4c613 + weak +[file ".netconfig"] + url = https://github.com/kzu/oss/blob/main/.netconfig + etag = 42998b33e06eb5c76b14cf6d7582ca3cc49d30421474a5f2b319865afd909dd0 + weak +[file "Directory.Build.rsp"] + url = https://github.com/kzu/oss/blob/main/Directory.Build.rsp + etag = 6a6c6e1d3895df953abf14c82b0899e3eea75cdcd679f6212dcfea15183d73d6 + weak +[file "_config.yml"] + url = https://github.com/kzu/oss/blob/main/_config.yml + etag = c7f2063ead734d0afc383a07c35da2864a221311da8e1c0c6fea8939e932d2ab + weak diff --git a/Directory.Build.rsp b/Directory.Build.rsp new file mode 100644 index 00000000..7c0dbc1e --- /dev/null +++ b/Directory.Build.rsp @@ -0,0 +1,5 @@ +# See https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-response-files +-nr:false +-m:1 +-v:m +-clp:Summary;ForceNoAlign \ No newline at end of file diff --git a/ThisAssembly.sln b/ThisAssembly.sln index 773a368a..19147f7e 100644 --- a/ThisAssembly.sln +++ b/ThisAssembly.sln @@ -9,6 +9,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject src\Directory.Build.props = src\Directory.Build.props src\Directory.Build.targets = src\Directory.Build.targets + src\Directory.props = src\Directory.props + src\Directory.targets = src\Directory.targets readme.md = readme.md EndProjectSection EndProject diff --git a/_config.yml b/_config.yml index c7418817..f980e760 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-slate \ No newline at end of file +theme: jekyll-theme-slate diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 00000000..775f221c --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,6 @@ +# Code of Conduct + +This project has adopted the code of conduct defined by the Contributor Covenant +to clarify expected behavior in our community. + +For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). diff --git a/img/icon-100.png b/img/icon-100.png deleted file mode 100644 index 761c454a..00000000 Binary files a/img/icon-100.png and /dev/null differ diff --git a/img/icon-1200.png b/img/icon-1200.png deleted file mode 100644 index e5cdbf47..00000000 Binary files a/img/icon-1200.png and /dev/null differ diff --git a/img/icon.png b/img/icon.png new file mode 100644 index 00000000..f6162aac Binary files /dev/null and b/img/icon.png differ diff --git a/license.txt b/license.txt index 0498a9a1..83969dca 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ -MIT License +The MIT License (MIT) -Copyright (c) 2020 Daniel Cazzulino +Copyright (c) Daniel Cazzulino and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/security.md b/security.md new file mode 100644 index 00000000..a17430a3 --- /dev/null +++ b/security.md @@ -0,0 +1,9 @@ +# Security Policy + +## Reporting a Vulnerability + +Security issues and bugs should be reported privately by emailing hello@clarius.org. +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your +original message and ping [@kzu](https://twitter.com/kzu) on Twitter. + +Please do not open issues for anything you think might have a security implication. \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 616f2f03..aade2e19 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,42 +1,128 @@ + - + kzu - Copyright 2020 - Daniel Cazzulino + Copyright (C) Daniel Cazzulino and Contributors. All rights reserved. false MIT - icon-128.png - dotnet - - 42.42.42 + icon.png true true - $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\bin)) + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\bin')) + + + true + + https://pkg.kzu.io/index.json;https://api.nuget.org/v3/index.json;$(RestoreSources) + + + + + + - true - analyzers\cs + + Latest + + + false + embedded true - Preview - - false + enable - $(DefaultItemExcludes);*.binlog;*.zip + + $(MSBuildProjectName) + $(MSBuildProjectName.IndexOf('.')) + $(MSBuildProjectName.Substring(0, $(RootNamespaceDot))) - https://pkg.kzu.io/index.json;https://api.nuget.org/v3/index.json;$(RestoreSources) - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\nugetizer\bin'));$(RestoreSources) + + $(DefaultItemExcludes);*.binlog;*.zip;*.rsp;*.items;**/TestResults/**/*.* + + + $(MSBuildThisFileDirectory)kzu.snk + + 002400000480000094000000060200000024000052534131000400000100010051155fd0ee280be78d81cc979423f1129ec5dd28edce9cd94fd679890639cad54c121ebdb606f8659659cd313d3b3db7fa41e2271158dd602bb0039a142717117fa1f63d93a2d288a1c2f920ec05c4858d344a45d48ebd31c1368ab783596b382b611d8c92f9c1b3d338296aa21b12f3bc9f34de87756100c172c52a24bad2db + 00352124762f2aa5 + true + + true + true + true + true + + + true + + + false + + + 42.42.42 + + + + <_VersionLabel>$(VersionLabel.Replace('refs/heads/', '')) + + <_VersionLabel Condition="$(_VersionLabel.Contains('refs/pull/'))">$(VersionLabel.TrimEnd('.0123456789')) + + <_VersionLabel>$(_VersionLabel.Replace('refs/pull/', 'pr')) + + <_VersionLabel>$(_VersionLabel.Replace('/merge', '')) + + <_VersionLabel>$(_VersionLabel.Replace('/', '-')) + + + $(_VersionLabel) + + + + + + + + + + + + false - true + + true - - - - - + + + $(CI) + + + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index e8cae4a7..2b376068 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,65 +1,146 @@ + - - - + + + false + true + + + + + 1.0.0 + $(VersionPrefix)-$(VersionSuffix) + $(VersionPrefix) + + + + + $(PackFolder) + $(PackFolderPath.Replace('\$(TargetFramework)', '')) + $(IntermediateOutputPath)$(PackFolderPath)\ + $(OutputPath)$(PackFolderPath)\ + $(OutputPath) + - + + + $(DefineConstants);$(TargetFramework.ToUpperInvariant().TrimEnd('0').TrimEnd('.').Replace('.', '')) + + + + + + + + - - - + + + + + - + + + + - - + + + + + + + + BeforeTargets="PrepareForBuild;GenerateMSBuildEditorConfigFileShouldRun;GetAssemblyVersion;GetPackageMetadata;GenerateNuspec;Pack" + DependsOnTargets="InitializeSourceControlInformation" + Condition="'$(SourceControlInformationFeatureSupported)' == 'true' And + '$(IsPackable)' == 'true'"> - - $(Description) + $(Description) - Built from $(RepositoryUrl)/tree/$(SourceRevisionId.Substring(0, 9)) +Built from $(RepositoryUrl)/tree/$(SourceRevisionId.Substring(0, 9)) $(Description) - $(RepositoryUrl) - $(Description) - - - - - - - - - @(NuGetPackageId -> Distinct()) - - - - - - @(PackageReferenceDependency -> '%(Pack)') + + $(PrivateRepositoryUrl) + $(RepositoryUrl) + + $(SourceRevisionId) + $(SourceRevisionId.Substring(0, 9)) - - <_PackageFiles Include="@(RuntimeCopyLocalItems)" PackagePath="$(BuildOutputTargetFolder)\$(TargetFramework)\%(Filename)%(Extension)" /> - - - + + + + + + + + + + + + + + + + + + + + i.ItemSpec)) + { + Log.LogMessage(MessageImportance.High, "{0}: {1}", itemName, item.ItemSpec); + foreach (var name in item.MetadataNames.OfType().OrderBy(_ => _)) + { + try + { + Log.LogMessage(MessageImportance.High, "\t{0}={1}", name, item.GetMetadata(name)); + } + catch { } + } + } + ]]> + + + + diff --git a/src/Directory.props b/src/Directory.props new file mode 100644 index 00000000..1adbf5ce --- /dev/null +++ b/src/Directory.props @@ -0,0 +1,21 @@ + + + + + dotnet dotnet-tool dotnet-tools tool + true + analyzers\cs + + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\nugetizer\bin'));$(RestoreSources) + + + + false + false + + + + + + + \ No newline at end of file diff --git a/src/Directory.targets b/src/Directory.targets new file mode 100644 index 00000000..c547958e --- /dev/null +++ b/src/Directory.targets @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ThisAssembly.AssemblyInfo/AssemblyInfoGenerator.cs b/src/ThisAssembly.AssemblyInfo/AssemblyInfoGenerator.cs index 03b7567e..9c25566c 100644 --- a/src/ThisAssembly.AssemblyInfo/AssemblyInfoGenerator.cs +++ b/src/ThisAssembly.AssemblyInfo/AssemblyInfoGenerator.cs @@ -31,8 +31,8 @@ public void Execute(GeneratorExecutionContext context) context.CheckDebugger("ThisAssemblyAssemblyInfo"); var metadata = context.Compilation.Assembly.GetAttributes() - .Where(x => attributes.Contains(x.AttributeClass?.Name)) - .Select(x => new KeyValuePair(x.AttributeClass.Name.Substring(8).Replace("Attribute", ""), (string)x.ConstructorArguments[0].Value)) + .Where(x => !string.IsNullOrEmpty(x.AttributeClass?.Name) && attributes.Contains(x.AttributeClass!.Name)) + .Select(x => new KeyValuePair(x.AttributeClass!.Name.Substring(8).Replace("Attribute", ""), (string?)x.ConstructorArguments[0].Value)) .ToDictionary(x => x.Key, x => x.Value); var model = new Model(metadata); diff --git a/src/ThisAssembly.AssemblyInfo/Model.cs b/src/ThisAssembly.AssemblyInfo/Model.cs index 13adbc84..5ca8055b 100644 --- a/src/ThisAssembly.AssemblyInfo/Model.cs +++ b/src/ThisAssembly.AssemblyInfo/Model.cs @@ -6,10 +6,10 @@ namespace ThisAssembly { public class Model { - public Model(IEnumerable> properties) => Properties = properties.ToList(); + public Model(IEnumerable> properties) => Properties = properties.ToList(); public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(3); - public List> Properties { get; } + public List> Properties { get; } } } diff --git a/src/ThisAssembly.Constants/Model.cs b/src/ThisAssembly.Constants/Model.cs index 45dfbffd..e5b1ff76 100644 --- a/src/ThisAssembly.Constants/Model.cs +++ b/src/ThisAssembly.Constants/Model.cs @@ -73,4 +73,4 @@ static Area GetArea(Area area, IEnumerable areaPath) } [DebuggerDisplay("{Name} = {Value}")] -record Constant(string Name, string Value, string Comment); \ No newline at end of file +record Constant(string Name, string? Value, string? Comment); \ No newline at end of file diff --git a/src/ThisAssembly.Metadata/MetadataGenerator.cs b/src/ThisAssembly.Metadata/MetadataGenerator.cs index 881c5a54..820eb34f 100644 --- a/src/ThisAssembly.Metadata/MetadataGenerator.cs +++ b/src/ThisAssembly.Metadata/MetadataGenerator.cs @@ -19,8 +19,8 @@ public void Execute(GeneratorExecutionContext context) var metadata = context.Compilation.Assembly.GetAttributes() .Where(x => x.AttributeClass?.Name == nameof(System.Reflection.AssemblyMetadataAttribute) && - Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsValidIdentifier((string)x.ConstructorArguments[0].Value)) - .Select(x => new KeyValuePair((string)x.ConstructorArguments[0].Value, (string)x.ConstructorArguments[1].Value)) + Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsValidIdentifier((string)x.ConstructorArguments[0].Value!)) + .Select(x => new KeyValuePair((string)x.ConstructorArguments[0].Value!, (string)x.ConstructorArguments[1].Value!)) .Distinct(new KeyValueComparer()) .ToDictionary(x => x.Key, x => x.Value); diff --git a/src/ThisAssembly.Project/ProjectPropertyGenerator.cs b/src/ThisAssembly.Project/ProjectPropertyGenerator.cs index 05b9a26b..3cd11979 100644 --- a/src/ThisAssembly.Project/ProjectPropertyGenerator.cs +++ b/src/ThisAssembly.Project/ProjectPropertyGenerator.cs @@ -21,7 +21,7 @@ public void Execute(GeneratorExecutionContext context) return; var metadata = properties.Split('|') - .Select(prop => new KeyValuePair(prop, + .Select(prop => new KeyValuePair(prop, context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property." + prop, out var value) ? value : null)) .Where(pair => pair.Value != null) @@ -38,13 +38,13 @@ public void Execute(GeneratorExecutionContext context) context.AddSource("ThisAssembly.Project", SourceText.From(output, Encoding.UTF8)); } - class KeyValueComparer : IEqualityComparer> + class KeyValueComparer : IEqualityComparer> { - public bool Equals(KeyValuePair x, KeyValuePair y) + public bool Equals(KeyValuePair x, KeyValuePair y) => x.Key == y.Key && x.Value == y.Value; - public int GetHashCode(KeyValuePair obj) - => new HashCode().AddRange(obj.Key, obj.Value).ToHashCode(); + public int GetHashCode(KeyValuePair obj) + => new HashCode().AddRange(obj.Key, obj.Value ?? "").ToHashCode(); } public static string[] GetItems(GeneratorExecutionContext context) diff --git a/src/ThisAssembly.Strings/Model.cs b/src/ThisAssembly.Strings/Model.cs index d866bbd3..78f7ff89 100644 --- a/src/ThisAssembly.Strings/Model.cs +++ b/src/ThisAssembly.Strings/Model.cs @@ -14,7 +14,7 @@ record Model(ResourceArea RootArea, string ResourceName) static class ResourceFile { - private static Regex FormatExpression = new Regex("{(?[^{}]+)}", RegexOptions.Compiled); + static readonly Regex FormatExpression = new Regex("{(?[^{}]+)}", RegexOptions.Compiled); public static ResourceArea Load(string fileName, string rootArea) { @@ -105,18 +105,18 @@ static ResourceValue GetValue(string resourceName, string resourceValue) record ResourceArea(string Name, string Prefix) { public List NestedAreas { get; init; } = new List(); -public List Values { get; init; } = new List(); + public List Values { get; init; } = new List(); } [DebuggerDisplay("{Name} = {Value}")] -record ResourceValue(string Name, string raw) +record ResourceValue(string Name, string? Raw) { - public string Value => raw?.Replace(Environment.NewLine, "")?.Replace("<", "<")?.Replace(">", ">"); -public string Comment { get; init; } -public bool HasFormat => Format != null && Format.Count > 0; -// We either have *all* named or all indexed. Can't mix. We'll skip generating -// methods for mixed ones and report as an analyzer error on the Resx. -public bool IsNamedFormat => HasFormat && Format.All(x => !int.TryParse(x, out _)); -public bool IsIndexedFormat => HasFormat && Format.All(x => int.TryParse(x, out _)); -public List Format { get; } = new List(); + public string? Value => Raw?.Replace(Environment.NewLine, "")?.Replace("<", "<")?.Replace(">", ">"); + public string? Comment { get; init; } + public bool HasFormat => Format != null && Format.Count > 0; + // We either have *all* named or all indexed. Can't mix. We'll skip generating + // methods for mixed ones and report as an analyzer error on the Resx. + public bool IsNamedFormat => HasFormat && Format.All(x => !int.TryParse(x, out _)); + public bool IsIndexedFormat => HasFormat && Format.All(x => int.TryParse(x, out _)); + public List Format { get; } = new List(); } \ No newline at end of file diff --git a/src/icon.png b/src/icon.png new file mode 100644 index 00000000..f6162aac Binary files /dev/null and b/src/icon.png differ diff --git a/src/kzu.snk b/src/kzu.snk new file mode 100644 index 00000000..8e181aea Binary files /dev/null and b/src/kzu.snk differ